Android のプラットフォーム API
アプリパーミッションのテスト
概要
Android はインストールされたすべてのアプリに異なるシステム識別子 (Linux ユーザー ID とグループ ID) を割り当てます。各 Android アプリはプロセスサンドボックス内で動作するため、アプリはサンドボックス外のリソースやデータへのアクセスを明示的に要求する必要があります。特定のシステムデータや機能を使用するために必要なパーミッションを宣言することにより、このアクセスを要求します。データや機能の機密性や重要性に応じて、Android システムは自動的にパーミッションを与えたり、ユーザーに要求を承認するよう求めます。
Android のパーミッションは提供する保護レベルに基づいて四つの異なるカテゴリに分類されます。
Normal: このパーミッションは、他のアプリ、ユーザー、システムへのリスクを最小限に抑えながら、アプリが独立したアプリケーションレベルの機能にアクセスできるようにします。これはアプリのインストール時に付与されます。保護レベルが指定されていない場合、normal がデフォルト値です。例:
android.permission.INTERNET
Dangerous: このパーミッションはアプリにユーザーデータの制御やデバイスの制御を与え、ユーザーに影響を与えます。このタイプのパーミッションはインストール時には付与されないかもしれません。アプリにパーミッションを与えるかどうかをユーザーに委ねます。例:
android.permission.RECORD_AUDIO
Signature: このパーミッションは、要求しているアプリがパーミッションを宣言したアプリと同じ証明書で署名されている場合にのみ付与されます。署名が一致する場合、パーミッションは自動的に付与されます。例:
android.permission.ACCESS_MOCK_LOCATION
SystemOrSignature: このパーミッションはシステムイメージに組み込まれたアプリケーション、もしくはそのパーミッションを宣言したアプリケーションと同じ証明書を使用して署名されたアプリケーションにのみ付与されます。例:
android.permission.ACCESS_DOWNLOAD_MANAGER
すべての Android パーミッションの完全なリストは、開発者ドキュメント [1] にあります。
カスタムパーミッション
Android ではアプリのサービスやコンポーネントを他のアプリに公開できます。公開されているコンポーネントにアクセスできるアプリを制限するには、カスタムパーミッションが必要です。カスタムパーミッションは AndroidManifest.xml
で定義でき、二つの必須の属性を持つ permission タグを作成します。
android:name
android:protectionLevel
最小限の権限の原則 に準拠したカスタムパーミッションを作成することは重要です。パーミッションはその目的のために意味のある正確なラベルと説明で明示的に定義する必要があります。
以下は TEST_ACTIVITY
アクティビティを起動する際に必要となる START_MAIN_ACTIVITY
というカスタムパーミッションの例です。
最初のコードブロックは自明である新しいパーミッションを定義しています。label タグはパーミッションの要約であり、description は要約より詳細な説明です。protection level は付与しているパーミッションの種類に基づいて設定できます。 パーミッションを定義したら、アプリケーションのマニフェストでそれを指定することにより、コンポーネントに適用できます。この例では、二つ目のブロックが作成したパーミッションで制限するコンポーネントです。これは android:permission
属性を加えることで適用できます。
新しいパーミッション START_MAIN_ACTIVTY
が作成されたので、アプリは AndroidManifest.xml
ファイルで uses-permission
タグを使用して、それを要求できます。カスタムパーミッション START_MAIN_ACTIVITY
を付与された場合、任意のアプリケーションが TEST_ACTIVITY
を起動できます。Any application can now launch the TEST_ACTIVITY
if it is granted with the custom permission START_MAIN_ACTIVITY
.
静的解析
Android パーミッション
パーミッションがアプリ内で本当に必要かどうかチェックする必要があります。例えば、アクティビティがウェブページを WebView にロードするには、Android マニフェストファイルに INTERNET
パーミッションが必要です。
すべてのパーミッションセットのインテントを識別し、必要のないものを削除するには、開発者と共にパーミッションを調べることを常にお勧めします。
また、Android Asset Packaging ツールを使用して、パーミッションを調べることもできます。
カスタムパーミッション
アプリケーションマニフェストファイルを使用してカスタムパーミッションを適用するのではなく、プログラムで適用することもできます。これはパーミッションのリークを引き起こし、認証されない操作を実行する可能性があるため、お勧めしません。これは定義されたすべてのカスタムパーミッションが Android マニフェストファイルに適用されているかどうかを調べることにより検証できます。
動的解析
デバイスにインストールされているアプリケーションのパーミッションは Android セキュリティ評価フレームワーク Drozer を使用して取得できます。以下の抜粋はアプリケーションで使用されるパーミッションに加えてアプリで呈されたカスタムパーミッションを調べる方法を示しています。
Android アプリケーションが IPC コンポーネントを他のアプリケーションに公開する場合、特定のアプリケーションに対するコンポーネントにアクセスを制限するパーミッションを定義できます。normal
または dangerous
パーミッションで保護されたコンポーネントと通信するために、Drozer は必要なパーミッションを含むように再ビルドできます。
この手法は signature
レベルのパーミッションには使用できないことに注意します。Drozer をターゲットアプリケーションと同じ証明書で署名する必要があるためです。
改善方法
Android マニフェストファイルではアプリ内で必要となるパーミッションのみを要求し、他のパーミッションはすべて削除すべきです。
開発者は signature
保護レベルの機密性の高い IPC コンポーネントをセキュアにするよう注意する必要があります。同じ証明書で署名されたアプリケーションのみコンポーネントにアクセスできるようにします。
参考情報
OWASP Mobile Top 10 2016
M1 - 不適切なプラットフォームの利用 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M1-Improper_Platform_Usage
OWASP MASVS
V6.1: "アプリは必要となる最低限の権限のみを要求している。"
CWE
CWE-250 - Execution with Unnecessary Privileges
その他
[1] Android Permissions - https://developer.android.com/guide/topics/permissions/requesting.html
[2] Custom Permissions - https://developer.android.com/guide/topics/permissions/defining.html
[3] An In-Depth Introduction to the Android Permission Model - https://www.owasp.org/images/c/ca/ASDC12-An_InDepth_Introduction_to_the_Android_Permissions_Modeland_How_to_Secure_MultiComponent_Applications.pdf
[4] Android Permissions - https://developer.android.com/reference/android/Manifest.permission.html#ACCESS_LOCATION_EXTRA_COMMANDS
ツール
AAPT - http://elinux.org/Android_aapt
Drozer - https://github.com/mwrlabs/drozer
入力の妥当性確認とサニタイズのテスト
概要
-- TODO [Provide a general description of the issue.] --
静的解析
-- TODO [Describe how to assess this given either the source code or installer package (APK/IPA/etc.), but without running the app. Tailor this to the general situation (e.g., in some situations, having the decompiled classes is just as good as having the original source, in others it might make a bigger difference). If required, include a subsection about how to test with or without the original sources.] --
-- TODO [Clarify the purpose of "[Use the <sup> tag to reference external sources, e.g. Meyer's recipe for tomato soup[1].]" ] --
-- TODO [Develop content for "Testing Input Validation and Sanitization" with source code] --
動的解析
-- TODO [Describe how to test for this issue by running and interacting with the app. This can include everything from simply monitoring network traffic or aspects of the app’s behavior to code injection, debugging, instrumentation, etc.] --
改善方法
-- TODO [Describe the best practices that developers should follow to prevent this issue.] --
参考情報
OWASP Mobile Top 10 2016
M7 - 脆弱なコード品質 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M7-Poor_Code_Quality
OWASP MASVS
V6.2: "外部ソースおよびユーザーからの入力がすべて検証されており、必要に応じてサニタイズされている。これにはUI、インテントやカスタムURLなどのIPCメカニズム、ネットワークソースを介して受信したデータを含んでいる。"
CWE
CWE-20 - Improper Input Validation
その他
[1] xyz
ツール
Enjarify - https://github.com/google/enjarify
カスタム URL スキームのテスト
概要
Android と iOS の両者はカスタム URL スキームを使用してアプリ間通信が可能です。これらのカスタム URL により、他のアプリケーションはカスタム URL スキームをホストするアプリケーション内で特定のアクションを実行できます。https://
で始まる標準のウェブ URL と同様に、カスタム URI は任意のスキーム接頭辞で始まり、一般的にアプリケーション内で実行するアクションとそのアクションのパラメータを定義します。
事例として、sms://compose/to=your.boss@company.com&message=I%20QUIT!&sendImmediately=true
を考えます。このようなものをリンクとしてウェブページに埋め込み、モバイルデバイス上で被害者がクリックした場合、悪意を持って作成されたパラメータでカスタム URI を呼び出し、攻撃者が定義したコンテンツを持つ脆弱な SMS アプリケーションにより SMS が送信される可能性があります。
どのアプリケーションでも、これらのカスタム URL スキームのそれぞれを列挙する必要があり、それらが実行するアクションをテストする必要があります。
静的解析
カスタム URL スキームが定義されているかどうかを調査する必要があります。これは AndroidManifest ファイル内の intent-filter 要素でできます [1] 。
上記の例では myapp://
という新しい URL を指定しています。
動的解析
ウェブブラウザで呼び出すことができるアプリケーション内の URL スキームを列挙するには、Drozer モジュール scanner.activity.browsable
を使用する必要があります。
カスタム URL スキームは Drozer モジュール app.activity.start
を使用して呼び出すことができます。
-- TODO [Describe how to test for this issue by running and interacting with the app. This can include everything from simply monitoring network traffic or aspects of the app’s behavior to code injection, debugging, instrumentation, etc.] --
改善方法
-- TODO [Describe the best practices that developers should follow to prevent this issue.] --
参考情報
OWASP Mobile Top 10 2016
M1 - 不適切なプラットフォームの利用 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M1-Improper_Platform_Usage
OWASP MASVS
V6.3: "アプリはメカニズムが適切に保護されていない限り、カスタムURLスキームを介して機密な機能をエクスポートしていない。"
CWE
N/A
その他
[1] Custom URL scheme - https://developer.android.com/guide/components/intents-filters.html#DataTest
ツール
Drozer - https://github.com/mwrlabs/drozer
IPC による機密性の高い機能の開示のテスト
概要
-- TODO [Provide a general description of the issue.] --
静的解析
-- TODO [Describe how to assess this given either the source code or installer package (APK/IPA/etc.), but without running the app. Tailor this to the general situation (e.g., in some situations, having the decompiled classes is just as good as having the original source, in others it might make a bigger difference). If required, include a subsection about how to test with or without the original sources.] --
-- TODO [Clarify purpose of "Use the <sup> tag to reference external sources, e.g. Meyer's recipe for tomato soup[1]."] --
-- TODO [Add content for "Testing For Sensitive Functionality Exposure Through IPC" with source code] --
動的解析
IPC コンポーネントは Drozer を使用して列挙できます。エクスポートされたすべての IPC コンポーネントを一覧表示するには、モジュール app.package.attacksurface
を使用する必要があります。
アクティビティ
アプリケーションによりエクスポートされたアクティビティを一覧表示するには、モジュール app.activity.info
を使用する必要があります。-a
でターゲットパッケージを指定するか、ブランクのままにしてデバイス上のすべてのアプリケーションを対象にします。
脆弱なパスワードマネージャ "Sieve" [1] のアクティビティを列挙することにより、アクティビティ com.mwr.example.sieve.PWList
は必要なパーミッションなしでエクスポートされていることがわかります。このアクティビティを起動するには、モジュール app.activity.start
を使用できます。
アクティビティが直接呼び出されたため、パスワードマネージャを保護するログインフォームはバイパスされ、パスワードマネージャに含まれるデータにアクセスすることができます。
サービス
サービスは Drozer モジュール app.service.info
を使用して列挙できます。
サービスと通信するには、静的解析を最初に使用して必要な入力を特定する必要があります。ターゲットアプリケーションをリバースすることで、サービス AuthService
がターゲットアプリを保護するパスワードと PIN を変更する機能を提供することが分かります。
このサービスはエクスポートされるため、モジュール app.service.send
を使用してサービスと通信し、ターゲットアプリケーションに格納されているパスワードを変更することが可能です。
ブロードキャスト
ブロードキャストは Drozer モジュール app.broadcast.info
を使用して列挙できます。ターゲットパッケージは -a
パラメータを使用して指定する必要があります。
例題アプリ "Android Insecure Bank" 2 では、ひとつのブロードキャストレシーバがエクスポートされており、パーミッションを必要とせず、ブロードキャストレシーバをトリガするインテントを記述できることを示しています。ブロードキャストレシーバをテストする際、静的解析を使用してブロードキャストレシーバの機能を理解する必要もあります。
以下の抜粋は、ターゲットアプリケーションのソースコードから取得したもので、ブロードキャストレシーバが SMS メッセージをトリガし、復号されたユーザーのパスワードを含むものを送信することが分かります。
Drozer モジュール app.broadcast.send
を使用して、ブロードキャストをトリガするインテントを記述し、コントロール内の電話番号にパスワードを送信できます。
これにより以下の SMS が生成されます。
インテントの傍受
Android アプリケーションが必要なパーミッションの設定をせずに、または受け側のパッケージを指定せずにインテントをブロードキャストする場合、そのインテントはデバイス上の任意のアプリケーションにより傍受される可能性があります。
ブロードキャストレシーバを登録してインテントを傍受するには、Drozer モジュール app.broadcast.sniff
を使用する必要があります。--action
パラメータで傍受するアクションを指定します。
改善方法
-- TODO [Describe the best practices that developers should follow to prevent this issue.] --
参考情報
OWASP Mobile Top 10 2016
M1 - 不適切なプラットフォームの利用 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M1-Improper_Platform_Usage
OWASP MASVS
V6.4: "アプリはメカニズムが適切に保護されていない限り、IPC機構を通じて機密な機能をエクスポートしていない。"
CWE
-- TODO [Add links and titles for CWE related to the "Testing For Sensitive Functionality Exposure Through IPC" topic] --
その他
[1] Sieve: Vulnerable Password Manager - https://github.com/mwrlabs/drozer/releases/download/2.3.4/sieve.apk
[2] Android Insecure Bank V2 - https://github.com/dineshshetty/Android-InsecureBankv2
ツール
Drozer - https://github.com/mwrlabs/drozer
WebView での JavaScript 実行のテスト
概要
ウェブアプリケーションでは、さまざまな方法で JavaScript を注入できます。反射型、格納型(蓄積型)、DOM ベースのクロスサイトスクリプティング (XSS) を利用します。モバイルアプリはサンドボックス環境で実行され、ネイティブに実装された場合この攻撃経路は存在しません。ですが、WebView はネイティブアプリの一部として、ウェブページを表示できます。すべてのアプリには WebView 用の個別のキャッシュがあり、ネイティブブラウザや他のアプリとは共有しません。Android の WebView は WebKit レンダリングエンジンを使用してウェブページを表示していますが、アドレスバーが利用できないなど、最低限の機能に抑えられています。WebView が不適切に実装され JavaScript の使用が許可されている場合、それを使用してアプリを攻撃し、そのデータにアクセスすることが可能です。
静的解析
WebView を作成および使用するには、クラス WebView のインスタンスを作成する必要があります。
個別の設定を WebView に適用して、JavaScript を有効または無効にできます。デフォルトでは、JavaScript は WebView では無効であるため、明示的に有効にする必要があります。メソッド setJavaScriptEnabled
を探して、JavaScript が有効になっているかどうかを確認します。
これにより WebView は JavaScript を解釈して、そのコマンドを実行できます。
動的解析
動的解析はさまざまな周囲の条件に依存します。アプリの WebView に JavaScript を注入するさまざまな可能性があるためです。
エンドポイントの格納型(蓄積型)クロスサイトスクリプティング(XSS)、脆弱な機能に移動する際にエクスプロイトがモバイルアプリの WebView に送信されます。
中間者 (MITM) ポジション、攻撃者がレスポンスを改竄して JavaScript を注入する可能性があります。
マルウェア、WebView によりロードされローカルファイルを改竄します。
これらの攻撃ベクトルに対処するには、以下のチェック結果を検証する必要があります。
エンドポイントにより提供されるすべての機能が格納型(蓄積型) XSS [4] からフリーである必要があります。
HTTPS 通信はベストプラクティスに従って実装され、MITM 攻撃を避ける必要があります。これは以下を意味します。
通信全体が TLS 経由で暗号化されている (OMTG-NET-001 参照)
証明書は適切にチェックされている (OMTG-NET-002 参照)
証明書はさらにピンニングされている (OMTG-NET-004 参照)
アプリデータディレクトリ内のファイルのみが WebView でレンダリングされている必要があります (OMTG-ENV-007 参照) 。
改善方法
JavaScript はデフォルトで無効にされており、必要でない場合には有効にしてはいけません。これにより攻撃領域とアプリの潜在的な脅威を減らします。JavaScript が必要とされる場合には、以下を保証する必要があります。
通信は一貫して HTTPS に依存 (OMTG-NET-001 も参照) し、HTML と JavaScript を通信時の攻撃から保護すること。
JavaScript と HTML はアプリデータディレクトリ内から、または信頼できるウェブサーバーからのみローカルにロードされること。
WebView のキャッシュをクリアして、JavaScript とローカルに格納されたデータのすべてを削除します。アプリ終了時に clearCache()
[2] を使用します。
Android 4.4 (API レベル 19) より古いプラットフォームを実行しているデバイスでは、セキュリティ上の問題が多くあるバージョンの Webkit を使用しています。回避策として、アプリがこれらのデバイスで動作している場合、WebView オブジェクトは信頼できるコンテンツのみ表示することを確認する必要があります [3] 。
参考情報
OWASP Mobile Top 10 2016
M7 - 脆弱なコード品質 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M7-Poor_Code_Quality
OWASP MASVS
V6.5: "明示的に必要でない限りWebViewでJavaScriptが無効にされている。"
CWE
CWE-79 - Improper Neutralization of Input During Web Page Generation https://cwe.mitre.org/data/definitions/79.html
その他
[1] setJavaScriptEnabled in WebViews - https://developer.android.com/reference/android/webkit/WebSettings.html#setJavaScriptEnabled(boolean)
[2] clearCache() in WebViews - https://developer.android.com/reference/android/webkit/WebView.html#clearCache(boolean)
[3] WebView Best Practices - https://developer.android.com/training/articles/security-tips.html#WebView
[4] Stored Cross-Site Scripting - https://www.owasp.org/index.php/Testing_for_Stored_Cross_site_scripting_(OTG-INPVAL-002)
WebView プロトコルハンドラのテスト
概要
いくつかのスキーマがデフォルトで Android の URI に利用可能であり、WebView 内でトリガできます [3] 。
http(s):
file:
tel:
geo:
それらをリンクで使用する場合、アプリはトリガできます。例えば、file:///storage/emulated/0/private.xml
を使用して、ローカルファイルにアクセスできます。WebView に JavaScript を注入して、ファイルスキーマを介してローカルリソースにアクセスできる場合、これは攻撃者により悪用される可能性があります。
-- TODO [Further develop content on "Testing WebView Protocol Handlers"] --
静的解析
以下のメソッドが WebView に利用でき、さまざまなリソースへのアクセスを制御できます [4] 。
setAllowContentAccess()
: コンテンツ URL アクセスにより WebView はシステムにインストールされたコンテンツプロバイダからコンテンツをロードできます。デフォルトは有効です。setAllowFileAccess()
: WebView 内でのファイルアクセスを有効または無効にします。ファイルアクセスはデフォルトで有効です。setAllowFileAccessFromFileURLs()
: ファイルスキーム URL のコンテキストで実行されている JavaScript が他のファイルスキーム URL のコンテンツにアクセスできるようにするかどうかを設定します。デフォルト値は API レベル ICE_CREAM_SANDWICH_MR1 およびそれ以下では true 、API レベル JELLY_BEAN およびそれ以上では false です。setAllowUniversalAccessFromFileURLs()
: ファイルスキーム URL のコンテキストで実行されている JavaScript が任意のオリジンのコンテンツにアクセスできるようにするかどうかを設定します。デフォルト値は API レベル ICE_CREAM_SANDWICH_MR1 およびそれ以下では true 、API レベル JELLY_BEAN およびそれ以上では false です。
上記のメソッドのひとつまたはすべてを特定でき、それらが有効になっている場合には、アプリが適切に機能するために本当に必要かどうかを検証する必要があります。
動的解析
アプリを使用する中で、電話を呼び出す方法や、ファイルシステムからファイルにアクセスする方法を探し、プロトコルハンドラの使用方法を特定します。
-- TODO [Further develop content on dynamic analysis for "Testing WebView Protocol Handlers" ] --
改善方法
適用可能である場合、以下のベストプラクティスを設定し、プロトコルハンドラを無効にします [2] 。
ファイルシステム内のファイルへのアクセスは WebView に対して setAllowFileAccess()
を使用して有効または無効にできます。ファイルアクセスはデフォルトで有効であり、必要がない場合には無効にすべきです。これによりファイルシステムアクセスのみが有効または無効になることに注意します。アセットおよびリソースは依然として file:///android_asset
および file:///android_res
を使用してアクセスできます [1] 。
-- TODO [How to disable tel and geo schema?] --
参考情報
OWASP Mobile Top 10 2016
M7 - 脆弱なコード品質 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M7-Poor_Code_Quality
OWASP MASVS
V6.6: "WebViewは最低限必要なプロトコルハンドラのセットのみを許可するよう構成されている(理想的には、httpsのみがサポートされている)。file, tel, app-id などの潜在的に危険なハンドラは無効にされている。"
CWE
N/A
その他
[1] File Access in WebView - https://developer.android.com/reference/android/webkit/WebSettings.html#setAllowFileAccess%28boolean%29
[2] WebView best practices - https://github.com/nowsecure/secure-mobile-development/blob/master/en/android/webview-best-practices.md#remediation
[3] Intent List - https://developer.android.com/guide/appendix/g-app-intents.html
[4] WebView Settings - https://developer.android.com/reference/android/webkit/WebSettings.html
WebView でのローカルファイルのインクルードのテスト
概要
WebView はコンテンツをリモートからロードできますが、アプリデータディレクトリや外部ストレージからローカルにロードすることもできます。コンテンツがローカルにロードされる場合、ファイルがロードされるファイル名やパスにユーザーが影響を与えてはいけません。さもなくば、ロードされるファイルを編集できることになります。
-- TODO [Further develop content on the overview for "Testing for Local File Inclusion in WebViews"] --
静的解析
WebView の使用方法についてソースコードを確認します。WebView インスタンスが特定できる場合、ローカルファイルがメソッド loadURL()
[1] によりロードされているか確認します。
どこから HTML ファイルがロードされているかを検証する必要があります。例えば、外部ストレージからロードされる場合、ファイルは誰でも読み書き可能であり、バッドプラクティスと考えられます。
loadURL()
で指定された URL は、操作が可能な動的パラメータが使用されているかどうかをチェックすべきであり、ローカルファイルがインクルードされている可能性があります。
動的解析
-- TODO [Describe how to test for this issue by running and interacting with the app. This can include everything from simply monitoring network traffic or aspects of the app’s behavior to code injection, debugging, instrumentation, etc.] --
改善方法
ローカルおよびリモートでロードすることができるウェブページとそのプロトコル (HTTP または HTTPS) を定義するホワイトリストを作成します。外部ストレージからウェブページをロードすることは、Android のすべてのユーザーが読み書きできるため、避けるべきです。代わりに、それらはアプリのアセットディレクトリに配置すべきです。
ローカル HTML/JavaScript ファイルのチェックサムを作成し、アプリの起動時に確認します。JavaScript ファイルを圧縮して、それらを読みにくくします。
参考情報
OWASP Mobile Top 10 2016
M7 - 脆弱なコード品質 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M7-Poor_Code_Quality
OWASP MASVS
V6.7: "アプリは WebView にユーザー提供のローカルリソースをロードしていない。"
CWE
N/A
その他
[1] loadURL() in WebView - https://developer.android.com/reference/android/webkit/WebView.html#loadUrl(java.lang.String)
Java オブジェクトが WebView を介して公開されているかのテスト
概要
Android は WebView 内で実行される JavaScript が Android アプリ内でネイティブ関数を呼び出しおよび使用できる二つの方法を提供しています。
shouldOverrideUrlLoading()
[4]addJavascriptInterface()
[5]
shouldOverrideUrlLoading
このメソッドは、新しい URL が現在の WebView にロードされる直前に、ホストアプリケーションにコントロールを引き継ぐことができます。メソッド shouldOverrideUrlLoading()
は二つの異なるメソッドシグネチャで利用できます。
boolean shouldOverrideUrlLoading
(WebView view, String url)このメソッドは API レベル 24 で非推奨になりました。
boolean shouldOverrideUrlLoading
(WebView view, WebResourceRequest request)このメソッドは API レベル 24 で追加されました。
addJavascriptInterface
addJavascriptInterface()
メソッドは Java オブジェクトを WebView に公開することを可能にします。このメソッドを Android アプリで使用する場合、WebView の JavaScript コードで Android アプリのネイティブメソッドを呼び出すことが可能です。
Android 4.2 JELLY_BEAN (API レベル 17) 以前で addJavascriptInterface()
の実装に脆弱性が見つかりました。WebView に悪意のある JavaScript を注入する際にリモートコード実行につながるリフレクションを使用するものです [2] 。
API レベル 17 で、この脆弱性が修正され、JavaScript 用の Java オブジェクトのメソッドに付与されたアクセスが変更されました。addJavascriptInterface()
を使用する際は、アノテーション @JavascriptInterface
を明示的に追加した場合にのみ、Java オブジェクトのメソッドは JavaScript でアクセスできます。API レベル 17 以前では、Java オブジェクトのすべてのメソッドがデフォルトでアクセス可能です。
Android 4.2 以前の Android バージョンをターゲットとしているアプリは、addJavascriptInterface()
で特定された欠陥に対して依然として脆弱であり、細心の注意を払って使用する必要があります。したがって、このメソッドを必要とする場合にはいくつかのベストプラクティスを適用する必要があります。
静的解析
shouldOverrideUrlLoading
メソッド shouldOverrideUrlLoading()
が使用されているかどうか、および攻撃者が悪意のある JavaScript を注入することが可能であるかどうかを検証する必要があります。
以下の例はメソッドの使用方法を示したものです。
攻撃者が例えば、格納型(蓄積型) XSS や MITM などを介して、 JavaScript コードにアクセスできる際には、公開された Java メソッドがセキュアではない方法で実装されている場合にネイティブ関数を直接トリガできます。
addJavascriptInterface
メソッド addJavascriptInterface()
が使用されているかどうか、および攻撃者が悪意のある JavaScript を注入することが可能であるかどうかを検証する必要があります。
以下の例は、addJavascriptInterface
を WebView で使用して、Java オブジェクトを JavaScript にブリッジする方法を示しています。
Android API レベル 17 以上では、特別なアノテーションを使用して明示的に JavaScript から Java メソッドにアクセスを許可します。
アノテーション @JavascriptInterface
が使用されている場合、このメソッドは JavaScript から呼び出すことが可能です。アプリが API レベル < 17 をターゲットとする場合、すべての Java オブジェクトのメソッドは JavaScript に公開され、呼び出すことが可能です。
JavaScript ではメソッド returnString()
を呼び出すことができ、戻り値はパラメータ result
に格納されます。
攻撃者が例えば、格納型(蓄積型) XSS や MITM などを介して、 JavaScript コードにアクセスできる際には、直接公開された Java メソッドを呼び出して、悪用できます。
動的解析
-- TODO [Describe how to test for this issue by running and interacting with the app. This can include everything from simply monitoring network traffic or aspects of the app’s behavior to code injection, debugging, instrumentation, etc.] --
改善方法
shouldOverrideUrlLoading()
が必要である場合、どのように入力が処理され、悪意のある JavaScript を介してネイティブ関数を実行することが可能であるかどうかを検証する必要があります。
addJavascriptInterface()
が必要である場合、APK で提供される JavaScript だけが呼び出せるべきであり、リモートエンドポイントからロードされた JavaScript は不可にすべきです。
別の素直な解決策はアプリのマニフェストファイルに API レベル 17 (JELLY_BEAN_MR1) 以上を定義することです。これらの API レベルでは、JavascriptInterface
でアノテーションされたパブリックメソッドだけが JavaScript からアクセスできます [1] 。
参考情報
OWASP Mobile Top 10 2016
M7 - 脆弱なコード品質 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M7-Poor_Code_Quality
OWASP MASVS
V6.8: "JavaオブジェクトがWebViewで公開されている場合、WebViewはアプリパッケージ内に含まれるJavaScriptのみをレンダリングしている。"
CWE
CWE-502 - Deserialization of Untrusted Data
その他
[1] DRD13 addJavascriptInterface() - https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=129859614
[2] WebView addJavascriptInterface Remote Code Execution - https://labs.mwrinfosecurity.com/blog/webview-addjavascriptinterface-remote-code-execution/
[3] Method shouldOverrideUrlLoading() - https://developer.android.com/reference/android/webkit/WebViewClient.html#shouldOverrideUrlLoading(android.webkit.WebView,%20java.lang.String)
[4] Method addJavascriptInterface() - https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)
オブジェクト(逆)シリアライゼーションのテスト
概要
オブジェクトとそのデータはバイト列として表現できます。Java では、これはオブジェクトシリアライゼーションを使用することで可能です。シリアライゼーションはデフォルトでセキュアではなく、単なるバイナリ形式、または .ser ファイルとしてローカルにデータを格納するために使用できる表現形式です。シリアライズされたデータを署名および暗号化することは可能ですが、ソースコードが利用可能である場合、これは常に元に戻せます。
静的解析
ソースコードで以下のキーワードを検索します。
import java.io.Serializable
implements Serializable
シリアライズ化されたデータが一時的または永続的にアプリのデータディレクトリや外部ストレージに格納されているかどうか、それには機密データが含まれているかどうかを確認します。
https://www.securecoding.cert.org/confluence/display/java/SER04-J.+Do+not+allow+serialization+and+deserialization+to+bypass+the+security+manager
動的解析
-- TODO [Create content for dynamic analysis of "Testing Object (De-)Serialization" ] --
改善方法
-- TODO [Describe the best practices that developers should follow to prevent this issue "Testing Object (De-)Serialization".] --
参考情報
OWASP Mobile Top 10 2016
M7 - 脆弱なコード品質 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M7-Poor_Code_Quality
OWASP MASVS
V6.9: "オブジェクトシリアライズ化は、可能であれば、安全なシリアライズ化APIを使用して実装されている。"
CWE
N/A
その他
[1] Update Security Provider - https://developer.android.com/training/articles/security-gms-provider.html
ルート検出のテスト
概要
アプリが実行されている環境の完全性を確認することは Android プラットフォームでますます一般的になっています。ルート化されたデバイスの使用により、Android のいくつかの基本的なセキュリティメカニズムが無効になるか、どのアプリでも簡単に回避することができます。機密情報を処理したり、ゲームアプリなど、知的財産 (IP) を大量に使用しているアプリでは、データやその IP を保護するためにルート化フォンでの実行を避けたいでしょう。
ルート検出は攻撃者からアプリを保護するものではありませんが、攻撃者を劇的に減速させ、ローカル攻撃が成功するバーを引き上げることを心に留めておきます。ルート検出は幅広い多層セキュリティ戦略の一環として考慮すべきであり、攻撃者に対してより耐性があり、解析をより困難にします。
静的解析
ルート検出は Rootbeer
[1] などの既存のルート検出ライブラリを活用して、または手動でチェックを実装することにより実装できます。
ソースコードで文字列 rootbeer
を、また、gradle
ファイルも Rootbeer の依存関係が定義されているかどうかを確認します。
このライブラリを使用している場合、以下のようなコードがルート検出に使用されている可能性があります。
ルート検出が一から実装されている場合、以下を確認してルート検出ロジックを含む関数を特定します。ルート検出には以下のチェックが最も一般的なものです。
ルート化デバイスで利用可能な設定、ファイルをチェックします。BUILD プロパティのパラメータ
android.os.build.tags
で test-keys を確認するなど。特定のディレクトリのパーミッションをチェックします。非ルート化デバイスでは読み取り専用ですが、ルート化デバイスでは読み書き可であるもの。
インストールされているアプリをチェックします。デバイスのルート化を許可またはサポートするもの。Superuser.apk の存在を確認するなど。
利用可能なコマンドをチェックします。
su
を実行した後にルートになることが可能であるかどうかなど。
動的解析
ホワイトボックステストでは、ルート検出を無効化したデバッグビルドを提供し、アプリのすべてのテストケースを適用できるようにします。
ブラックボックステストの場合、ルート化フォンによりアプリがすぐに終了するなど、実装されたルート検出は困難となることがあります。理想的には、ルート化フォンをブラックボックステストに使用する際、SSL ピンニングを無効にする必要がある可能性があります。SSL ピンニングを無効化して傍受プロキシの使用を許可するには、その場合ルート検出をはじめに無効にする必要があります。実装されたルート検出ロジックをソースコードなしに動的スキャンで特定することはかなり困難となります。
Xposed モジュール RootCloak
を使用することにより、ルートを無効にすることなくルートを検出するアプリを実行できます。ですが、ルート検出メカニズムが RootCloak でカバーされていないアプリで使用されている場合、このメカニズムを識別し、RootCloak に追加して無効にする必要があります。
他の選択肢としては金曜日にアプリを動的にパッチしたり、アプリを再パッケージしたりします。これは smali コードの関数を削除して再パッケージするのと同じくらい簡単ですが、いくつかの異なるチェックがルート検出メカニズムの一部である場合、困難になる可能性があります。ランタイム操作、改竄を防ぐ対策が実装されている場合、アプリの動的パッチも難しくなります。
あるいは、非ルート化デバイスに切り替えて、テスト時間を賢く使用し、非ルート化設定で適用できる他のすべてのテストケースを実行します。これはもちろん、たとえば smali で SSL ピンニングを無効にしてアプリを再パッケージするなどの場合にのみ可能です。
改善方法
Android アプリ内でルート検出を実装するには、RootBeer
[1] などのライブラリを使用します。ルート検出では、起動後にユーザーに警告を表示し、デバイスがルート化されていること、およびユーザーが自己のリスクとしてのみ進めることを通知します。また、ルート化環境が検出された場合にアプリを終了することもできます。この判断はビジネス要件とステークホルダのリスク選好に依存します。
参考情報
OWASP Mobile Top 10 2016
M8 - コード改竄 - https://www.owasp.org/index.php/Mobile_Top_10_2016-M8-Code_Tampering
M9 - リバースエンジニアリング - https://www.owasp.org/index.php/Mobile_Top_10_2016-M9-Reverse_Engineering
OWASP MASVS
V6.10: "アプリはルート化デバイスや脱獄デバイスで実行されているかどうかを検出している。ビジネス要件に応じて、デバイスがルート化もしくは脱獄されている場合に、ユーザーに警告している、もしくはアプリが終了している。"
CWE
N/A
その他
[1] RootBeer - https://github.com/scottyab/rootbeer
ツール
RootCloak - http://repo.xposed.info/module/com.devadvance.rootcloak2
Last updated