輸入長度限制 (如用戶名 16 字元、密碼 16 字元) 可阻擋部分長 Payload,但**極短惡意語句**同樣毀滅性:
-- 僅 12 字元即可關閉 SQL Server
';shutdown--
-- DROP TABLE 亦極短
drop table users
場景:應用先 **清洗轉義** (單引號 → ``),**再截斷長度**。
aaaaaaaaaaaaaaa' (末尾單引號)aaaaaaaaaaaaaa'' (17 字元,雙引號)aaaaaaaaaaaaaa' (單引號**倖存**!)'; shutdown--
SELECT * FROM Users
WHERE Username = 'aaaaaaaaaaaaaa''
AND Password = ''';shutdown--'
結果:`Username` 變為 `aaaaaaaaaaaaaa' AND Password='`,後接 `shutdown` 執行。
**修補**:**先截斷/驗證長度,再參數化**;或直接參數化 (長度由型別約束)。
SQL Server 內建保護:若批次文本含 `sp_password`,**整個批次文本在審計日志中被替換為註釋** (為隱藏明文密碼)。
-- 攻擊者利用此特性隱藏注入
Username: admin'--sp_password
-- 審計日志只見
-- 'sp_password' was found in the text of this event. The text has been replaced...
-- 實際執行的注入 SQL 被隱藏
**對策**:
-- 階段 1: 註冊 (參數化存入安全)
Username: admin'-- → 資料庫存 'admin''--'
-- 階段 2: 修改密碼頁面 (脆弱代碼)
var sql = "UPDATE Users SET Pass='" + newPass + "' WHERE User='" + dbUser.UserName + "'";
-- dbUser.UserName 來自資料庫,值為 admin''--
-- 執行 SQL:
UPDATE Users SET Pass='new' WHERE User='admin''--'
-- 等同: UPDATE Users SET Pass='new' WHERE User='admin' -- 註釋掉尾部單引號
-- 成功竄改 admin 密碼!
| 層面 | 核心措施 | 工具/技術 |
|---|---|---|
| 代碼層 | 參數化查詢 (唯一根治) | SqlParameter, PreparedStatement, ORM (EF/Dapper) |
| 輸入層 | 白名單驗證 (型別/長度/格式/範圍) | FluentValidation, DataAnnotations, 正則 |
| 資料庫層 | 最小權限帳號、移除危險擴展、審計 | GRANT 最小權限, sp_dropextendedproc, SQL Audit |
| 網路層 | WAF/RASP、防火牆限制來源 | ModSecurity, OpenRASP, 云 WAF |
| 運維層 | 錯誤不外露、日志審計、滲透測試 | SIEM, 紅隊演練, 代碼掃描 (SAST/DAST) |