【问题标题】:mysql_real_escape_string() leaving slashes in MySQLmysql_real_escape_string() 在 MySQL 中留下斜杠
【发布时间】:2008-10-06 04:33:29
【问题描述】:

我刚搬到一家新的托管公司,现在每当一个字符串被转义时使用:

mysql_real_escape_string($str);

斜线保留在数据库中。这是我第一次看到这种情况发生,所以我的脚本都没有使用

stripslashes()

没有了。

这是在 CentOS 4.5 64 位上运行 php 5.2.6 作为 fastcgi 在 lighttpd 1.4 服务器上。我确保所有的 magic_quotes 选项都关闭了,并且 mysql 客户端 api 是 5.0.51a。

我的所有 6 个网络服务器都有相同的问题。

任何帮助将不胜感激。

谢谢。

编辑:

Magic Quotes 未开启。请不要建议关闭它。这不是问题。

【问题讨论】:

  • 如果您回显 SQL 语句,它们的斜线是否正确?
  • 是的。这是MySQL在插入时在字符串中留下斜杠,就好像我调用了addslashes()一样。
  • 使用 PDO 那么你所有的逃逸和注入问题都会消失。
  • 埃里克,你有没有解决这个问题?我也只是切换主机并看到同样的问题。当然有 varified magic_quotes 已关闭。

标签: php mysql mysql-real-escape-string


【解决方案1】:

您移动的主机可能已打开magic_quotes_runtime。您可以使用set_magic_quotes_runtime(0) 将其关闭。

请关闭magic_quotes_runtime,然后将代码更改为使用绑定变量,而不是使用字符串转义。

【讨论】:

  • 它真正的“正确”部分是建议使用绑定变量而不是字符串连接/转义的部分,从而避免了转义、引用、潜在安全漏洞的所有麻烦(你好, sql注入)等等
  • 可以在mysql中使用绑定变量吗?这是我第一次听说这种方法而不是转义值。
  • $sql = "更新..."; $stmt = $db->prepare($sql); $stmt->bind_param('ss',$bio,$name); $stmt->执行();
【解决方案2】:

我能想到许多可能导致这种情况的事情。但这取决于您如何调用 SQL 查询。如果您转而使用 PDO 等参数化查询,则无需转义,这意味着对 mysql_real_escape_string 的调用会添加额外的斜杠。

如果您使用的是mysql_query 等,那么一定有一些类似addslashes 的代码正在执行此操作。这可能是在数据进入数据库之前,也可能是之后。

您还说您禁用了魔术引号...如果您还没有,只需使用以下代码仔细检查代码:

echo htmlentities($_GET['value']); // or $_POST, whichever is appropriate

确保该值中没有斜线,然后还要检查:

echo "Magic quotes is " . (get_magic_quotes_gpc() ? "ON" : "OFF");

我知道你已经多次说过这不是魔术引号,但对于我们这些试图提供帮助的人来说,我们需要确保你检查了实际的 PHP 输出,而不仅仅是更改配置(这可能不起作用) .

