OWASP準拠の脆弱でない iOS/Androidアプリ開発

【セキュリティ】OWASP準拠の脆弱でない iOS/Androidアプリ開発を行うためのポイントを解説

投稿日: カテゴリー: セキュアコーディング
Pocket

セキュアなiOS/Androidアプリ開発をOWASP準拠しつつ具体的に実践していく方法を解説します。

スマートフォンアプリケーションのセキュリティ観点はサーバサイドのWebアプリケーションに比べ、「開発範囲」がクライアント側に及ぶことに伴い「責任範囲」もクライアント側に延伸しています。サーバ側の保存データに比べ、他のアプリケーションからの攻撃やマルウェア、USBやHTTPS以外の通信手段によるクライアント側の個人情報への攻撃が加わり大きくセキュリティ観点が異なります。世の中的にはモバイルファーストが謳われ、実際に特に一般ユーザ向けのサービスであればPCよりモバイルからのアクセスが多いサービスも多いのではないのでしょうか?
もちろんOWASPやENISAなどではモバイルアプリケーションの開発の基準となるようなドキュメントガイドラインなどを公開しています。しかし、あまり浸透していない印象があります。
OWASP Mobile Top10は2016年とちょっと古いし、JSSEC、『Androidアプリのセキュア設計・セキュアコーディングガイド』 はAndroidだけと言う問題が提起されます。
しかし、OWASPにはMASVSがありますし、対応したOWASPは「Mobile Security Testing Guide(MSTG)」と「Mobile App Security Checklists(チェックリスト)」まで存在します。さらにENISAでは配布の基準も含めた優秀なドキュメントが存在します。
残念ながらこれらが活用されていると言うのも広くは聞きません。
今回はOWASP Mobile Top10カテゴリに準拠しつつ iOS/Androidアプリ開発を行うためのポイントを解説していきます。

M1 – 不適切なプラットフォームの利用 (M1: Improper Platform Usage)

機微情報のシステムログへの出力

システムログに個人情報を出すのはやめましょう。ここには具体的な手段は記載しませんが、他アプリのログは制限されていてもみる手段自体は存在します。
デバッグ時は有効な改修のヒントになるので利用すること自体を否定はしませんが、リリースビルドに含まれるのかは確認すべき項目です。

【Android】

android.util.Logクラスによるログ出力はリリースビルドでもLogCatで閲覧できます。

【iOS】

NSLog,debugPrintによるログ出力はリリースビルドでもXcodeで閲覧できます。

端末時間を基準とした期限

タイムマシンアタックとも呼ぶようですが、利用開始1ヶ月間無料期間などを端末時間を基準にしていた場合、端末時間を未来日付にしてから処理を行って未来日付基準の期日まで不正に無料で利用するなどの悪用手段です。

位置偽装による不正

○ケモンGoなどで位置を基準としたゲームで実際はそこまで移動しないと獲得できないモンスターを獲得するなどでゲームバランスを壊すなどの被害やチェックインクーポンのようにお店の近くに行ったからこそ有効になる割引券の取得、パーキングアプリのようにその車の近くにいることを認証の基準にしているアプリなどで不正が行われる脆弱性などが考えられます。

クリップボードからの情報漏洩

パソコンで言えば範囲指定して右クリックしてコピーや切り取りの際に利用される保存領域です。クリップボードにはシステムクリップボードとアプリケーションクリップボードが存在します。
システムクリップボードはその名の通りシステム内の全てのアプリで共有されるクリップボードであるため他のアプリからコピーした内容が見えることになります。
パスワードやAndroid/Clipper.Cのようにビットコインのウォレットアドレスをすり替える悪質な攻撃もあるので注意が必要です。

【Android】

Androidはシステムクリップボードオンリーです。ClipboardManagerはどのアプリからでも常時Clipboardの中身が取得できるようになっています。つまり、ユーザーがコピー・カットした情報は全て悪意あるアプリに対して筒抜けになっていると言うことです。
そもそもコピー&カットをさせないと言う方法が考えられます。具体的には2つ方法があります。文字列選択時のメニューからandroid.R.id.copy、ndroid.R.id.cutを削除する方法とViewの長押し(Long Click)を無効にする方法です。
長押し(Long Click)を無効にする方法はコピー・カットを禁止するViewはandroid:longClickableをfalseにすると実現可能です。

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/unlongclickable_description" /> 

