Home  >  Article  >  Backend Development  >  Detailed analysis of a SQL injection vulnerability in early versions of the ThinkPHP framework_PHP Tutorial

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

WBOY
WBOYOriginal
2016-07-13 10:26:35885browse

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();

or

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

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);

or

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

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;
}

Verification vulnerability (example):
Request address:

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

or

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

action code:

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

or:

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

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;
}

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...
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