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'];
}
  • echo
    将变量转换为HTML时,将其包装在
    htmlentities()中
  • 将其放入mysql时,至少要使用准备好的语句或
    mysql\u real\u escape\u string()
  • echo
    将变量转换为Javascritpt代码时,使用
    json\u encode()

Joel Spolsky在

中提供了一些不错的入门建议,刚刚在上发现了这一点,看起来是一种非常聪明的剥离em的方法(处理键和值…):

和的预处理语句是防止SQL注入的更好方法

但是,如果您要迁移基于每个SQL查询的魔引号的遗留代码,您可以参考在PHP5.4以上版本的环境中实现魔引号


我是手册上那个注释的作者,只是别忘了,因为我们使用的是
JSON\u HEX\u APOS
常量,所以这个解决方案只与PHP5.3及以上版本兼容,更多信息请参见这个问题()。除了PHP6从未看到曙光。非常棒的快速故障。我不知道!