2010-03-31 79 views
2

我得到這個從登錄表單教程說明:這個SQL消毒代碼

function sanitize($securitystring) { 
     $securitystring = @trim($str); 
     if(get_magic_quotes_gpc()) { 
      $securitystring = stripslashes($str); 
     } 
     return mysql_real_escape_string($securitystring); 
    } 

能有一個人正是這樣做解釋?我知道後來調用'乾淨'變種來清理田地;即$email = sanitize($_POST['email']);

回答

2

首先,這段代碼是錯誤的。
它有錯誤的意思和錯誤的名稱。

沒有SQL數據準備代碼進行任何清理或消毒。 它只是逃避。而這種逃避必須是無條件的。 和逃逸不應該混入其他任何東西。

所以,它必須是三個分開的功能,而不是一個。

  1. 擺脫魔術引號。必須在數據輸入處單獨完成。
  2. 如果你願意修剪。這只是文本美化,沒有關鍵功能。
  3. mysql_real_escape_string()爲SQL查詢準備數據。

所以,這裏唯一與mysql有關的函數是mysql_real_escape_string()。儘管它沒有提供任何數據「乾淨」,但僅僅是避開了分隔符。因此,必須使用此功能只有與數據被視爲一個字符串,並用引號括起來。所以,這是一個很好的例子:

$num=6; 
$string='name'; 
$num=mysql_real_escape_string($num); 
$string=mysql_real_escape_string($string); 
$query="SELECT * FROM table WHERE name='$name' AND num='$num'"; 

而這個例子是錯誤的:

$num=6; 
$string='name'; 
$num=mysql_real_escape_string($num); 
$string=mysql_real_escape_string($string); 
$query2="SELECT * FROM table WHERE name='$name' AND num=$num"; 

即使$ QUERY2不會拋出一個語法錯誤,這是錯誤的數據準備和mysql_real_escape_string將幫助這裏沒有什麼。所以,這個函數只能用於轉義被視爲字符串的數據。儘管可以對任何數據類型進行操作,但也有一些例外,例如LIMIT參數,不能將其視爲字符串。

6

基本上,如果你有魔術引號開啓時,在POST /會話數據的特殊字符會自動進行轉義(同應用和addslashes ()到字符串)。 MySQL轉義函數比PHP的addslashes()更好(儘管我不記得確切的原因)。

你的代碼的作用是檢查php.ini文件是否啓用了魔術引號,如果是這樣,斜線從數據中除去,然後使用MySQL函數重新清理。如果魔術引號沒有打開,則不需要去除斜線,因此數據只需使用MySQL函數進行消毒並返回即可。

+1

@Moonshield,MAGIC QUOTES功能已被棄用,所以我們不應該依賴它。另外,如你所說,MySQL功能更好。 MySQL轉義函數轉義所有MySQL特定的特殊字符。 MAGIC QUOTES只會引用引號,反斜槓和空字符。 – 2010-03-31 13:27:52

+0

有一些奇怪的情況,在SO上廣泛宣傳,當addslashes會失敗並出現一些罕見的數據集時。 – 2010-03-31 13:57:16

0

mysql_real_escape_string用於轉義字符串中的字符以將反斜槓添加到字符,如',這可防止攻擊者將其他SQL語句嵌入到字符串中。如果字符串未被轉義,則可以附加額外的SQL。例如,可能會執行以下內容:

SELECT * FROM tbl WHERE col ='test'; DELETE * FROM tbl; SELECT'擁有'

magic_quotes確實轉義了它自己,雖然如果我沒記錯的話現在它的使用已經不受歡迎了。此外,MySQL函數將完成所有需要防止SQL注入攻擊的轉義。

+0

如果數據沒有被轉義**並且沒有用引號**括起來,可以附加額外的SQL。每個人都會忘記這部分 – 2010-03-31 13:35:54

0

一些(舊)服務器已啓用magic_quotes。這意味着所有的外部輸入都被修改爲(假定)將其轉義以便在MySQL查詢中注入。所以O'Brian變成O\'Brian。這是由PHP團隊的早期設計的決定,證明是錯誤的:

  • 你並不總是需要注入輸入到數據庫查詢
  • 並不是所有DB引擎使用反斜槓作爲轉義字符
  • 逃逸單與背部斜線的報價是不夠的,即使對MySQL
  • 你的服務器的安全性依賴於可被禁用

一個PHP設定所以這是沒有辦法magic_quotes的更好的代碼。問題出現在可重新分發的代碼中:您無法知道服務器是否啓用或禁用了magic_quotes。因此,您可以使用get_magic_quotes_gpc()來檢測它們是否處於開啓狀態,如果是,則使用stripslashes()來(嘗試)恢復原始輸入。