mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
129 lines
4.8 KiB
Markdown
129 lines
4.8 KiB
Markdown
# Vue.js
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Sinks XSS in Vue.js
|
||
|
||
### Direttiva v-html
|
||
La direttiva `v-html` rende HTML **grezzo**, quindi qualsiasi `<script>` (o un attributo come `onerror`) incorporato in input utente non sanitizzati viene eseguito immediatamente.
|
||
```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 con src o href
|
||
Collegare una stringa utente ad attributi che contengono URL (`href`, `src`, `xlink:href`, `formaction` …) consente l'esecuzione di payload come `javascript:alert(1)` quando il link viene seguito.
|
||
```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 con gestori controllati dall'utente
|
||
`v-on` compila il suo valore con `new Function`; se quel valore proviene dall'utente, gli offri l'esecuzione del codice su un piatto.
|
||
```html
|
||
<div id="app">
|
||
<button v-on:click="malicious">Click me</button>
|
||
</div>
|
||
<script>
|
||
new Vue({
|
||
el: '#app',
|
||
data: { malicious: 'alert(1)' }
|
||
})
|
||
</script>
|
||
```
|
||
### Nomi dinamici di attributi / eventi
|
||
I nomi forniti dall'utente in `v-bind:[attr]` o `v-on:[event]` consentono agli attaccanti di creare qualsiasi attributo o gestore di eventi, eludendo l'analisi statica e molte regole CSP.
|
||
```html
|
||
<img v-bind:[userAttr]="payload">
|
||
<!-- userAttr = 'onerror', payload = 'alert(1)' -->
|
||
```
|
||
### Componente dinamico (`<component :is>`)
|
||
Consentire stringhe utente in `:is` può montare componenti arbitrari o modelli inline—pericoloso nel browser e catastrofico in SSR.
|
||
```html
|
||
<component :is="userChoice"></component>
|
||
<!-- userChoice = '<script>alert(1)</script>' -->
|
||
```
|
||
### Modelli non attendibili in SSR
|
||
Durante il rendering lato server, il modello viene eseguito **sul tuo server**; l'iniezione di HTML da parte dell'utente può elevare l'XSS a una piena Esecuzione Remota di Codice (RCE). Le CVE in `vue-template-compiler` dimostrano il rischio.
|
||
```js
|
||
// DANGER – never do this
|
||
const app = createSSRApp({ template: userProvidedHtml })
|
||
```
|
||
### Filtri / funzioni di rendering che valutano
|
||
I filtri legacy che costruiscono stringhe di rendering o chiamano `eval`/`new Function` sui dati degli utenti sono un altro vettore XSS—sostituiscili con proprietà calcolate.
|
||
```js
|
||
Vue.filter('run', code => eval(code)) // DANGER
|
||
```
|
||
---
|
||
|
||
## Altre vulnerabilità comuni nei progetti Vue
|
||
|
||
### Inquinamento del prototipo nei plugin
|
||
I helper di deep-merge in alcuni plugin (ad es., **vue-i18n**) hanno permesso agli attaccanti di scrivere in `Object.prototype`.
|
||
```js
|
||
import merge from 'deepmerge'
|
||
merge({}, JSON.parse('{ "__proto__": { "polluted": true } }'))
|
||
```
|
||
### Open redirects con vue-router
|
||
Passare URL utente non controllati a `router.push` o `<router-link>` può reindirizzare a URI `javascript:` o domini di phishing.
|
||
```js
|
||
this.$router.push(this.$route.query.next) // DANGER
|
||
```
|
||
### CSRF in Axios / fetch
|
||
Le SPA hanno ancora bisogno di token CSRF lato server; i cookie SameSite da soli non possono bloccare i POST cross-origin inviati automaticamente.
|
||
```js
|
||
axios.post('/api/transfer', data, {
|
||
headers: { 'X-CSRF-TOKEN': token }
|
||
})
|
||
```
|
||
### Click-jacking
|
||
Le app Vue sono incapsulabili a meno che non invii sia `X-Frame-Options: DENY` che `Content-Security-Policy: frame-ancestors 'none'`.
|
||
```http
|
||
X-Frame-Options: DENY
|
||
Content-Security-Policy: frame-ancestors 'none';
|
||
```
|
||
### Content-Security-Policy pitfalls
|
||
La build completa di Vue necessita di `unsafe-eval`; passa alla build runtime o ai template precompilati in modo da poter eliminare quella fonte pericolosa.
|
||
```http
|
||
Content-Security-Policy: default-src 'self'; script-src 'self';
|
||
```
|
||
### Attacchi alla supply-chain (node-ipc – Marzo 2022)
|
||
Il sabotaggio di **node-ipc**—estratto da Vue CLI—ha mostrato come una dipendenza transitiva possa eseguire codice arbitrario sulle macchine di sviluppo. Blocca le versioni e controlla spesso.
|
||
```shell
|
||
npm ci --ignore-scripts # safer install
|
||
```
|
||
---
|
||
|
||
## Hardening Checklist
|
||
|
||
1. **Sanitizza** ogni stringa prima che raggiunga `v-html` (DOMPurify).
|
||
2. **Whitelist** schemi, attributi, componenti ed eventi consentiti.
|
||
3. **Evita `eval`** e template dinamici del tutto.
|
||
4. **Aggiorna le dipendenze settimanalmente** e monitora gli avvisi.
|
||
5. **Invia intestazioni HTTP forti** (CSP, HSTS, XFO, CSRF).
|
||
6. **Blocca la tua catena di fornitura** con audit, lockfile e commit firmati.
|
||
|
||
## 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}}
|