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 漏洞。