2012-08-08 148 views
1

我讀了很多關於常見SQL注入的東西,所以對如何解決它們感興趣。在我剛剛使用 addslashes()之前,我認爲它很合適。然後我發現mysql(i)_real_escape_string()addslashes()更有用和可信。從那時起我使用mysqli_real_escape_string(),但最近我陷入了一些我還沒有真正理解的東西。 我有一些關於發送數據到MySQL和字符集的問題。 因此,我再次搜索,許多用戶表示SET NAMES UTF8是讓所有事情順利進行的方法。 但後來我讀到,使用該查詢使得mysqli_real_escape_string()無法正常工作。轉義sql語句的正確方法是什麼?

所以畢竟我有點困惑。

轉義sql語句的正確方法是什麼?

使用SET NAMES UTF8有什麼可能的漏洞利用?

mysqli_set_charset()使連接在指定字符集中通信的正確方法是什麼?

使用mysqli_sey_charset()是mysql的內部變量cchanged在這個過程中嗎?

感謝

+0

請編輯您的文章,並在'mysqli_real_escape_string()'處理之前和之後包含SQL示例。 – 2012-08-08 11:42:25

回答

0

只是爲了糾正問題和答案中的大量錯誤信息。

  1. 不是「聲明」,而是字符串文字。轉義「SQL語句」是一種直接注入方式。只有字符串必須轉義,而其他查詢部分需要截然不同的格式和轉義,對他們來說不會有絲毫好處。
  2. 所有轉義/編碼混亂只連接到一些邊際編碼,如GBK。使用UTF-8,您甚至可以使用addslashes()
  3. 由於5.3只要設置了DSN,PDO就可以設置客戶端編碼。

轉義sql語句的正確方法是什麼?

In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?

什麼是使用SET NAMES UTF8可能的漏洞?

是mysqli_set_charset()的正確途徑,以指定的charset的連接進行通信?

當然。
必須使用HTML頁面上使用的實際字符集。

2

您可以使用mysqli prepared statements避免SQL注入 - 而不需要擔心字符集編碼。

來自鏈路的一個例子:

<?php 
$mysqli = new mysqli("localhost", "my_user", "my_password", "world"); 

/* check connection */ 
if (mysqli_connect_errno()) { 
    printf("Connect failed: %s\n", mysqli_connect_error()); 
    exit(); 
} 

$city = "Amersfoort"; 

/* create a prepared statement */ 
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) { 

    /* bind parameters for markers */ 
    $stmt->bind_param("s", $city); 

    /* execute query */ 
    $stmt->execute(); 

    /* bind result variables */ 
    $stmt->bind_result($district); 

    /* fetch value */ 
    $stmt->fetch(); 

    printf("%s is in district %s\n", $city, $district); 

    /* close statement */ 
    $stmt->close(); 
} 

/* close connection */ 
$mysqli->close(); 
?> 
+0

不能使用此方法。我也想知道事情是如何工作的。 – Kei 2012-08-09 14:57:31

+0

@kei爲什麼你不能使用這種方法? – Fluffeh 2012-08-09 14:59:59

+0

正如我所說我想了解事情如何工作,所以我的問題是確切的。 然後,在這個項目中我們決定使用標準方法,所以我不能只是說「嘿,讓我們用這種方式做所有事情吧」。 – Kei 2012-08-09 15:11:56

0

傳遞手動構造查詢僅由於向後兼容性問題的支持。現代應用程序絕不應該這樣做,而是使用預處理語句。儘管如此,如果您使用手動構建的查詢已經死了,正確的方法是使用mysql_real_escape_string()並將編碼設置爲UTF-8。

你可以找到在OWASP網站的詳細信息:https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

0

只要你明確地設置字符集連接對象的,你應該罰款:

mysql_set_charset('utf8', $db); // for mysql 
$db->set_charset('utf8'); // for mysqli 

同樣的問題與字符集適用於PDO預處理語句,因此PDO是推薦的方式,但在這種情況下它不會使您安全。

使用mysqli_real_escape_string()和定義的字符集沒有任何問題。請注意,您使用UTF-8作爲連接對象以及HTML頁面,這樣可以避免很多問題。

我發現這個主題的最好解釋是從PHP作者ircmacell,一次爲mysql_real_escape_string(),一次爲PDO

相關問題