2017-03-07 30 views
1

下面是一個例子查詢:不使用PDO :: PARAM可以安全地綁定嗎?

$sql = $db->prepare("INSERT INTO `accounts` 
    (`id`, `name`, `email`, `phoneNumber`, `country`, `city`, `addrLine1`, `company`, `zipCode`, `sha_pass_hash`, `ClientGroup`, `Newsletter`, `signedIN`) VALUES 
    (NULL, :name, :email, :phoneNumber, :country, :city, :addrLine1, :company, :zipCode, :sha_pass_hash, '1', '1', NOW())"); 
$sql->bindParam(':name',$name); 
$sql->bindParam(':email',$email); 
$sql->bindParam(':phoneNumber',$phoneNumber); 
$sql->bindParam(':country',$country); 
$sql->bindParam(':city',$city); 
$sql->bindParam(':addrLine1',$addrLine1); 
$sql->bindParam(':company',$company); 
$sql->bindParam(':zipCode',$zipCode); 
$sql->bindParam(':sha_pass_hash',$sha_pass_hash); 
$sql->execute(); 

由於當bindParam使用PDO::PARAMPDO::PARAM_STRPDO::PARAM_INT未設置就可以看到。

我的問題畢竟是: 當PDO::PARAM未設置時,該查詢是否可以SQL調用?

+1

你沒有義務來指定數據類型。如果你想要,你可以。它對安全性沒有影響,只有在值被提供給語句之前如何轉換。 – tadman

+1

**警告**:編寫您自己的訪問控制層並不容易,並且有很多機會使其嚴重錯誤。請不要在[Laravel](http://laravel.com/)等任何現代開發框架(http://codegeekz.com/best-php-frameworks-for-developers/)上編寫自己的認證系統,內置了強大的[認證系統](https://laravel.com/docs/5.4/authentication)。絕對不會遵循[推薦的安全最佳實踐](http://www.phptherightway.com/#security),並且從不使用SHA1 **等弱散列存儲密碼。 – tadman

+0

謝謝你的回答,但我的主要問題是「當PDO :: PARAM未設置時,此查詢是否可以SQL注入?我假設你」投票「是的,這是安全的嗎? –

回答

1

這是做正確的方式。 PARAM常數是爲了方便使用的,所以如果需要的話,您可以根據需要將您的數據轉換/轉換爲適當的類型。

有時候,這是相關的,則可能需要一定的值作爲整數插入非數值數據爲數字列時,爲了避免錯誤,但如果你準備捕獲和報告這些錯誤,你會在這裏有沒有問題。這可能是一個更好的解決方案,而不是靜靜地篡改數據。

+0

非常感謝你@tadman –

1

在我看來,這是完全安全的,忽略的數據類型。因爲變量被綁定爲引用,並且只會在調用PDOStatement :: execute()時進行評估。

並注意,使用PDOStatement對象時:: bindParam的整數。在PDOStatement對象改變爲字符串值::執行()。 (用MySQL測試)。

所以我用以下命令來運行查詢,這是scape框架

/** @var string|array $query 
*/ 
public function runQuery($query){ 
    /** @var \PDOStatement $statement 
    */ 
    $result=NULL; 

    $statement=$this->con->prepare(is_array($query)? $query['query']: $query); 

    try 
    { 
     $statement->execute(is_array($query)?$query['param']:null); 
     return $statement; 
    } 
    catch (\Exception $e) 
    { 
     if($e->errorInfo[1]==1062) 
      echo PHP_EOL."Duplicate Entry. Check your unique Entry such as username, ID etc.".PHP_EOL; 
     else if ($e->errorInfo[1]==1146) 
      echo PHP_EOL."Table ".$this->getName()." Not Found".PHP_EOL; 
     else 
      echo $e->getCode().": ".$e->getMessage(); 
     return false; 
    } 
} 
在我的函數調用

的一部分,$查詢是格式化的查詢或以下格式的陣列的任刺痛這是動態格式化。

$query= ["query" => $tmpQ, 
     "param" => [$search], 
     ] 
+1

看起來很大,但它總是建議綁定PARAM。 –

+0

謝謝你的建議。但是我在查詢中傳遞的數據事先進行了驗證和格式化。 –

相關問題