是否需要从数据库中转义用户输入?

Kok*_*kos 15 php mysql user-input sql-injection escaping

所以我知道MySQL注入并在将它放入我的数据库之前总是转义我的所有用户输入.但是我想知道,想象一个用户试图提交一个查询注入,我逃避它.如果我稍后从数据库中获取此值并在查询中使用它,该怎么办?我必须再次逃脱吗?

所以:( sql::escape()包含我的转义功能)

$userinput = "'); DROP `table` --";
mysql_query("INSERT INTO `table` 
             (`foo`,`bar`) 
             VALUES 
             ('foobar','".sql::escape($userinput)."')");

// insert php/mysql to fetch `table`.`bar` into $output here

mysql_query("INSERT INTO `table2` 
            (`foo`,`bar`) 
            VALUES
            ('foobar','".$output."')");
Run Code Online (Sandbox Code Playgroud)

MySQL会自动转义它们的输出还是类似的东西,还是应该在第二个查询中转义?

这是一个测试用例,但这在我的程序中以其他方式发生,我想知道这样的情况下安全性有多紧.

编辑

我的逃生功能

static function escape($string){

    if(get_magic_quotes_gpc()) 
        $string = stripslashes($string); 

    return mysql_real_escape_string($string);

}
Run Code Online (Sandbox Code Playgroud)

Pek*_*ica 14

MySQL会自动转义它们的输出还是类似的东西,还是应该在第二个查询中转义?

您还需要在第二个查询中转义.MySQL不会对其输出进行任何转义.

答案很长:MySQL字符串转义不会修改正在插入的字符串,只是确保它不会对当前查询造成任何伤害.任何SQL注入尝试仍保留在数据中.


TMS*_*TMS 5

是的,你必须在第二个查询中转义字符串.

逃离弦乐对许多人来说听起来很神奇,就像屏蔽了一些神秘的危险,但事实上它并不神奇.它只是启用查询处理特殊字符的方法.

最好的只是看看逃避真正做到了什么.说输入字符串是:

'); DROP `table` --
Run Code Online (Sandbox Code Playgroud)

逃跑后:

\'); DROP `table` --
Run Code Online (Sandbox Code Playgroud)

实际上它只逃脱了单斜线.这是你需要确保的唯一一件事 - 当你在查询中插入字符串时,语法就可以了!

insert into table set column = '\'); DROP `table` --'
Run Code Online (Sandbox Code Playgroud)

它就像危险盾牌之类的东西一样神奇,它只是为了确保结果查询具有正确的语法!(当然,如果没有,它可以被利用)

然后查询解析器查看\'序列并知道它仍然是变量,而不是它的值的结尾.它将删除反斜杠,以下内容将存储在数据库中:

'); DROP `table` --
Run Code Online (Sandbox Code Playgroud)

这与用户输入的值完全相同.这正是你想要在数据库中拥有的!!

因此,这意味着如果从数据库中获取该字符串并希望再次在查询中使用它,则需要再次转义它以确保生成的查询具有正确的语法.

但是,在你的例子中,非常重要的是magic_quotes_gpc指令!

此功能会自动转义所有用户输入(gpc - _GET,_POST和_COOKIE).对于不了解sql注入的人来说,这是一个邪恶的功能.这有两个原因是邪恶的.第一个原因是,你必须区分你的第一个和第二个查询的情况 - 第一个你不逃避,第二个你做.大多数人要做的是关闭"功能"(我更喜欢这个解决方案)或首先取消用户输入,然后在需要时再次将其转义.unescape代码可能如下所示:

function stripslashes_deep($value)
{
        return is_array($value) ?
               array_map('stripslashes_deep', $value) :
               stripslashes($value);
}

if (get_magic_quotes_gpc()) {
        $_POST = stripslashes_deep($_POST);
        $_GET = stripslashes_deep($_GET);
        $_COOKIE = stripslashes_deep($_COOKIE);
}
Run Code Online (Sandbox Code Playgroud)

这是邪恶的第二个原因是因为没有像"普遍引用"那样的东西.在引用时,您总是引用某些特定输出的文本,例如:

  1. mysql查询的字符串值
  2. like mysql查询的表达式
  3. HTML代码
  4. JSON
  5. mysql正则表达式
  6. php正则表达式

对于每种情况,您需要不同的引用,因为每种用法都存在于不同的语法上下文中.这也意味着引用不应该在PHP的输入中进行,而是在特定的输出中进行!这就是为什么功能magic_quotes_gpc被破坏的原因(永远不要忘记处理它,或者更好,确保它被关闭!!!).

那么,在这些特定情况下,用什么方法来引用?(随意纠正我,可能有更现代的方法,但这些对我有用)

  1. mysql_real_escape_string($str)
  2. mysql_real_escape_string(addcslashes($str, "%_"))
  3. htmlspecialchars($str)
  4. json_encode() - 仅限utf8!我将我的功能用于iso-8859-2
  5. mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}')) - 在这种情况下你不能使用preg_quote,因为反斜杠会被转义两次!
  6. preg_quote()