问题描述
为了获得更多的 WordPress 的经验,我深入其代码基础来研究其内部工作及其工作流程,当我看到这一点时,我感到非常惊讶:
-
他们实施 register_globals(摘自 wp-includes /class-wp.php):
// The query_vars property will be extracted to the GLOBALS. So care should // be taken when naming global variables that might interfere with the // WordPress environment. function register_globals() { global $wp_query; // Extract updated query vars back into global namespace. foreach ( (array) $wp_query->query_vars as $key => $value) { $GLOBALS[$key] = $value; }
-
它们依赖于魔术引号 (从 wp-includes /functions.php 发出) 。在调用此函数之前,magic_quotes_gpc 在引导时被关闭):
function add_magic_quotes( $array ) { foreach ( (array) $array as $k => $v ) { if ( is_array( $v ) ) { $array[$k] = add_magic_quotes( $v ); } else { $array[$k] = addslashes( $v ); }
-
它们依赖于 addslash(但是从 2.8.0 起,他们还引入了 mysql_real_escape_string,但是使用
addslashes()
的_weak_escape()
函数仍然存在于 wpdb 类中)UPDATE:我看到他们通过使用sprintf()
和自定义放置器来模拟准备好的语句,所以查询应该是安全的认为。仍然我很困惑,为什么他们至少不提供 mysqli,所有的检测 Mysql 和 PHP 版本发生在引导序列的早期。
现在,从 year-long 的经验中我学到了很多东西,特别是上述三个功能都是”deprecated”,显示安全问题,被许多人惊恐地看着。
但 WP 必须有理由使用它们。如果有真正的安全问题,或者有时候他们的使用在传闻和虚假的说服中太多了,我想从更有经验的程序员那里知道。我知道 magic_quotes 是过去的遗产,对于 addslash 也可以这样说 (至少用于数据库的时候),但是在发问之前,我发现许多网站都在谈论在 mysql_real_escape_string() 上使用 addslashes() 。
我有兴趣了解为什么使用这些功能很差的功能的清晰详细的原因; WordPress 多年来取得了许多改进,处理不同的方面,但这些功能仍然被使用; 因此,我正在寻找一个具体的解释,积极的方面,以某种方式超越负面的,并证明使用这些功能。
我不是在寻找意见 (我完全知道他们在这里是偏执的),也不是我对 Wordpress 的愤怒,我希望这是清楚的。我只想知道为什么许多 php 程序员认为这些功能”bad”,而一个像 Wordpress 这样的世界级巨头,现在在第三版,仍然使用它们。
这是为了兼容不同的服务器和 php 版本? (他们检查非常耳朵,但是) 。有一些我想念的功能,他们可以在一个如 WordPress(或一般) 的环境中有多重要?老实说,我很困惑
最佳解决方案
(WordPress Open Tickets over Time)
不要依靠 Wordpress 代码库对 PHP 编码中的良好做法或现行标准做假设。我在说这是一个在更长一段时间内发生了 wordpress 发展的人。
WordPress 代码库大约是 10 岁,它的遗留代码 [1] 。该程序不能在 code-level 上发展,因为这样,所以你发现很多解决方案已经解决了现在好多了。
只要讲这个故事:PHP 有魔术报价。 WordPress 开发人员认为这是有用的。所以对于没有配置的那些主机,他们添加了它。结束希望经常和在不同地方削减输入数据的代码。简单的是,现在,由于 (超级) 全局变量在几乎无处不在的情况下引入静态全局状态,所以现在他们不能轻易地将其改变为适当的输入处理和消毒。
你不能轻易地重构这样的代码。
相同的数据库类。它具有悠久的历史,最初基于 ezSQL 的早期版本。当时没有 mysql_real_escape_string
,当它被介绍时,WP 开发人员的问题是并不是所有的安装基础都支持它。
所以不要怀疑你在 Wordpress 代码中找到的编码实践。你将会学到如何在几年前完成的工作,以及多少或更少的过时的 PHP 版本。不久之前,Wordpress 转为 PHP 5 。
-
向后兼容性
-
瞄准大量 (技术上或多或少过时的) 主机。
-
不要打破有缺陷的工作。
这可能不是您的优先事项列表 (希望),项目在这里有很多不同。不管单独使用遗留 code-base 如何设置项目优先级都是一种负担。 WordPress 只是一个例子。
[1] 看到 WordPress 的里程碑:早期项目时间表 (约 2000 年至 2005 年))
次佳解决方案
补充 @tom 答案。
魔术报价
自动解析整个条目并添加魔术引号都是创建错误和无用的。
-
无用,因为您无法依靠魔术引号来保护您的输入 (multy-bytes 编码错误 SQL 注入是一个例子) 。因此,在将数据保存到数据库之前,需要应用一个实际的过滤器
-
创建错误:如果您需要在数据库中保存之前真正转义数据库,那么您必须检查它是否已经被转义 (并且这个设置存在的简单事实可能由托管环境执行,这样您必须检查此设置是否为设置或不设置) 。
-
创建错误:用户发送的所有数据并不总是专用于数据库存储。逃避它可能会破坏内容,想想一个 json 内容,甚至文件内容与危险的 magic_quote_runtime
-
创建错误:所有数据库存储不会以相同的方式转义引号…
那么为什么?为什么我们在 CMS 中看到这样的功能?
-
看到这里是一个
add_magic_quotes
功能,可以在专用阵列上使用,也可能不在_GET 或_POST 上。但实际上这个功能只是使用 addslashes 而不是数据库专用功能,这使得它非常糟糕。 -
主机提供商可能会强制执行自动魔术引用的事实是 CMS 开发人员的噩梦。您可以检测到它,并告诉用户您拒绝运行,或者您必须管理内容可能或可能不是 magically-addslahed … 并将每个人都处于相同状态的事实,则在此功能中运行 non-addslashed 内容至少每个人都处于同一 (坏) 状态。
-
从 Wordpress 中可以看到的,在 wp_insert_post 中执行保存
stripslahes_deep
之前。通常在将数据发送到 wp_insert_post 之前,从 Db 提取的数据执行 add_magic_quotes 。这可能我认为问题是有效地删除它们之前添加斜杠… 可能是因为在保存之前发生的消除过滤器预期内容与斜杠,或者也许是因为没有人记住为什么代码以这种方式运行:-)
register_globals
似乎这是在 wordpress 中实现注册表模式的方法… 他们希望使代码变得简单易懂,并允许一种简单的方式来访问诸如查询或帖子的 important 对象。而面向对象的 Registry 类不是简单的 PHP 方式,$_GLOBALS
数组已经是现有的注册表。
拥有注册表是应用程序中完全有效的东西。只有当您允许某些用户输入覆盖您的有效安全输入时,register_global 才是危险的。当然,只有在 $_GLOBALS
在其他地方 (或使用 global
关键字) 进行此安全输入。
这里功能中的危险部分是您提取的功能的一部分,$query->query_vars
上的循环。您将必须跟踪呼叫,以查看用户注入的密钥是否可以通过 wp_parse_args
并在该功能中结束。但这个功能的下一部分是为几个对象修复 $_GLOBALS
内容:
$GLOBALS['query_string'] = $this->query_string;
$GLOBALS['posts'] = & $wp_query->posts;
$GLOBALS['post'] = (isset($wp_query->post)) ? $wp_query->post : null;
$GLOBALS['request'] = $wp_query->request;
所以至少这些全局变量不能被用户输入覆盖并且是安全的。
所以这些功能不好。但是,如果您了解他们的工作以及您需要做什么来防止不良影响,您可以使用它们。而当您想为开发人员实施一个简单的框架时,可以在非常宽的环境中使用,您有时需要使用它们。
但是肯定这是一个糟糕的做法,你肯定会发现使用 $ _GLOBALS 错误的方式或滥用 add_magic_quotes to data pulled from db
wordpress 概念的坏 wordpress 插件。但是,Zend Framework CMS 将有多年才能获得如此大量的贡献。
第三种解决方案
魔术报价
The following text is taken from PHP.net
http://www.php.net/manual/en/security.magicquotes.why.php
There is no reason to use magic quotes because they are no longer a supported part of PHP. However, they did exist and did help a few beginners blissfully and unknowingly write better (more secure) code. But, when dealing with code that relies upon this behavior it’s better to update the code instead of turning magic quotes on. So why did this feature exist? Simple, to help prevent SQL Injection. Today developers are better aware of security and end up using database specific escaping mechanisms and/or prepared statements instead of relying upon features like magical quotes.
addslashes()vs mysql_real_escape_string()
您应该使用 mysql_real_escape_string()
的原因是因为它是一个”MySQL function”,是专门为在 mysql 查询执行之前转义用户输入而创建的,而 addslashes()
是一个”PHP function” 。这可能听起来有点奇怪,但两者之间有一个重要的区别,它与使用单和 multi-byte 字符有关。您仍然可以注册数据库受保护的 addslashes 功能,但注入数据库受 mysql_real_escape_string 保护是非常困难的。你可以阅读更多关于它的 HERE
注册全局
您不应该使用 register_globals
的原因是因为变量可供所有人访问,这意味着在以下示例中,您可以将 $ access 设置为 true,如果尚未初始化
<?php
if (isAuthenticated()) { $access = true; }
if ($access == true) {
include(controlpanel.php);
}
?>
上面的代码会给你 sh#!负载的问题,但如果我们初始化变量,首先添加以下到页面的顶部
$access = false;
即使我们有 register_globals,我们也应该很好
所以,如果 Wordpress 团队已经初始化了所有变量 (他们可能拥有的),那么你不必担心使用全局变量。
结论
这是绝对不好的做法,使用这 3 个功能/功能,我永远不会自己做。您确定使用最新版本的 Wordpress 吗?像有人评论说,如果你使用最新版本,那是因为懒惰,或者更糟糕的是它仍然在那里。我永远不会使用 Wordpress,除了不需要很多安全性的博客以外的任何东西。
第四种方案
WordPress 的。我花了很多不眠之夜试图回答唯一的一个问题:”Why??”
由于我遇到了源代码,所以我讨厌它。太可怕了让我的帖子 (以及声誉) 也将被微调,但它是真实的。
它没有核心有一个垃圾的代码而不是核心。它提醒了 php3 。在这里使用了大量无关和不统一的功能。 「复制和粘贴」 – 在 wordpress 中使用的唯一一种设计模式。
是的,仿效使用准备好的语句。但是为什么他们不使用 PDO,还是 mysqli?他们已经将几乎所有的 PDO 功能进行了复制,但是却没有使用它。使用 mysqli 代替 mysql 需要更少的努力。
他们使用 myql_real_escape_string 。但是还有一些像 protect_string_strongly
,protect_string_weakly
这样的东西。不仅仅有一个功能 – do_not_protect_string_i_believe_my_users
。
全局变量 – 是 wordpress 的哲学。 「如果我们不知道如何改变这个 var,我们会把它标记为全局变量,每个人都会高兴。」 – 这是开发人员在开发 hellpress 时想到的 wordpress 开发者。
每个新版本都包含了很多新的设计,它们添加了新的默认主题,它们将管理区域中的背景颜色从 #ccc 更改为 #cdcdcd,它们在管理区域中使用下拉菜单而不是通配符。而且真棒但是它们并没有改进其代码。
你看过 WP “core” 的评论吗?没有?我做了他们是”awesome” 。像 「这个功能叫什么」 呢?让我们来吧,以防万一。 「或 「不要在新版本中硬编码」 。等等。
问题”Why?” 的唯一答案是:「因为它的工作,如果它的工作不要碰它!!!」
wordpress.org 是世界上最受欢迎的网站之一。为什么?因为没有人能够理解 wordpress 的逻辑。每个人每次都需要在论坛上提出问题,或者阅读这些法规。
我希望你明白我的观点。
第五种方案
没有比 magic_quotes
提到 PHP 文档更好的方法来回答他们为什么不好。
另请注意:
This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged.
那么为什么 Wordpress 仍然使用魔术报价?
WordPress minimum requirements 使用 PHP 4.3 。是的,这绝对是向后兼容的原因。
其他功能怎么样?
我老实说不确定依靠超级全局是一个非常坏的主意。这是 Wordpress 开发团队的简单懒惰。也许他们有更重要的问题需要解决。
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。