【iOS】

iOSにはアプリケーションクリップボードが存在するのでそちらを利用しましょう。アプリ内のみ、正確には同じ開発者により署名されたアプリ間で䛾み共有されます。iOSではペーストボードと呼ばれてます。ここに不正にアクセスしていたアプリがAppleでも確認されたようです。コピー&カットを禁止する方法もありますが以下の方法で制限する方が良いでしょう。
iOS10からはUniversal Clipboard「有効範囲をローカルのみに制限する」「有効期限を設定する」が設定可能になりました。

let pasteboard = UIPasteboard.general
pasteboard.setItems([["key": "value"]], options: [UIPasteboardOption.localOnly : true]) 
let expiration = Date().addingTimeInterval(60 * 60) //1時間有効 
pasteboard.setItems([["key": "value"]], options: [UIPasteboardOption.expirationDate: expiration])

スナップショットからの情報漏洩

個人情報や機微情報が表示されたページのスクリーンショットを取得される被害も考えられますが、ゲーム実況動画を作成するアプリケーションなどを不正に背後で起動してログイン画面を取得させた場合、パスワードを容易に取得することが可能です。堂々とバックグラウンドで通信するケースも考えられますし、正規の通信に混ぜてどさくさに紛れて送信されるケースも考えられます。

【Android】

FLAG_SECUREを対象のウィジェットにセットしてスクリーンショットを妨害させることができます。

【iOS】

実はiOSでは直接スクリーンショットを妨害する仕組みはありません。タップしたときだけ個人情報を表示するなどが画面としては有効な対策手段となりそうです。一方、動画であれば@objc funccaptureStatusDidChange()などでキャプチャして塗りつぶす。またはDRMを利用するなどの手段で対策することとなります。
具体的には以下のコードで黒塗りができます。(別に黒塗りにこだわる必要はありませんが・・・)

@objc funccaptureStatusDidChange()
{
    if UIScreen.mai.isCaptured{
        self.view.backgraudColor = UIColor.black
    }
}

M2 – 安全でないデータストレージ (M2: Insecure Data Storage)

ファイルへの保存:平文の個人情報や暗号鍵の保存はNG

【Android】Shared Preferences

場所:data/data//shared_prefs/
キーストアから取得した鍵で暗号化した上、SharedPreferencesなどを用いて端末に保存する

【iOS】plist

場所:/var/mobile/Containers/Data/Application/$APP_ID/

データベースへの保存:平文の個人情報や暗号鍵の保存はNG

【Android】SQLite データベース

場所:data/data//databases/
SQLCipherを利用することで暗号化されます。

【iOS】CoreData/SQLite データベース

場所:/var/mobile/Containers/Data/Application/$APP_ID/

セキュアストレージ:暗号鍵の保存場所として利用可能

【Android】KeyStore (AndroidKeyStore)

iOSで言うKeycahinですと言うと伝わるのが悲しいですが、暗号鍵やセッショントークンなどが保存すべき場所です。

【iOS】Keycahin

キーチェーンは暗号鍵やセッショントークンなどの短く機密性の高いデータを安全に保管するために使用されます。
keychain dumper

その他の保存場所とセキュリティ

【Android】内部ストレージ

内部ストレージに保存されたファイルはアプリケーション専用であり、他のアプリケーションはアクセスできません。
しかし、MODE_WORLD_READABLEやMODE_WORLD_WRITEABLEであった場合、他のアプリからもアクセスできてしまいます。

FileOutputStream fos = null;
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(test.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

【Android】外部ストレージ

外部ストレージに保存されたファイルは world-readable となるため機微な情報を消して保存してはなりません。
機微でなくとも、利用者の同意の得ていない個人情報となる情報もアウトです。

 

M1 – 不適切なプラットフォームの利用 (M1: Improper Platform Usage)とM2 – 安全でないデータストレージ (M2: Insecure Data Storage)について解説してまいりましたが、
残り8つのOWASP Mobile Top 10項目に関してご興味ございましたらお問い合わせください。
M3: Insecure Communication
M4: Insecure Authentication
M5: Insufficient Cryptography
M6: Insecure Authorization
M7: Client Code Quality
M8: Code Tampering
M9: Reverse Engineering
M10: Extraneous Functionality

以上です。参考になれば幸いです。