對於ThinkPHP框架早期版本的一個SQL隱碼攻擊漏洞詳細分析

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

ThinkPHP官網上曾有一段公告指出,在ThinkPHP 3.1.3及之前的版本存在一個SQL隱碼攻擊漏洞,漏洞存在於ThinkPHP/Lib/Core/Model.class.php 檔案
根據官方文件對”防止SQL隱碼攻擊”的方法解釋(參考http://doc.thinkphp.cn/manual/sql_injection.html)
使用查詢條件預處理可以防止SQL隱碼攻擊,沒錯,當使用如下程式碼時可以起到效果:


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

或者


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

但是,當你使用如下程式碼時,卻沒有”防止SQL隱碼攻擊”的效果(但是官方文件卻說可以防止SQL隱碼攻擊): 


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

或者


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

原因分析:

ThinkPHP/Lib/Core/Model.class.php 檔案裡的parseSql函式沒有實現SQL過濾.
其原函式為: 


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

 

驗證漏洞(舉例):
請求地址:


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


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

action程式碼: 


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

或者:


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

結果:

表peipeidui所有資料被列出,SQL隱碼攻擊語句起效.
 
解決方法:

可將parseSql函式修改為: 


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

總結:
1.不要過分依賴TP的底層SQL過濾,程式設計師要做好安全檢查
2.不建議直接用$_GET,$_POST

您可能感興趣的文章:

thinkphp中多表查詢中防止資料重複的sql語句(必看)Thinkphp實現MySQL讀寫分離操作示例thinkphp區間查詢、統計查詢與SQL直接查詢例項分析ThinkPHP結合ajax、Mysql實現的客戶端通訊功能程式碼示例thinkPHP連線sqlite3資料庫的實現方法(附Thinkphp程式碼生成器下載)thinkPHP使用pclzip打包備份mysql資料庫的方法thinkphp3.x連線mysql資料庫的方法(具體操作步驟)thinkphp下MySQL資料庫讀寫分離程式碼剖析thinkPHP框架中執行原生SQL語句的方法

相關文章

程式語言 最新文章