Home  >  Article  >  php教程  >  ThinkPHP 3.1.3及之前的版本存在一个SQL注入漏洞

ThinkPHP 3.1.3及之前的版本存在一个SQL注入漏洞

WBOY
WBOYOriginal
2016-06-07 11:44:261504browse

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) {<br>         // 分析表达式<br>         if(true === $parse) {<br>             $options =  $this->_parseOptions();<br>             $sql  =   $this->db->parseSql($sql,$options);<br>         }elseif(is_array($parse)){ // SQL预处理<br>             $sql  = vsprintf($sql,$parse);<br>         }else{<br>             $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));<br>         }<br>         $this->db->setModel($this->name);<br>         return $sql;<br>     }验证漏洞(举例):
请求地址:
http://localhost/Main?id=boo" or 1="1

http://localhost/Main?id=boo%22%20or%201=%221
action代码:$model=M('Peipeidui');<br>         $m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);<br>         dump($m);exit;$model=M('Peipeidui');<br>         $m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));<br>         dump($m);exit;结果:
表peipeidui所有数据被列出,SQL注入语句起效.

解决办法:
将parseSql函数修改为:protected function parseSql($sql,$parse) {<br>         // 分析表达式<br>         if(true === $parse) {<br>             $options =  $this->_parseOptions();<br>             $sql  =   $this->db->parseSql($sql,$options);<br>         }elseif(is_array($parse)){ // SQL预处理<br>             $parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码<br>             $sql  = vsprintf($sql,$parse);<br>         }else{<br>             $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));<br>         }<br>         $this->db->setModel($this->name);<br>         return $sql;<br>     }总结:
不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
不建议直接用$_GET,$_POST

AD:真正免费,域名+虚机+企业邮箱=0元

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:ThinkPHP整合百度UeditorNext article:简单的ajax封装