【讨论】:

    【解决方案3】:

    听起来好像您打开了魔术引号。将其关闭并不难:只需在您的根目录中创建一个名为 .htaccess 的文件并将这一行放入其中:

    php_flag magic_quotes off
    

    如果由于某种原因无法做到这一点,或者您想更改应用程序以能够处理魔术引号,请使用以下技术:

    不要直接访问请求变量,而是使用函数。然后该函数可以检查魔术引号是打开还是关闭,并相应地去除斜线。简单地在所有东西上运行 stripslashes() 是行不通的,因为你会去掉你真正想要的斜线。

    function getVar($key) {
        if (get_magic_quotes_gpc()) {
            return stripslashes($_POST[$key]);
        } else {
            return $_POST[$key];
        }
    }
    
    $x = getVar('x');
    

    现在你已经知道了,所有传入的变量都准备好再次转义,mysql_real_escape_string() 不会把它们塞满。

    【讨论】:

    • 请注意,您可能无法始终在 .htaccess 文件中禁用 magic_quotes。如果该值是在 php.ini 中用 php_admin_flag 设置的,则以后不能被覆盖。
    【解决方案4】:

    斜线保留在数据库中。

    这意味着您的数据被双重转义。

    有两个可能的原因:

    1. 魔法引语开启,尽管你有感觉。仔细检查一下

    2. 您的应用程序中有一些代码只是模仿魔术引号行为,转义所有输入。
      这是一个非常常见的误解,即拥有一个通用的转义函数来“保护”所有传入的数据。虽然它一点用都没有,但它也对这种情况负责。
      当然 - 只需找到该功能并将其清除即可。

    【讨论】:

      【解决方案5】:

      您可能必须打开魔术引号。弄清楚如何关闭它在 PHP 中可能是一件非常头疼的事情。虽然您可以使用set_magic_quotes_runtime(0) 关闭魔术引号,但这还不够——魔术引号此时已经更改了输入数据,因此您必须撤消更改。试试这个 sn-p:http://talks.php.net/show/php-best-practices/26

      或者更好——禁用 php.ini 中的魔术引号,以及任何可能设置它的 .htaccess 文件。

      【讨论】:

        【解决方案6】:

        我不确定我是否正确理解了这个问题,但我遇到了同样的问题。无论我做什么,当字符串逃脱时,斜线就在那里。因为我需要插入的值与输入的格式完全相同,所以我使用了

        htmlentities($inserted_value)
        

        这将使所有插入的引号不转义但无害。

        【讨论】:

          【解决方案7】:

          您在同一个 var 上多次使用 mysql_real_escape_string() 可能是什么问题(这是我们的问题)。当你多次使用它时,它会添加斜线。

          【讨论】:

            【解决方案8】:

            下面的函数将在插入数据库之前正确删除斜线。我知道你说魔术引号没有打开,但有些东西正在添加斜杠,所以请尝试以下页面并查看输出。这将有助于弄清楚在哪里。调用 page.php?var=something-with'data_that;will`be|escaped

            您很可能会看到第三个输出的斜线比需要的多。

            *也更改数据库详细信息。

            <?php
            
            $db = mysql_connect('host', 'user', 'pass');
            
            $var = $_REQUEST['var'];
            echo "1: $var :1<br />";
            echo "2: ".stripslashes($var)." :2<br />";
            echo "3: ".mysql_real_escape_string($var)." :3<br />";
            echo "4: ".quote_smart($var)." :4<br />";
            
            
            function quote_smart($value)
            {
                // Stripslashes is gpc on
                if (get_magic_quotes_gpc())
                {
                    $value = stripslashes($value);
                }
                // Quote if not a number or a numeric string
                if ( !is_numeric($value) )
                {
                    $value = mysql_real_escape_string($value);
                }
                return $value;
            }
            

            ?>

            【讨论】:

              【解决方案9】:

              mysql_real_escape_string($str); 应该正是这样做的。它旨在为特殊字符添加反斜杠,尤其是当您要将查询传递给 mysql 时。注意这里还考虑了mysql的字符集。

              为了更安全的编码实践,最好编辑您的代码并使用stripslashes() 读出数据并删除斜线。

              【讨论】:

              • 在非转义字符串上运行 stripslashes() 是否也会删除好的斜杠?
              • 斜杠只是为了转义正在插入的字符串,它们不应该最终出现在数据库中。您永远不必对从数据库中提取的数据运行 stripslashes()。
              • 当使用 mysql_real_escape_string($str); 时,斜杠也会从 \ 转义到 \\;如果你在相同的文本中使用 stripslashes() 那么它会删除任何额外的斜杠,你最终会得到 1 个斜杠。
              猜你喜欢
              • 2010-12-04
              • 2010-09-21
              • 2011-03-29
              • 1970-01-01
              • 2023-03-20
              • 1970-01-01
              • 2022-11-25
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多