Pinkie,感謝您發佈的代碼。
$sql = 'SELECT a.videote as videote, b.user_name as user_name'.
' FROM '.$video.' as a,'.$users.' as b'.
' where b.user_name=$_GET['user'] and... //if i replace $_GET['user'] with john then it works
這裏有幾個問題,但我們可以通過它們。
更改字符串時會引入語法錯誤。你有正確的想法$video
和$users
。但是,在添加$_GET['user']
時,PHP認爲第一個撇號正在結束當前字符串。
考慮以下因素:
' where b.user_name=$_GET['user'] and...'
看起來像兩個字符串,由單詞 「用戶」 分隔:
' where b.user_name=$_GET[' user '] and...'
這不是正確的語法,所以返回500錯誤。我猜,如果你想你的錯誤會消失:
' where b.user_name=' . $_GET['user'] . ' and...'
下一個問題是,如果用戶要發送一個精心製作的價值,爲「用戶」的參數,它們可能會導致查詢的行爲以你不打算的方式。
試試這個:創建一個名爲的login.php文件,包含以下內容:
<?php
// Just display the output; no HTML formatting needed
header("Content-Type: text/plain");
// This must succeed, or mysql_real_escape_string() won't have any effect
mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
$safeQuery = 'SELECT count(*) FROM users WHERE user=\'' . mysql_real_escape_string($_GET['username']) . '\' AND pass=\'' . mysql_real_escape_string($_GET['password']) . '\';';
echo " safeQuery is: $safeQuery\n";
$unsafeQuery = 'SELECT count(*) FROM users WHERE user=\'' . $_GET['username'] . '\' AND pass=\'' . $_GET['password'] . '\';';
echo "unsafeQuery is: $unsafeQuery\n";
?>
負載login.php?username=bob&password=sample
。輸出看起來合理的:
safeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample';
unsafeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample';
現在嘗試加載login.php?username=bob&password=sample' OR 'hello'='hello"
:
safeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample\' OR \'hello\'=\'hello';
unsafeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample' OR 'hello'='hello';
的安全查詢將返回零,除非你有一個叫鮑勃其密碼真的是sample' OR 'hello'='hello"
用戶。
但是,不安全的版本將返回數據庫中用戶的總數。 WHERE子句現在是:
WHERE user='bob' AND pass='sample' OR 'hello'='hello'
的OR 'hello'='hello'
將在所有情況下,條件爲真,即使bob
不存在或具有比其他sample
密碼。
部分查詢甚至可能被註釋掉。嘗試login.php?username=bob' --
:
safeQuery is: SELECT count(*) FROM users WHERE user='bob\' --' AND pass='';
unsafeQuery is: SELECT count(*) FROM users WHERE user='bob' --' AND pass='';
password參數現在被忽略,因爲它嵌入在SQL註釋中。
因此,即使您只是執行SELECT語句,如果其輸入未被轉義,結果也可以由聰明的用戶操縱。
您可以使用mysql_real_escape_string來防止這些不良值。此功能將在必要時添加反斜槓,以防止輸入數據作爲SQL執行。
$sql = 'SELECT a.videote as videote, b.user_name as user_name'.
' FROM '.$video.' as a,'.$users.' as b'.
' where b.user_name=\'' . mysql_real_escape_string($_GET['user']) . '\' and...';
實施例1從php.net page for mysql_real_escape_string具有使用sprintf的一個很好的例子:
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
每個%s
被替換爲參數(在它們的順序依次指定)。這樣可以更輕鬆地保持查詢的可讀性,同時防止錯誤的輸入數據。
你可以發佈相關的代碼位?另外,加載x.php或content.php時是否返回服務器錯誤? – GargantuChet 2011-06-03 01:58:31
@GargantuChe檢查更新的文章 – Pinkie 2011-06-03 02:09:26
@GargantuChe也500錯誤是由content.php而不是x。php – Pinkie 2011-06-03 02:10:07