2016-08-04 105 views
0

我的網站似乎在過去幾天遭受了幾次MySQL注入攻擊,導致我的用戶數據庫受到一些(幸好大多是可修復的)損害。我發現這一點,因爲我的網站被記錄與用戶ID的新用戶:防止SQL注入谷歌登錄

999999.9 /**/uNiOn/**/aLl /**/sElEcT 0x39313335313 

(我不能肯定什麼上面的查詢設計做改變我的用戶表的每一行所涉及的實際損害。使它看起來像每個用戶最近登錄。奇怪,但表明他們做了比我的日誌拾起更多的攻擊。)

這是通過我的谷歌登錄按鈕完成。我的登錄按鈕使用javascript與Google進行通信,然後通過GET將返回的用戶標識發送到我的下一頁(我決定是登錄還是註冊新帳戶)。這是正在被注入的GET查詢。

我使用MySQLi來完成我的SQL查詢。我非常善於處理PHP,並且已經使用了MySQL多年,但是非常非常地是一名業餘開發人員。我真的很感激任何有關如何確保這一點的建議。謝謝。

編輯:

這裏是我的代碼示例,按照要求:使用未保護的字符串連接或更換時出現

$db = new mysqli('localhost', 'XXX', 'XXX', 'seatingplan'); 

if($db->connect_errno > 0){ 
    die('Unable to connect to database [' . $db->connect_error . ']'); 
} 

$sql = <<<SQL 
    SELECT * 
    FROM `users` 
    WHERE `userid` = '$userid' 
SQL; 

if(!$result = $db->query($sql)){ 
    die('There was an error running the query [' . $db->error . ']'); 
} 


while($row = $result->fetch_assoc()){ 
    $useridcheck = $row['userid'] ; 
    $existingImageUrl = $row['image'] ; 
} 

$lastlogin = date("Y-m-d H:i:s") ; 

$sql = <<<SQL 
    UPDATE `users` 
    SET `lastlogin` = '$lastlogin', 
    `logins` = `logins` + 1 
    WHERE `userid` = '$userid' 
SQL; 


if(!$result = $db->query($sql)){ 
    die('There was an error running the query [' . $db->error . ']'); 
} 
+0

一個想法我有可能是一個安全的方式約束驗證GET以確保它看起來像Google用戶標識。這聽起來像是一個明智的事情嗎? – Rob

+0

我們需要代碼來說明這一點。 –

+0

@NorbertvanNobelen對不起,我已經添加了一個例子 – Rob

回答

3

SQL注入。 MySQLi和(更好的)PDO可以通過注意替換字符串以安全的方式來防止這些問題。這意味着字符串中的數據會被轉義,從而惡意代碼不會被執行。

問題的代碼在上面的代碼是:

$sql = <<<SQL 
    UPDATE `users` 
    SET `lastlogin` = '$lastlogin', 
    `logins` = `logins` + 1 
    WHERE `userid` = '$userid' 
SQL; 

在這裏$lastLogin$userid可如果開發商沒有檢查這些值被濫用。

用PHP PDO查詢應該是這樣的:

$sql = "UPDATE `users` 
    SET `lastlogin` = :lastlogin, 
    `logins` = `logins` + 1 
    WHERE `userid` = :userid" 

:lastlogin:userid然後使用PDO提供替換你的參數

+0

'mysqli'可以做到這一點,但由於它不支持指定的佔位符,你必須使用'?'。由於此功能,PDO更友好,而且PDO不是MySQL特定的。 – tadman

+0

@tadman我有很多代碼需要更新,所以可能會堅持MySQLi來減少我必須做出的改變。但是,我不知道我是否仍然能夠使用此代碼以'$ row ['whatever']'格式返回結果。 ($ row = $ result-> fetch_assoc()){ $ useridcheck = $ row ['userid']; $ existingImageUrl = $ row ['image']; }' – Rob

+0

我讀到的每個指南都使用參數化的msqli告訴我使用'$ statement-> bind_result(blah)'綁定結果。再次,我寧願避免這樣做,因爲這會導致更大的代碼更改。 – Rob