首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 單位元組與寬字節 SQL 注入原理與防禦

     編輯:MySQL 資料庫相關知識

一、單位元組 SQL 注入

常見攻擊步驟

  1. 判斷注入點:在 GET 參數加 /* 或 #(MySQL 註釋),如 id=1607 and 1=1/*。
  2. 猜解欄位數:ORDER BY n 遞增直到報錯,得知欄位數。
  3. 聯合查詢竊取資料:UNION SELECT username,password,1,2,3 FROM user 將管理帳號密碼顯示於前端。

防禦措施

  • 資料過濾:在適當位置嚴格驗證輸入格式、長度、型別。
  • 統一加單引號:所有資料型別在 SQL 中皆以單引號包裹,避免數值型注入。
  • 轉義處理:使用 mysql_real_escape_string()(PHP)或驅動程式提供的參數化查詢(Prepared Statement),addslashes() 為最後備援。

二、寬字節注入

原理

當連線字符集為 GBK 等多位元組編碼時,%df' 經 addslashes 轉義變 %df\'(\ 為 %5c)。MySQL 以 GBK 解碼時,%df%5c 被視為一個雙位元組字元「縗」,單引號得以「倖存」並閉合 SQL 語句。

攻擊範例

$conn = mysql_connect("localhost","root","pwd");
mysql_query("SET NAMES 'GBK'");
$user = mysql_escape_string($_GET['user']);
$pass = mysql_escape_string($_GET['pass']);
$sql = "SELECT * FROM cms_user WHERE username='$user' AND password='$pass'";

攻擊 URL:login.php?user=%df' OR 1=1 LIMIT 1,1%23&pass=
實際 SQL:SELECT * FROM cms_user WHERE username='縗' OR 1=1 LIMIT 1,1#' AND password=''

根本解決方案

連線建立並設定字符集後,強制客戶端字符集為二進制:

mysql_query("SET character_set_client=binary");

或改用 mysqli/PDO 參數化查詢,完全避開字元編碼陷阱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved