Precheck:モバイルスキャンが機能するかを、数時間の実行前に確認する
Precheckは、モバイルアプリが実機上でインストール、起動、ログインでき、UIプロンプトを実行できることを検証します。認証情報の拒否、クラッシュ、インストールできないビルドといった阻害要因によってカバレッジが得られない場合、スキャンはエラーとしてマークされ、その理由と問題を示す画面が提示されます。
何も検出しなかったモバイルスキャンは、本来アプリが安全であることを意味するはずです。しかし実際には、アプリがログイン画面から先に進めなかっただけ、ということが少なくありません。
Precheckは、Ostorlabのモバイルスキャンに新たに加わったステップです。すべてのモバイル動的スキャンで実行され、実機にアプリをインストールして起動し、提供された認証情報でログインし、UIプロンプトを実行します。インストールできないビルド、クラッシュやフリーズするアプリ、拒否される認証情報といった阻害要因があれば、スキャンはエラーとしてマークされ、その理由と根拠となる画面が提示されます。
スキャン自体はバックグラウンドで継続するため、静的解析の結果と、部分的にしか動作しないアプリで可能な範囲の動的カバレッジが得られます。
Precheckの役割(TL;DR)
Precheckは、アプリを実際にテストできることを確認します。阻害要因によってテストできない場合、Precheckはスキャンをエラーとしてマークし、UIコールグラフへのLearn moreリンクを追加します。UIコールグラフでは、各画面がステータスごとに色分けされています。静的解析と到達可能な範囲の動的カバレッジは、そのまま最後まで実行されます。
空のレポートが最悪のレポートである理由
完全なモバイルスキャンでは、静的解析、動的解析、コールトレース、トラフィックの傍受といった複数の解析が並行して実行されます。これらを合わせると数時間かかることもあります。動的カバレッジは一つの条件に依存します。アプリが端末上で実際に動作し、操作できることです。
この条件が満たされなくても、スキャンは「完了」します。
- ビルドが端末の対応していないアーキテクチャを対象としており、インストールされない
- アプリがスプラッシュ画面でクラッシュする、またはフリーズする
- ステージング環境のパスワードが先週失効しており、認証が必要な画面にはどれも到達できない
- 2FAのステップが設定されておらず、アプリがコードを待ち続ける
- ステージング環境のバックエンドが停止しており、アプリが「Unable to connect」と表示したまま何もしない
いずれの場合も、動的解析は可能な範囲を探索するだけで、ほとんど何も報告しません。壊れた実行から得られた静かなレポートは、安全なアプリから得られた静かなレポートと見分けがつきません。それに気付くのは数時間後か、あるいはまったく気付かないままです。
CI/CDパイプラインにおいては、誤った理由で成功するパイプラインは、失敗するパイプラインよりも悪い結果をもたらします。
Precheckは、この曖昧さを取り除くために作られました。
Precheckが確認する内容
Precheckは二つのチェックを順に実行します。アプリをインストールできない場合、UIチェックはスキップされます。
1. ビルドはデバイスにインストールできるか?
Precheckは実機を確保し、クリーンな状態にリセットしてからビルドをインストールします。「インストーラーがOKを返した」ことで終わりにはせず、アプリが実際に端末上に存在することまで確認します。
- Android(APK、AAB、XAPK):パッケージが端末のインストール済みパッケージ一覧に表示される必要があります。Precheckはバイナリからアプリの起動アクティビティも読み取ります。XAPKバンドルの場合は、ベースAPKが見つかるまですべての分割APKを探索します。
- iOS(IPA):バンドルが端末のインストール済みアプリケーションに表示される必要があります。Precheckはバンドルの
Info.plistを読み取り、バンドル識別子、最小iOSバージョン、必要なデバイス機能を端末と照合します。
インストールできないビルドはエラーとして報告されます。これがなければ動的解析は機能しませんが、静的解析は引き続き実行されます。
2. アプリは起動し、ログインし、プロンプトに従えるか?
続いてPrecheckは、モバイルUIを操作するOstorlabのAIエージェントであるMonkey Testerにアプリを引き渡します。渡す情報は次のとおりです。
- 使用する端末
- 設定済みの認証情報(ログインIDとパスワード、カスタムのキー/値フィールド、およびSMS、メール、TOTP、手動による2FA)
- UIプロンプト:スキャンに与える自然言語の指示(例:「利用規約に同意し、オンボーディングをスキップし、送金ページを開く」)
Monkey Testerはアプリを起動してログインし、各プロンプトを順に処理します。単にスクリーンショットを撮るだけではありません。到達したすべての画面を判定します。
すべての画面に判定が下される
Monkey Testerは、スクリーンショットごとに四つの情報を返します。
| フィールド | 意味 |
|---|---|
prompt |
スクリーンショット撮影時に処理していたプロンプト(該当する場合) |
status |
ONGOING、SUCCESS、ERROR、CRITICALのいずれか |
reason |
そのステータスの根拠となった画面上の要素 |
remediation |
ERRORとCRITICALの場合に取るべき対処 |
- ONGOING:ステップが進行中で、まだ問題は発生していない
- SUCCESS:プロンプトが完了し、その結果が画面上に表示されている
- ERROR:プロンプトが失敗した(例:ボタンが無効になっている、送金が完了しなかった)が、アプリ自体は動作している
- CRITICAL:実際の阻害要因。提供された認証情報が拒否された、またはアプリがクラッシュを繰り返す、もしくはフリーズしている
各画面にはステータスが付けられるため、何が機能していて何が機能していないかが一目でわかります。また、どのステータスにもその具体的な理由と修正方法が添えられています。
Duolingoのスキャンでの例を見てみます。UIプロンプトでは、Monkey Testerにフランス語コース、続いてジョージア語コースを開始するよう指示しました。
SUCCESS:ログイン。Monkey Testerがホーム画面に到達しており、認証情報が有効であることが実証されています。

