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

SQL 注入漏洞原理與防範:從字串拼接到參數化查詢

     編輯:關於SqlServer

漏洞重現

典型登入驗證代碼 (VB6 + ADO):

sqlstr = "SELECT * FROM users WHERE name='" & Text1.Text & "' AND pwd='" & Text2.Text & "'"
Set adors = Adocon.Execute(sqlstr)
If adors.RecordCount > 0 Then MsgBox "Pass" Else MsgBox "Fail"

輸入:
用戶名:123
密碼:a' OR 'a'='a

實際執行 SQL 變為:

SELECT * FROM users WHERE name='123' AND pwd='a' OR 'a'='a'

'a'='a' 永真,繞過驗證直接登入。

漏洞特徵

  • 跨語言/平台:VB、Delphi、ASP、JSP、PHP、Java 等所有拼接 SQL 的場景皆受影響。
  • 隱蔽性強:代碼外觀正常,無語法錯誤,測試常漏測。
  • 破壞力大:無需猜解帳密即可越權,甚至執行 DROP TABLE、xp_cmdshell 等危險操作。

修復方案(按推薦順序)

1. 參數化查詢 / 預編譯語句(根治)

-- VB6 ADO 範例
cmd.CommandText = "SELECT * FROM users WHERE name=? AND pwd=?"
cmd.Parameters.Append cmd.CreateParameter("name", adVarChar, adParamInput, 50, Text1.Text)
cmd.Parameters.Append cmd.CreateParameter("pwd", adVarChar, adParamInput, 50, Text2.Text)
Set rs = cmd.Execute

參數與代碼分離,資料庫將輸入視為字面值而非 SQL 片段。

2. 儲存程序 + 參數

將邏輯封裝於伺服器端,應用僅呼叫 EXEC sp_login @name, @pwd,同樣享受參數化保護。

3. 分步驗證(緩解)

-- 先查用戶是否存在
SELECT pwd_hash FROM users WHERE name = ?
-- 應用層比對雜湊值

雖不如參數化徹底,但能阻擋最簡單的 OR 'a'='a 攻擊。

4. 輸入過濾(輔助)

  • 禁止密碼含單引號、分號、註釋符等特殊字元。
  • 採用強雜湊 (bcrypt/Argon2) 儲存密碼,即使資料外洩也難逆向。

最佳實踐清單

  1. 所有動態 SQL **一律使用參數化**,拒絕字串拼接。
  2. 資料庫帳號遵循最小權限:Web 應用僅需 SELECT/INSERT/UPDATE/DELETE,禁止 DROP、EXECUTE 等高危權限。
  3. 啟用 WAF / SQL 防火牆,記錄異常查詢模式。
  4. 定期進行代碼審查與滲透測試。

結語

SQL 注入已知超過 20 年,仍是 OWASP Top 10 常客。根源不在資料庫,而在應用層「代碼與資料未分離」。養成參數化習慣,才是唯一銀彈。

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