# 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
Click me
``` ### 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}}