LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

HTML Sanitizer API 深度解析

admin
2026年5月21日 16:40 本文热度 135

跨站脚本攻击(XSS)长期以来一直是 Web 安全领域最难根治的漏洞之一。在过去近十年中,CWE-79(XSS 漏洞)始终位列最严重的三大 Web 安全漏洞。尽管内容安全策略(CSP)等防御手段为 Web 安全提供了强有力的防线,但由于其要求网站进行显著的架构调整以及持续的安全审查,在实际部署中并未获得广泛的采纳。

HTML Sanitizer API 的诞生正是为了填补这一安全空白。它提供了一种由浏览器原生支持的标准化方法,在将不可信的 HTML 插入页面之前,自动移除其中所有危险元素和属性——即“清理”(sanitize)不可信内容。开发者只需将原有的 innerHTML 赋值替换为 setHTML(),即可在不显著改动现有代码的情况下获得内置的 XSS 防护能力。

本文将基于 2026 年的最新规范进展,深入解析 HTML Sanitizer API 的核心设计、使用方法与实践要点。

特性

说明

API 类型

浏览器原生 Web API

核心功能

过滤和清理不可信 HTML,移除危险标签和属性和不安全协议

适用场景

用户评论区、富文本编辑器、第三方内容嵌入、客户端模板渲染等

当前状态

已实现标准化,逐步获得主流浏览器支持

2026 年 2 月,Firefox 148 成为首个正式发布标准化 Sanitizer API 的浏览器。这一里程碑标志着 Web 平台原生 XSS 防护能力向前迈出了关键一步,其他主流浏览器预计也将很快跟进。

一、为什么需要 Sanitizer API?


场景

风险

Sanitizer 解决方案

用户评论区

<script>恶意代码</script>

自动移除 <script> 标签

富文本编辑器

onclick="窃取Cookie()"

移除危险事件属性

第三方内容嵌入

iframe src="恶意链接"

过滤不受信任的标签

SVG 图像上传

<svg><script>alert(1)</script>

清理 SVG 中的脚本

CSS 注入

style="background: url(javascript:alert(1))"

移除危险的 style 内容

链接劫持

<a href="javascript:恶意代码">

将 javascript: 协议置为 about:blank


二、核心接口与配置


2.1 Sanitizer 类

Sanitizer 接口是一个可复用的配置对象,用于定义在将 HTML 字符串插入 Element 或 ShadowRoot 时,哪些元素、属性和注释应当被允许或移除。

// 创建 Sanitizer 实例const sanitizer = new Sanitizer(options);

2.2 SanitizerConfig 配置详解

SanitizerConfig 字典定义了清理器的具体行为。配置项主要分为以下几类:

配置属性

类型

说明

elements

Array

允许保留的元素列表,可同时为每个元素指定允许或移除的属性

removeElements

Array

需要完全移除的元素列表

replaceWithChildrenElements

Array

用其子元素替换元素

attributes

Array

允许保留的属性列表

removeAttributes

Array

需要移除的属性列表

allowComments

Boolean

是否保留 HTML 注释

allowDataAttributes

Boolean

是否保留 data-* 属性

2.3 基础配置示例

