PHP 中的魔术引号

发布于 2024-07-07 18:57:06 字数 430 浏览 8 评论 0原文

根据PHP手册,依次为了使代码更具可移植性,他们建议使用类似以下内容的方法来转义数据:

if (!get_magic_quotes_gpc()) {
    $lastname = addslashes($_POST['lastname']);
} else {
    $lastname = $_POST['lastname'];
}

我将执行其他验证检查,但是就转义数据而言,上述严格检查的安全性如何? 我还看到 PHP 6 中将废弃魔术引号。这将如何影响上面的代码? 我不想依赖数据库特定的转义函数,如 mysql_real_escape_string()。

According to the PHP manual, in order to make code more portable, they recommend using something like the following for escaping data:

if (!get_magic_quotes_gpc()) {
    $lastname = addslashes($_POST['lastname']);
} else {
    $lastname = $_POST['lastname'];
}

I have other validation checks that I will be performing, but how secure is the above strictly in terms of escaping data? I also saw that magic quotes will be deprecated in PHP 6. How will that affect the above code? I would prefer not to have to rely on a database-specific escaping function like mysql_real_escape_string().

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

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

发布评论

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

评论(12

牛↙奶布丁 2024-07-14 18:57:06

魔法引号本质上是被破坏的。 它们的目的是清理 PHP 脚本的输入,但如果不知道如何使用该输入,就不可能正确清理。 如果有的话,你最好检查是否启用了魔术引号,然后在 $_GET/$_POST/$_COOKIES/$_REQUEST 上调用 stripslashes() ,然后在你在某个地方使用它的地方清理你的变量。 例如,如果您在 URL 中使用它,则使用 urlencode();如果您将其打印回网页,则使用 htmlentities();如果您将其存储到数据库,则使用数据库驱动程序的转义函数。 请注意,这些输入数组可能包含子数组,因此您可能需要编写一个可以递归到子数组的函数来删除这些斜杠。

PHP 关于魔法引用的手册页同意:

“此功能已被弃用,因为
PHP 5.3.0 的版本,自 PHP 起已删除
5.4.0。 强烈建议不要依赖此功能。 魔术行情是一个
自动逃逸的进程
PHP 脚本的传入数据。 它是
更喜欢使用魔术引号进行编码
关闭并转义数据
运行时,根据需要。”

Magic quotes are inherently broken. They were meant to sanitize input to the PHP script, but without knowing how that input will be used it's impossible to sanitize correctly. If anything, you're better off checking if magic quotes are enabled, then calling stripslashes() on $_GET/$_POST/$_COOKIES/$_REQUEST, and then sanitizing your variables at the point where you're using it somewhere. E.g. urlencode() if you're using it in a URL, htmlentities() if you're printing it back to a web page, or using your database driver's escaping function if you're storing it to a database. Note those input arrays could contain sub-arrays so you might need to write a function can recurse into the sub-arrays to strip those slashes too.

The PHP man page on magic quotes agrees:

"This feature has been DEPRECATED as
of PHP 5.3.0 and REMOVED as of PHP
5.4.0. Relying on this feature is highly discouraged. Magic Quotes is a
process that automagically escapes
incoming data to the PHP script. It's
preferred to code with magic quotes
off and to instead escape the data at
runtime, as needed."

旧伤还要旧人安 2024-07-14 18:57:06

魔术引号是一个设计错误。 它们的使用与保持你的理智不相容。

我更喜欢:

if (get_magic_quotes_gpc()) {
   throw new Exception("Turn magic quotes off now!");
}

不要编写与固有损坏的设置兼容的代码。 相反,通过让您的代码FAIL FAST来防御它们的使用。

Magic quotes were a design error. Their use is incompatible with retainnig your sanity.

I prefer:

if (get_magic_quotes_gpc()) {
   throw new Exception("Turn magic quotes off now!");
}

Don't write code for compatibility with inherently broken setups. Instead defend aginst their use by having your code FAIL FAST.

无声无音无过去 2024-07-14 18:57:06

我在网站的头文件中使用以下代码来反转 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);
}

?>

然后我可以编写其余的代码,就好像 magic_quotes 从未存在过一样。

I use the following code in the header file of my website to reverse the effects of 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);
}

?>

Then I can write the rest of my code as if magic_quotes never existed.

安穩 2024-07-14 18:57:06

“我不想依赖像 mysql_real_escape_string() 这样的特定于数据库的转义函数”

然后使用类似 PDO 。 但无论如何你都必须扭转魔法引号造成的伤害。

"I would prefer not to have to rely on a database-specific escaping function like mysql_real_escape_string()"

Then use something like PDO. But you have to reverse the damage done by magic quotes anyway.

離人涙 2024-07-14 18:57:06

对您的代码提出 PHP 5.2 或更高版本的要求,并使用过滤器 APIfilter_* 函数直接访问原始输入数据(它们不会接触 $_POST 等),因此它们完全不受 magic_quotes_gpc 的影响>。

那么这个例子:

if (!get_magic_quotes_gpc()) {
    $lastname = addslashes($_POST['lastname']);
} else {
    $lastname = $_POST['lastname'];
}

可以变成这样:

