CapacitorのAndroidおよびiOSランタイムに、深刻な脆弱性が見つかりました。攻撃者は悪意あるリンクを使い、影響を受けるアプリケーションの信頼されたオリジン内でリモートコンテンツを読み込ませることが可能です。その結果、アプリのデータやネイティブ機能が危険にさらされるおそれがあります。
この問題はCVE-2026-103922、GitHubアドバイザリGHSA-rvm3-566m-v7fvとして管理されています。影響を受けるのは、攻撃者が制御するリンク、または十分にサニタイズされていないリンクをWebView内に表示するCapacitorアプリケーションです。
この脆弱性のCVSS v3.1スコアは「重大(Critical)」の範囲に入り、ベクターはCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:Nです。
悪用にはユーザーの操作が必要ですが、攻撃者に認証情報は不要です。チャットメッセージ、コメント、ユーザープロフィール、リッチテキスト投稿など、CapacitorのWebView内に表示されるコンテンツを通じて、悪意あるURLを届けられます。
従来、CapacitorのWebViewナビゲーションガードは、遷移先URLのスキームとホストを確認する一方、パスは検証していませんでした。このため、Capacitorの内部HTTPプロキシエンドポイント/_capacitor_http_interceptor_に関する抜け穴が生じていました。
このパスはアプリ自身のオリジン配下で提供されるため、ここへの遷移は信頼されたアプリ内コンテンツとして扱われていました。攻撃者は、任意のリモートURLを指定したうえで、フレームを内部プロキシのパスへ遷移させるリンクを作成できます。
するとネイティブ層はリモートのレスポンスを取得し、アプリ自身のオリジンのコンテンツであるかのようにWebViewへ返します。
その結果、攻撃者が制御するサーバーから返されたJavaScriptが、本来は正規のアプリだけに許される同一オリジンの権限で実行される可能性があります。
アドバイザリは、根本的な弱点としてCWE-346(オリジン検証の不備)とCWE-441(意図しないプロキシ、いわゆる「confused deputy(混乱した代理人)」状態)を挙げています。
この問題はAndroid版とiOS版の両方のCapacitorに影響します。注目すべきは、CapacitorHttpプラグインを有効にしていなくても、内部プロキシハンドラーが利用可能だった点です。そのため、CapacitorHttpを無効にするだけでは、脆弱なアプリを守れません。
影響を受けるのは、Capacitor Android、Capacitor iOS、Mavenパッケージcom.capacitorjs:core、およびSwiftパッケージ配布版です。対象バージョンは、6.0.0~6.2.1、7.0.0~7.6.8、8.0.0~8.3.4、8.3.5~8.4.2、8.5.0です。
特に影響が大きいのは、遷移先を厳密に検証せずにユーザーがリンクを開けるハイブリッドアプリです。一見ありふれたリンクがアプリオリジンでのスクリプト実行の経路となり、アプリに組み込まれたWebViewとネイティブブリッジが攻撃対象になりかねません。
Capacitorのメンテナーは、プラットフォームレベルの2つの変更で問題に対処しました。1つ目はナビゲーションロジックの更新で、内部プロキシパスへのフレーム遷移をブロックします。2つ目はプロキシハンドラーの制限で、CapacitorHttpが有効な場合にのみ利用でき、ドキュメントリクエストやメインフレームのリクエストには決して応答しません。
各組織は、リリースブランチに応じて、Capacitor 6.2.2、7.6.9、8.3.5、8.4.3、8.5.1のいずれかにアップグレードし、AndroidおよびiOSアプリを再ビルドして再配布する必要があります。
すぐにアップグレードできない場合、開発者は小さなネイティブプラグインを追加し、パスが/_capacitor_http_interceptor_で始まるナビゲーションリクエストをキャンセルすることで対処できます。
AndroidではshouldOverrideLoad(Uri url)をオーバーライドし、iOSではshouldOverrideLoad(_:)を実装します。あわせて、アプリ内WebViewで表示する前に、ユーザーが制御できるリンク先をサニタイズし、制限することも重要です。
16,000以上のSOCチームがANY.RUNを導入し、脅威調査の効率化と手作業の削減を実現しています。チームでの導入を検討する