4.5 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	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.
<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.
<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.
<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.
<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.
<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.
// 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.
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.
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.
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.
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'.
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.
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.
npm ci --ignore-scripts   # safer install
Hardening Checklist
- Sanitise every string before it hits v-html(DOMPurify).
- Whitelist allowed schemes, attributes, components, and events.
- Avoid evaland dynamic templates altogether.
- Patch dependencies weekly and monitor advisories.
- Send strong HTTP headers (CSP, HSTS, XFO, CSRF).
- Lock your supply chain with audits, lockfiles, and signed commits.
References
- https://www.stackhawk.com/blog/vue-xss-guide-examples-and-prevention/
- https://medium.com/@isaacwangethi30/vue-js-security-6e246a7613da
- https://vuejs.org/guide/best-practices/security
{{#include ../../banners/hacktricks-training.md}}