The following is an official thinkphp announcement. It is very irresponsible to officially post these things directly. It is the same behavior as the code execution of Struts2 published by apache, this will cause many users to be hacked.Vendors with similar suggestions should not do such stupid things.ThinkPHP 3.1.3 and earlier versions have the SQL injection vulnerability in ThinkPHP/Lib/Core/Model. class. php files according to the official documentation on the "Prevent SQL injection" method interpretation (see the http://doc.thinkphp.cn/manual/ SQL _injection.html) using the query condition preprocessing can prevent SQL injection, yes, when using the following code can play a role: $ 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:The parseSql function in the ThinkPHP/Lib/Core/Model. class. php file does not implement SQL filtering. Original 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 $ 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 = % 221action 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. The SQL Injection statement takes effect.
Solution: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:Do not rely too much on the underlying SQL filter of TP. Do not use $ _ GET, $ _ POST directly for security checks.