Astro客户端路由器中的DOM Clobbering漏洞导致XSS攻击

本文详细分析了Astro框架客户端路由器中发现的DOM Clobbering安全漏洞(CVE-2024-47885)。该漏洞源于ViewTransitions组件对document.scripts的引用,可能被攻击者利用注入的非脚本HTML元素(如iframe)进行劫持,最终导致跨站脚本攻击(XSS)。

漏洞详情

包信息

  • 包管理器: npm
  • 包名称: astro

受影响版本

= 3.0.0, < 4.16.1

已修复版本

4.16.1

描述

摘要

在Astro的客户端路由器中发现了一个DOM Clobbering gadget。如果网站启用了Astro的客户端路由,并且在目标页面上存储了攻击者控制的非脚本HTML元素(例如,具有未清理名称属性的iframe标签),则可能导致跨站脚本(XSS)攻击。

详细说明

背景 DOM Clobbering是一种代码复用攻击,攻击者首先在网页中嵌入一段非脚本、看似良性的HTML标记(例如通过帖子或评论),然后利用现有JavaScript代码中的gadget将其转换为可执行代码。关于DOM Clobbering的更多信息,可参考以下资料: [1] https://scnps.co/papers/sp23_domclob.pdf [2] https://research.securitum.com/xss-in-amp4email-dom-clobbering/

在Astro中发现的Gadget 我们在Astro的客户端路由模块中识别出一个DOM Clobbering gadget,具体位于 <ViewTransitions /> 组件中。当集成此组件时,它会引入以下在页面转换期间(例如点击 <a> 链接)执行的易受攻击代码: https://github.com/withastro/astro/blob/7814a6cad15f06931f963580176d9b38aa7819f2/packages/astro/src/transitions/router.ts#L135-L156

然而,此实现容易受到DOM Clobbering攻击。document.scripts 查找可能通过浏览器的命名DOM访问机制被攻击者注入的非脚本HTML元素(例如 <img name="scripts"><img name="scripts">)所遮蔽。这种操纵允许攻击者用一组攻击者控制的非脚本HTML元素替换原本的脚本元素。

第138行的条件 script.dataset.astroExec === '' 可以被绕过,因为攻击者控制的元素没有 data-astroExec 属性。同样,第134行的检查也可以被绕过,因为该元素不需要 type 属性。

最终,攻击者注入的非脚本HTML元素的 innerHTML(原本是纯文本内容)将被设置为脚本元素的 .innerHTML,从而导致XSS。

概念验证(PoC)

考虑一个使用Astro作为框架并启用了客户端路由的Web应用程序,该应用程序允许用户嵌入某些非脚本HTML元素(例如form或iframe)。这可以通过允许用户嵌入某些非脚本HTML的网站功能(例如Markdown渲染器、Web电子邮件客户端、论坛)或通过页面上加载的第三方JavaScript中的HTML注入漏洞来实现。

PoC网站请参考:https://stackblitz.com/edit/github-4xgj2d。点击菜单中的“about”按钮将从攻击者注入的form元素触发 alert(1)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
---
import Header from "../components/Header.astro";
import Footer from "../components/Footer.astro";
import { ViewTransitions } from "astro:transitions";
import "../styles/global.css";
const { pageTitle } = Astro.props;
---
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{pageTitle}</title>
    <ViewTransitions />
  </head>
  <body>
    <!--用户输入-->
    <iframe name="scripts">alert(1)</iframe>
    <iframe name="scripts">alert(1)</iframe>
    <!--用户输入-->
    
    <Header />
    <h1>{pageTitle}</h1>
    <slot />
    <Footer />
    <script>
      import "../scripts/menu.js";
    </script>
  </body>
</html>

影响

此漏洞可能导致对使用Astro构建的网站进行跨站脚本(XSS)攻击,这些网站启用了带有ViewTransitions的客户端路由,并在页面上存储了用户插入的非脚本HTML标签且未正确清理其名称属性。

修复建议

我们建议将 document.scripts 替换为 document.getElementsByTagName('script') 来引用脚本元素。这将缓解利用名称属性进行DOM Clobbering攻击的可能性。

参考

类似问题供参考:

  • Webpack (CVE-2024-43788)
  • Vite (CVE-2024-45812)
  • layui (CVE-2024-47075)

参考文献

漏洞信息

严重等级

  • 等级: Moderate
  • CVSS总体评分: 5.9 / 10

CVSS v3基础指标

  • 攻击向量: Network
  • 攻击复杂度: High
  • 所需权限: Low
  • 用户交互: Required
  • 作用范围: Unchanged
  • 机密性影响: Low
  • 完整性影响: Low
  • 可用性影响: High

CVSS向量字符串

CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:H

EPSS评分

  • 评分: 0.905% (第75百分位)

弱点

  • CWE-ID: CWE-79
  • 描述: 在网页生成过程中对输入的清理不恰当(‘跨站脚本’)。该产品在将用户可控的输入放入提供给其他用户的网页输出之前,未进行清理或清理不当。

标识符

  • CVE ID: CVE-2024-47885
  • GHSA ID: GHSA-m85w-3h95-hcf9

源代码仓库

withastro/astro

致谢

  • jackfromeast (分析师)
  • ishmeals (分析师)
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计