http://zhangxugg-163-com.iteye.com/blog/1835721
http://my.oschina.net/zxu/blog/163135
db编码 |
db连接编码 |
db查询编码 |
ATTR_EMULATE_PREPARES |
是否注入 |
日志 |
gbk |
gbk |
SET NAMES GBK |
TRUE |
yes |
utf8编码 |
gbk |
gbk |
SET NAMES GBK |
FALSE |
no |
SELECT * FROM info WHERE username = |
gbk |
utf8 |
SET NAMES GBK |
TRUE |
yes |
SELECT * FROM info WHERE username = '縗' OR username=username #' |
gbk |
gbk |
不设置 |
TRUE |
报错 |
SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' |
gbk |
utf8 |
SET NAMES utf8 |
TRUE |
报错 |
SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' |
utf8 |
utf8 |
SET NAMES GBK |
TRUE |
yes |
SELECT * FROM info WHERE username = '縗' OR username=username #' |
utf8 |
utf8 |
SET NAMES utf8 |
TRUE |
no |
|
utf8 |
utf8 |
不设置 |
TRUE |
no |
|
总结:
在php 5.3.10 CI3 环境下
当 SET NAMES GBK 和 PDO::ATTR_EMULATE_PREPARES 为TRUE时, PDO存在注入的可能
这2个条件只要其中一个不成立,则可防止注入
查看CI数据库类,发现有针对小于php 5.3.6时有对默认编码进行处理,使其与连接设置编码保持一致
if ( ! is_php('5.3.6') && ! empty($this->char_set))
{
$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$this->char_set
.(empty($this->dbcollat) ? '' : ' COLLATE '.$this->dbcollat);
}
php 5.3.10 + CI3 在db连接设置编码中设置为utf8即可,无需其他设定