萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 網路安全 >  >> 駭客技術教學 >> 駭客防護

防範 SQL 注入攻擊:原理剖析與多語言防禦代碼實戰

SQL 注入原理:動態拼接 SQL 的原罪

動態生成 SQL 時未驗證用戶輸入,導致惡意輸入改變查詢邏輯。例:

-- 原查詢
SELECT * FROM admin WHERE username='&user' AND password='&pwd'
-- 攻擊輸入 username: 1' or '1'='1
-- 變為
SELECT * FROM admin WHERE username='1' or '1'='1' AND password='&pwd'
-- 條件永真,繞過驗證直接登入

必須過濾/轉義的高危字元與關鍵字

  • 單引號 `'`, 雙引號 `"` , 分號 `;`, 逗號 `,`, 冒號 `:`, 連接號 `--`
  • SQL 關鍵字: `SELECT`, `INSERT`, `DELETE`, `DROP`, `UPDATE`, `TRUNCATE`, `FROM`, `COUNT`, `ASC`, `CHAR`, `MID`
  • 危險延伸: `xp_cmdshell`, `exec master.dbo.xp_cmdshell`, `net user`, `net localgroup administrators`, `/add`
  • 編碼繞過: `%27` (URL 編碼單引號), `0x27` (Hex), Unicode, 雙重編碼等。

多語言防禦代碼實戰

1. JavaScript (客戶端輔助攔截,不可信任)

<script language="javascript">
var url = location.search;
var re = /^\?(.*)(select%20|insert%20|delete%20from%20|count\(|drop%20table|update%20truncate%20|asc\(|mid\(|char\(|xp_cmdshell|exec%20master|net%20localgroup%20administrators|"|:|net%20user|'|%20or%20)(.*)$/gi;
if (re.test(url)) {
    alert("地址中含有非法字符~");
    location.href = "error.asp";
}
</script>

局限: 僅檢查 URL 參數 (GET),無法防禦 POST、Cookie、Header;可被編碼繞過;僅作第一層輕量阻擋。

2. ASP / VBScript (伺服器端關鍵字攔截,輔助非根治)

<%
On Error Resume Next
Dim strTemp
If LCase(Request.ServerVariables("HTTPS")) = "off" Then strTemp = "https://" Else strTemp = "https://" End If
strTemp = strTemp & Request.ServerVariables("SERVER_NAME")
If Request.ServerVariables("SERVER_PORT") <> 80 Then strTemp = strTemp & ":" & Request.ServerVariables("SERVER_PORT")
strTemp = strTemp & Request.ServerVariables("URL")
If Trim(Request.QueryString) <> "" Then strTemp = strTemp & "?" & Trim(Request.QueryString)
strTemp = LCase(strTemp)
If InStr(strTemp, "select%") Or InStr(strTemp, "insert%") Or InStr(strTemp, "delete%20from") Or InStr(strTemp, "count(") Or InStr(strTemp, "drop%20table") Or InStr(strTemp, "update%") Or InStr(strTemp, "truncate%") Or InStr(strTemp, "asc(") Or InStr(strTemp, "mid(") Or InStr(strTemp, "char(") Or InStr(strTemp, "xp_cmdshell") Or InStr(strTemp, "exec%20master") Or InStr(strTemp, "net%20localgroup%20administrators") Or InStr(strTemp, ":") Or InStr(strTemp, "net%20user") Or InStr(strTemp, "'") Or InStr(strTemp, "%20or%20") Then
    Response.Write "<script language='javascript'>alert('非法地址!!');location.href='error.asp';</script>"
    Response.End
End If
%>

部署: 放入全站 include 頭部。警告: 會誤攔正常含關鍵字內容,**不可替代參數化查詢**。

3. C# / .NET 通用參數檢查 (黑名單正則,建議改白名單)

bool CheckParams(params object[] args) {
    string[] Lawlesses = { "=", "'" }; // 自定義非法字元
    if (Lawlesses == null || Lawlesses.Length <= 0) return true;
    string str_Regex = ".*[";
    for (int i = 0; i < Lawlesses.Length - 1; i++)
        str_Regex += Lawlesses[i] + "|";
    str_Regex += Lawlesses[Lawlesses.Length - 1] + "].*";
    foreach (object arg in args) {
        if (arg is string) {
            if (Regex.Matches(arg.ToString(), str_Regex).Count > 0) return false;
        }
        else if (arg is ICollection) {
            foreach (object obj in (ICollection)arg) {
                if (obj is string && Regex.Matches(obj.ToString(), str_Regex).Count > 0) return false;
            }
        }
    }
    return true;
}

最佳實踐: 改用白名單正則 (如 `^[a-zA-Z0-9_@.-]{1,50}$`) 驗證每個參數格式,拒絕不符合預期格式的輸入。

4. 根治方案:參數化查詢 / 預處理語句 (所有語言通用)

語言/平台參數化寫法範例
ASP (ADO)`cmd.CommandText = "SELECT * FROM users WHERE id=?"` → `cmd.Parameters.Append cmd.CreateParameter("@id", 3, 1, , id)` (adInteger)
PHP (PDO)`$stmt = $pdo->prepare("SELECT * FROM users WHERE id=?"); $stmt->execute([$id]);`
Java (JDBC)`PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id=?"); ps.setInt(1, id);`
C# (ADO.NET)`cmd.CommandText = "SELECT * FROM users WHERE id=@id"; cmd.Parameters.AddWithValue("@id", id);`
Python (DB-API)`cursor.execute("SELECT * FROM users WHERE id=%s", (id,))`
Node.js (mysql2)`await connection.execute('SELECT * FROM users WHERE id=?', [id])`

核心原則: **代碼與資料永久分離**,資料絕不被解析為 SQL 指令,徹底杜絕注入。

系統級纵深防禦 (代碼之外必做)

  1. WAF 部署: ModSecurity + OWASP CRS / 雲 WAF,虛擬補丁防 0day。
  2. 資料庫最小權限: Web 布號僅 `SELECT/INSERT/UPDATE/DELETE` 特定表,**永久禁用 `xp_cmdshell`、`OLE Automation` 等危險擴展**。
  3. 錯誤資訊不回顯: 生產環境關閉詳細錯誤,統一友善頁面。
  4. HTTP 安全標頭: CSP、HSTS、X-Frame-Options 等。
  5. 定期 SAST/DAST/人工滲透測試: 落實 SDL (安全開發生命週期)。

結語

SQL 注入防禦的鐵律是:**參數化查詢為唯一根治,關鍵字過濾僅為輔助,系統級 WAF/最小權限/安全標頭為纵深防線**。開發階段強制參數化、代碼審計攔截拼接 SQL;上線前滲透測試驗證;運行期 WAF 實時防護。三位一體,方能讓 SQL 注入成為歷史。

copyright © 萬盛學電腦網 all rights reserved