const sanitizer = new Sanitizer({  // 允许保留的元素  elements: ["div""p""span""a""img"],  // 需要完全移除的元素  removeElements: ["script""style""iframe"],  // 用其子元素替换元素  replaceWithChildrenElements: ["b""i"],  // 允许保留的属性  attributes: ["class""id"],  // 移除的属性(支持通配)  removeAttributes: ["onclick""onload""onerror"]});

2.4 命名空间支持

SanitizerConfig 还支持通过 namespace 字段区分 HTML、SVG 和 MathML 中的同名元素与属性,满足更复杂的清理需求。默认命名空间为 HTML 命名空间。

// 同时允许 SVG 和 HTML 中的同名元素const config = {  elements: [    "div",  // 默认 HTML 命名空间    { name: "circle"namespace"http://www.w3.org/2000/svg" }  ]};

2.5 三种元素处理策略对比

策略

配置字段

处理方式

示例

允许保留

elements

元素及其允许的属性被保留

示例一

完全移除

removeElements

整个元素被删除

示例二

替换为子元素

replaceWithChildrenElements

父标签被移除,子元素保留

示例三

示例一:元素及其允许的属性被保留

<p>文本</p> → <p>文本</p>

示例二:整个元素被删除

<script>alert(1)</script> →(空)

示例三:父标签被移除,子元素保留

<b>文本</b> → 文本

三、清理方法:安全方法 vs 不安全方法


HTML Sanitizer API 提供了两套方法:XSS 安全方法 和 XSS 不安全方法,分别适用于不同场景。

3.1 XSS 安全方法(推荐日常使用

安全方法始终会移除所有 XSS 不安全的元素和属性,即使用户传入了自定义的 Sanitizer 配置也无法绕过这一底线。

方法

所属对象

说明

Element.setHTML()

Element

替代 innerHTML 的安全方法

ShadowRoot.setHTML()

ShadowRoot

Shadow DOM 中的安全注入

Document.parseHTML()

Document(静态)

将 HTML 字符串解析为安全的 Document

核心用法:setHTML() 可以直接作为 innerHTML 的替代品使用:

const untrustedString = 'abc <script>alert(1)</script> def';const element = document.getElementById('target');
// 不安全的做法// element.innerHTML = untrustedString;
// 安全的做法element.setHTML(untrustedString);console.log(element.innerHTML); // "abc def"

3.2 XSS 不安全方法(慎用)

当输入的 HTML 需要包含某些不安全的元素或属性时,可以使用不安全方法。这些方法会严格按照传入的 Sanitizer 配置执行清理,不会自动补加安全限制。

方法

所属对象

说明

Element.setHTMLUnsafe()

Element

使用自定义配置注入,不自动移除不安全内容

ShadowRoot.setHTMLUnsafe()

ShadowRoot

Shadow DOM 中的不安全版本

Document.parseHTMLUnsafe()

Document(静态)

解析 HTML 字符串为 Document,不自动移除不安全内容

// 允许特定的不安全内容(仅当确实需要时使用)const customConfig = { elements: ["div""button"], attributes: ["onclick"] };element.setHTMLUnsafe(userInput, customConfig);// ⚠️ 仅当确实需要包含不安全实体时才使用此方法

重要提醒:日常开发中应始终优先使用安全方法 setHTML())。不安全方法仅在“确实需要包含某些不安全实体、且已通过自定义配置将其限制到最小安全集合”的场景下使用。

四、Sanitizer 实例的动态方法


Sanitizer 实例除通过构造函数一次性配置外,还提供了一系列动态方法,允许在运行时逐步调整配置,而无需重新创建实例。

方法

说明

allowElement(elementName, attributes?)

将元素加入允许列表

removeElement(elementName)

将元素加入移除列表

replaceElementWithChildren(elementName)

将元素替换为其子节点

allowAttribute(attributeName)

将属性加入允许列表

removeAttribute(attributeName)

将属性加入移除列表

setComments(allow)

设置是否保留注释

setDataAttributes(allow)

设置是否保留 data-* 属性

removeUnsafe()

更新清理器配置,移除所有 XSS 不安全的 HTML 实体

get()

获取当前配置的快照

const sanitizer = new Sanitizer();// 动态添加配置sanitizer.allowElement('div', ['class''id']);sanitizer.allowElement('img', ['src''alt']);sanitizer.removeAttribute('onclick');sanitizer.setComments(false);sanitizer.setDataAttributes(true);// 获取当前配置console.log(sanitizer.get());

五、清理配置的构建策略


策略一:允许列表(白名单)

只允许指定的元素和属性,其他一律移除。这种形式易于理解,尤其在确定目标上下文中应允许哪些 HTML 实体时非常有用。

const allowlistSanitizer new Sanitizer({  elements: ["p""strong""em""a""img"],  attributes: ["href""src""alt"]});

策略二:拒绝列表(黑名单)

允许大多数元素,只移除明确禁止的项。

const denylistSanitizer new Sanitizer({  removeElements: ["script""iframe""object"],  removeAttributes: ["onclick""onerror""onload"]});

策略三:基于默认配置调整

默认的 Sanitizer 配置已经是 XSS 安全的良好起点,它移除了所有 XSS 不安全的元素和属性(如 <script> 元素和 onclick 事件处理器等)。开发者可以在默认配置基础上,根据业务需求进行适度收紧或放松。

// 使用默认配置const defaultSanitizer = new Sanitizer();
// 在默认安全配置基础上,进一步允许不安全实体// 注意:安全方法会忽略 unsafe 元素,所以需要结合不安全方法使用const customSanitizer = new Sanitizer();customSanitizer.allowElement("button", ["onclick"]);element.setHTMLUnsafe(untrustedString, customSanitizer);

六、默认清理器配置详解


Sanitizer API 内置了一套默认清理器配置。该配置是 XSS 安全的良好起点,已知会移除以下类型的元素和属性:

始终移除的元素(即使传入自定义 Sanitizer 也仍会被安全方法移除):

  • <script>、<frame>、<iframe>、<embed>、<object>、<use>。

始终移除的属性

  • 所有事件处理属性(如 onclick、onload、onerror 等)。

  • 指向 javascript: 协议的导航属性(如 <a href="javascript:...">)。

安全方法使用此默认配置时,XSS 不安全实体永远不会被注入到 DOM 中。开发者传入的自定义配置仅能在默认安全配置的基础上进一步收紧允许的实体范围,而不能放宽已禁止的不安全实体。

七、与 DOMPurify 的对比


HTML Sanitizer API 的设计目标并非完全取代 DOMPurify,而是为 Web 开发者提供一种原生、轻量、安全的备选方案。

特性

HTML Sanitizer API

DOMPurify

类型

浏览器原生 API,由 WICG 孵化和标准化

第三方 JavaScript 库

大小

 0 KB(内置)

 ~30 KB(需额外加载和解析)

mXSS 防护

原生设计,只解析一次 HTML,从根本上杜绝 mXSS

依赖两轮解析,存在潜在的 mXSS 风险

性能

原生实现,比 JavaScript 库更快

JavaScript 实现

兼容性

现代浏览器

所有浏览器(含旧版)

自定义性

中等,通过 SanitizerConfig 控制

高度可定制,提供丰富 Hooks

更新维护

浏览器厂商负责

社区维护

SVG/MathML 支持

通过命名空间配置支持

内置支持

DOMPurify 在 Node.js 服务端环境中仍然扮演着重要角色。在 Sanitizer API 获得全面浏览器支持之前,DOMPurify 仍将是跨浏览器和跨环境(包括服务端 JS 需依赖 jsdom 时)最可靠的 HTML 清理方案。

在 Web 安全语境里,mXSS 指的是 Mutation-based XSS(基于突变的跨站脚本攻击),是一种比较隐蔽的 XSS 类型。


mXSS = 浏览器在解析/重构 HTML 时,把看似无害的内容“突变”成可执行的脚本。

八、完整应用示例


8.1 安全方法:替换 innerHTML

这是 Sanitizer API 最实用的场景——用 setHTML() 直接替换项目中的 innerHTML 赋值,以极低的代码改动换取更强的 XSS 防护。

// 包含恶意代码的用户输入const userComment = `  <div>    <p>This is a great article!</p>    <img src="x" onclick="alert('XSS')">    <script>stealCookies()</script>    <a href="javascript:alert('evil')">Click me</a>  </div>`;
// 方式一:直接使用 setHTML(默认安全配置)document.getElementById('comment').setHTML(userComment);
// 输出:<div><p>This is a great article!</p><img src="x"><a>Click me</a></div>

8.2 富文本编辑器场景

class SafeRichEditor {  constructor(containerId) {    this.container = document.getElementById(containerId);    // 创建适合富文本编辑的 Sanitizer    this.sanitizer = new Sanitizer({      elements: [        "p""h1""h2""h3""h4",        "ul""ol""li""blockquote",        "strong""em""a""img""br""hr"      ],      attributes: ["href""target""src""alt"]    });  }
    setContent(html) {    // 使用安全方法注入清理后的内容    this.container.setHTML(html, { sanitizerthis.sanitizer });  }
    getContent() {    return this.container.innerHTML;  }}
// 使用示例const editor = new SafeRichEditor('editor-container');editor.setContent(userInput);

8.3 在 Shadow DOM 中使用

const host = document.getElementById('host');const shadowRoot = host.attachShadow({ mode'open' });const userContent = '<p>Shadow DOM content</p><script>alert("XSS")</script>';
// 安全地注入到 Shadow DOMshadowRoot.setHTML(userContent);
// 结果:<p>Shadow DOM content</p>(script 标签被移除)

8.4 使用 replaceElementWithChildren() 清除样式

// 创建一个清理器,将 <strong> 元素替换为其子文本const sanitizer new Sanitizer({ elements: ["p""em""strong"] });sanitizer.replaceElementWithChildren("strong");
​const input = "<p>This is <strong>important</strong> text with <em>emphasis</em>.</p>";const element = document.getElementById("output");element.setHTML(input, { sanitizer: sanitizer });
// 输出:<p>This is important text with <em>emphasis</em>.</p>

8.6 将 HTML 字符串解析为安全的 Document

// 使用 parseHTML 静态方法解析 HTML 为安全的 Documentconst unsafeHtml = '<div>Hello</div><script>alert("XSS")</script>';const doc = Document.parseHTML(unsafeHtml);
// doc 是一个安全的 Document 对象,其中不包含 script 元素const safeContent = doc.body.innerHTML// <div>Hello</div>

九、与 Trusted Types 的配合使用


Trusted Types 和 Sanitizer API 是相辅相成的安全机制。Trusted Types 确保开发者不会忘记清理——任何试图将字符串注入 DOM API 的行为都会失败,除非传入一个 TrustedHTML 对象。Sanitizer API 则负责实际的清理工作,输出安全的 HTML 内容。

// 创建 Trusted Type 策略,内部集成 Sanitizer APIconst policy = trustedTypes.createPolicy('sanitizer-policy', {  createHTML(input) => {    const sanitizer = new Sanitizer();    const fragment = sanitizer.sanitize(input);    const div = document.createElement('div');    div.appendChild(fragment);    return div.innerHTML;  }});
// 使用策略创建安全的 HTMLconst safeHTML = policy.createHTML(userInput);element.innerHTML = safeHTML;

十、浏览器兼容性与生产环境建议


10.1 当前兼容性现状

截至 2026 年 5 月:

  • Firefox:Firefox 148+ 已正式支持 Sanitizer API,Firefox 成为首个发布标准化 Sanitizer API 的浏览器。

  • Chrome:Chrome 146+ 支持 setHTML(),Edge 同步 Chromium 版本。

  • Safari:尚未完全支持 Sanitizer API。

值得注意的是,截至 2026 年初,Sanitizer API 尚未达到 Baseline 状态(即在部分主流浏览器中尚不可用),因此生产环境中的代码应当进行特性检测并提供降级方案。

10.2 特性检测与降级方案

// 检测 Sanitizer API 是否可用if (window.Sanitizer && Element.prototype.setHTML) {  // 使用原生 API  element.setHTML(userInput);else {  // 回退到 DOMPurify  element.innerHTML = DOMPurify.sanitize(userInput);}

10.3 服务端清理

由于 Sanitizer API 是浏览器原生 API,在 Node.js 环境中可借助 jsdom 配合相关 polyfill(如 @ungap/sanitizer)实现服务端清理。服务端清理与客户端清理结合使用,可以构建纵深防御体系。

const { JSDOM } = require('jsdom');const { Sanitizer } = require('@ungap/sanitizer');const dom new JSDOM('<!DOCTYPE html>');const sanitizer new Sanitizer({ window: dom.window });const cleanHTML = sanitizer.sanitize(userInput);

十一、最佳实践


1. 优先使用 setHTML 替代 innerHTML

// 错误:直接使用 innerHTMLelement.innerHTML = userInput;
// 正确:使用 setHTMLelement.setHTML(userInput);

2. 为不同场景配置不同的 Sanitizer

// 评论区的严格配置const commentSanitizer new Sanitizer({  elements: ["p""strong""em""a""br"],  attributes: ["href"]});
// 博客正文的宽松配置const blogSanitizer new Sanitizer({  elements: ["p""h1""h2""h3""ul""ol""li""img""a""blockquote""code"],  attributes: ["href""src""alt""title"]});

3. 结合 Content Security Policy(CSP)

<!-- 设置严格的 CSP 作为纵深防御 --><meta http-equiv="Content-Security-Policy"       content="default-src 'self'; script-src 'none'; object-src 'none'">

4. 生产环境使用特性检测

function safelyInjectHTML(element, html) {  if (element.setHTML) {    element.setHTML(html);  } else {    element.innerHTML = DOMPurify.sanitize(html);  }}

5. 避免混淆配置策略

SanitizerConfig 的设计限制了同时指定“允许”和“移除”类型的配置项,以避免在清理策略上产生混淆。如果配置同时包含 elements(允许列表)和 removeElements(移除列表),将导致类型错误。开发者应根据使用场景选择一种策略:

  • 允许列表策略:适合需要严格控制注入内容格式的场景(如评论区)。

  • 移除列表策略:适合默认接受大多数 HTML 格式,只移除已知不安全实体的场景(如富文本编辑器)。


十二、常见问题


Q1:为什么 setHTML() 不直接返回清理后的 HTML 字符串?

因为setHTML() 的核心设计在于将清理机制深度集成至浏览器的原生 HTML 解析器中,通过“解析 → 清理 → 注入”的原子化流程,从根本上杜绝了 mXSS 攻击的可能性。若将清理后的结果以字符串形式返回,将导致二次解析风险;因此,该方法选择直接操作 DOM,从而确保安全性。

Q2:安全方法与不安全方法的核心区别是什么?
  • 安全方法:即使传入自定义 Sanitizer,也始终强制移除所有 XSS 不安全元素和属性。

  • 不安全方法:严格使用传入的配置进行清理,不会自动补加额外的安全基线。


Q3:默认配置足够安全吗?

对于大多数日常使用场景(如用户评论、富文本编辑等),默认配置已足够安全。但对于内容安全要求极高的场景(如金融、政府应用),建议传入自定义配置进一步限制允许的元素和属性范围,并结合 CSP 构建纵深防御。

Q4:如何实验和测试 Sanitizer API?

在将 Sanitizer API 引入实际网页之前,建议访问 Sanitizer API Playground (网址:https://sanitizer-api.dev/)进行实验和测试。

Q5:正则表达式清理的危险性

直接使用正则表达式匹配并剔除非法 HTML 标签存在严重的安全与可靠性风险。正则表达式难以正确解析复杂的 HTML 结构,容易被各种绕过技巧攻击。始终推荐使用专业的 HTML 清理方案(如 Sanitizer API 或 DOMPurify)。

总结


HTML Sanitizer API 是现代浏览器提供的一项原生安全工具,它通过以下优势为 Web 开发者带来了更便捷的 XSS 防护方案:

  1. 安全性高:由浏览器厂商维护,持续更新安全策略,默认配置即可防护常见 XSS 攻击。

  2. 性能优异:原生实现,相比 JavaScript 库更高效。

  3. 使用简单:API 设计简洁,setHTML() 可直接替换 innerHTML。

  4. 上下文感知:智能处理不同元素的安全需求,还支持 SVG 和 MathML 命名空间。

  5. 渐进增强:可与现有安全方案(CSP、Trusted Types、DOMPurify)协同工作。

实用建议:在支持 Sanitizer API 的浏览器中优先使用原生方案以获得最佳性能;对于需要兼容旧浏览器的项目,保留 DOMPurify 作为回退方案。同时,切勿完全依赖单一的防御手段——将 Sanitizer API 与 CSP 结合使用,可以为应用构建更加稳固的安全防线。


阅读原文:https://mp.weixin.qq.com/s/hWqdAA1VPHUaJk_NgkiPJg


该文章在 2026/5/22 11:09:37 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-2  粤公网安备44030602007207号