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


    ThinkPHP 3.1.3及之前的版本存在一个SQL注入漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件
    根据官方文档对"防止SQL注入"的方法解释(见http://doc.thinkphp.cn/manual/sql_injection.html)
    使用查询条件预处理可以防止SQL注入,没错,当使用如下代码时可以起到效果:

    1. $Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();
    复制代码

    或者

    1. $Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
    复制代码

    但是,当你使用如下代码时,却没有"防止SQL注入"效果(而官方文档却说可以防止SQL注入):

    1. $model->query('select * from user where id=%d and status=%s',$id,$status);
    复制代码

    或者

    1. $model->query('select * from user where id=%d and status=%s',array($id,$status));
    复制代码

    原因:
    ThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.
    原函数:

    1. protected function parseSql($sql,$parse) {
    2.         // 分析表达式
    3.         if(true === $parse) {
    4.             $options =  $this->_parseOptions();
    5.             $sql  =   $this->db->parseSql($sql,$options);
    6.         }elseif(is_array($parse)){ // SQL预处理
    7.             $sql  = vsprintf($sql,$parse);
    8.         }else{
    9.             $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
    10.         }
    11.         $this->db->setModel($this->name);
    12.         return $sql;
    13.     }
    复制代码

    验证漏洞(举例):
    请求地址:
    http://localhost/Main?id=boo" or 1="1

    http://localhost/Main?id=boo%22%20or%201=%221
    action代码:

    1. $model=M('Peipeidui');
    2.         $m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);
    3.         dump($m);exit;
    复制代码

    1. $model=M('Peipeidui');
    2.         $m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
    3.         dump($m);exit;
    复制代码

    结果:
    表peipeidui所有数据被列出,SQL注入语句起效.

    解决办法:
    将parseSql函数修改为:

    1. protected function parseSql($sql,$parse) {
    2.         // 分析表达式
    3.         if(true === $parse) {
    4.             $options =  $this->_parseOptions();
    5.             $sql  =   $this->db->parseSql($sql,$options);
    6.         }elseif(is_array($parse)){ // SQL预处理
    7.             $parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码
    8.             $sql  = vsprintf($sql,$parse);
    9.         }else{
    10.             $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
    11.         }
    12.         $this->db->setModel($this->name);
    13.         return $sql;
    14.     }
    复制代码

    总结:
    不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
    不建议直接用$_GET,$_POST

  • 相关阅读:
    ArcObjects
    Dojo是什么?
    百度地图是什么坐标系?
    高德地图API
    地理POI数据爬取-以百度地图为例
    Microsoft Help Viewer&ArcGIS Server二次开发.net篇 (一) 安装
    DevOps:Docker VS Kubernetes
    JUnit测试环境搭建
    嵌入式tomcat
    如何使用ABAP发送带有PDF格式附件的电子邮件
  • 原文地址:https://www.cnblogs.com/0daybug/p/12417140.html
Copyright © 2020-2023  润新知