Vue.js

Reading time: 7 minutes

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

Vue.jsにおけるXSSシンク

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 with src or href

ユーザーストリングをURLを持つ属性(hrefsrcxlink:hrefformaction …)にバインドすると、リンクがフォローされたときに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 with user-controlled handlers

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)にエスカレートする可能性があります。vue-template-compilerのCVEがリスクを証明しています。

js
// DANGER – never do this
const app = createSSRApp({ template: userProvidedHtml })

フィルター / レンダー関数の評価

ユーザーデータに対してevalnew Functionを呼び出すレンダーストリングを構築するレガシーフィルターは、別のXSSベクターです。これらを計算プロパティに置き換えてください。

js
Vue.filter('run', code => eval(code))   // DANGER

Vueプロジェクトにおけるその他の一般的な脆弱性

プラグインにおけるプロトタイプ汚染

一部のプラグイン(例: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 in Axios / fetch

SPAsは依然としてサーバー側のCSRFトークンが必要です; SameSiteクッキーだけでは自動送信されたクロスオリジンPOSTをブロックできません。

js
axios.post('/api/transfer', data, {
headers: { 'X-CSRF-TOKEN': token }
})

Click-jacking

Vueアプリは、X-Frame-Options: DENYContent-Security-Policy: frame-ancestors 'none' の両方を送信しない限り、フレーム内に表示可能です。

http
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none';

Content-Security-Policyの落とし穴

フル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

ハードニングチェックリスト

  1. すべての文字列をサニタイズしてからv-htmlに渡す(DOMPurify)。
  2. 許可されたスキーム、属性、コンポーネント、およびイベントをホワイトリスト化する。
  3. evalと動的テンプレートを完全に避ける
  4. 依存関係を毎週パッチし、アドバイザリーを監視する。
  5. 強力なHTTPヘッダーを送信する(CSP、HSTS、XFO、CSRF)。
  6. 監査、ロックファイル、および署名付きコミットでサプライチェーンをロックする。

参考文献

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする