概要
VueはHTML、CSS、JSのフレームワークで、きめ細かな反応性を持つウェブ・アプリケーションを開発できる。
Vue 2のテンプレートコンパイラにクロスサイトスクリプティング(XSS)の脆弱性が確認されました。フルビルドでは、ユーザーコードによって文字列テンプレートがVueコンポーネントにコンパイルされ、ブラウザ内で動的に関数がレンダリングされ、その関数が実行されます。
OWASPによるクロスサイト・スクリプティング攻撃は、インジェクションの一種であり、悪意のあるスクリプトが、他の良識ある信頼できるウェブサイトに注入されます。XSS 攻撃は、攻撃者がウェブ・アプリケーションを使って悪意のあるコードを、一般的にはブラウザ・サイドのスクリプトの形で、別のエンド・ ユーザに送信することで発生します。攻撃者は XSS を使って、疑うことを知らないユーザに悪意のあるスクリプトを送ることができます。
詳細
モジュール情報
- パッケージマネージャ: npm
- 影響を受けるパッケージ: vue-template-compiler
- Affected versions: >= 2.0.0 < 3.0.0
- 公開パッケージへのリンク: https://www.npmjs.com/package/vue-template-compiler
- Github repo: https://github.com/vuejs/vue
- 概念実証:https://stackblitz.com/edit/cve-2024-6783?file=index.html
脆弱性情報
This Medium-severity level exploit can be found in Vue versions greater than or equal to 2.0.0 and before 3.0.0. It is found inside of the in-browser Vue template compiler which is shipped inside the “full build” of Vue. The in-browser Vue template compiler is responsible for creating a string of code to be executed so that component templates like “<div>{{ variables }}</div>” can be parsed and turned into render functions. These render functions are then executed by Vue when it evaluates the render functions within a stringified eval statement, thus allowing a third-party script to run arbitrary code.
Object.prototypeを拡張した場合、特定のプロパティだけがクライアントサイドのXSS脆弱性の影響を受けます。そのようなプロパティの1つが staticClass であり、テンプレート文字列が `class` 属性を非動的なクラスで使用する場合に、AST 構築フェーズで取得されます。
テンプレート文字列全体に依存する最適化が行われており、このコードパスがトリガーされる場合とされない場合があります。この攻撃を受けやすいコンポーネントの例については、「再現手順」を参照してください。
再現の手順
Vueのブラウザ内テンプレート・コンパイラのAST Codegen経路は、最初は未設定のプロパティに依存しています。最終的に、プロパティは値を文字列化する関数によって消費され、レンダリング中に eval 文に渡されます。これらのプロパティが明示的にundefinedに設定されたり、hasOwnPropertyがチェックされたりすると、プロトタイプの汚染は不可能になる。現在、ASTElement(SSR、ブラウザ内コンパイル、Vue SFCファイルパーサでcodegenノードを作成するために使用される主要なデータ構造)のほぼすべてのプロパティはオプションであり、このXSS脆弱性の影響を受ける可能性があります。
クロスサイト・スクリプティング攻撃はインジェクションの一種で、悪意のあるスクリプトが良性で信頼できる ウェブサイトに注入されます。XSS 攻撃は、攻撃者がウェブ・アプリケーションを使用して、一般にブラウザの形で悪意あるコードを送信するときに発生します。テンプレート・コンパイラ・コードは AST を消費し、レンダリング中に最終的に呼び出されるプロパティに配置されるコンテンツを適切にサニタイズしません。次節のコード例と概念実証は網羅的なものではありません。
<head>
<script>
window.Proxy = undefined // Not necessary, but helpfull in demonstrating breaking out into `window.alert`
Object.prototype.staticClass = `alert("Polluted")`
</script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
new window.Vue({
template: `<div class="">Content</div>`,
}).$mount('#app')
</script>
</body>
プルーフ・オブ・コンセプト
プルーフ・オブ・コンセプトのウェブサイトで上記のコードを完全再現したものは、こちらでご覧いただけます: https://stackblitz.com/edit/cve-2024-6783?file=index.html
緩和
Vue 2 が End-of-Life に達しました。 影響を受けるコンポーネントのユーザーは、以下のいずれかの緩和策を適用してください:
- Vueの新しいバージョンへの移行
- 独自のパッチを適用する
- EOL後のセキュリティ・サポートには、HeroDevsのような商用サポート・パートナーを活用する。
クレジット
- ジフェン・カン・ファインダー
- ムキシ・リュウ・ファインダー
- 曹英之
弊社がサポートするオープンソースソフトウェアに新たな脆弱性が修正された場合、いつでもアラートを受け取ることができます。