mysql_real_escape_string() 完美嗎?
雖然通常用於防範 SQL 注入攻擊,但 mysql_real_escape_string() 可以被規避,儘管是在罕見且複雜的情況下。
巧妙的攻擊
透過在高度特定的字元集中精心設計的有效負載,mysql_real_escape_string() 可以被利用。詳細介紹如下:
-
字元集選擇: 伺服器的連接字元集必須設定為既支援 ASCII 反斜線 ('') 又支援最終位元組為 ASCII ' 的字元。例如,“gbk”滿足此條件。
-
有效負載:選擇由位元組序列「0xbf27」組成的有效負載。在 'gbk' 中,它是一個無效字符,而在 'latin1' 中,它代表 '¿ ''。
-
mysql_real_escape_string(): MySQL 對此函數的實作識別連接字元集 (在本例中為「gbk」)並根據其規則套用轉義。但是,客戶端仍然認為連線正在使用“latin1”。因此,當它使用 'mysql_real_escape_string()' 對位元組序列進行轉義時,它會插入一個反斜線。
-
查詢: 結果字串包含一個自由懸掛的 ' 字元:'纓' OR 1=1 /*' in 'gbk'.這是攻擊所需的惡意負載。
明顯的漏洞
-
PDO 模擬語句:預設情況下,PDO模擬使用準備好的語句mysql_real_escape_string(),使其容易受到此攻擊
-
mysql_real_escape_string() 錯誤:在 MySQL 4.1.20 和 5.0.22 之前,mystring_real_escape_string()有一個錯誤,它將無效的多字節字元視為單一字節,即使客戶端是獲悉正確的連接編碼,允許此攻擊
-
PDO 的有限保護措施: PDO的DSN 字元集參數(在PHP ≥ 5.3.6 中引入)並非所有指令都一致支援。這為可利用性留下了空間。
消除陰影
-
安全字元集:利用「utf8」或「utf8mb4」等無懈可擊的字元集可以緩解這
-
NO_BACKSLASH_ESCAPES SQL模式:啟用此模式會改變 mysql_real_escape_string() 的功能,防止在易受攻擊的編碼中建立有效字元。
-
現代MySQL 版本和準備好的語句: MySQL 版本5.1(最新), 5.5 及更高版本以及真正的準備好的語句(例如,在MySQLi 中)不會受到此漏洞的影響。
總之,雖然 mysql_real_escape_string() 通常是有效的,但在特定情況下可能會被繞過。現代版本的 MySQL、適當的字元集選擇和真正的準備好的語句可確保完全防禦這種複雜的攻擊。
以上是`mysql_real_escape_string()` 是否真的能夠安全地防止 SQL 注入,或者是否有微妙的漏洞?的詳細內容。更多資訊請關注PHP中文網其他相關文章!