2016-12-08 93 views
0

我建設有select, insert, delete, update功能的PDO包裝,其實我所做的看起來是這樣的更新functon:Pdo包裝功能是否安全?

/** 
* @param string $table name of the table 
* @param array $data data to update 
* @param string $where where clause 
* @return bool result 
*/ 
public function update($table, $data, $where) 
{ 
    ksort($data); 

    $fieldDetails = NULL; 
    foreach($data as $key=> $value) 
    { 
     $fieldDetails .= "`$key`=:$key,"; 
    } 
    $fieldDetails = rtrim($fieldDetails, ','); 

    $sth = $this->prepare("UPDATE $table SET $fieldDetails WHERE $where"); 

    foreach ($data as $key => $value) 
    { 
     $sth->bindValue(":$key", $value); 
    } 

    return $sth->execute(); 
} 

使用的例子:

$postData = array(
     'username' => 'foo', 
     'role' =>'admin' 
    ); 

$this->db->update('login', $postData, "`id` = {$data['id']}"); 

我不知道這是安全的,或者我錯過了一些重要的東西,有人建議改善這一點?

在此先感謝。

+0

它取決於'$ data'中的值來自哪裏。如果他們來自用戶輸入,那麼你可以得到SQL注入。如果這是一個像'$ postData'這樣的數組,那麼會更好,並且您也使用了'bindValue'。 – Barmar

+0

@Barmar是來自用戶輸入.. – AgainMe

+0

然後你應該使用'bindValue',或者至少在$ where $> escape()' – Barmar

回答

2

不是,它不安全,有兩個原因。

  • 首先,$data['id']直接放到查詢中,因此不安全。它也必須受到約束。
  • 二,$key直接放到查詢中,因此不安全。我寫了一篇文章演示了這種漏洞並提供了一個解決方案:An SQL injection against which prepared statements won't help
  • 第三,$table直接放到查詢中,因此不安全。我知道的意思是在函數調用中被硬編碼,但是你問這裏這個函數是否安全,而我們不知道你是怎麼調用它的。
    此外,隨着項目的增長,難以對數據流進行手動控制。所以最終表名會成爲一個變量,有一天可能會從用戶輸入中接受。因此,最好讓你的功能本身難以理解,與任何外部事務無關。就像準備好的陳述一樣。

要修復後兩個漏洞,您應該將您的密鑰列入白名單,或者至少應正確格式化它們。而它應該完成這個功能。否則,你決不能說它是安全的。

+0

謝謝我會調整您的建議。 – AgainMe

-1

我偶然發現你的問題來自https://laurent22.github.io/so-injections/這是一個關於SO與SQL注入漏洞的PHP相關問題的統計數據。

所以,沒有。這是不安全的,因爲它現在。

這是報告的弱點,我在此引用它以備將來參考。

$sth = $this->prepare("UPDATE $table SET $fieldDetails WHERE $where"); 

毫無疑問,這被用在很多代碼中,在很多軟件中。希望這對其他人也有用。

+0

爲什麼downvote而不解釋? – zzz

+0

答案錯了嗎?它是否是安全代碼? – zzz