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

SQL 注入攻擊原理與防禦實戰:從漏洞偵測到參數化查詢的完整防護體系

     編輯:關於SqlServer

什麼是 SQL Injection?

應用程式未對使用者輸入進行驗證/過濾,直接拼接至 SQL 陳述式,導致攻擊者能注入任意 SQL 片段,竊取/篡改/刪除資料,甚至透過 xp_cmdshell 奪取作業系統控制權。

攻擊偵測與判斷流程

1. 尋找注入點

  • 整數型參數: id=123 AND 1=1 正常 / id=123 AND 1=2 異常 → 存在注入。
  • 字串型參數: name=test' AND '1'='1 正常 / name=test' AND '1'='2 異常。
  • 盲注判斷: 無回顯時,利用時間延遲 WAITFOR DELAY '0:0:5' 或布林邏輯差異推斷。

2. 判斷後端資料庫類型

-- SQL Server 特徵
SELECT @@VERSION;
-- Oracle 特徵
SELECT * FROM v$version;
-- MySQL 特徵
SELECT VERSION();

3. 權限評估與擴大攻擊面

  • 當前連線是否 sysadmin? SELECT IS_SRVROLEMEMBER('sysadmin')。
  • xp_cmdshell 是否啟用? EXEC sp_configure 'xp_cmdshell'。
  • 若兩者皆滿足 → 直接作業系統級控制(建立帳號、植入 Web Shell、横向移動)。
  • 否則:尋找 Web 根目錄 → 上傳 Web Shell → 提權。

繞過 WAF/過濾的常見技巧(僅供防禦驗證)

技巧範例原理
大小寫混淆SeLeCt, UnIoNVBScript/ASP 不區分大小寫,過濾器可能遺漏
URL 編碼%27 (')、%20 (空白)IIS 解碼後才交給應用,繞過字串比對
Unicode/雙重編碼%u0027, %2527利用解碼層次差異
註釋截斷';--, ';/*截斷後續原始 SQL
內聯註釋/**/SELECT/***/繞過關鍵字過濾

防禦體系:分層纏繞策略

第 1 層:參數化查詢(核心、必要、充分)

-- C# ADO.NET
cmd.CommandText = "SELECT * FROM Users WHERE UserName = @u AND PwdHash = @p";
cmd.Parameters.AddWithValue("@u", userInput);
cmd.Parameters.AddWithValue("@p", pwdHash);

-- Java JDBC
PreparedStatement ps = conn.prepareStatement("SELECT * FROM Users WHERE UserName = ? AND PwdHash = ?");
ps.setString(1, userInput);
ps.setString(2, pwdHash);

-- PHP PDO
$stmt = $pdo->prepare("SELECT * FROM Users WHERE UserName = ? AND PwdHash = ?");
$stmt->execute([$userInput, $pwdHash]);

原理: SQL 碼與資料分離,資料庫引擎將參數視為字面值,永遠不會被解析為 SQL 指令。

第 2 層:預存程序(同樣需參數化)

CREATE PROC usp_GetUser @UserName NVARCHAR(50), @PwdHash NVARCHAR(128)
AS
SELECT * FROM Users WHERE UserName = @UserName AND PwdHash = @PwdHash;

⚠️ 嚴禁在預存程序內動態拼接 SQL 再 EXEC(@sql),除非對參數做嚴格白名單驗證。

第 3 層:輸入驗證與白名單(輔助、不可替代參數化)

  • 整數欄位:Int32.TryParse、範圍檢查。
  • 列舉值:白名單比對。
  • 字串長度、字元集限制(如僅允許英數字、底線)。

第 4 層:最小權限資料庫帳號

  • Web 應用連線帳號:僅擁有必要資料表的 SELECT/INSERT/UPDATE/DELETE,無 DDL、無 sysadmin、無 xp_cmdshell。
  • 不同功能模組使用不同帳號(唯讀報表帳號、寫入業務帳號)。
  • 第 5 層:錯誤訊息隱藏與日誌稽核

    • 生產環境關閉詳細錯誤頁面(ASP.NET customErrors="RemoteOnly"、PHP display_errors=Off)。
    • 資料庫層啟用稽核 / Extended Events 記錄失敗登入、DDL 變更、xp_cmdshell 呼叫。
    • WAF 規則集(OWASP CRS)攔截已知攻擊模式。

    第 6 層:定期滲透測試與代碼審查

    • 自動掃描工具:SQLMap、OWASP ZAP、Burp Suite。
    • 人工代碼審查:搜尋 EXEC(, sp_executesql, + @var + 等動態 SQL 模式。

    SQL Server 特定防護設定

    -- 關閉 xp_cmdshell(預設關閉)
    EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
    EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE;
    
    -- 啟用參數化強制(資料庫範圍,SQL 2008+)
    ALTER DATABASE [MyDB] SET PARAMETERIZATION FORCED;
    
    -- 限制登入失敗鎖定
    ALTER LOGIN [WebAppUser] WITH CHECK_POLICY = ON;
    

    結語

    SQL Injection 不是資料庫漏洞,是**應用層拼接字串的架構缺陷**。參數化查詢是唯一根治方案;其餘層級(驗證、最小權限、WAF、稽核)是縱深防禦的安全網。將「拼接 SQL」視為代碼審查的紅線,建立「參數化優先」的開發文化,才能從根本上消除這類風險。

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