PHP:使用预准备语句并防止SQL注入vs转义

我确实理解准备好的语句是寻求防止SQL注入的最终方法.但是,它们以有限的方式提供覆盖;例如,在我让用户决定操作顺序如何(即ASC或DESC等等)的情况下,我没有用准备好的语句覆盖那里.

我知道我可以将用户输入映射到预定义的白名单.但是,这只有在事先可以创建或猜测白名单时才有可能.

例如,在我上面提到的情况(ASC或DESC)中,可以根据接受的值列表轻松映射和验证.但是,是否存在无法针对白名单验证SQL语句部分的情况?

如果存在这种情况,那么推荐的方法是什么?

如果我要使用底层数据库的内置转义实用程序(例如mysql的mysqL_real_escape_string)来逃避user_input,我将在哪里失败?

我问这个问题的假设是我总是使用引用值构造我的sql语句 – 即使对于整数……

让我们看看下面的例子并反思它.

select {$fields} from {$table} where Age='{$age}' order by {$orderby_pref}

假设所有变量都是用户提供的.

如果我是mysql_real_escape_string上面的SQL中的所有变量(而不是使用准备好的语句,这只包括我中途迫使我为另一半的白名单提供它无法帮助),它不会同样安全(并且更容易编码)?如果没有,输入方案转义实用程序将失败?

$fields       = mysql_escape($fields);
$table        = mysql_escape($table);
$age          = mysql_escape($age);
$orderby_pref = mysql_escape($orderby_pref);

select {$fields} from {$table} where Age='{$age}' order by {$orderby_pref}
最佳答案
无论是使用预处理语句还是使用mysql转义函数,总是需要使用white-lists来表示诸如表名或列名之类的东西.

问题是表名和列名不是用单引号或双引号引用的,所以如果你使用一个专门引用这些字符的函数(当然还有一些……),它对你的表名不起作用.

考虑表名my_table; DELETE * FROM mysql; SELECT * FROM my_table.这个字符串中的任何内容都不会被mysql的转义函数转义,但它绝对是一个你想要检查白名单的字符串.

除此之外,mysql转义函数的字符集存在问题,这些问题可能会使它们变得无用,因此您最好使用预处理语句.

转载注明原文:PHP:使用预准备语句并防止SQL注入vs转义 - 代码日志