mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
129 lines
6.7 KiB
Markdown
129 lines
6.7 KiB
Markdown
# Vue.js
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## XSS Sinks in Vue.js
|
||
|
||
### v-html Директива
|
||
Директива `v-html` рендерить **сирий** HTML, тому будь-який `<script>` (або атрибут, як `onerror`), вбудований в неочищений ввід користувача, виконується негайно.
|
||
```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 з src або href
|
||
Прив'язка рядка користувача до атрибутів, що містять URL (`href`, `src`, `xlink:href`, `formaction` …), дозволяє виконувати такі payloads, як `javascript:alert(1)`, коли посилання відкривається.
|
||
```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 з обробниками, контрольованими користувачем
|
||
`v-on` компілює своє значення з `new Function`; якщо це значення походить від користувача, ви надаєте їм виконання коду на блюді.
|
||
```html
|
||
<div id="app">
|
||
<button v-on:click="malicious">Click me</button>
|
||
</div>
|
||
<script>
|
||
new Vue({
|
||
el: '#app',
|
||
data: { malicious: 'alert(1)' }
|
||
})
|
||
</script>
|
||
```
|
||
### Динамічні імена атрибутів / подій
|
||
Імена, надані користувачем, в `v-bind:[attr]` або `v-on:[event]` дозволяють зловмисникам створювати будь-який атрибут або обробник подій, обходячи статичний аналіз і багато правил CSP.
|
||
```html
|
||
<img v-bind:[userAttr]="payload">
|
||
<!-- userAttr = 'onerror', payload = 'alert(1)' -->
|
||
```
|
||
### Динамічний компонент (`<component :is>`)
|
||
Дозволення рядків користувача в `:is` може монтувати довільні компоненти або вбудовані шаблони — небезпечно в браузері та катастрофічно в SSR.
|
||
```html
|
||
<component :is="userChoice"></component>
|
||
<!-- userChoice = '<script>alert(1)</script>' -->
|
||
```
|
||
### Ненадійні шаблони в SSR
|
||
Під час рендерингу на стороні сервера шаблон виконується **на вашому сервері**; ін'єкція HTML користувача може підвищити XSS до повного віддаленого виконання коду (RCE). CVE у `vue-template-compiler` підтверджують ризик.
|
||
```js
|
||
// DANGER – never do this
|
||
const app = createSSRApp({ template: userProvidedHtml })
|
||
```
|
||
### Фільтри / функції рендерингу, які використовують eval
|
||
Спадкові фільтри, які створюють рядки рендерингу або викликають `eval`/`new Function` на даних користувача, є ще одним вектором XSS — замініть їх на обчислювальні властивості.
|
||
```js
|
||
Vue.filter('run', code => eval(code)) // DANGER
|
||
```
|
||
---
|
||
|
||
## Інші загальні вразливості в проектах Vue
|
||
|
||
### Забруднення прототипу в плагінах
|
||
Deep-merge допоміжні засоби в деяких плагінах (наприклад, **vue-i18n**) дозволили зловмисникам записувати в `Object.prototype`.
|
||
```js
|
||
import merge from 'deepmerge'
|
||
merge({}, JSON.parse('{ "__proto__": { "polluted": true } }'))
|
||
```
|
||
### Відкриті редиректи з vue-router
|
||
Передача неперевірених URL-адрес користувачів до `router.push` або `<router-link>` може перенаправити на `javascript:` URI або фішингові домени.
|
||
```js
|
||
this.$router.push(this.$route.query.next) // DANGER
|
||
```
|
||
### CSRF в Axios / fetch
|
||
SPAs все ще потребують токенів CSRF на стороні сервера; лише куки з атрибутом SameSite не можуть заблокувати автоматично надіслані крос-доменні POST-запити.
|
||
```js
|
||
axios.post('/api/transfer', data, {
|
||
headers: { 'X-CSRF-TOKEN': token }
|
||
})
|
||
```
|
||
### Click-jacking
|
||
Додатки Vue можна вбудовувати, якщо ви не надішлете обидва `X-Frame-Options: DENY` та `Content-Security-Policy: frame-ancestors 'none'`.
|
||
```http
|
||
X-Frame-Options: DENY
|
||
Content-Security-Policy: frame-ancestors 'none';
|
||
```
|
||
### Content-Security-Policy pitfalls
|
||
Повна збірка Vue потребує `unsafe-eval`; перейдіть на збірку часу виконання або попередньо скомпільовані шаблони, щоб ви могли відмовитися від цього небезпечного джерела.
|
||
```http
|
||
Content-Security-Policy: default-src 'self'; script-src 'self';
|
||
```
|
||
### Supply-chain attacks (node-ipc – March 2022)
|
||
Саботаж **node-ipc**, який був витягнутий Vue CLI, показав, як транзитивна залежність може виконувати довільний код на розробницьких машинах. Закріплюйте версії та часто проводьте аудит.
|
||
```shell
|
||
npm ci --ignore-scripts # safer install
|
||
```
|
||
---
|
||
|
||
## Hardening Checklist
|
||
|
||
1. **Санітизуйте** кожен рядок перед тим, як він потрапить у `v-html` (DOMPurify).
|
||
2. **Дозвольте** лише дозволені схеми, атрибути, компоненти та події.
|
||
3. **Уникайте `eval`** та динамічних шаблонів взагалі.
|
||
4. **Оновлюйте залежності щотижня** та слідкуйте за рекомендаціями.
|
||
5. **Відправляйте сильні HTTP заголовки** (CSP, HSTS, XFO, CSRF).
|
||
6. **Забезпечте свою ланцюг постачання** за допомогою аудитів, lockfiles та підписаних комітів.
|
||
|
||
## 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}}
|