SUCCESS:プロンプトの完了。フランス語コースの設定画面が開いているため、プロンプトは完了としてマークされます。

ERROR:完了できないプロンプト。Duolingoにはジョージア語コースがないため、プロンプトは失敗します。アプリ自体は動作しているので、これは阻害要因ではなくERRORです。

CRITICAL:認証情報の拒否。アプリに「Wrong username or password」と表示されており、ログインの先にある画面は一切テストできません。

reasonには、エラーメッセージ、拒否されたパスワード、不足している権限など、利用者側で何が問題だったのかが記述されます。実際の例は、修正方法そのもので締めくくられています。
提供された認証情報を入力した後、「Wrong username or password」という明示的なメッセージが表示され、認証に失敗しました。修復:テストアカウント用の有効なDuolingoの認証情報を提供してください。
Precheckが失敗したときの表示
スキャンがエラーとしてマークされると、スキャンページにその理由が表示されます。Learn moreボタンを押すと、失敗した画面の位置でUIコールグラフが開きます。UIコールグラフとは、Monkey Testerが到達したすべての画面とその間の遷移を示すマップで、各画面はPrecheckのステータスごとに色分けされています。
内部の仕組み:Precheckの構築方法
Precheckは独立した軽量なステップとして実行されます。Monkey Testerが各画面を判定し、スキャンをエラーとしてマークするかどうかの最終判断はPrecheckが下します。
各解析の負担を増やすのではなく、専用のステップとして実装
わかりやすい近道は、各動的解析にヘルスチェックを追加することでした。しかし当社は、二つの理由からその方法を採りませんでした。
- 最初の回答までの速さ:本格的な動的テストには、トラフィック傍受の設定など、端末の完全な準備が必要です。「このアプリは起動するか」という問いに答えるにはそのどれも不要なので、Precheckはそれらを省略します。テスト対象はアプリだけです。
- 判断を一か所に集約:各解析がそれぞれ独自に失敗を検出すると、判定が食い違います。専用のステップにすることで、明確な答えが一つに定まります。
そのためPrecheckは、スキャンの他の処理と並行して、独立した軽量なステップとして実行されます。
モデルが判定し、コードが決定する
Monkey Testerのモデルは、もともと次にどこをタップするかを判断していました。当社はこれを拡張し、各ステップについて、処理中のプロンプト、ステータス、理由、修復方法も返すようにしました。
モデルには次のように指示しています。
CRITICALは明示的な阻害要因に限って使用する- ログイン失敗は、認証情報が実際に提供された場合にのみ報告する
- 各理由は修正方法として記述する(例:「2FA required」ではなく「SMS 2FAの番号を設定する」)
モデルは画面ごとに判定を下します。スキャンをエラーとしてマークする決定は、それらすべての判定を総合してPrecheckが行います。そのため、一つの画面を誤って読み取ったとしても、明らかに進行しているスキャンにフラグが立つことはありません。
エビデンスが先、判定は後
Monkey Testerが訪れたすべての画面は、Precheckが決定を下す前に、スクリーンショット、ステータス、理由、関連するUIプロンプトとともに保存されます。そのため、スキャンがエラーとしてマークされた時点でエビデンスはすでに揃っており、「Learn more」リンクは常に完全なコールグラフを開きます。
これらの判定はOstorlabのAPIとMCPツールからも利用できるため、Ostorlabに接続されたAIコーディングアシスタントがPrecheckの失敗理由を説明できます。
Precheckを最大限に活用するには
Precheckのエラーの多くはスキャンの設定に起因するため、特に重要なのは認証情報、目標として記述したUIプロンプト、2FAの設定の三つです。
- ログインのあるアプリでは認証情報を提供してください。これにより、スキャンの残りの処理が認証情報に依存する前に、Precheckがその有効性を確認できます。
- UIプロンプトは目標として記述してください。座標や正確なタップ手順ではなく、「アカウント設定ページを開く」のように書きます。Precheckは、目標が画面上に表示された時点でプロンプトを成功とマークします。
- ログイン時に必要であれば、2FAを設定してください(TOTPシークレット、SMS、またはメールの受信箱)。応答のない2FA画面は阻害要因として扱われます。
- CI/CDでは、Precheckのエラーをパイプラインステップの失敗として扱ってください。エラーメッセージに、パイプラインを再実行する前に修正すべき点が示されています。
信頼に値するのは、実際に実行されたスキャンだけ
セキュリティスキャンの検出結果に価値があるのは、スキャンが実際に実行された場合だけです。Precheckは、実機、アプリの実際の画面、そして自社の認証情報とプロンプトを使って、スキャンを実行できることを検証します。実行できない場合は、数時間後に静かなレポートを受け取る代わりに、スキャンがエラーとしてマークされ、理由、修正案、問題を示す画面が提示されます。
その間もスキャンは継続し、得られるすべての結果を提供します。
Precheckは、AndroidとiOSを対象とするすべてのOstorlabモバイル動的スキャンで実行されます。利用するには、ビルド、テスト用の認証情報、UIプロンプトを指定してモバイルスキャンを開始するだけで、Precheckが自動的に実行されます。セットアップについてはモバイルスキャンの前提条件を参照してください。