为什么WordPress仍然使用addslashes(),register_globals()和magic_quotes?
为了获得更多的Wordpress经验,我深入研究了它的代码库来研究它的内部工作和工作stream程,当我看到这些时,我感到非常惊讶:
-
他们实现了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中得到,在引导之前closuresmagic_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 ); }
- 它们依赖于addslashes(但是自2.8.0以来,它们也引入了mysql_real_escape_string,但是使用
addslashes()
的_weak_escape()
函数仍然存在于wpdb类中)
更新:我看到他们通过使用sprintf()
和自定义占位符模拟准备好的语句,所以查询应该是安全的,我认为。 尽pipe如此,我仍然不明白为什么他们不提供至lessmysqli,毕竟MySQL和PHP版本的检测发生在引导顺序的早期 。
现在,从一年多的时间里,我学到了很多东西,尤其是以上三个function是“不推荐”,显示出安全问题,并且被很多人惊恐地看着。
但是WP必须有一个使用它们的理由。 我想从更有经验的程序员那里知道是否存在真正的安全问题,或者有时候他们的使用过于谣言和虚假的说服。 我知道magic_quotes是过去的传统,同样可以用于addslashes(至less在用于数据库时),但是在问这个问题之前,我发现很多网站都在讨论在mysql_real_escape_string()上使用addslashes()。
我有兴趣了解为什么使用那些描述得不好的function的明确而详细的原因; WordPress多年来有了很多改进,解决了不同的方面,但是这些function仍然被使用; 因此,我正在寻求对积极方面的具体解释,以某种方式超越消极方面,并certificate这些function的使用是合理的。
我不是在寻找意见(我完全知道他们是在这里offtopic),也不是我咆哮WordPress的,我希望这是明确的。 我只想知道为什么许多PHP程序员认为这些function“不好”,而像Wordpress这样的全球巨人现在仍然在使用第三版。
这是为了兼容不同的服务器和PHP版本? (虽然他们检查非常伯爵)。
有什么我想念这个function,他们可以在像wordpress(或一般)的环境中有多重要? 我很困惑,说实话。
( 随着时间的推移Wordpress开放票 )
不要依赖Wordpress代码库来对PHP编码中的良好实践或当前标准进行假设。 我把这个说成是一个长期以来一直在wordpress开发中摆弄的人。
WordPress的代码库大约有10年历史,它充满了传统代码[1] 。 程序无法在代码级进化,因此,您可以find很多解决方法,以解决当今已经解决的问题。
只要看看这个故事:PHP有神奇的引号。 WordPress开发者认为这很有用。 所以对于那些没有configuration的主机,他们添加了它。 结束了预期经常在各个地方削减input数据的代码。 简单的说就是,现在他们几乎无处不在,因为使用引入静态全局状态的(超)全局variables,所以他们不能轻易地将其改变为适当的input处理和消毒。
你不能轻易重构这样的代码。
数据库类相同。 它有很长的历史,最初基于ezSQL的早期版本。 当时没有mysql_real_escape_string
,当它被引入时,WP开发者有问题,并不是所有的安装基础都支持它。
所以不要怀疑你在WordPress代码中find的编码习惯。 您将了解到多年前可能已经完成的事情以及多less已经过时的PHP版本。 例如,不久之前,Wordpress切换到PHP 5。
- 向后兼容。
- 定位大量(技术上或多或less过时的)主机。
- 不要打破与缺陷有关的东西。
这可能不是你的优先事项清单(希望),项目不同这里很多。 但是无论项目的优先级如何设置,单独使用遗留的代码库都是一个负担。 WordPress的只是一个例子。
[1]参见WordPress的里程碑:早期项目时间表(约2000年至2005年) )
补充@tom的答案。
魔术行情
自动parsing整个条目并添加魔术引号既是造成错误也是无用的。
- 无用的,因为你不能依靠魔术引号来保护你的input(例如SQL注入的多字节编码错误)。 因此,在将数据保存到数据库之前,您需要应用真实的filter
- 创build错误:如果你需要在数据库保存之前真的逃避你的数据,你必须检查它是否已经被转义了(这个设置存在并且可能由宿主环境强制执行的简单事实使得你必须检查这个设置是设置与否)。
- 创build错误:用户发送的所有数据并不总是专用于数据库存储。 转义它可能会破坏内容,例如考虑一个json内容,甚至用危险的magic_quote_runtime
- 创build错误:所有数据库存储都不是以同样的方式转义引号
那么为什么? 为什么我们在CMS中看到这样的function?
- 看到这里是一个
add_magic_quotes
函数,可以在专用数组上使用,也许不在_GET或_POST上。 但事实上,这个函数只是使用addslashes而不是数据库专用函数,这使得它非常糟糕。 - 托pipe服务提供商可能会强制执行一个自动魔术引用的事实是一个CMS开发人员的噩梦。 要么你发现它,并告诉用户你拒绝运行,或者你必须pipe理的内容可能会或可能没有神奇的东西……并把所有人都放在同一个状态,你运行非增加内容在这个函数中,至less每个人都处于相同(不好)的状态。
- 从我在Wordpress上可以看到的,在保存之前在wp_insert_post中执行
stripslahes_deep
。 而add_magic_quotes通常是在数据发送到wp_insert_post之前,从Db提取的数据上执行的。 这可能是我认为问题是有效的删除它们之前添加斜杠…也许是因为清理filter发生在保存期望的内容与斜线之前,或者因为没有人记得为什么代码运行在这种方式:-)
register_globals的
似乎这是在wordpress中实现registry模式的方法…他们希望简化代码,并允许一种简单的方式来访问查询或post之类的重要对象。 面向对象的registry类不是简单的PHP方式 ,其中$_GLOBALS
数组已经是一个现有的registry。
拥有registry在应用程序中是完全有效的。 只有当你允许一些用户input覆盖你有效的安全input时,register_global才是危险的。 当然,只有当这个安全的input来自其他地方的$_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;
所以至less这些全局variables不能被用户input覆盖,并且是安全的 。
所以,这些function是不好的。 但是,如果你了解他们做了什么以及你需要做什么来防止不良影响,你可以使用它们。 而当你想为开发者实现一个简单的框架时,你可能需要在非常广泛的环境中使用它们。
但肯定这是一个不好的做法,你可以肯定地发现使用$ _GLOBALS错误的wordpress插件或滥用add_magic_quotes to data pulled from db
wordpress概念add_magic_quotes to data pulled from db
。 但Zend Framework CMS获得如此大量的贡献还有好几年的时间。
魔术行情
以下文字摘自PHP.net
http://www.php.net/manual/en/security.magicquotes.why.php
没有理由使用魔术引号,因为它们不再是PHP的支持部分。 然而,他们确实存在,并帮助一些初学者幸福,不知不觉地写出更好(更安全)的代码。 但是,在处理依赖此行为的代码时,最好更新代码而不是打开魔术引号。 那么为什么这个function存在? 简单,帮助防止SQL注入。 今天,开发人员更好地了解安全性,并最终使用数据库特定的转义机制和/或准备好的语句,而不是依赖像魔术引号这样的function。
addslashes()vs mysql_real_escape_string()
你应该使用mysql_real_escape_string()
的原因是因为它是一个“MySQL函数”,它是在mysql查询执行之前为逃避用户input而创build的,而addslashes()
是一个“PHP函数”。 这可能听起来有点奇怪,但是两者之间有一个重要的区别,它与使用单字节和多字节字符有关。 您仍然可以注入由addslashes函数保护的数据库,但注入由mysql_real_escape_string保护的数据库要困难得多。 你可以在这里阅读更多关于它
注册全局
你不应该使用register_globals
的原因是因为variables对所有人都是可访问的,这意味着在下面的例子中,如果以前没有初始化,那么你可以将$ access设置为true
<?php if (isAuthenticated()) { $access = true; } if ($access == true) { include(controlpanel.php); } ?>
上面的代码会给你sh#! 大量的问题,但如果我们首先通过将以下内容添加到页面顶部来初始化variables
$access = false;
…即使我们有register_globals ON,我们也应该没问题
所以,如果WordPress的团队已经初始化所有的variables(他们可能有),那么你不必担心使用全局variables。
结论
使用这三种function/特性中的任何一种都绝对是不好的做法,我绝不会自己做。 你确定你正在使用最新版本的WordPress? 就像有人评论的那样,如果你使用的是最新版本,那是因为懒惰或者更糟,它仍然在那里。 我从来没有使用Wordpress除了不需要太多安全性的博客以外的其他任何东西。
WordPress的。 我花了很多不眠之夜试图回答唯一的问题:“为什么?
由于我面对它的源代码,我讨厌它。 太糟糕了。 而且让我的职位(以及名誉)将被利用,但这是事实。
它没有核心。 有代码的垃圾,而不是核心。 它提醒了php3。 大量的无关和不合逻辑的function被使用在其中。 “复制和粘贴” – wordpress中唯一使用的devise模式。
是的,模仿使用了准备好的陈述。 但为什么他们不使用PDO或mysqli? 他们已经拷贝了几乎所有的PDOfunction,但没有使用它。 使用mysqli而不是mysql需要更less的努力。
他们使用myql_real_escape_string。 但是仍然有些东西像protect_string_strongly
, protect_string_weakly
。 不只有一个函数 – do_not_protect_string_i_believe_my_users
。
全局variables – 是wordpress的哲学。 “如果我们不知道如何改变这个variables,我们会把它标记为全局variables,每个人都会很高兴。” – 这是wordpress开发者在开发hellpress的时候所认为的。
每个新版本都包含了很多新的devise,它们添加了新的默认主题,它们将admin区域中的背景颜色从#ccc更改为#cdcdcd,它们使用pipe理区域中的下拉菜单而不是accordeon。 它真棒。 但是他们没有改进它的代码。
你有没有阅读WP“核心”的评论? 没有? 我做了。 他们很棒”。 就像“这个函数被调用了什么?让它离开以防万一”。 或者“不要在新版本中硬编码”。 等等。
唯一的答案是“为什么? 我得到的是:“因为它工作,如果它工作,不要碰它!”
wordpress.org是世界上访问量最大的网站之一。 为什么? 因为没有人能够理解wordpress的逻辑。 每个人每次都需要在论坛上问一些问题或者阅读法典。
我希望你能理解我的观点。
没有比在magic_quotes
上引用PHP文档更好的方法来回答它们的原因了:
- 为什么我们使用魔术语录?
- 为什么不使用魔术引号
另请注意:
从PHP 5.3.0起,此function已被拒绝。 依靠这个function是非常沮丧的。
那么为什么Wordpress仍然使用魔术引号?
WordPress的最低要求使用PHP 4.3 。 是的,这绝对是一个向后兼容的原因。
其他function呢?
我真的不确定。 依靠超级全局是一个非常糟糕的主意。 这只是懒惰的Wordpress开发团队。 也许他们有更重要的问题要处理。
他们这样做是有原因的:
确保Wordpress与大多数虚拟主机提供商兼容。
问这样一个问题,这是错误的地方。
问一些第三方人其他人的原因总是一个坏主意。
很明显,你不能在这里得到答案,除非你会用这样的奖金引诱一些授权的WordPress开发者。
然而你的问题太广泛了。 但是,可以回答它的抽象部分:
我想从更有经验的程序员那里知道是否存在真正的安全问题,或者有时候他们的使用过于谣言和虚假的说服。
洗手真的能预防疾病吗?
如果我不洗手,我肯定会生病吗?
大部分时间 – 没有。
作为一个普遍的习惯 – 是的。
这些特征(虽然的确如同我们不幸的语言的任何其他特征,都笼罩在谣言中)仅仅是每个人都必须遵循的卫生作为基本的本能。
虽然大部分时间…
- 只要你的编码是utf-8或任何单字节的,addslashes就不会造成任何伤害;
- 如果初始化所有variables,注册全局variables不会造成任何伤害;
- 只要你的SQL引用了所有的variables,并且删除了用于其他任何用途的斜杠,魔术引号就不会造成任何伤害;
…从这些情况下的任何例外可以使你生病的概率很高。
mysql_real_escape_string()和addslashes之间的主要区别之一是mysql_real_escape_string()与字符集一起工作,所以它知道如何正确地转义基于字符集的数据。
一般来说,我认为最好的方法是使用请求类,并在那里做所有的东西。 这样,只有一个地方,你处理GET,POST,COOKIE,SERVER等,这使得它更容易pipe理,而不是一堆随机函数做不同的事情。 这只是一场灾难。