跨網站指令碼 (XSS):攻擊向量與防禦

Security2026-09-13TryQuickToolBox

為何 XSS 仍困擾網頁應用程式

跨網站指令碼(XSS)仍是最普遍的網頁弱點之一。儘管大家普遍意識到這個問題,它仍持續出現在 OWASP Top 10 中。核心問題在於:應用程式信任使用者輸入,並在未妥善處理的情況下直接渲染。攻擊者注入惡意指令碼,在受害者的瀏覽器中執行,導致工作階段劫持、資料竊取和網頁竄改。

本文將解析 XSS 攻擊向量,並提供您今天就能實作的實用防禦措施。

什麼是 XSS?它如何運作?

當應用程式未經驗證或編碼就將不受信任的資料包含在網頁中時,就會發生 XSS。瀏覽器接著會將注入的指令碼視為合法網站的一部分來執行。由於指令碼在易受攻擊網站的上下文中執行,它可以存取 cookie、本機儲存空間,並代表使用者發出請求。

考慮一個簡單的搜尋頁面,它會反射查詢內容:

<?php echo 'You searched for: ' . $_GET['q']; ?>

如果攻擊者建構一個像 search.php?q=<script>alert('XSS')</script> 的 URL,當受害者造訪該連結時,指令碼就會執行。

三種主要的 XSS 類型

1. 反射型 XSS

惡意指令碼是請求的一部分(例如 URL 參數),並立即反射在回應中。必須誘騙受害者點擊連結或提交表單。這常用於網路釣魚活動中。

2. 儲存型 XSS

指令碼被永久儲存在伺服器上(例如資料庫、留言欄位或使用者個人資料中)。每個造訪受影響頁面的訪客都會執行該指令碼。儲存型 XSS 更危險,因為除了檢視頁面外,不需要任何互動。

3. DOM 型 XSS

弱點存在於用戶端 JavaScript 中,它從不受信任的來源(如 location.hash)讀取資料,並在未安全處理的情況下寫入 DOM。伺服器可能永遠不會看到惡意酬載。

document.getElementById('output').innerHTML = location.hash.substring(1);

如果雜湊包含 <img src=x>,指令碼就會執行。

常見攻擊向量

XSS 防禦措施

1. 輸出編碼(情境轉義)

在將所有不受信任的資料渲染到 HTML、屬性、JavaScript、CSS 或 URL 之前進行編碼。使用適合情境的編碼:

大多數現代框架(React、Angular、Vue)預設會自動轉義,但在使用 dangerouslySetInnerHTML 或類似的逃生出口時要謹慎。

2. 輸入驗證與清理

使用允許清單在伺服器端驗證輸入。對於富文字,使用 DOMPurify 等函式庫來清理 HTML,移除危險的標籤和屬性。

const clean = DOMPurify.sanitize(userInput);

絕不要僅依賴用戶端驗證。

3. 內容安全政策(CSP)

CSP 是強大的縱深防禦機制。它限制可執行指令碼、內聯指令碼和其他資源的來源。嚴格的 CSP 即使發生注入也能阻止 XSS。

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; object-src 'none';

避免使用 unsafe-inline 和 unsafe-eval。對合法的內聯指令碼使用 nonce 或雜湊。

4. 安全的 Cookie 屬性

設定 Cookie 時使用 HttpOnly(防止 JavaScript 存取)和 Secure(僅限 HTTPS)。這可減輕透過 XSS 進行的工作階段劫持。

5. 使用現代框架並避免危險的 API

像 React、Angular 和 Vue 等框架會自動轉義資料。避免使用 innerHTML 直接操作 DOM。如果必須插入 HTML,請先清理。

6. 定期安全測試

納入 SAST、DAST 和手動滲透測試。像 OWASP ZAP 等工具可以幫助識別 XSS 弱點。

XSS 類型與主要防禦比較

XSS 類型說明主要防禦
反射型酬載在請求中,反射於回應中輸出編碼、輸入驗證
儲存型酬載儲存在伺服器上,提供給所有使用者清理、輸出編碼、CSP
DOM 型透過不安全的 DOM API 進行用戶端注入安全的 DOM API、CSP、避免 eval

逐步指南:實作 XSS 防禦

  1. 識別所有輸入點:表單、URL 參數、標頭、Cookie。
  2. 套用情境輸出編碼:使用內建函式或 OWASP Java Encoder 等函式庫。
  3. 清理富文字:使用 DOMPurify 或類似工具。
  4. 部署 CSP:從僅報告模式開始,然後強制執行。
  5. 設定 HttpOnly 和 Secure Cookie。
  6. 教育開發人員:培訓安全編碼實踐。
  7. 定期測試:將安全測試整合到 CI/CD 中。

常見問題

XSS 和 CSRF 有什麼區別?

XSS 在受害者的瀏覽器中執行惡意指令碼,而 CSRF 誘騙瀏覽器向使用者已驗證的網站發送未經授權的請求。XSS 可用於繞過 CSRF 保護。

內容安全政策能完全防止 XSS 嗎?

不能,CSP 是一種縱深防禦措施。它顯著降低風險,但無法取代適當的輸出編碼和輸入驗證。設定錯誤的 CSP 仍可能允許某些攻擊。

僅靠用戶端驗證足以防止 XSS 嗎?

不夠。用戶端驗證很容易被繞過。始終在伺服器端進行驗證和編碼,並將所有用戶端資料視為不受信任。

結論

XSS 是一個持續存在的威脅,但透過分層防禦策略——輸出編碼、輸入驗證、CSP 和安全 Cookie——您可以有效減輕它。保持警覺,保持框架更新,並持續測試。

如需更多安全工具,請查看我們的 Nginx 日誌分析器,以偵測伺服器日誌中的可疑模式。