mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
129 lines
4.5 KiB
Markdown
129 lines
4.5 KiB
Markdown
# Vue.js
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Vue.js中的XSS漏洞
|
||
|
||
### v-html指令
|
||
`v-html`指令渲染**原始**HTML,因此任何嵌入在未经过滤的用户输入中的`<script>`(或像`onerror`这样的属性)会立即执行。
|
||
```html
|
||
<div id="app">
|
||
<div v-html="htmlContent"></div>
|
||
</div>
|
||
<script>
|
||
new Vue({
|
||
el: '#app',
|
||
data: {
|
||
htmlContent: '<img src=x onerror=alert(1)>'
|
||
}
|
||
})
|
||
</script>
|
||
```
|
||
### v-bind with src or href
|
||
将用户字符串绑定到带有 URL 的属性(`href`、`src`、`xlink:href`、`formaction` 等)允许在跟随链接时运行诸如 `javascript:alert(1)` 的有效载荷。
|
||
```html
|
||
<div id="app">
|
||
<a v-bind:href="userInput">Click me</a>
|
||
</div>
|
||
<script>
|
||
new Vue({
|
||
el: '#app',
|
||
data: {
|
||
userInput: 'javascript:alert(1)'
|
||
}
|
||
})
|
||
</script>
|
||
```
|
||
### v-on 与用户控制的处理程序
|
||
`v-on` 使用 `new Function` 编译其值;如果该值来自用户,您就将代码执行的权限直接交给他们。
|
||
```html
|
||
<div id="app">
|
||
<button v-on:click="malicious">Click me</button>
|
||
</div>
|
||
<script>
|
||
new Vue({
|
||
el: '#app',
|
||
data: { malicious: 'alert(1)' }
|
||
})
|
||
</script>
|
||
```
|
||
### 动态属性 / 事件名称
|
||
用户提供的名称在 `v-bind:[attr]` 或 `v-on:[event]` 中允许攻击者创建任何属性或事件处理程序,从而绕过静态分析和许多 CSP 规则。
|
||
```html
|
||
<img v-bind:[userAttr]="payload">
|
||
<!-- userAttr = 'onerror', payload = 'alert(1)' -->
|
||
```
|
||
### 动态组件 (`<component :is>`)
|
||
允许用户字符串在 `:is` 中可以挂载任意组件或内联模板——在浏览器中是危险的,在 SSR 中是灾难性的。
|
||
```html
|
||
<component :is="userChoice"></component>
|
||
<!-- userChoice = '<script>alert(1)</script>' -->
|
||
```
|
||
### 不可信的模板在SSR中
|
||
在服务器端渲染期间,模板在**你的服务器**上运行;注入用户HTML可能会将XSS升级为完全的远程代码执行(RCE)。`vue-template-compiler`中的CVE证明了这一风险。
|
||
```js
|
||
// DANGER – never do this
|
||
const app = createSSRApp({ template: userProvidedHtml })
|
||
```
|
||
### 过滤器 / 渲染函数的 eval
|
||
构建渲染字符串或在用户数据上调用 `eval`/`new Function` 的遗留过滤器是另一个 XSS 向量——用计算属性替换它们。
|
||
```js
|
||
Vue.filter('run', code => eval(code)) // DANGER
|
||
```
|
||
---
|
||
|
||
## Vue项目中的其他常见漏洞
|
||
|
||
### 插件中的原型污染
|
||
某些插件中的深度合并助手(例如,**vue-i18n**)允许攻击者写入 `Object.prototype`。
|
||
```js
|
||
import merge from 'deepmerge'
|
||
merge({}, JSON.parse('{ "__proto__": { "polluted": true } }'))
|
||
```
|
||
### 使用 vue-router 的开放重定向
|
||
将未经检查的用户 URL 传递给 `router.push` 或 `<router-link>` 可能会重定向到 `javascript:` URI 或钓鱼域。
|
||
```js
|
||
this.$router.push(this.$route.query.next) // DANGER
|
||
```
|
||
### CSRF in Axios / fetch
|
||
单页应用仍然需要服务器端的CSRF令牌;仅使用SameSite cookies无法阻止自动提交的跨源POST请求。
|
||
```js
|
||
axios.post('/api/transfer', data, {
|
||
headers: { 'X-CSRF-TOKEN': token }
|
||
})
|
||
```
|
||
### Click-jacking
|
||
Vue 应用程序是可以被框架化的,除非您同时发送 `X-Frame-Options: DENY` 和 `Content-Security-Policy: frame-ancestors 'none'`。
|
||
```http
|
||
X-Frame-Options: DENY
|
||
Content-Security-Policy: frame-ancestors 'none';
|
||
```
|
||
### Content-Security-Policy pitfalls
|
||
完整的 Vue 构建需要 `unsafe-eval`;切换到运行时构建或预编译模板,以便您可以去掉这个危险的源。
|
||
```http
|
||
Content-Security-Policy: default-src 'self'; script-src 'self';
|
||
```
|
||
### 供应链攻击 (node-ipc – 2022年3月)
|
||
对 **node-ipc** 的破坏——由 Vue CLI 拉取——显示了一个传递依赖如何在开发机器上运行任意代码。固定版本并经常审计。
|
||
```shell
|
||
npm ci --ignore-scripts # safer install
|
||
```
|
||
---
|
||
|
||
## 加固检查清单
|
||
|
||
1. **在字符串进入 `v-html` 之前进行清理** (DOMPurify)。
|
||
2. **列出** 允许的方案、属性、组件和事件。
|
||
3. **完全避免使用 `eval`** 和动态模板。
|
||
4. **每周修补依赖** 并监控安全通告。
|
||
5. **发送强大的 HTTP 头** (CSP, HSTS, XFO, CSRF)。
|
||
6. **通过审计、锁定文件和签名提交来锁定你的供应链**。
|
||
|
||
## 参考资料
|
||
|
||
- [https://www.stackhawk.com/blog/vue-xss-guide-examples-and-prevention/](https://www.stackhawk.com/blog/vue-xss-guide-examples-and-prevention/)
|
||
- [https://medium.com/@isaacwangethi30/vue-js-security-6e246a7613da](https://medium.com/@isaacwangethi30/vue-js-security-6e246a7613da)
|
||
- [https://vuejs.org/guide/best-practices/security](https://vuejs.org/guide/best-practices/security)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|