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

使用 LINQ to SQL 徹底解決 SQL 注入攻擊

     編輯:關於.NET

SQL 注入:最危險的 Web 應用程式漏洞

攻擊者透過惡意輸入竄改動態 SQL 命令,在資料庫伺服器執行任意指令。經典脆弱程式碼:

string cmd = "SELECT * FROM Customers WHERE CompanyName = '" + txtCompanyName.Text + "'";
SqlDataSource1.SelectCommand = cmd;

輸入 Ernst Handel' UNION SELECT CustomerID, ShipName, ShipAddress FROM ORDERS-- 即可竄改查詢,洩露訂單資料。

傳統防禦手段與局限

  • 輸入驗證:型別、長度、格式、範圍檢查。但易遺漏欄位、僅客戶端驗證、邏輯疏漏。
  • 參數化查詢:WHERE CompanyName = @CompanyName。較安全,但需開發者嚴格遵守,存儲程序若動態拼接 SQL 仍有風險。
  • 管理成本高:需教育全團隊、程式碼審查、自動化掃描,人為疏失難免。

LINQ to SQL:從根源消除 SQL 注入

核心機制:LINQ to SQL 將所有查詢參數化。編譯器與 IntelliSense 提供編譯期語法檢查,運行時自動產生參數化 SQL。

實作範例:安全的客戶搜尋

  1. 使用 Object Relational Designer (O/R Designer) 拖曳 Customers 資料表,自動產生 CustomersDataContext 與實體類別。
  2. 查詢程式碼:

protected void Page_Load(object sender, EventArgs e) {
    string connStr = ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
    var db = new CustomersDataContext(connStr);

    GridView1.DataSource = from c in db.Customers
                           where c.CompanyName == txtCompanyName.Text
                           orderby c.CompanyName
                           select c;
    GridView1.DataBind();
}

運行時產生的 SQL (安全)


SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], ...
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[CompanyName] = @p0
ORDER BY [t0].[CompanyName]

@p0 為參數,使用者輸入被視為字面值,無法竄改查詢結構。即使輸入注入字串,查詢只會嘗試比對字面字串,回傳空結果,不會執行額外命令。

為什麼 LINQ to SQL 能保證安全?

  1. 查詢與資料分離:開發者操作物件模型,不寫 SQL 字串。
  2. 強制參數化:所有外部輸入自動轉為參數,無例外。
  3. 編譯期驗證:語法錯誤、型別不符在建置階段即被攔截。
  4. IntelliSense 輔助:減少拼字錯誤導致的運行時例外。

殘留風險與對策

唯一攻擊面:誘騙 LINQ 產生非預期 SQL(極難)。語言與編譯器設計即為防範此風險。
暴力破解(窮舉 CompanyName)仍可能,但僅能存取該頁面暴露的資料範圍,無法注入命令存取其他資料表。

結論

採用 LINQ to SQL (或 Entity Framework) 進行資料存取,從架構層面杜絕 SQL 注入。新專案首選;舊專案可模組化遷移。這是構建安全應用程式最高效的選擇。

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