| 類型 | 原理 | 範例 | 危害 |
|---|---|---|---|
| 1. 未過濾轉義字元 | 單引號閉合原查詢,注入任意 SQL | ' OR '1'='1 → 繞過登入 | 資料洩露、繞過驗證 |
| 2. 型別處理不當 | 數值欄位未驗證型別,直接拼接 | 1; DROP TABLE users | 資料破壞、結構破壞 |
| 3. 資料庫引擎漏洞 | MySQL mysql_real_escape_string() 編碼繞過 | 特定字元集下繞過跳脫 | 繞過防護 |
| 4. 盲目注入 | 無回顯,透過邏輯判斷 (真/假、延遲、錯誤) 推測資料 | IF (SELECT SUBSTRING(pwd,1,1)='a') WAITFOR DELAY '0:0:5' | 逐位元竊取敏感資料 |
| 5. 條件回應 | 頁面根據邏輯真假顯示不同內容 | AND 1=1 正常 / AND 1=2 異常 | 確認注入點 |
| 6. 條件錯誤 | 強制產生錯誤 (除零、轉換失敗) 判斷真假 | CASE WHEN (SELECT 1) = 1 THEN 1/0 ELSE 1 END | 繞過 WAF、提取資料 |
| 7. 時間延遲 | 注入長耗時操作 (WAITFOR、重度運算) 計時判斷 | WAITFOR DELAY '0:0:10' | 無回顯環境提取資料 |
inurl:.asp、inurl:.aspx 表單頁// 錯誤:字串拼接
string sql = "SELECT * FROM Users WHERE Name = '" + userName + "'";
// 正確:參數化
string sql = "SELECT * FROM Users WHERE Name = @Name";
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add("@Name", SqlDbType.NVarChar, 50).Value = userName;
// 執行...
}
PreparedStatement ps = conn.prepareStatement("SELECT * FROM Users WHERE Name = ?");
ps.setString(1, userName);
ResultSet rs = ps.executeQuery();
$stmt = $pdo->prepare("SELECT * FROM Users WHERE Name = :name");
$stmt->execute([':name' => $userName]);
cursor.execute("SELECT * FROM Users WHERE Name = ?", userName)
DENY EXECUTE ON xp_cmdshell-- 僅用於結構描述/物件名稱動態,資料值仍用參數
DECLARE @Schema SYSNAME = QUOTENAME(@InputSchema) -- QUOTENAME 防注入
DECLARE @Table SYSNAME = QUOTENAME(@InputTable)
DECLARE @SQL NVARCHAR(MAX) = N'SELECT * FROM ' + @Schema + N'.' + @Table + N' WHERE Id = @Id'
EXEC sp_executesql @SQL, N'@Id INT', @Id
QUOTENAME() 安全包裝識別碼sp_executesql 參數化資料值EXEC('SQL ' + @Input)在所有輸入框輸入 ' (單引號) → 若頁面拋錯 (黃畫面、500、SQL 錯誤訊息) → 99.9% 存在注入漏洞。