mXSS:隐藏在代码中的漏洞
mXSS:隐藏在代码中的漏洞
Ots安全 2024-06-02 12:20
跨站点脚本 (XSS) 是一种众所周知的漏洞类型,攻击者可以将 JavaScript 代码注入易受攻击的页面。当不知情的受害者访问该页面时,注入的代码将在受害者的会话中执行。此攻击的影响可能因应用程序而异,但不会造成业务影响,例如帐户接管(ATO)、数据泄露,甚至远程代码执行(RCE)。
XSS 有多种类型,例如反射型、存储型和通用型。但近年来,XSS 的变异类型因绕过 DOMPurify、Mozilla bleach、Google Caja 等清理程序而令人生畏……影响了包括 Google 搜索在内的众多应用程序。到目前为止,我们发现许多应用程序都容易受到此类攻击。
但是 mXSS 是什么?
(我们还在 Insomnihack 2024 演讲中探讨了这个主题:击败 Sanitizer:为什么你应该将 mXSS 添加到你的工具箱中。)
背景
如果您是 Web 开发人员,您可能已经集成甚至实施了某种清理措施来保护您的应用程序免受 XSS 攻击。但人们对制作合适的 HTML 清理程序有多难知之甚少。HTML 清理程序的目标是确保用户生成的内容(例如文本输入或从外部来源获取的数据)不会带来任何安全风险或破坏网站或应用程序的预期功能。
实施 HTML 清理程序的主要挑战之一在于 HTML 本身的复杂性。HTML 是一种多功能语言,具有各种元素、属性和潜在组合,这些元素、属性和组合可能会影响网页的结构和行为。准确解析和分析 HTML 代码并保留其预期功能可能是一项艰巨的任务。
HTML
在讨论 mXSS 之前,我们先来了解一下 HTML,它是网页的基础标记语言。了解 HTML 的结构及其工作原理至关重要,因为 mXSS(突变跨站点脚本)攻击利用了 HTML 的怪癖和复杂性。
HTML 被认为是一种宽容的语言,因为它在遇到错误或意外代码时具有宽容的特性。与一些更严格的编程语言不同,即使代码编写得不完美,HTML 也会优先显示内容。这种宽容的表现如下:
当呈现损坏的标记时,浏览器不会崩溃或显示错误消息,而是会尝试尽可能地解释和修复 HTML,即使其中包含轻微的语法错误或缺少元素。例如,在浏览器中打开以下标记
test将按预期执行,尽管缺少结束p标记。查看最终页面的 HTML 代码时,我们可以看到解析器修复了损坏的标记并
p自行关闭了元素:
test
。
它为何具有宽容度:
– 可访问性:网络应该对所有人都开放,HTML 中的小错误不应妨碍用户查看内容。宽容度允许更广泛的用户和开发人员与网络互动。
– 灵活性:HTML 经常被具有不同编码经验水平的人们使用。容忍度允许一些粗心或错误,而不会完全破坏页面的功能。
– 向后兼容性:网络在不断发展,但许多现有网站都是使用较旧的 HTML 标准构建的。即使这些较旧的网站不符合最新规范,Tolerance 也能确保它们仍可在现代浏览器中显示。
但是我们的 HTML 解析器如何 知道 以何种方式“修复”损坏的标记?应该
变成
还是
?
为了回答这个问题,有一个文档齐全的HTML 规范,但不幸的是,仍然存在一些歧义,导致即使在当今的主流浏览器之间也存在不同的 HTML 解析行为。
突变
好的,那么 HTML 可以容忍损坏的标记,这有什么关系呢?
mXSS 中的 M 代表“变异”,HTML 中的变异是由于某种原因对标记所做的任何类型的改变。
– 当解析器修复损坏的标记(
test
→
test
)时,这就是一次变异。
– 重新排列元素(
),这是一个突变
– 等等…
mXSS 利用这种行为来绕过清理,我们将在技术细节中展示示例。
HTML 解析背景
将长达 1500 多页的 HTML 解析标准总结为一个章节是不现实的。但是,由于它对于深入理解 mXSS 以及有效载荷的工作原理非常重要,我们必须至少涵盖一些主要主题。为了简化操作,我们开发了一个mXSS 速查表(稍后将在本博客中介绍),将这个繁琐的标准浓缩为研究人员和开发人员更易于管理的资源。
不同的内容解析类型
HTML 并不是一个通用的解析环境。元素以不同的方式处理其内容,有七种不同的解析模式。我们将探索这些模式,以了解它们如何影响 mXSS 漏洞:
– 空元素
area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr
– 元素template
template
– 原始文本元素
script, style, noscript, xmp, iframe, noembed, noframes
– 可转义的原始文本元素
textarea, title
– 外来内容元素
svg, math
– 明文状态
plaintext
– 普通元素
All other allowed HTML elements are normal elements.
我们可以使用以下示例相当容易地展示解析类型之间的区别:
1、我们的第一个输入是一个div元素,它是一个“普通元素”元素: