简体   繁体   English

magic_quotes_gpc()的解毒剂?

[英]Antidote for magic_quotes_gpc()?

I've seen dozens of PHP snippets that go like this: 我看过数十个PHP代码段,如下所示:

function DB_Quote($string)
{
    if (get_magic_quotes_gpc() == true)
    {
        $string = stripslashes($string);
    }

    return mysql_real_escape_string($string);
}

What happens if I call DB_Quote("the (\\\\) character is cool"); 如果我叫DB_Quote("the (\\\\) character is cool");会发生什么? ? (Thanks jspcal!) (感谢jspcal!)

Aren't we supposed to strip slashes only when get_magic_quotes_gpc() == true and the value originated from $_GET , $_POST or $_COOKIE superglobals? 我们难道不应该只在get_magic_quotes_gpc() == true 值源自$_GET$_POST$_COOKIE superglobals时才删除斜线吗?

Step one is to turn off magic quotes altogether and issue large unignorable warnings if it is on. 第一步是完全关闭魔术引号,如果打开,则发出大的不可忽略的警告。

If this isn't an option to you, then in my opinion, the best way to go is to remove all magic quotes all the time. 如果这不是您的选择,那么我认为,最好的方法是始终删除所有魔术引号。

// in an include used on every page load:
if (get_magic_quotes_gpc()) {
    foreach (array('_GET', '_POST', '_COOKIE', '_REQUEST') as $src) {
        foreach ($$src as $key => $val) {
            $$src[$key] = stripslashes($val);
        }
    }
}

A small performance hit, but will give you a LOT more ease of mind when working with your variables from then on. 对性能的影响不大,但是从那时起使用变量时,您将更加放心。

Yeah, I've seen dozens of PHP snippets like that, too. 是的,我也看过数十个这样的PHP代码段。 It's a bit sad. 有点伤心

Magic quotes are an input issue. 魔术引号是输入问题。 It has to be fixed at the input stage, by iterating the GET/POST/COOKIES arrays and removing the slashes, if you need your app to run on servers using the foul archaic wrongness that is magic_quotes_gpc . 如果您需要让应用程序使用旧的错误性magic_quotes_gpc在服务器上运行,则必须在输入阶段通过迭代GET / POST / COOKIES数组并删除斜杠来解决该问题。 The simple alternative is to detect the magic quotes option and die with a “your server sucks” error when set. 一种简单的替代方法是检测魔术引号选项,并在设置时死于“服务器糟透”错误。

mysql_real_escape_string is an output issue. mysql_real_escape_string是输出问题。 It needs to be run on the way out of the script, on content heading to the database, if you're not using parameterised queries (which you should definitely consider). 如果您不使用参数化查询(肯定应该考虑),则需要在脚本之外,内容指向数据库的情况下运行它。

These are two separate unrelated stages in the program. 这是程序中两个独立的无关阶段。 You can't put them in the same function, tempting though it may be to try to encapsulate all your string processing into one box. 您不能将它们放在相同的函数中,尽管试图将所有字符串处理封装到一个盒子中,这很诱人。

Aren't we supposed to strip slashes only when [...] the value originated from $_GET, $_POST or $_COOKIE superglobals? 难道我们不应该仅在值源自$ _GET,$ _POST或$ _COOKIE超全局变量时才去除斜线吗?

Yes, exactly. 对,就是这样。 Which is why the snippet you quoted is indeed harmful. 这就是为什么您引用的代码段确实有害的原因。 Because tracking the origin of a string is impractical (especially as you might combine strings from different sources, one of which is slashed and the other not), you can't do it in one function. 因为跟踪字符串的原点是不切实际的(特别是因为您可能组合了来自不同来源的字符串,其中一个被斜杠,另一个未被斜杠),所以您不能在一个函数中做到这一点。 It has to be two separate string handling functions called at the appropriate time. 它必须是在适当的时候调用的两个单独的字符串处理函数。

yeah as dav said, up to the script to only use stripslashes on form input... 是的,就像dav所说的那样,直到脚本只在表单输入上使用反斜杠...

if you call stripslashes with the string "O'Reilly", the string won't be changed. 如果您使用字符串“ O'Reilly”调用脱衣舞,则该字符串将不会更改。 if you call stripslashes with a string like: "the backslash (\\) character is cool", the result will replace the escape sequence \\) with ). 如果您使用以下字符串调用反斜杠:“反斜杠(\\)字符很酷”,则结果将转义序列\\)替换为)。 so, using that function on all db values could subtly break things, but it might not be noticed. 因此,在所有db值上使用该函数可能会破坏某些内容,但可能不会引起注意。

like many apps, you could also just not support magic quotes mode. 像许多应用程序一样,您也可能不支持魔术引号模式。 check for it and print an error if it's on. 检查并打印错误(如果打开)。 it's been off by default for years and it's not recommended. 默认情况下已禁用多年,不建议这样做。

Number 6 is the right idea but doesn't work, because until PHP 5.4 $$src[$key] uses variable variable syntax on $src[$key] which is interpreted as $src[0], creating a variable $_ which is useless. 数字6是正确的主意,但是没有用,因为直到PHP 5.4 $$ src [$ key]在$ src [$ key]上使用变量变量语法,该语法被解释为$ src [0],从而创建变量$ _是没用的。 Just use & (the reference operator) on $val and $val = stripslashes($val). 只需在$ val和$ val = stripslashes($ val)上使用&(引用运算符)。 In addition, otherwise from PHP 5.4 on, you probably get an error because PHP won't just cast the _ to 0 此外,否则从PHP 5.4开始,您可能会收到错误消息,因为PHP不仅会将_强制转换为0

You could try doing the following on $_GET, $_POST or $_COOKIE before doing anything else with them: 您可以先对$ _GET,$ _ POST或$ _COOKIE进行以下操作,然后再对它们进行其他操作:

<?php
if (get_magic_quotes_gpc ())
{
    $_POST = array_map ('stripslashes', $_POST);
}
?>

Note, this will only work if your input array is "flat" (doesn't contain sub-arrays). 请注意,这仅在输入数组为“ flat”(不包含子数组)的情况下有效。 If you expect sub-arrays in the input then you'll need to write your own callback to handle it. 如果您希望输入中包含子数组,则需要编写自己的回调来进行处理。 Something like 就像是

<?php
function slashField ($input)
{
    if (is_array ($input))
    {
        foreach ($input as $key => $row)
        {
            $input [$key]   = slashField ($row);
        }
    }
    else
    {
        $input  = stripslashes ($input);
    }
    return ($input);
}

if (get_magic_quotes_gpc ())
{
    $_POST = array_map ('slashfield', $_POST);
}
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM