2011-11-27 74 views
3

我已經發布了關於此之前,但從來沒有在這方面,所以請看看:這將如何影響防止SQL注入的機會?

我被告知一種方法來做sql注入是使用1 = 1,其中有人可以看到所有不屬於他們。

但可以說,構建我的查詢,以便它也選擇了當前用戶的USER_ID,將這項工作:

$userid = Current users stored id in database; 
    $postid = mysql_real_escape_string($_GET['id']); 

現在讓我們假設我進入:domain.com/page.php?id='' OR '1'='1'

Select article_name from table where user_id=$userid and post_id=$postid 

查詢是否仍會返回所有內容,否則將不會返回,因爲我添加了User_id屏障?

回答

3

mysql_real_escape_string()僅用於消毒字符串。它不能保護SQL注入中未包含引號的整數,因此您的觀察結果是正確的:儘管mysql_real_escape_string()是上述內容,但確實不安全。

你需要或者用引號括你的價值觀:

Select article_name from table where user_id='$userid' and post_id='$postid' 

,或者確保$userid$postid是運行查詢之前整數。

+0

謝謝!如果$ userid類似於42343AKJKLJKLDJ,$ postid類似於34kAja,它會繼續工作,如果我使用int() –

+1

@Sam,但它們不會是整數,但字符串,不是嗎?在這種情況下,你可以將它們包裝在引號中,並保持安全 –

+0

我有點新,所以我不明白。整數是整數,但如果我有字母數字ID將它仍然工作,那麼如果我用int ..? –

4

如果使用PDO你不必擔心逃逸(在這種情況下)的數據:

$stmt = $pdo->prepare('SELECT article_name FROM table WHERE user_id = :userid AND post_id = :postid'); 
$stmt->execute(array(
    ':userid' => $userid, 
    ':postid' => intval($_GET['id']) //Just to be safe 
)); 

// You could also do this instead (thanks @Digital Precision) 
//$stmt->bindValue(':postid', $_GET['id'], PDO::PARAM_INT); 
//$stmt->execute(array(':userid' => $userid)); 

while($row = $stmt->fetch()) { 
    //Work with data 
} 

更多關於PDO看到PHP docs

使用mysql_real_escape_string()的問題在於,顧名思義它只能轉義字符串。它轉義了可用於終止字符串的字符,以便攻擊者無法關閉字符串並輸入惡意SQL。 如果你固執並拒絕使用PDO,你可以在任何unsanitized整數上使用intval()這樣的函數,以確保它們只包含數字。

$post_id = intval($_GET['id']); //Now $post_id can only be a number 
+0

不是100%正確 - 例如,PDO無法清理表名和列名。當然,您需要使用您在示例中顯示的準備好的語句。不過,對於所有OP的意圖和目的來說都是正確的 –

+0

@Pekka那裏的關鍵詞是「*你*不必擔心。」在這種情況下,PDO不需要轉義數據。但是,我看到這可能會被誤解,所以我會修改。謝謝! –

+0

您確定PDO將在幕後執行數據類型嗎?我總是顯式地鍵入:'$ stmt-> bindValue(':userid',$ userId,PDO :: PARAM_INT);' –

1

不知道你的意思是「有人告訴我做SQL注入一個方法是使用1 = 1,其中有人可以看出,不屬於他們所有條目」。

1 = 1總是計算爲真。我只有在應用程序生成的查詢只有條件where子句沒有root where子句的情況下才看到這一點。不知道它與防止sql注入有什麼關係。

+0

如果一個黑客使用他將能夠從表中返回所有條目... –

+1

有趣的是,我從來沒有聽說過這個,如果你運行或不使用1 = 1的查詢,你會得到相同的結果集。 –

1

您的查詢看起來像:

Select article_name from table where user_id=$userid and post_id=\'\' OR \'1\'=\'1\' 

至於其他提及,而我打字這一點,最好用你的價值觀。所以,你將有:

Select article_name from table where user_id=$userid and post_id='\'\' OR \'1\'=\'1\'' 

這將返回什麼,如果沒有這樣的ID後。

因此,您的查詢不會返回當前用戶的每篇文章。但請記住引用你的價值觀。