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转义函数的字符集存在问题,这些问题可能会使它们变得无用,因此您最好使用预处理语句. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |