对于ThinkPHP框架早期版本的一个SQL注入漏洞详细分析
2015-01-24信息快讯网
这篇文章主要介绍了对于ThinkPHP框架早期版本的一个SQL注入漏洞详细分析,对于网站安全十分重要!需要的朋友可以参考下
ThinkPHP官网上曾有一段公告指出,在ThinkPHP 3.1.3及之前的版本存在一个SQL注入漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件
根据官方文档对"防止SQL注入"的方法解释(参考http://doc.thinkphp.cn/manual/sql_injection.html)
使用查询条件预处理可以防止SQL注入,没错,当使用如下代码时可以起到效果:
$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();或者
$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();但是,当你使用如下代码时,却没有"防止SQL注入"的效果(但是官方文档却说可以防止SQL注入):
$model->query('select * from user where id=%d and status=%s',$id,$status);
或者
$model->query('select * from user where id=%d and status=%s',array($id,$status));
原因分析:
ThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.
其原函数为:
protected function parseSql($sql,$parse) {
// 分析表达式
if(true === $parse) {
$options = $this->_parseOptions();
$sql = $this->db->parseSql($sql,$options);
}elseif(is_array($parse)){ // SQL预处理
$sql = vsprintf($sql,$parse);
}else{
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
}
$this->db->setModel($this->name);
return $sql;
}
验证漏洞(举例):
请求地址:
http://localhost/Main?id=boo" or 1="1
或
http://localhost/Main?id=boo%22%20or%201=%221
action代码:
$model=M('Peipeidui');
$m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);
dump($m);exit;
或者:
$model=M('Peipeidui');
$m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
dump($m);exit;
结果:
表peipeidui所有数据被列出,SQL注入语句起效.
解决方法:
可将parseSql函数修改为:
protected function parseSql($sql,$parse) {
// 分析表达式
if(true === $parse) {
$options = $this->_parseOptions();
$sql = $this->db->parseSql($sql,$options);
}elseif(is_array($parse)){ // SQL预处理
$parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码
$sql = vsprintf($sql,$parse);
}else{
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
}
$this->db->setModel($this->name);
return $sql;
}
总结:
1.不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
2.不建议直接用$_GET,$_POST
php的mssql数据库连接类实例
php最简单的删除目录与文件实现方法
php查找指定目录下指定大小文件的方法
thinkphp四种url访问方式详解
thinkphp数据查询和遍历数组实例
thinkphp模板用法和内容输出实例
配置php.ini实现PHP文件上传功能
thinkphp的URL路由规则与配置实例
thinkphp文件引用与分支结构用法实例
PHP中mysql_field_type()函数用法
thinkphp区间查询、统计查询与SQL直接查询实例分析
php中addslashes函数与sql防注入
php中使用session_set_save_handler()函数把session保存到MySQL数据库实例
PHP不用递归遍历目录下所有文件的代码
PHP+Memcache实现wordpress访问总数统计(非插件)
php+memcache实现的网站在线人数统计代码
PHP轻量级数据库操作类Medoo增加、删除、修改、查询例子
php使用pack处理二进制文件的方法
PHP源码分析之变量的存储过程分解
ThinkPHP让分页保持搜索状态的方法
ThinkPHP实现批量删除数据的代码实例
Thinkphp中import的几个用法详细介绍
改写ThinkPHP的U方法使其路由下分页正常
浅析ThinkPHP的模板输出功能
PHP登录环节防止sql注入的方法浅析
编译PHP报错configure error Cannot find libmysqlclient under usr的解决方法
ThinkPHP2.0读取MSSQL提示Incorrect syntax near the keyword 'AS'的解决方法
Thinkphp实现MySQL读写分离操作示例
PHP获取MySql新增记录ID值的3种方法