Featured image of post Web開發中XSS的防禦原則Featured image of post Web開發中XSS的防禦原則

Web開發中XSS的防禦原則

了解透過正確的 HTML 轉義、DOM API 和內容安全策略保護 Web 應用程式免受跨站腳本 (XSS) 侵害的核心概念。

介紹

在網路安全中,跨站腳本 (XSS) 是最古老、最持久的漏洞之一。

如果惡意腳本在受害者的瀏覽器上執行,它們可能會破壞整個會話、竊取會話令牌 (cookie)、劫持帳戶或動態變更頁面內容以取得敏感憑證。

本文回顧了消除現代 Web 應用程式中 XSS 漏洞所需的基本防禦原則。我們將探索上下文轉義、清理、安全 DOM 操作和防禦深度機制。


1.XSS的三種分類

根據惡意負載的傳輸方式,XSS 漏洞大致分為三類:

  1. 反射的XSS: 當惡意負載嵌入到連結或表單提交時會發生。當使用者點擊連結時,伺服器會將不受信任的輸入「反射」迴響應 HTML,而無需進行適當的轉義。
  2. 儲存(持久)XSS: 最危險的形式。有效負載儲存在伺服器的資料庫中(例如,論壇貼文、使用者簡介)並傳遞給任何存取該頁面的後續使用者。
  3. 基於 DOM 的 XSS: 與反射或儲存 XSS 不同,這完全發生在客戶端 JavaScript 中。此腳本處理不受信任的來源資料(例如 location.hash 或查詢參數)並使用不安全的 API 將其直接寫入 DOM。

2. 原則 1:上下文感知 HTML 轉義

XSS 的根本解決方法是在渲染不受信任的動態資料之前對其進行轉義。轉義將 HTML 語法中具有特殊意義的字元文字轉換為各自的惰性 HTML 實體(字元引用)。

基本字元映射表

  • & -> &
  • < -> &lt;
  • > -> &gt;
  • " -> &quot;
  • ' -> &#x27; (或 &apos;

警告:上下文很重要

轉義規則會根據資料放置的「位置」而變化。

  • 放置在元素標記內的文字需要標準實體轉義。
  • 放置在元素屬性內的文字(例如 <input value="DYNAMIC_DATA">)需要嚴格的引號轉義。
  • 單獨使用 HTML 轉義無法保護 <script> 區塊、CSS 版面配置或 URL 屬性 (href) 內呈現的資料。它們分別需要 JavaScript 轉義、CSS 轉義或 URL 編碼。

3. 原則 2:安全 DOM API(防止基於 DOM 的 XSS)

使用 JavaScript 動態更新頁面內容時,選擇錯誤的 API 可能會造成安全漏洞。

不良做法

// Reading a query parameter and injecting it directly
const params = new URLSearchParams(window.location.search);
const username = params.get("name");

// DANGEROUS: If name is "<img src=x onerror=alert(1)>", the script will execute
document.getElementById("greeting").innerHTML = `Hello, ${username}!`;

最佳實踐

如果要將動態資料解釋為純文本,請務必使用 textContentinnerText 而不是 innerHTML

const params = new URLSearchParams(window.location.search);
const username = params.get("name");

// SAFE: The browser treats input strictly as plain text, rendering tags harmlessly
document.getElementById("greeting").textContent = `Hello, ${username}!`;

如果您的應用程式必須呈現使用者提供的 HTML 標記(例如,Markdown 預覽),則必須先將字串傳遞給經過考驗的清理庫(例如 DOMPurify)。


4. 原則 3:安全連結方案

當應用程式允許使用者保存網站連結並直接在錨元素 (<a href="USER_URL">) 中呈現它們時,就會出現常見的安全漏洞。

風險

即使您轉義 HTML 字符,使用者也可以提供類似 javascript:alert(document.cookie) 的有效負載。點擊該連結將立即執行該腳本。

<!-- DANGEROUS: The script executes when clicked -->
<a href="javascript:alert(document.cookie)">Visit Website</a>

解決方案

對使用者 URL 實施嚴格的方案驗證。僅允許明確以 http://https:// 開頭的 URL,拒絕 javascript:data: 等方案。


5.縱深防禦

僅依靠程式碼清理是有風險的。分層瀏覽器安全控制提供了一個重要的安全網。

內容安全策略 (CSP)

內容安全策略是一個 HTTP 回應標頭,它定義允許哪些腳本來源在您的頁面上運行。

Content-Security-Policy: default-src 'self'; script-src 'self' https://trustedscripts.com;

強大的 CSP 可以限制內聯腳本,即使存在逃逸漏洞,也可以防止注入的有效負載運作。

透過 cookie 發出會話識別碼時,請務必設定 HttpOnly 標誌。這可以防止客戶端腳本讀取 cookie 值(透過 document.cookie),從而減少會話盜竊,即使 XSS 攻擊成功也是如此。

結論

保護您的 Web 應用程式免受 XSS 侵害需要一致性:

  1. **將上下文感知轉義應用於所有動態輸入。 **
  2. **對於 DOM 操作,優先使用 textContent 而不是 innerHTML。 **
  3. **在渲染連結之前驗證 URL 方案 (http:/https:)。 **
  4. **使用內容安全策略和 HttpOnly cookie 作為安全網。 **

透過將這些安全實務納入您的開發工作流程,您可以防止 XSS 漏洞。