magic_quotes_gpc() 的解药?

发布于 2024-08-17 01:46:11 字数 487 浏览 6 评论 0原文

我见过很多这样的 PHP 片段:

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

    return mysql_real_escape_string($string);
}

如果我调用 DB_Quote("the (\\) character is Cool"); 会发生什么? (感谢 jspcal!)

难道我们不应该只在 get_magic_quotes_gpc() == true 并且值源自 时才去掉斜杠吗$_GET$_POST$_COOKIE 超全局变量?

I've seen dozens of PHP snippets that go like this:

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");? (Thanks 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

暖心男生 2024-08-24 01:46:11

第一步是完全关闭魔术引号,并在其打开时发出大量不可忽略的警告。

如果这对您来说不是一个选择,那么在我看来,最好的方法就是始终删除所有魔术引号。

// 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);
        }
    }
}

虽然性能受到了一些影响,但从那时起,您在处理变量时会更加轻松。

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.

铜锣湾横着走 2024-08-24 01:46:11

是的,我也见过几十个这样的 PHP 片段。有点难过。

魔术引号是一个输入问题。如果您需要您的应用程序使用古老的错误 magic_quotes_gpc 在服务器上运行,则必须在输入阶段通过迭代 GET/POST/COOKIES 数组并删除斜杠来修复它。简单的替代方法是检测魔术引号选项,并在设置时因“你的服务器很糟糕”错误而死亡。

mysql_real_escape_string 是一个输出问题。如果您不使用参数化查询(您绝对应该考虑),它需要在脚本外、内容发送到数据库时运行。

这是程序中两个独立的、不相关的阶段。您不能将它们放在同一个函数中,尽管尝试将所有字符串处理封装到一个盒子中可能很诱人。

难道我们不应该只在 [...] 值源自 $_GET、$_POST 或 $_COOKIE 超全局变量时才去除斜杠吗?

是的,完全正确。这就是为什么您引用的片段确实有害。由于跟踪字符串的来源是不切实际的(特别是当您可能组合来自不同来源的字符串时,其中一个被斜杠,另一个没有),因此您无法在一个函数中完成此操作。它必须是在适当的时间调用的两个单独的字符串处理函数。

Yeah, I've seen dozens of PHP snippets like that, too. 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. 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. 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?

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.

沙沙粒小 2024-08-24 01:46:11

是的,正如 dav 所说,直到脚本仅在表单输入上使用 stripslashes...

如果您使用字符串“O'Reilly”调用 stripslashes,则该字符串将不会更改。如果您使用如下字符串调用 stripslashes:“反斜杠 (\) 字符很酷”,结果将用 ) 替换转义序列 \)。因此,在所有数据库值上使用该函数可能会巧妙地破坏事物,但可能不会被注意到。

与许多应用程序一样,您也可以不支持魔术引号模式。检查它并在打开时打印错误。多年来它一直默认关闭,不建议这样做。

yeah as dav said, up to the script to only use stripslashes on form input...

if you call stripslashes with the string "O'Reilly", the string won't be changed. 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.

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.

春花秋月 2024-08-24 01:46:11

在对 $_GET、$_POST 或 $_COOKIE 执行其他操作之前,您可以尝试对它们执行以下操作:

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

注意,只有当您的输入数组是“平面”(不包含子数组)时,这才有效。如果您期望输入中有子数组,那么您需要编写自己的回调来处理它。类似的东西

<?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);
}
?>

You could try doing the following on $_GET, $_POST or $_COOKIE before doing anything else with them:

<?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). 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);
}
?>
要走干脆点 2024-08-24 01:46:11

数字 6 是正确的想法,但不起作用,因为直到 PHP 5.4 $$src[$key] 在 $src[$key] 上使用变量变量语法,它被解释为 $src[0],创建一个变量 $_ ,它是没用的。只需使用 & (引用运算符)在 $val 和 $val = stripslashes($val) 上。另外,从 PHP 5.4 开始,您可能会收到错误,因为 PHP 不会将 _ 强制转换为 0

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. Just use & (the reference operator) on $val and $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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文