LOAD DATA INFILE 宽字节导致字段错位
流程:Apache日志分析,解析GET的URL参数,生成CSV后,使用LOAD INFILE导入数据库;
问题:字段错位
一行数据(1,2,3),导入后成了(1,23,NULL);
原因:分隔符和字段值中的宽字节字符组合成了新字符;
相当于命中了宽字节编码漏洞:
高字节范围129-254的ASCII编码可以和基础字符编码组成一个非法宽字节字符。
造成漏洞的高字节编码范围:0xC0-0xFE
安全的生成CSV文件的方法:
- 过滤宽字节
- 转义分隔符,引号
过滤宽字符函数:
function safe_string($string){
if( strlen($string) > 2 &&
//攻击发生在字符串的最后两个字节,倒数第二个字节ASCII码大于129,倒数第一个字节ASCII码小于127.
(ord(substr($string,-2,1)) >= 129 && ord(substr($string,-1,1))<127) ){
$string = substr($string, 0, -1);
return safe_string($string);
}
return $string;
}
示例代码:
$value = mysql_real_escape_string(safe_string($value));
“$value”,”$value”
倒入这样的CSV就万无一失了,不会出现字段对齐问题。
