Luke a Pro

Luke Sun

Developer & Marketer

🇺🇦
EN||

SQL 注入 (SQLi)

| , 2 minutes reading.

1. 定義

SQL 注入 (SQL Injection, SQLi) 發生在不受信任的用戶輸入被動態拼接至結構化查詢語言 (SQL) 語句中時。這允許攻擊者操縱查詢結構,從而查看、修改或刪除他們未被授權訪問的數據。

2. 技術原理

SQL 解釋器會同時處理指令和數據。如果應用程式通過字串拼接來構建查詢:

query = "SELECT * FROM users WHERE username = '" + user_input + "'";

攻擊者可以輸入 ' OR '1'='1。生成的查詢將變為:

SELECT * FROM users WHERE username = '' OR '1'='1';

由於 '1'='1' 永遠為真,資料庫將返回表中的所有行,從而繞過用戶名檢查。

SQLi 的類型:

  • 帶內 (In-band, 經典型): 結果直接返回在網頁中(如基於 UNION 的注入)。
  • 盲注 (Blind): 不直接返回數據,但應用程式的行為會發生變化(基於時間或布爾值)。
  • 帶外 (Out-of-band): 通過 DNS 或 HTTP 請求將數據導出(較罕見,取決於資料庫)。

3. 攻擊流程 (基於 Union)

sequenceDiagram
    participant Attacker
    participant App
    participant DB as 資料庫

    Attacker->>App: GET /search?q=' UNION SELECT username, password FROM users--
    
    Note over App: 程式碼構建查詢:<br/>SELECT title FROM products WHERE name = '' UNION ... --'
    
    App->>DB: 執行畸形查詢
    
    Note over DB: 'UNION' 合併了來自 'products' 和 'users' 的結果
    
    DB-->>App: 返回產品列表 + 用戶憑據
    App-->>Attacker: 在搜尋結果中顯示管理員密碼

4. 真實案例:TalkTalk 遭受黑客攻擊 (2015)

目標: TalkTalk (英國電信營運商)。 漏洞類別: 盲 SQL 注入。

事件回顧: 攻擊者在 TalkTalk 網域上發現了一些未維護的舊網頁,這些網頁仍然連接著核心客戶資料庫。這些頁面使用的 GET 參數存在 SQL 注入漏洞。

攻擊技術: 他們使用 SQLMap(一種自動化工具)利用了盲 SQLi 漏洞。

  • 注入 SQL 命令來提取資料庫架構資訊。
  • 導出了 156,959 名客戶 的個人資料和 15,000 多個銀行帳號。

影響: TalkTalk 被處以 40 萬英鎊 的罰款(當時創下了紀錄),並估計在業務流失和補救方面損失了 7700 萬英鎊。這凸顯了「殭屍」遺留程式碼帶來的巨大風險。

5. 深度防禦策略

A. 預處理語句 (參數化查詢)

這是唯一的主要防禦手段。 使用資料庫驅動提供的參數化功能,而不是字串拼接。

  • 機制: SQL 查詢結構先被發送到資料庫並編譯。用戶輸入隨後發送,且僅被視為數據,而非可執行的程式碼。

  • Java/JDBC 範例:

    String query = "SELECT * FROM users WHERE username = ?";
    PreparedStatement pstmt = connection.prepareStatement(query);
    pstmt.setString(1, userInput); // 安全
    ResultSet results = pstmt.executeQuery();

B. 存儲程序

將查詢封裝在資料庫內部。但請注意,存儲程序本身必須使用參數,並避免在程序內部生成動態 SQL。

C. 最小權限原則

Web 應用程式使用的資料庫帳號應僅擁有以下權限:

  • 僅訪問其所需的特定表。
  • 僅執行必要的命令(SELECT, INSERT, UPDATE)。
  • 絕不擁有 DROP TABLE, GRANT 或管理員權限。
  • 絕不允許訪問作業系統檔案系統(如 xp_cmdshell)。

6. 參考資料