[转] PHP中用PDO查询MySQL避免SQL注入示例和应注意的地方

2016-04-20 20:24:01 查看评论 871 人阅读    

当我们使用传统的 mysql_connect 、mysql_query方法来连接查询数据库时,如果过滤不严,就有SQL注入风险,导致网站被攻击,失去控制。虽然可以用mysql_real_escape_string()函数过滤用户提交的值,但是也有缺陷。(注:请弃用mysql_escape_string,php5.5已经废弃,php7已经移除。

mysql_real_escape_stringaddslashes的区别

区别一

addslashes不知道任何有关MySQL连接的字符集。
如果你给所使用的MySQL连接传递一个包含字节编码之外的其他编码的字符串,
它会很愉快地把所有值为字符'、"、\和\x00的字节进行转义。
如果你正在使用不同于8位和UTF-8的其它字符,
这些字节的值不一定全部都是表示字符'、"、\和\x00。可能造成的结果是,MySQL接收这些字符后出现错误。
如果要修正这个bug,可尝试使用iconv函数,将变量转为UTF-16,然后再使用addslashes进行转义。

 区别二

与addslashes对比,mysql_real_escape_string同时还对\r、\n和\x1a进行转义。看来,这些字符必须正确地告诉MySQL,否则会得到错误的查询结果

在GBK里,0xbf27不是一个合法的多字符字符,但0xbf5c却是。在单字节环境里,0xbf27被视为0xbf后面跟着0x27('),同时0xbf5c被视为0xbf后面跟着0x5c(\)。

一个用反斜杠转义的单引号,是无法有效阻止针对MySQL的SQL注入攻击的。
如果你使用addslashes,那么,我(攻击者,下同)是很幸运的。
我只要注入一些类似0xbf27,然后addslashes将它修改为0xbf5c27,一个合法的多字节字符后面接着一个单引号。
换句话说,我可以无视你的转义,成功地注入一个单引号。这是因为0xbf5c被当作单字节字符,而非双字节。

所以不管转义,针对针对php 5.3.6以前版本,这套方法还是可以找到漏洞的。而使用PHP的PDO扩展的 prepare 方法,就可以避免sql injection 风险。

PDO(PHP Data Object) 是PHP5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,如 php_mysql.dll。 PHP6中也将默认使用PDO的方式连接,mysql扩展将被作为辅助 。官方:http://php.net/manual/en/book.pdo.php


分类: PHP 标签: pdo sql注入