2012-08-05 64 views
-1

可能重複:
Best way to prevent SQL Injection in PHPPDO和hash來防止SQL注入

我試圖插入用戶輸入到數據庫中。
這是PDO和散列足夠安全:

$dbh = new PDO("mysql:host=hostName; dbname=dbName", "user", "pass"); 
if(isset($_POST['Submit'])) 
{ 
$user = $_POST['user']; 
$pass = $_POST['pass']; 
$salt = substr(str_replace('+', '.', base64_encode(sha1(microtime(true), true))), 0, 22); 
$hash = crypt($pass, '$2a$12$' . $salt); 
$mail = $_POST['mail']; 
$confirm_key=md5(uniqid(rand())); 

$sth = $dbh->prepare("INSERT INTO members(user, pass, mail, confirm_key) 
VALUES ('$user', '$hash', '$mail', '$confirm_key')"); 
$sth->execute(); 
+0

不可以。不要通過將字符串混合在一起(特別是當它們包含用戶數據時,特別是在它們包含未修改的用戶數據(例如用戶和郵件)時加倍)來構建SQL。 – Quentin 2012-08-05 12:40:51

+1

自上次您詢問[相同問題](http://stackoverflow.com/questions/11805986/pdo-to-prevent-sql-injection)上次關於此代碼的迭代以來,您已*添加*問題。 – Quentin 2012-08-05 12:42:31

+2

如果您希望人們查看您的代碼,請在[codereview](http://codereview.stackexchange.com/)上詢問,而不是在這裏。 – Quentin 2012-08-05 12:42:53

回答

2

您濫用準備好的聲明,您的代碼更改爲:

$stmt = $dbh->prepare("INSERT INTO members(user, pass, mail, confirm_key) VALUES (:user, :hash,:mail,:confirm)"); 
$stmt->bindParam(':user', $user); 
$stmt->bindParam(':hash', $hash); 
... 

詳情請參閱here

+0

謝謝ftom2,我會嘗試 – Alegro 2012-08-05 12:49:10

4

對於什麼是SQL注入以及爲什麼我們需要散列密碼,您似乎有點困惑。

完成密碼哈希(和醃製),以便數據庫包含足夠的信息來驗證密碼,但不足以檢索它。如果攻擊者獲得(離線)訪問數據庫的權限,她仍然無法讀出任何密碼而不破解安全哈希。爲此,你的代碼看起來很合理。

SQL注入是一個完全不同的野獸。漏洞通過向您的PHP代碼發送值,當插入到動態SQL查詢中時,它會以有趣的方式破壞它,以便查詢現在可以完成與它打算做的不同的事情。例如,用戶可以爲$user提供一個值,該值保持INSERT查詢的有效性,但會跳出引用的字符串並添加第二個查詢,這可能會造成一些有害影響,例如在每個其他用戶的密碼哈希上覆蓋已知值攻擊者可以登錄到他們想要的任何帳戶(包括管理帳戶)。

防止SQL注入的最佳方法是通過參數化查詢,該PDO提供了開箱即用的功能;你並沒有使用它們,所以你的代碼很脆弱。閱讀documentation on PDO's parametrized queries;如果您不確定自己的工作方式,請隨時回來再問一次。

+0

非常感謝,tdammers。 – Alegro 2012-08-05 12:48:16