2025 年 5 月 20 日,HTML 规范更新,以转义属性中的 <
和 >
,有助于防范突变 XSS (mXSS) 漏洞。此变更已应用于 Chrome 138,该版本已于 2025 年 5 月 28 日升级为 Beta 版,并将于 2025 年 6 月 24 日升级为稳定版。
本文详细介绍了 HTML 属性转义变更对 Web 开发者的影响以及可能出现的破坏情况;安全工程博客上的相关博文介绍了此次变更背后的安全原理。
有何变化
假设您有一个 <div>
元素,其属性 data-content
的值为 "<u>hello</u>"
。读取 div.outerHTML
后会发生什么?
以前,您会收到以下 HTML:
<div data-content="<u>hello</u>"></div>
更改后,您将获得以下 HTML:
<div data-content="<u>hello</u>"></div>
以前,属性中不会对 <
或 >
进行转义。现在,这两个字符始终会进行转义。
未改动的地方
此更改仅修改了在序列化过程中将 HTML 片段转换回字符串表示的方式。影响仅限于访问
innerHTML
或 outerHTML
属性或对元素调用 getHTML()
方法的情况。这些操作会采用现有的 DOM 结构,并生成文本 HTML 表示法。
此更改不会影响 HTML 解析。请考虑以下 HTML:
<div id="div1" data-content="<u>hello</u>"></div>
<div id="div2" data-content="<u>hello</u>"></div>
这两个 div
将以完全相同的方式解析,在这两种情况下,div.dataset.content
都会返回 "<u>hello</u>"
。
哪些内容不会中断?
如果您使用任何 DOM API(例如 getAttribute
、getAttributeNS
、dataset
或 attributes
)检索属性值,它们将返回与之前相同的解码值,尤其是在解码了 <
和 >
的情况下。
请考虑以下示例,其中所有 console.log
行都会记录 "<u>"
:
<div data-content="<u>"></div>
const div = document.querySelector("div");
// All of the following will log "<u>"
console.log(div.getAttribute("data-content"));
console.log(div.dataset.content);
console.log(div.attributes['data-content'].value);
哪些内容可能会损坏?
使用 innerHTML 和 outerHTML 获取属性
如果您使用 innerHTML
或 outerHTML
提取属性的值,您的代码可能会中断。请考虑以下虽然略显复杂的示例:
<div data-content="<u>"></div>
const div = div.querySelector("div");
const content = div.outerHTML.match(/"([^"]+)"/)[1];
console.log(content);
此代码在发生此更改后将表现出不同的行为。以前,content
等于 "<u>"
,但现在等于 "<u>"
。
请注意,不建议使用正则表达式解析 HTML。如果您需要获取某个属性的值,请使用前面部分介绍的 DOM API。
端到端测试
如果您有一个 CI/CD 流水线,其中使用 Chromium 生成 HTML,并且您编写了测试来将 HTML 与静态预期值进行比较,那么如果任何属性包含 <
或 >
,这些测试可能会中断。
这是预期的破坏情况 – 您需要更新预期值,以便将所有 <
和 >
字符分别转义为 <
和 >,
。
摘要
这篇博文介绍了 HTML 规范中的一项变更,该变更将导致浏览器开始对属性中的 <
和 >
进行转义,以通过防止某些突变 XSS 实例来提高安全性。
自 2025 年 6 月 24 日起,所有使用 Chromium(版本 138)和 Firefox(版本 140)的用户均可使用此更改。它也包含在 Safari 26 Beta 版中,该版本应该会在 2025 年 9 月左右发布。
如果您认为此更改破坏了您的网站,并且您无法轻松解决此问题,请访问 https://issues.chromium.org/ 提交 bug。
对于这篇文章,你的反应是: