ReactがXSSを制圧した?もう一度考えてみてください。2025年のJavaScript開発者が直面する現実は、攻撃者が静かにインジェクション手法を進化させ、プロトタイプ汚染からAI生成コードまであらゆるものを悪用し、アプリケーションを守るために設計されたフレームワークさえもすり抜けているというものです。
フレームワーク別の防御策を網羅した全47ページのガイド(PDF、無料)
JavaScriptはウェブを制覇しましたが、その勝利とともに新たな戦場が生まれました。開発者がReact、Vue、Angularを採用する一方で、攻撃者はAIプロンプトインジェクション、サプライチェーンの侵害、プロトタイプ汚染など、従来のセキュリティ対策では検知できない手法を駆使して進化しています。
警鐘:Polyfill.io攻撃#
2024年6月、1件のJavaScriptインジェクション攻撃により、10万以上のウェブサイトが今年最大規模の被害を受けました。Polyfill.ioサプライチェーン攻撃では、中国企業が信頼されていたJavaScriptライブラリを買収し、悪意のあるコードを注入する武器として利用。Hulu、Mercedes-Benz、WarnerBrosなどの大手プラットフォームも被害を受けました。これは脆弱なフォームや古いシステムを狙った孤立した事件ではありません。ウェブサイト自身のセキュリティツールを逆手に取る高度なインジェクションであり、従来のJavaScript防御策が危険なほど時代遅れになっていることを証明しました。
脅威の状況は変化した#
もはや、単純なinnerHTMLのサニタイズだけでアプリを守れる時代ではありません。現在の攻撃者は以下を活用しています:
- サプライチェーンの侵害:お気に入りのnpmパッケージが標的に
- プロトタイプ汚染攻撃:オブジェクトモデル全体を乗っ取る可能性
- AI駆動のプロンプトインジェクション:LLMを騙して悪意あるコードを生成させる
- シングルページアプリケーションでのDOMベースXSS:サーバー側の防御を回避
数字が物語っています。2024年半ばまでに22,254件のCVEが報告され、2023年から30%増加、2022年比では56%増加。ウェブサイトの98%がクライアントサイドでJavaScriptを使用し、67.9%の開発者が主言語として頼っている今、攻撃対象面はかつてないほど広がっています。
何がこれまでと違うのか#
多くのセキュリティガイドは今でも10年以上前の攻撃パターンに焦点を当てています。本分析では、インパクト重視の多層防御アプローチで現代の脅威を分解しています:
実際のコード例や優先順位付きロードマップは、完全ガイドをご覧ください
フレームワーク現実チェック#
最新のフレームワークでさえ万能ではありません:
このReactコードは安全そうに見えますが、実は違います –
// 🚨 脆弱:未サニタイズの入力
適切なサニタイズによるより良いアプローチ –
// ✅ 安全:DOMPurifyを使ったReactコンポーネント
なぜ重要なのか:
dangerouslySetInnerHTMLは、Reactの組み込みXSS防御をバイパスしてHTMLを直接DOMに注入します。ユーザーコンテンツに悪意あるスクリプトが含まれていると、被害者のブラウザで即座に実行され、以下のような被害が発生する可能性があります:
- 認証クッキーやセッショントークンの窃取
- ユーザーになりすました操作の実行
- 悪意あるサイトへのリダイレクト
- 機密情報のキーロギング
DOMPurifyはHTMLをパースし、危険な要素を除去しつつ、<b>、<i>、<p>などの安全なフォーマットタグは保持してサニタイズします。
包囲される銀行業界#
金融業界は高度なJavaScriptインジェクション攻撃の主要標的となっています。2023年3月、IBMはマルウェアキャンペーンを発見。アメリカ、ヨーロッパ、日本の40以上の銀行が標的となり、5万件以上の個別ユーザーセッションが侵害されました。この攻撃は銀行プラットフォーム特有のページ構造を検出し、動的に悪意あるスクリプトを注入してユーザー認証情報やワンタイムパスワードトークンを盗みました。
このキャンペーンが特に危険だったのは、その適応的な挙動です。マルウェアは常にコマンド&コントロールサーバーと通信し、ページの状態やセキュリティ検知の試みに応じてリアルタイムで戦術を調整。高度な難読化技術を使い、セキュリティ製品が検知された場合は実行を回避し、自身の痕跡を消すために関数をパッチするなど、従来のJavaScript防御策では太刀打ちできない、動的かつ進化する脅威であることを証明しました。
「生データ保存・出力時エンコード」原則#
本ガイドの最も実践的な洞察の一つは、基本的なセキュリティベストプラクティスを強調しています:常に生データを保存し、出力コンテキストに応じてエンコードすること。
このアプローチの流れ:
- データベースには生(エンコード前)のデータを保存する
- データの表示場所に応じて、レンダリング時にコンテキスト固有のエンコードを適用する
- 出力コンテキストごとに異なるエンコード手法を使う(HTMLコンテンツにはHTMLエンティティ、JavaScriptにはJSエスケープ、URLにはURLエンコード、スタイルシートにはCSSエスケープ)
このコンテキスト認識型エンコードにより、二重エンコード問題を防ぎ、データの整合性を保ち、最終的な表示方法に関わらず適切な保護を実現します。TypeScriptで堅牢なドメインモデルを構築する開発者なら、この重要性を理解できるでしょう。同じユーザー入力でも、divで表示する場合はHTMLエンコード、scriptタグで使う場合はJavaScriptエスケープ、リンクパラメータで使う場合はURLエンコードが必要になることがあります。
WebAssemblyのセキュリティ考慮事項#
WebAssemblyはパフォーマンスとサンドボックス化の利点を提供しますが、そのセキュリティ上の意味を理解することが重要です。本ガイドでは、Wasmがもたらす特有の考慮点を解説しています:
- ソースコードの脆弱性が引き継がれる:C/C++などメモリ安全でない言語をWasmにコンパイルすると、元の脆弱性(バッファオーバーフロー、use-after-freeなど)がそのまま残る
- 透明性の低下:バイナリ形式のため、可読性の高いJavaScriptソースと比べてセキュリティ監査が難しい
- 新たな攻撃面:タイミング分析によるサイドチャネル攻撃やVMエスケープの可能性(現状ではほぼ理論的)
WebAssemblyのサンドボックス実行モデルは強力な隔離を提供しますが、どんな技術も同様、慎重な実装が必要であり、JavaScriptからの自動的なセキュリティ向上とは見なせません。
新たなAI脅威#
LLM(大規模言語モデル)がウェブアプリに統合されるにつれ、新たな攻撃ベクトルが登場しました:プロンプトインジェクション攻撃です。悪意あるユーザーがAIモデルを騙してクライアントサイドで実行されるJavaScriptコードを生成させる、まったく新しいタイプのインジェクション脆弱性です。詳細は完全ガイドでご覧いただけます。
まとめ#
現代のJavaScriptセキュリティは、チェックリストを実装することではなく、攻撃者の思考を理解し、進化する脅威に適応する多層防御を構築することです。React、Angular、Vueのいずれを使っていても、根本原則は変わりません:クライアントサイドのコードを決して信用せず、必ずサーバー側で検証し、コンテキストに応じてエンコードすることです。
完全ガイドでは、主要フレームワークすべての実装例、実践的なコードサンプル、最も重要な脆弱性から優先的に対処できるアプローチを提供しています。
翻訳元: https://thehackernews.com/2025/07/why-react-didnt-kill-xss-new-javascript.html