PHP中的神奇引号
根据,为了使代码更具可移植性,他们建议使用以下方法来转义数据:PHP中的神奇引号,php,security,magic-quotes,Php,Security,Magic Quotes,根据,为了使代码更具可移植性,他们建议使用以下方法来转义数据: if (!get_magic_quotes_gpc()) { $lastname = addslashes($_POST['lastname']); } else { $lastname = $_POST['lastname']; } 我还将执行其他验证检查,但就转义数据而言,上述检查的安全性如何?我还看到,在PHP6中,magic quotes将被弃用。这将如何影响上述代码?我不希望依赖于特定于数据库的转义函数,
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
我还将执行其他验证检查,但就转义数据而言,上述检查的安全性如何?我还看到,在PHP6中,magic quotes将被弃用。这将如何影响上述代码?我不希望依赖于特定于数据库的转义函数,如mysql\u real\u escape\u string()。神奇的引号天生就是不正确的。它们旨在清理PHP脚本的输入,但如果不知道如何使用该输入,就不可能正确清理。如果有的话,最好先检查是否启用了magic quotes,然后在$\u GET/$\u POST/$\u COOKIES/$\u请求上调用stripslashes(),然后在某个地方使用变量时对其进行清理。例如,如果在URL中使用urlencode(),如果将其打印回网页,则使用htmlentities(),如果将其存储到数据库,则使用数据库驱动程序的转义函数。请注意,这些输入数组可能包含子数组,因此您可能需要编写一个函数,该函数可以递归到子数组中,以去除这些斜杠 菲律宾政府同意: “此功能已被弃用为 从PHP 5.3.0开始,从PHP开始删除 5.4.0.不鼓励依赖此功能。Magic Quotes是 自动逃逸的过程 PHP脚本的传入数据。它是 喜欢用神奇的引号编码 关闭,而不是在 运行时,视需要而定。”
对,这不是最好的方法,也不是最安全的方法。逃跑最好是根据你逃跑的目的。如果要存储在mysql数据库中,请使用mysql\u real\u escape\u字符串,该字符串考虑了其他地区、字符集。对于HTML,htmlentities。用于代码中的escapeshellcmd、escapeshellarg。是的,如果启用了magic quotes,您可能需要首先使用stirpslashes。但最好不要指望它或使用它 我在我的网站的头文件中使用了以下代码来逆转magic_quotes的效果:
<?php
// Strips slashes recursively only up to 3 levels to prevent attackers from
// causing a stack overflow error.
function stripslashes_array(&$array, $iterations=0) {
if ($iterations < 3) {
foreach ($array as $key => $value) {
if (is_array($value)) {
stripslashes_array($array[$key], $iterations + 1);
} else {
$array[$key] = stripslashes($array[$key]);
}
}
}
}
if (get_magic_quotes_gpc()) {
stripslashes_array($_GET);
stripslashes_array($_POST);
stripslashes_array($_COOKIE);
}
?>
然后我就可以编写代码的其余部分,就好像魔术师的引号从未存在过一样。关于使用特定于数据库的转义函数,您几乎需要这样做。我发现在MySQL中使用
addslashes()
很少失败。您可以编写一个函数来转义,该函数确定您正在使用的数据库,然后使用适当的转义函数。“我不希望依赖特定于数据库的转义函数,如mysql\u real\u escape\u string()
然后用类似的方法。但无论如何,你必须扭转魔法引号造成的伤害。魔法引号是一个设计错误。它们的使用与保持你的理智是不相容的 我更喜欢:
if (get_magic_quotes_gpc()) {
throw new Exception("Turn magic quotes off now!");
}
不要编写与固有的坏设置兼容的代码。相反,通过使用您的代码来阻止它们的使用。您可以尝试以下方法:
if (get_magic_quotes_gpc()) {
$_REQUEST = array_map('stripslashes', $_REQUEST);
$_GET = array_map('stripslashes', $_GET);
$_POST = array_map('stripslashes', $_POST);
$_GET = array_map('stripslashes', $_COOKIES);
}
“我希望不必依赖mysql\u real\u escape\u string()等特定于数据库的转义函数。”
此外,addslashes也可能被欺骗,请查看以下帖子:
将PHP 5.2或更高版本的要求放在代码中,然后使用。
filter.*
函数直接访问原始输入数据(它们从不触摸$\u POST
等),因此它们完全不受magic\u quotes\u gpc
的影响
然后这个例子:
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
可以变成这样:
$lastname = filter_input(INPUT_POST, 'lastname');
您的示例代码是反向的,您应该执行以下操作:
if (get_magic_quotes_gpc()) {
$lastname = stripslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
请注意,这会让您的输入数据保持与用户键入的完全相同的“原始”状态—没有额外的反斜杠,并且可能会加载SQL注入和XSRF攻击—这正是您想要的。然后,确保始终使用以下选项之一:
if (get_magic_quotes_gpc()) {
$lastname = stripslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
- 当
将变量转换为HTML时,将其包装在echo
htmlentities()中
- 将其放入mysql时,至少要使用准备好的语句或
mysql\u real\u escape\u string()
- 当
将变量转换为Javascritpt代码时,使用echo
json\u encode()
Joel Spolsky在中提供了一些不错的入门建议,刚刚在上发现了这一点,看起来是一种非常聪明的剥离em的方法(处理键和值…): 和的预处理语句是防止SQL注入的更好方法 但是,如果您要迁移基于每个SQL查询的魔引号的遗留代码,您可以参考在PHP5.4以上版本的环境中实现魔引号
我是手册上那个注释的作者,只是别忘了,因为我们使用的是
JSON\u HEX\u APOS
常量,所以这个解决方案只与PHP5.3及以上版本兼容,更多信息请参见这个问题()。除了PHP6从未看到曙光。非常棒的快速故障。我不知道!