Detailed analysis of a SQL injection vulnerability in early versions of the ThinkPHP framework_PHP Tutorial

WBOY
Release: 2016-07-13 10:26:35
Original
884 people have browsed it

There was an announcement on the ThinkPHP official website stating that there is a SQL injection vulnerability in ThinkPHP 3.1.3 and previous versions. The vulnerability exists in the ThinkPHP/Lib/Core/Model.class.php file
According to the official documentation, the method of "preventing SQL injection" is explained (refer to http://doc.thinkphp.cn/manual/sql_injection.html)
Using query condition preprocessing can prevent SQL injection. Yes, it can be effective when using the following code:

$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();
Copy after login

or

$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
Copy after login

However, when you use the following code, there is no "preventing SQL injection" effect (but the official document says that it can prevent SQL injection):

$model->query('select * from user where id=%d and status=%s',$id,$status);
Copy after login

or

$model->query('select * from user where id=%d and status=%s',array($id,$status));
Copy after login

Cause analysis:

The parseSql function in the ThinkPHP/Lib/Core/Model.class.php file does not implement SQL filtering.
Its original function is:

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;
}
Copy after login

Verification vulnerability (example):
Request address:

http://localhost/Main?id=boo" or 1="1
Copy after login

or

http://localhost/Main?id=boo%22%20or%201=%221
Copy after login

action code:

$model=M('Peipeidui');
$m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);
dump($m);exit;
Copy after login

or:

$model=M('Peipeidui');
$m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
dump($m);exit;
Copy after login

Result:

All data in table peipeidui is listed, and the SQL injection statement takes effect.

Solution:

The parseSql function can be modified to:

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;
}
Copy after login

Summary:
1. Don’t rely too much on TP’s underlying SQL filtering. Programmers must do security checks
2. It is not recommended to use $_GET, $_POST directly

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/824645.htmlTechArticleThere was an announcement on the ThinkPHP official website stating that there is a SQL injection vulnerability in ThinkPHP 3.1.3 and previous versions. The vulnerability exists in the ThinkPHP/Lib/Core/Model.class.php file. According to the official documentation...
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template