概述
Vue 是一个 HTML、CSS 和 JS 框架,用于开发具有细粒度反应性的网络应用程序。
在 Vue 2 模板编译器中发现了一个跨站脚本 (XSS) 漏洞,该漏洞存在于 Vue 2 的 "完整版 "中。完整版允许用户代码将字符串模板编译为 Vue 组件,并在浏览器中动态渲染函数,然后在浏览器中执行这些函数。
根据 OWASP:跨站脚本攻击是一种注入式攻击,在这种攻击中,恶意脚本被注入到原本良性和可信的网站中。当攻击者使用网络应用程序向不同的终端用户发送恶意代码(通常以浏览器侧脚本的形式)时,就会发生 XSS 攻击。攻击者可以利用 XSS 向毫无戒心的用户发送恶意脚本。
详细信息
模块信息
- 软件包管理器:npm
- 受影响的软件包: vue-template-compiler
- Affected versions: >= 2.0.0 < 3.0.0
- 已发布软件包的链接: https://www.npmjs.com/package/vue-template-compiler
- Github repo: https://github.com/vuejs/vue
- 概念验证:https://stackblitz.com/edit/cve-2024-6783?file=index.html
漏洞信息
This Medium-severity level exploit can be found in Vue versions greater than or equal to 2.0.0 and before 3.0.0. It is found inside of the in-browser Vue template compiler which is shipped inside the “full build” of Vue. The in-browser Vue template compiler is responsible for creating a string of code to be executed so that component templates like “<div>{{ variables }}</div>” can be parsed and turned into render functions. These render functions are then executed by Vue when it evaluates the render functions within a stringified eval statement, thus allowing a third-party script to run arbitrary code.
在扩展 Object.prototype 时,只有某些属性容易受到客户端 XSS 漏洞的影响。其中一个属性是 staticClass,当模板字符串使用带有非动态类的 `class` 属性时,会在 AST 构建阶段检索到该属性。
有一些优化取决于整个模板字符串,这些优化可能会也可能不会触发此代码路径。有关易受此攻击影响的组件示例,请参阅 "重现步骤"。
复制步骤
Vue 浏览器内模板编译器的 AST Codegen 路径依赖于最初未设置的属性。最终,属性会被一个函数消耗,该函数会对值进行字符串化,并在呈现时将它们传递给一个 eval 语句。如果将这些属性明确设置为未定义或检查 hasOwnProperty,那么原型污染将无法实现。目前,ASTElement(在 SSR、浏览器内编译和 Vue SFC 文件解析器期间用于创建代码生成节点的主要数据结构)上的几乎所有属性都是可选的,因此可能会受到此 XSS 漏洞的影响。
跨站脚本攻击是一种注入攻击,在这种攻击中,恶意脚本会被注入到原本良性和可信的网站中。当攻击者使用网络应用程序发送恶意代码时,就会发生 XSS 攻击,通常是以浏览器的形式--模板编译器代码会消耗 AST,并且不会对最终在呈现过程中调用的属性中的内容进行适当的消毒。下一节中的示例代码和概念验证并不详尽。
<head>
<script>
window.Proxy = undefined // Not necessary, but helpfull in demonstrating breaking out into `window.alert`
Object.prototype.staticClass = `alert("Polluted")`
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
new window.Vue({
template: `<div class="">Content</div>`,
}).$mount('#app')
</script>
</body>
概念验证
上述代码在概念验证网站中的完整再现可在此处查看: https://stackblitz.com/edit/cve-2024-6783?file=index.html
缓解
Vue 2 已达到生命周期终点。 受影响组件的用户应采用以下缓解措施之一:
- 迁移到新版本的 Vue
- 打上自己的补丁
- 利用 HeroDevs 这样的商业支持合作伙伴提供 EOL 后的安全支持。
荣誉
- Zifeng Kang 查找器
- 木樨柳查找器
- 曹银芝
每当我们支持的开源软件修复了新的漏洞,我们就会发出警报。