# Vue.js
{{#include ../../banners/hacktricks-training.md}}
## XSS Sinks in Vue.js
### v-html Directive
The `v-html` directive renders **raw** HTML, so any `
```
### 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
```
### 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
```
### 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
```
### Dynamic component (``)
Allowing user strings in `:is` can mount arbitrary components or inline templates—dangerous in the browser and catastrophic in SSR.
```html
```
### 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 `` 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 can’t 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}}