$lastname = filter_input(INPUT_POST, 'lastname');

Put a requirement of PHP 5.2 or higher on your code and use the filter API. The filter_* functions access the raw input data directly (they don't ever touch $_POST etc.) so they're completely unaffected by magic_quotes_gpc.

Then this example:

if (!get_magic_quotes_gpc()) {
    $lastname = addslashes($_POST['lastname']);
} else {
    $lastname = $_POST['lastname'];
}

Can become this:

$lastname = filter_input(INPUT_POST, 'lastname');
坦然微笑 2024-07-14 18:57:06

是的,这不是最好的方法,也不是最安全的方法。 逃避最好与你逃避的目的相关。 如果要存储在 mysql 数据库中,请使用 mysql_real_escape_string ,它会考虑其他语言环境、字符集。 对于 HTML,html 实体。 对于在代码中使用,escapeshellcmd、escapeshellarg。 是的,如果启用了魔术引号,您可能需要先搅拌斜杠。 但最好不要指望它或使用它。

Right, it's not the best way to do it and not the most secure. Escaping is best done in relation to what you are escaping for. If it is to store in a mysql database, use mysql_real_escape_string which takes into account other locales, character sets. For HTML, htmlentities. For use in code, escapeshellcmd, escapeshellarg. Yes, you probably need to stirpslashes first if magic quotes is on. But best not to count on it or use it.

宁愿没拥抱 2024-07-14 18:57:06

关于使用数据库特定的转义函数,您非常需要这样做。 我发现在 MySQL 中使用 addslashes() 在极少数情况下会失败。 您可以编写一个转义函数来确定您正在使用哪个数据库,然后使用适当的转义函数。

Regarding using a database specific escaping function, you pretty much need to. I have found just using addslashes() to fail in rare cases with MySQL. You can write a function to escape which determines which DB you are using and then use the approriate escape function.

风筝有风,海豚有海 2024-07-14 18:57:06

你可以试试这个:

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

    }

You may try this:

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

    }
椵侞 2024-07-14 18:57:06

“我不想依赖像 mysql_real_escape_string() 这样的特定于数据库的转义函数”

另外,addslashes 也可以被欺骗,请查看这篇文章:

http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

"I would prefer not to have to rely on a database-specific escaping function like mysql_real_escape_string()"

Also addslashes can be tricked as well check out this post:

http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

旧城烟雨 2024-07-14 18:57:06

您的示例代码是向后的,您应该执行以下操作:

if (get_magic_quotes_gpc()) {
  $lastname = stripslashes($_POST['lastname']);
} else {
  $lastname = $_POST['lastname'];
}

请注意,这会使您的输入数据完全处于用户键入的“原始”状态 - 没有额外的反斜杠,并且可能加载 SQL 注入和 XSRF 攻击 - 这正是你要。 然后,确保始终使用以下其中一项:

  • 将变量回显到 HTML 中时,将其包装在 htmlentities()
  • 中将其导入 mysql,至少使用准备好的语句或 mysql_real_escape_string()
  • 将变量echo到 JavaScript 代码中时,请使用 json_encode()

Joel Spolsky 在 让错误的代码看起来错误

Your sample code is backwards, you should be doing the following:

if (get_magic_quotes_gpc()) {
  $lastname = stripslashes($_POST['lastname']);
} else {
  $lastname = $_POST['lastname'];
}

Note that this leaves your input data in a 'raw' state exactly as the user typed it - no extra backslashes and potentially loaded with SQL Injection and XSRF attacks - and that's exactly what you want. Then, you make sure you always use one of the following:

  • When echoing the variable into HTML, wrap it in htmlentities()
  • When putting it into mysql, use prepared statements or else mysql_real_escape_string() as a minimum.
  • When echoing the variable into Javascritpt code, use json_encode()

Joel Spolsky has some good starting advice in Making Wrong Code Look Wrong

空气里的味道 2024-07-14 18:57:06

刚刚在 PHP 手册页< /a>,看起来是一个非常聪明的剥离 em 的方法(处理键和值......):

if (get_magic_quotes_gpc())
{
    $_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
    $_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
    $_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
    $_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true);
    ini_set('magic_quotes_gpc', 0);
}

Just found this over on the PHP manual pages, looks like a pretty clever way to strip em (deals with keys and values...):

if (get_magic_quotes_gpc())
{
    $_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
    $_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
    $_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
    $_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true);
    ini_set('magic_quotes_gpc', 0);
}
守望孤独 2024-07-14 18:57:06

PDOMysqli 是防止 SQL 注入的更好方法。

但是,如果您要迁移基于每个 SQL 查询的 Magic Quotes 的遗留代码,您可以参考 yidas/php-magic-quotes 用于在 PHP 5.4 以上版本的环境下实现 Magic Quotes。

https://github.com/yidas/php-magic-quotes

Prepared statements of PDO and Mysqli are the better way to prevent SQL injection.

But if you are migrating a legacy code which is base on Magic Quotes for every SQL queries, you can refer yidas/php-magic-quotes for implementing Magic Quotes on the environment with PHP 5.4 above version.

https://github.com/yidas/php-magic-quotes

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