首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 防禦 SQL 注入攻擊完整指南:原理、手法與多層防護策略

     編輯:關於ASP.NET

什麼是 SQL 注入?

SQL Injection 發生於應用程式將使用者輸入直接拼接至 SQL 命令字串,導致惡意輸入改變查詢語意、竊取/竄改/刪除資料,甚至執行系統指令。典型攻擊流程:

  1. 登入頁面接受帳號/密碼輸入。
  2. 後端拼接:"SELECT * FROM Users WHERE login='" + txtLogin.Text + "' AND password='" + txtPassword.Text + "'"
  3. 攻擊者輸入:' OR '1'='1
  4. 實際 SQL 變為:SELECT * FROM Users WHERE login='' OR '1'='1' AND password='' OR '1'='1',永真條件繞過驗證。

六大防護層級

1. 參數化查詢(首選、最有效)

// 錯誤示範
string sql = "SELECT * FROM Users WHERE UserName='" + txtUser.Text + "'";

// 正確做法
string sql = "SELECT * FROM Users WHERE UserName=@UserName";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@UserName", txtUser.Text);

參數化查詢將程式碼與資料分離,資料庫引擎將參數視為字面值而非可執行片段,徹底阻斷注入。

2. 預存程序

  • 所有邏輯封裝於資料庫,應用程式僅呼叫 EXEC sp_Login @User, @Pwd。
  • 搭配 CommandType.StoredProcedure 與參數集合。
  • 授權原則:應用程式帳號僅具 EXECUTE 特定預存程序權限,無直接資料表存取權。

3. 輸入驗證與清理(纵深防禦)

4. 最小權限原則

  • Web 應用程式連線資料庫使用專用低權限帳號(非 sa、非 db_owner)。
  • 僅授予必要資料表的 SELECT/INSERT/UPDATE/DELETE,嚴禁 DROP、TRUNCATE、xp_cmdshell 等高危權限。
  • 讀寫分離:查詢用唯讀帳號,寫入用低權限帳號。

5. 錯誤資訊隱藏

  • web.config 設定 <customErrors mode="RemoteOnly" />。
  • 避免在例外訊息中洩露 SQL 片段、資料表結構、連線字串。
  • 記錄詳細錯誤至伺服器端日誌(Serilog、NLog、ELMAH),前端僅顯示友善提示。

6. 進階防護:WAF、ORM、程式碼分析

  • Web Application Firewall:Azure WAF、ModSecurity、Imperva 等攔截已知攻擊模式。
  • Entity Framework / Dapper:ORM 內建參數化,Dapper 以 @param 方式安全執行原生 SQL。
  • 靜態程式碼分析:SonarQube、Roslyn Analyzers 偵測字串拼接 SQL、硬編碼密碼等反模式。
  • 資料庫審計:SQL Server Audit、Extended Events 記錄可疑查詢、失敗登入、結構變更。

實戰檢核清單

[ ] 所有資料庫存取是否使用參數化查詢或預存程序?
[ ] 連線字串帳號是否為最低權限專用帳號?
[ ] 所有使用者輸入是否經過伺服器端白名單驗證?
[ ] 前端 maxlength、Regex 驗證是否與後端一致?
[ ] 錯誤頁面是否隱藏技術細節?
[ ] 是否部署 WAF 或啟用資料庫審計?
[ ] 定期進行滲透測試與程式碼審查?

總結

SQL 注入雖歷久不衰,但透過「參數化查詢為核心、最小權限為基石、多層驗證為纵深、監控審計為保障」的系統性防禦,可將風險降至最低。永遠記住:永不信任任何外部輸入,永不拼接 SQL 字串。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
手法說明適用場景
白名單驗證Regex 限定允許字元(如 ^[a-zA-Z0-9_]{3,20}$)帳號、編號、代碼等格式固定欄位
長度限制前後端同步限制 maxlength、StringLength 屬性所有輸入欄位
單引號轉義單引號替換為兩個單引號('')動態 SQL 無法參數化的極少數情境
移除註釋符過濾 --、/* */、;輔助防禦,不可單獨依賴