155 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Vue.js
{{#include ../../banners/hacktricks-training.md}}
## XSS Sinks in Vue.js
### v-html Directive
The `v-html` directive renders **raw** HTML, so any `<script>` (or an attribute like `onerror`) embedded in unsanitised user input executes immediately.
```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
Binding a user string to URL-bearing attributes (`href`, `src`, `xlink:href`, `formaction` …) lets payloads such as `javascript:alert(1)` run when the link is followed.
```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 with user-controlled handlers
`v-on` compiles its value with `new Function`; if that value comes from the user, you hand them code-execution on a plate.
```html
<div id="app">
<button v-on:click="malicious">Click me</button>
</div>
<script>
new Vue({
el: '#app',
data: { malicious: 'alert(1)' }
})
</script>
```
### Dynamic attribute / event names
User-supplied names in `v-bind:[attr]` or `v-on:[event]` let attackers create any attribute or event handler, bypassing static analysis and many CSP rules.
```html
<img v-bind:[userAttr]="payload">
<!-- userAttr = 'onerror', payload = 'alert(1)' -->
```
### Dynamic component (`<component :is>`)
Allowing user strings in `:is` can mount arbitrary components or inline templates—dangerous in the browser and catastrophic in SSR.
```html
<component :is="userChoice"></component>
<!-- userChoice = '<script>alert(1)</script>' -->
```
### Untrusted templates in SSR
During server-side rendering, the template runs **on your server**; injecting user HTML can escalate XSS to full Remote Code Execution (RCE). CVEs in `vue-template-compiler` prove the risk.
```js
// DANGER never do this
const app = createSSRApp({ template: userProvidedHtml })
```
### Filters / render functions that eval
Legacy filters that build render strings or call `eval`/`new Function` on user data are another XSS vector—replace them with computed properties.
```js
Vue.filter('run', code => eval(code)) // DANGER
```
---
## Other Common Vulnerabilities in Vue Projects
### Prototype pollution in plugins
Deep-merge helpers in some plugins (e.g., **vue-i18n**) have allowed attackers to write to `Object.prototype`.
```js
import merge from 'deepmerge'
merge({}, JSON.parse('{ "__proto__": { "polluted": true } }'))
```
### Open redirects with vue-router
Passing unchecked user URLs to `router.push` or `<router-link>` can redirect to `javascript:` URIs or phishing domains.
```js
this.$router.push(this.$route.query.next) // DANGER
```
### CSRF in Axios / fetch
SPAs still need server-side CSRF tokens; SameSite cookies alone cant block auto-submitted cross-origin POSTs.
```js
axios.post('/api/transfer', data, {
headers: { 'X-CSRF-TOKEN': token }
})
```
### Click-jacking
Vue apps are frameable unless you send both `X-Frame-Options: DENY` and `Content-Security-Policy: frame-ancestors 'none'`.
```http
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none';
```
### Content-Security-Policy pitfalls
The full Vue build needs `unsafe-eval`; switch to the runtime build or pre-compiled templates so you can drop that dangerous source.
```http
Content-Security-Policy: default-src 'self'; script-src 'self';
```
### Supply-chain attacks (node-ipc March 2022)
The sabotage of **node-ipc**—pulled by Vue CLI—showed how a transitive dependency can run arbitrary code on dev machines. Pin versions and audit often.
```shell
npm ci --ignore-scripts # safer install
```
---
## Hardening Checklist
1. **Sanitise** every string before it hits `v-html` (DOMPurify).
2. **Whitelist** allowed schemes, attributes, components, and events.
3. **Avoid `eval`** and dynamic templates altogether.
4. **Patch dependencies weekly** and monitor advisories.
5. **Send strong HTTP headers** (CSP, HSTS, XFO, CSRF).
6. **Lock your supply chain** with audits, lockfiles, and signed commits.
## References
- [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}}