Detailed analysis of an SQL injection vulnerability in earlier versions of the ThinkPHP framework

Source: Internet
Author: User

On the ThinkPHP official website, an announcement pointed out that the SQL injection vulnerability exists in ThinkPHP 3.1.3 and earlier versions. The vulnerability exists in the ThinkPHP/Lib/Core/Model. class. php file.
Explanation of the "SQL Injection prevention" approach (refer to the http://doc.thinkphp.cn/manual/ SQL _injection.html) according to the official documentation)
The use of query condition preprocessing can prevent SQL injection. That's right, it can be effective when the following code is used:

$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, it does not have the effect of "preventing SQL injection" (but the official documentation says 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.
The original function is:

Protected function parseSql ($ SQL, $ parse) {// analysis expression if (true ===$ parse) {$ options = $ this-> _ parseOptions (); $ SQL = $ this-> db-> parseSql ($ SQL, $ options);} elseif (is_array ($ parse )) {// SQL preprocessing $ SQL = vsprintf ($ SQL, $ parse);} else {$ SQL = strtr ($ SQL, array ('_ TABLE _' => $ this-> getTableName (), '_ PREFIX _' => C ('db _ prefix ')));} $ this-> db-> setModel ($ this-> name); return $ SQL ;}

 

Vulnerability verification (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 the peipeidui table is listed, and the SQL Injection statement takes effect.
 
Solution:

You can modify the parseSql function:

Protected function parseSql ($ SQL, $ parse) {// analysis expression if (true ===$ parse) {$ options = $ this-> _ parseOptions (); $ SQL = $ this-> db-> parseSql ($ SQL, $ options);} elseif (is_array ($ parse )) {// SQL preprocessing $ parse = array_map (array ($ this-> db, 'escapestring'), $ parse ); // code $ SQL = vsprintf ($ SQL, $ parse) added for this behavior;} else {$ SQL = strtr ($ SQL, array ('_ TABLE _' => $ this-> getTableName (), '_ PREFIX _' => C ('db _ prefix ')));} $ this-> db-> setModel ($ this-> name); return $ SQL ;}

Summary:
1. Do not rely too much on the underlying SQL filter of TP. programmers should perform security checks.
2. It is not recommended to use $ _ GET, $ _ POST directly.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.