【问题标题】:PHP what happens when a string is double times mysqli_real_escape_stringPHP 当一个字符串是 mysqli_real_escape_string 的两倍时会发生什么
【发布时间】:2010-01-14 15:50:02
【问题描述】:

我正在使用 mysqli。

当我回显mysqli_real_escape_string($db,mysqli_real_escape_string($db,'"'));

其中哪一个将是输出: 1.\" 2.\\\" ?

有没有一种安全的方法来检查一个字符串是否已经被转义了?

很遗憾,我目前无法测试,因为我 24 小时无法访问 MySQL。

【问题讨论】:

  • 删除的 cmets 基本上相当于“Q:你能自己测试一下吗”,“A:不,我有时间限制,见问题顶部”。
  • sigh 一个完美的核心问题,最后被一句坏话毁了。不想拖钓:简要说明为什么你不能自己做而不是那个尖刻的话会是一个问题吗?我们不想要你的生活故事,而是一个简单的“我目前无法访问 MySQL”,这个问题会得到应得的,因为双重转义很容易发生,具体取决于如何该应用程序的设计...
  • @Michael:虽然我同意他可以说明原因,换句话说,我认为这个问题不值得-10 票,并以“公然冒犯”而结束。 拜托,不要问我“你不能自己做吗?”种cmets。 谢谢 - 他最后一句话中的两个非常愉快的词。这是多么令人反感?我相信我们都需要放松一点。投票重新开放。
  • 我同意(我是在派对结束后来到这里的),但你种下什么就收什么。我不会重新投票,因为我倾向于认为最好删除并重新创建这样的问题以摆脱负面含义。同样,我认为这个问题本身是非常好的和有效的,应该得到好的答案。下面给出的已经很好了,但有时人们会想出一些很好的技巧来帮助“检查是否已经被替换”部分......

标签: php mysql escaping


【解决方案1】:

输出是\\\"(你的第二个例子)。

我认为你不能可靠地判断一个字符串是否已经被转义,你应该以一种你只能调用mysqli_real_escape_string() 一次的方式来组织你的代码。

【讨论】:

    【解决方案2】:

    你无法判断一个字符串是否已经被转义,因为一个已经被转义的字符串也可能已经被用户输入(因此未被转义)。

    【讨论】:

    • 这没有任何意义。输入的 '\"' 与 escape_string('"') 有何不同?
    • 这正是我想说的。因为字符串没有什么不同,所以您无法分辨出哪个字符串被转义了。
    【解决方案3】:

    生成的字符串将为\\\"(转义两个字符中的每一个)。

    如果“安全”是指“万无一失”,那么不是。即使您检查相关字符是否已转义,您也无法知道它是否应该\",并且字符串不提供任何可以设置为将其标记为的隐藏标志已经逃跑了。

    但是,您不应该手动调用 mysqli_real_escape_string 两次。只在你需要的时候做。

    “双重转义”的主要来源是当您通过转义做正确的事情时,但既不要关闭魔术引号也不要在它们打开时删除它们。

    *好吧,在不使用参数化查询的情况下尽可能接近。

    【讨论】:

      【解决方案4】:

      第二个将被退回。 " 将首先转换为\"(转义"),然后再转换为\\\"(转义\")。

      一般来说,你必须自己做。尽管 Magic Quotes 的“功能”确实为字符 '"\ 和传入数据中的 NULL 字符添加反斜杠,但魔术引号是一项可怕的发明,将在 PHP 6 中删除. 此外,它们可以在一台服务器上启用并在另一台服务器上禁用。所以它甚至不可靠。

      但更重要的是它们不适合 MySQL,因为在 MySQL 中,您不仅需要处理这些元字符,还需要处理其他字符(请参阅string syntax in MySQL 了解更多信息)。

      【讨论】:

        【解决方案5】:

        多次调用 mysqli_real_escape_string() 不会降低查询的安全性。但是,它确实会损坏您的数据。一个很好的例子是柯南奥布莱恩。

        如果您执行以下操作:

        $name=mysqli_real_escape_string($db,mysqli_real_escape_string($db,"Conan O'Brien"));
        //At this point $name is Conan O\\\'Brien
        mysql_query("insert into table (name)values('$name')")
        //In the database the name will be stored as: Conan O\'Brien  Which is corrupt.   
        

        要处理这种损坏,您可以执行以下操作:

        funciton strip_all($var){
            $len=strlen($var);
            $ret=stripslashes($var);
            while($len!=strlen($ret)){
                $len=strlen($ret);
                $ret=stripslashes($ret);
            }
            return ret;
        }
        //$name is unkown somthing like: Conan O\\\\\\\'Brien
        $name=strip_all($name);
        //$name is: Conan O'Brien
        $name=mysqli_real_escape_string($db,$name);
        //$name is: Conan O\'Brien,  which is properly escaped.
        mysql_query("insert into table (name)values('$name')")
        //In the database the value is Conan O'Brien,  mysql will eat the back slash. 
        

        最好的方法是跟踪你的逃跑是从哪里来的。在这种情况下,我们考虑是否禁用或启用了magic_quotes,然后我们使用 mysqli_real_escape_string() 提供更好的安全性,因为它可以转义更多字符。

        if(get_magic_quotes_gpc())
        {
           $name=stripslashes($_GET[name]);
        }
        $name=mysqli_real_escape_string($db,$_GET[name]);
        //At this point $name is Conan O\'Brien
        mysql_query("insert into table (name)values('$name')")
        

        【讨论】:

          【解决方案6】:

          添加一些额外的信息。

          转义是一种在不引入额外符号的情况下向符号序列添加额外信息的方法。为了做到这一点,至少有一个符号可以用作“转义”符号。这意味着原始角色丢失,需要使用转义序列添加。

          例子:

          我们的语言有 3 个符号:a、b 和 c。其中符号具有以下功能:

          Language 1
          a has the function A
          b has the function B
          c has the function C
          

          我们现在需要引入函数 D 和 E,但我们无法添加额外的符号。

          所以我们可以使用转义符号来做到这一点:

          Language 2
          a, is now the escape symbol.
          aa has the function A
          ab had the function D
          ac has the function E
          b  has the function B
          c  has the function C
          

          如果使用语言 1 解释序列 aabcabac,则读作 AABCABAC。但是使用语言 2 进行解释时读取的是 ABCDE。

          问题在于,大多数情况下,您无法从符号中确定使用的语言。需要在处理数据之前提供此元信息。

          底线是你没有安全的方法来确定一个字符串是否被足够的转义。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-04-07
            • 1970-01-01
            • 2013-11-21
            • 1970-01-01
            • 2014-08-02
            • 2017-02-17
            • 1970-01-01
            相关资源
            最近更新 更多