首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Injection 原理深度解析與根治方案:拒絕字串拼湊,擁抱參數化查詢與預存程序

     編輯:關於SqlServer

前言

網路上關於 SQL Injection 的文章眾多,但真正講透原理與根治之道者寡。本文從攻擊本質切入,揭示為何「拼湊 SQL 字串」是萬惡之源,並給出徹底解決方案。

SQL Injection 核心原理:三層本質

SQL Injection 就是向伺服器提交精心構造的資料,拼湊出攻擊者想要的 SQL 陳述式,以改變資料庫操作執行計畫。

這句話包含三層關鍵含義:

  1. 注入途徑:凡是「客戶端資料替換預定義變數」的地方皆可能被注入 (GET、POST、Cookie、Header、Server Variables...)
  2. 成功原因:伺服端採用**字串拼湊**方式構建 SQL,使攻擊者能夠在提交資料中摻入 SQL 關鍵字/運算子
  3. 最終結果:**改變資料庫操作執行計畫** — 不一定是惡意破壞,只要 SQL 未按預期計畫執行即屬注入

經典範例還原

-- 應用程式原始碼 (ASP/PHP/Java 等)
UPDATE tableName 
SET columnName1 = "$Client_Submit_Data" 
WHERE PK_ID = 1234

若使用者輸入:誰能告訴我 "SQL injection" 是什麼?

拼湊後 SQL 變為:

UPDATE tableName 
SET columnName1 = "誰能告訴我" SQL injection "是什麼?" 
WHERE PK_ID = 1234

實際執行:UPDATE tableName SET columnName1 = "誰能告訴我" — **WHERE 子句被截斷,全表資料被竄改!**

此例中使用者無惡意,但結果等同 SQL Injection。

為何 Replace 過濾特殊字元不是根治之道?

  • 黑名單永遠追不上變種 (編碼、Unicode、二次注入、截斷注入...)
  • 不同資料庫保留字、語法差異大,過濾邏輯極難完備
  • 正規業務資料可能合法包含引號、註解符號 (如人名 O'Brien、備註含 --)
  • **治標不治本**:問題根源在於「字串拼湊」架構,而非特定字元

徹底解決方案:避免拼湊 SQL 字串

黃金法則:使用參數化查詢 / 預存程序

-- 參數化查詢 (ADO.NET 範例)
string sql = "UPDATE tableName SET columnName1 = @title WHERE PK_ID = @id";
using (SqlCommand cmd = new SqlCommand(sql, conn)) {
    cmd.Parameters.AddWithValue("@title", userInput);  // 傳入值,非字串拼湊
    cmd.Parameters.AddWithValue("@id", 1234);
    cmd.ExecuteNonQuery();
}

為何參數化能根治?

  • **執行計畫與資料分離**:DBMS 先編譯 SQL 模板 (含參數佔位符),生成執行計畫,**再**綁定參數值
  • 參數值**永遠不會被解析為 SQL 语法** — 即使包含引號、分號、註解,也僅作為字面值處理
  • 效能提升:重複執行同樣模板可重用執行計畫 (Plan Cache)

預存程序的額外優勢

  • 邏輯封裝在資料庫層,應用程式僅呼叫 EXEC sp_UpdateTitle @id, @title
  • 權限控管:僅授與 EXEC 權限,無需直接表權限
  • 網路傳輸量減少:僅傳遞呼叫指令與參數
  • 維護彈性:修改邏輯無需重新編譯部署應用程式

進階防護層級

層級措施說明
1. 開發規範禁止字串拼湊 SQL,Code Review 強制檢查源頭阻斷
2. ORM 框架Entity Framework、Dapper、Hibernate 等內建參數化,降低手寫 SQL 風險
3. 資料庫權限應用帳號僅擁有必要權限,嚴禁 sysadmin/db_owner縮小受損範圍
4. WAF/IDSWeb 應用防火牆偵測異常 SQL 模式防禦深度,非首要依賴
5. 審計與監控啟用 SQL Server Audit、Extended Events 記錄異常執行事後追蹤與合規

MySQL / ODBC 特殊機制:Prepared Statements

MySQL 4.1+ 提供 PREPARE/EXECUTE 機制,本質同屬參數化查詢,系統預置的預存程序形式。

結語

**SQL Injection 的根源不在使用者輸入,而在開發者選擇了「字串拼湊」這條捷徑。** 只要堅持「執行計畫與資料分離」的參數化原則,SQL Injection 即可從架構層面徹底消除。這不僅是安全需求,更是專業軟體工程的基本素養。

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