Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutterで実装する実践的な攻撃対策とセキュリティ向上

Avatar for FujiKinaga FujiKinaga
November 13, 2025

 Flutterで実装する実践的な攻撃対策とセキュリティ向上

Flutter Kaigi 2025

Avatar for FujiKinaga

FujiKinaga

November 13, 2025
Tweet

More Decks by FujiKinaga

Other Decks in Technology

Transcript

  1. 株式会社WinTicket Mobile Application Engineer Fuji Kinaga 職歴 2020年 株式会社サイバーエージェント 中途入社

    株式会社AbemaTVでAndroidエンジニア 株式会社WinTicketでFlutterエンジニア 最近 アプリチームのマネージャー サーバーチーム バックエンド勉強中です 趣味 睡眠, 盆栽, レコード, 働いた後の家系ラーメン
  2. “As it turns out, mobile security is all about data

    protection” 結局のところ、モバイルセキュリティとはデータ保護がすべてである OWASP MASVS 序文
  3. “It depends on the particular client-side threats one aims to

    defend against.” レジリエンスは、防御対象となるクライアント側の具体的な脅威によって異なる OWASP MASVS 序文
  4. Androidの位置情報偽造の手段 位置情報偽造ツールの使用 位置情報モックのアプリを選択。そこから注入された位置情報に差し 替わり、本当の位置情報のようにデバイス側で扱われる 開発者オプション → 仮の現在地情報アプリを選択 から選ぶ PC接続型のツールやアプリインストール型のツールがある デバイスからの応答を差し替え

    アプリケーションにルートアクセスを提供(Root化)したり、動的解析 ツールを使用して、フレームワークやロケーションプロバイダに介入 偽の位置情報を返すようにフックする 理屈上は可能 引用: https://jp.imyfone.com/ 引用: https://github.com/topjohnwu/Magisk, https://frida.re/
  5. Androidではどういう位置情報のレスポンスになるか? latitude: 35.xxx longitude: 139.xxx timestamp: YYYY-MM-DD HH:mm:ss.SSSZ accuracy: 15.555000305175781


    altitude: 100.80000305175781
 altitudeAccuracy: 0.6149576306343079
 heading: 217.95425415039062
 headingAccuracy: 45.0
 speed: 0.32402801513671875
 speedAccuracy: 1.5
 isMocked: false 偽造時 isMockedがtrueになる 一部の値が常に固定で返却される 偽造には開発者オプションの設定が必須 latitude: 36.xxx longitude: 138.xxx
 timestamp: YYYY-MM-DD HH:mm:ss.SSSZ
 accuracy: 2.0
 altitude: 18.337348515379652
 altitudeAccuracy: 0.0
 heading: 1.0
 headingAccuracy: 0.0
 speed: 0.0
 speedAccuracy: 0.0
 isMocked: true 正常時 isMockedでは以下を参照 API31以降 → Location.isMock API31未満 → isFromMockProvider
  6. Androidではどういう位置情報のレスポンスになるか? latitude: 35.xxx longitude: 139.xxx timestamp: YYYY-MM-DD HH:mm:ss.SSSZ accuracy: 15.555000305175781


    altitude: 100.80000305175781
 altitudeAccuracy: 0.6149576306343079
 heading: 217.95425415039062
 headingAccuracy: 45.0
 speed: 0.32402801513671875
 speedAccuracy: 1.5
 isMocked: false 偽造時 isMockedがtrueになる 一部の値が常に固定で返却される 偽造には開発者オプションの設定が必須 latitude: 36.xxx longitude: 138.xxx
 timestamp: YYYY-MM-DD HH:mm:ss.SSSZ
 altitude: 18.337348515379652
 accuracy: 2.0
 altitudeAccuracy: 0.0
 heading: 1.0
 headingAccuracy: 0.0
 speed: 0.0
 speedAccuracy: 0.0
 isMocked: true 正常時 isMockedでは以下を参照 API31以降 → Location.isMock API31未満 → isFromMockProvider
  7. iOSではどういう位置情報のレスポンスになるか? latitude: 35.xxx longitude: 139.xxx timestamp: YYYY-MM-DD HH:mm:ss.SSSZ accuracy: 8.991563588862155

    altitude: 23.232012915556 altitudeAccuracy: 30.0 heading: -1.0 headingAccuracy: -1.0 speed: 0.0 speedAccuracy: 0.0 isMocked: false 偽造時 isMockedがtrueになる 一部の値が常に固定で返却される 正常時 isMocked以下を参照 iOS15以降 → Core Location#isSimulatedBySoftware iOS15未満 → 常にfalse latitude: 36.xxx longitude: 138.xxx
 timestamp: YYYY-MM-DD HH:mm:ss.SSSZ
 accuracy: 5.0
 altitude: 0.0
 altitudeAccuracy: 0.0
 heading: -1.0
 headingAccuracy: -1.0
 speed: 0.0
 speedAccuracy: 0.0
 isMocked: true 偽造解除時(端末再起動前) isMockedがfalseになる accuracyが大きい値で返却される latitude: 35.xxx longitude: 139.xxx timestamp: YYYY-MM-DD HH:mm:ss.SSSZ
 accuracy: 1414.0
 altitude: 0.0
 altitudeAccuracy: 0.0
 heading: -1.0
 headingAccuracy: -1.0
 speed: 0.0
 speedAccuracy: 0.0
 isMocked: false
  8. iOSではどういう位置情報のレスポンスになるか? latitude: 35.xxx longitude: 139.xxx timestamp: YYYY-MM-DD HH:mm:ss.SSSZ accuracy: 8.991563588862155

    altitude: 23.232012915556 altitudeAccuracy: 30.0 heading: -1.0 headingAccuracy: -1.0 speed: 0.0 speedAccuracy: 0.0 isMocked: false 偽造時 isMockedがtrueになる 一部の値が常に固定で返却される 正常時 isMocked以下を参照 iOS15以降 → Core Location#isSimulatedBySoftware iOS15未満 → 常にfalse latitude: 36.xxx longitude: 138.xxx
 timestamp: YYYY-MM-DD HH:mm:ss.SSSZ
 heading: -1.0
 headingAccuracy: -1.0
 speed: 0.0
 speedAccuracy: 0.0
 accuracy: 5.0
 altitude: 0.0
 altitudeAccuracy: 0.0
 isMocked: true 偽造解除時(端末再起動前) isMockedがfalseになる accuracyが大きい値で返却される latitude: 35.xxx longitude: 139.xxx timestamp: YYYY-MM-DD HH:mm:ss.SSSZ
 accuracy: 1414.0
 altitude: 0.0
 altitudeAccuracy: 0.0
 heading: -1.0
 headingAccuracy: -1.0
 speed: 0.0
 speedAccuracy: 0.0
 isMocked: false
  9. iOSではどういう位置情報のレスポンスになるか? latitude: 35.xxx longitude: 139.xxx timestamp: YYYY-MM-DD HH:mm:ss.SSSZ accuracy: 8.991563588862155

    altitude: 23.232012915556 altitudeAccuracy: 30.0 heading: -1.0 headingAccuracy: -1.0 speed: 0.0 speedAccuracy: 0.0 isMocked: false 偽造時 isMockedがtrueになる 一部の値が常に固定で返却される 正常時 isMocked以下を参照 iOS15以降 → Core Location#isSimulatedBySoftware iOS15未満 → 常にfalse latitude: 36.xxx longitude: 138.xxx
 timestamp: YYYY-MM-DD HH:mm:ss.SSSZ
 heading: -1.0
 headingAccuracy: -1.0
 speed: 0.0
 speedAccuracy: 0.0
 accuracy: 5.0
 altitude: 0.0
 altitudeAccuracy: 0.0
 isMocked: true 偽造解除時(端末再起動前) isMockedがfalseになる accuracyが大きい値で返却される latitude: 35.xxx longitude: 139.xxx timestamp: YYYY-MM-DD HH:mm:ss.SSSZ
 heading: -1.0
 headingAccuracy: -1.0
 speed: 0.0
 speedAccuracy: 0.0
 accuracy: 1414.0
 altitude: 0.0
 altitudeAccuracy: 0.0
 isMocked: false
  10. どう防ぐか Androidの対策 偽造ツール使用の検知は、isMockedがtrueかを見ればOK isMockedの値をフックして返されると偽造のチェックが 通ってしまうリスクがある iOSの対策 偽造ツール使用の検知は、isMockedがtrueかを見るだけで は不十分 ただ、常に固定で送られるフィールドの前後比較ができれば 検知は可能かもしれない

    isMockedの値をフックして返されると偽造のチェックが 通ってしまうリスクがある アプリやデバイスの改ざんの対策が必要 偽造ツールの検知だけでなく、アプリやデバイスの不正利 用でも突破されづらくする多層防御を検討する必要がある
  11. root_jailbreak_sniffer Rjsniffer.amICompromised() Android Root化や危険アプリのインストール、Magisk使用の有 無などで判定 iOS IOSSecuritySuiteのライブラリとブリッジ Rjsniffer.amIEmulator() Android エミュレーターによる起動の判定

    iOS IOSSecuritySuiteのライブラリとブリッジ Rjsniffer.amIDebugged() Android 開発者オプションの有効可否やfrifaの接続可否で判定 iOS IOSSecuritySuiteのライブラリとブリッジ
  12. リクエスト改ざんの例 中間者攻撃(MITM攻撃) 攻撃者がユーザーと利用サービス の間に割り込んで、受け渡すデー タを盗聴したり、改ざんしたりす る リクエストを覗かれて処理の詳細 を把握されてしまう リプレイ攻撃 ユーザーとサーバー間でやり取り

    された認証情報や通信データを傍 受し、そのデータを再送信する 正しく考慮できていないと高負荷 につながったり、複数回有効な処 理を通してしまう 逆コンパイル ソースコードを解析し、特定の処 理についての情報を得る 正しいリクエストを生成されて有 効な処理として判定されてしまう
  13. 対策の基礎 通信の暗号化 HTTPS/TLS AES/RSA 秘匿情報を持たない/出力しない ソースコードに置かない デバイスストレージに保存しない ログに出力しない コードの難読化 --obfuscate

    --split-debug-info iOS/Androidネイティブ側も忘れずに 最新OSやSDKに追従する 同時に低いバージョンを使い続けないこ とも大事 ストアコンソール機能でも対策できます ex. Play App Signing, Cloud- managed certificates, Xcode Cloud
  14. iOSとAndroidの完全性の判定方法 Play Integrity API Playサーバーと連携し、アプリ・デバイス・ユーザーの完全性を担保する Google Play によってインストールされたか 正規の認定 Android

    デバイスで実行されているか 正規のアプリから送信されているか App Attest / Device Check Appleサーバーと連携し、完全性を担保する Device Check 主にデバイス、部分的にアプリの完全性を検証する App Attest 正規のiOSデバイスで実行されているか 正規のアプリから送信されているか ペイロードに改変が加えられていないか 引用: https://jp.imyfone.com/ 引用: https://www.apple.com/privacy/
  15. Play Integrity API リクエスト種別 標準リクエスト standardTokenProviderを事前に取得し、メモリに保持しておく 部分的な構成証明情報をキャッシュしておくことで、整合性判定のリク エストのレイテンシを削減することができる。 トークンに端末情報やリクエスト情報を含めてPlay(Google) Server側

    で判定しており、 Play(Google) Server側でリプレイ攻撃も防止できる クラシックリクエスト 標準リクエストに比べて作成コストが高い サーバーローカルで復号化して検証する選択肢がある 標準リクエストは Googleサーバーでの復号しか対応していない こっちを選択すると実装を正しく行う必要があり、開発負荷増 引用: https://developer.android.com/google/play/integrity/classic Figure.1 引用: https://developer.android.com/google/play/integrity/standard Figure.1
  16. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 { { , , }, { , , [ ], }, { [ ] }, { } } "requestDetails" "requestPackageName" "timestampMillis" "nonce" "requestHash" "appIntegrity" "appRecognitionVerdict" "packageName" "certificateSha256Digest" "versionCode" "deviceIntegrity" "deviceRecognitionVerdict" "accountDetails" "appLicensingVerdict" : : : : : : : : : : : : : : "com.package.name" "1617893780" "xxxxx" "xxxxx" "PLAY_RECOGNIZED" "com.package.name" "6a6a1474b5cbbb2b1aa57e0bc3" "42" "MEETS_DEVICE_INTEGRITY" "LICENSED" Token payloadの中身
  17. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 { { , , }, { , , [ ], }, { [ ] }, { } } "requestDetails" "requestPackageName" "timestampMillis" "nonce" "requestHash" "appIntegrity" "appRecognitionVerdict" "packageName" "certificateSha256Digest" "versionCode" "deviceIntegrity" "deviceRecognitionVerdict" "accountDetails" "appLicensingVerdict" : : : : : : : : : : : : : : "com.package.name" "1617893780" "xxxxx" "xxxxx" "PLAY_RECOGNIZED" "com.package.name" "6a6a1474b5cbbb2b1aa57e0bc3" "42" "MEETS_DEVICE_INTEGRITY" "LICENSED" requestDetails アプリからリクエストしたデータとPlayサーバー から返却されたデータが一致しているかを確認す るためのフィールド リクエスト形式で異なる 標準リクエスト: requestHash クラシックリクエスト: nonce
  18. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 { { , , }, { , , [ ], }, { [ ] }, { } } "requestDetails" "requestPackageName" "timestampMillis" "nonce" "requestHash" "appIntegrity" "appRecognitionVerdict" "packageName" "certificateSha256Digest" "versionCode" "deviceIntegrity" "deviceRecognitionVerdict" "accountDetails" "appLicensingVerdict" : : : : : : : : : : : : : : "com.package.name" "1617893780" "xxxxx" "xxxxx" "PLAY_RECOGNIZED" "com.package.name" "6a6a1474b5cbbb2b1aa57e0bc3" "42" "MEETS_DEVICE_INTEGRITY" "LICENSED" appIntegrity アプリの完全性を検証するためのフィールド PLAY_RECOGNIZED: アプリと証明書が GooglePlayから配布されているバージョンと一 致 UNRECOGNIZED_VERSION: GooglePlayの記録 と一致しない UNEVALUATED: 評価の要件を満たせなかった (デバイスの完全性が不十分など)
  19. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 { { , , }, { , , [ ], }, { [ ] }, { } } "requestDetails" "requestPackageName" "timestampMillis" "nonce" "requestHash" "appIntegrity" "appRecognitionVerdict" "packageName" "certificateSha256Digest" "versionCode" "deviceIntegrity" "deviceRecognitionVerdict" "accountDetails" "appLicensingVerdict" : : : : : : : : : : : : : : "com.package.name" "1617893780" "xxxxx" "xxxxx" "PLAY_RECOGNIZED" "com.package.name" "6a6a1474b5cbbb2b1aa57e0bc3" "42" "MEETS_DEVICE_INTEGRITY" "LICENSED" deviceIntegrity デバイスの完全性を検証するためのフィールド MEETS_DEVICE_INTEGRITY: 正規の認証済み Android端末で動作している 空: フック実行やRoot化、エミュレータの疑い がある PlayConsole上でオプショナルなチェックをオプト インできる
  20. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 { { , , }, { , , [ ], }, { [ , , ] }, { } } "requestDetails" "requestPackageName" "timestampMillis" "nonce" "requestHash" "appIntegrity" "appRecognitionVerdict" "packageName" "certificateSha256Digest" "versionCode" "deviceIntegrity" "deviceRecognitionVerdict" "accountDetails" "appLicensingVerdict" : : : : : : : : : : : : : : "com.package.name" "1617893780" "xxxxx" "xxxxx" "PLAY_RECOGNIZED" "com.package.name" "6a6a1474b5cbbb2b1aa57e0bc3" "42" "MEETS_DEVICE_INTEGRITY" "MEETS_BASIC_INTEGRITY" "MEETS_STRONG_INTEGRITY" "LICENSED" (optional) deviceIntegrity デバイスの完全性を検証するためのフィールド MEETS_BASIC_INTEGRITY: ブートローダーの ロック可否やブート状態の検証状態に関わら ず、基本的なシステム整合性チェックを通過し たかどうか MEETS_STRONG_INTEGRITY: 最新のセキュリ ティアップデートが適用された正規の認証済み Androidデバイスかどうか
  21. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 { { , , }, { , , [ ], }, { [ ] }, { } } "requestDetails" "requestPackageName" "timestampMillis" "nonce" "requestHash" "appIntegrity" "appRecognitionVerdict" "packageName" "certificateSha256Digest" "versionCode" "deviceIntegrity" "deviceRecognitionVerdict" "accountDetails" "appLicensingVerdict" : : : : : : : : : : : : : : "com.package.name" "1617893780" "xxxxx" "xxxxx" "PLAY_RECOGNIZED" "com.package.name" "6a6a1474b5cbbb2b1aa57e0bc3" "42" "MEETS_DEVICE_INTEGRITY" "LICENSED" accountDetails デバイスにログインしているユーザーアカウントに おけるアプリのGoogle Playライセンスステータス を表すフィールド LICENSED: デバイス上のGoogle Playからアプ リをインストールまたはアップデートした UNLICENSED: アプリをサイドロードしたり、 Google Play外からのインストールの疑いがあ る UNEVALUATED: 評価の要件を満たせなかった
  22. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 { { { }, { } }, { , { [ , , ] } } } "deviceIntegrity" "recentDeviceActivity" "deviceActivityLevel" "deviceAttributes" "sdkVersion" "environmentDetails" "playProtectVerdict" "appAccessRiskVerdict" "appsDetected" : : : : : : : : : "LEVEL_3" "NO_ISSUES" "KNOWN_INSTALLED" "UNKNOWN_INSTALLED" "UNKNOWN_CAPTURING" 32 そのほかのoptional recentDeviceActivity: 過去1時間に特定のデバ イスでアプリが整合性トークンを要求した回数 deviceAttributes.sdkVersion: デバイスのバー ジョン番号。要件を満たしてない場合、返却さ れない playProtectVerdict: Google Play Protectの有 効可否 appAccessRiskVerdict: 画面のキャプチャや オーバーレイの表示、デバイスの制御に使用で きる他アプリが実行中かどうかなど ※deviceRecallはまだβ版で情報が少なく割愛
  23. Remediation dialogs ※AndroidプラットフォームAPI呼び出しが必要 ①PlayStoreへの誘導 いずれかの状態時に表示 appLicensingVerdict: ”UNLICENSED” appRecognitionVerdict: ”UNRECOGNIZED_VERSION” ②不正アプリを閉じるよう促す

    appsDetectedが以下のいずれか ”KNOWN_CAPTURING” “KNOWN_CONTROLLING” ”UNKNOWN_CAPTURING” ”UNKNOWN_CONTROLLING” ③デバイスの整合性の判定 ①に加えてdeviceRecognitionVerdictに以下が 含まれない ”MEETS_DEVICE_INTEGRITY” ”MEETS_STRONG_INTEGRITY” または修復可能なクライアント例外が発生した 場合 引用: https://developer.android.com/google/play/integrity/remediation
  24. アプリとデバイスの完全性 Play Integrity API Playサーバーと連携し、アプリ・デバイス・ユーザーの完全性を担保する Google Play によってインストールされたか 正規の認定 Android

    デバイスで実行されているか 正規のアプリから送信されているか App Attest / Device Check Appleサーバーと連携し、完全性を担保する Device Check 主にデバイス、部分的にアプリの完全性を検証する App Attest 正規のiOSデバイスで実行されているか 正規のアプリから送信されているか ペイロードに改変が加えられていないか 引用: https://jp.imyfone.com/ 引用: https://www.apple.com/privacy/
  25. iOSで使える機能の紹介 Device Check デバイスが持つ情報と開発者アカウントの情報に紐づく識別子を生成 Appleアカウントやアプリケーションの情報を見ない 2ビット(true, false)からなる二つの識別子をデバイス×開発者アカウン トの分だけ Appleサーバーで管理する ex.

    {0, 1} + timestamp 今後使われるケースは減っていくと予想されるので詳細の解説は割愛 App Attest App AttestAPI呼び出し時に取得したKeyとデバイスが持つ SecureEnclaveに保存された秘密鍵のキーペア、Appleサーバー間でデ バイス・アプリの完全性を保証する SecureEnclaveはICレベルのプロセッサやストレージがメインから隔離 されており、侵害されてもユーザーのデータを安全に守る サーバーに送る際は構成証明を取得しておいたキーペアで署名する 構成証明の中にアプリに関する身元のハッシュデータを入れている 引用: https://developer.apple.com/jp/videos/play/wwdc2021/10244/
  26. 1 2 3 4 5 6 7 8 9 10

    11 12 // attestation { fmt 'apple-appattest', attStmt { x5c [ <Buffer cc ... >, <Buffer ... > ], receipt <Buffer ... > }, authData <Buffer c9 9e ... > } : : : : : 30 82 02 30 82 02 36 30 80 06 09 21 00 1 2 3 4 5 // assertion { signature <Buffer ... >, authenticatorData <Buffer c9 9e ... > } : : 30 45 02 20 21 00 Token payloadの中身 (実際はJSONではないので注意)
  27. 【おさらい】 アプリとデバイスの完全性 Play Integrity API Playサーバーと連携し、アプリ・デバイス・ユーザーの完全性を担保する Google Play によってインストールされたか 正規の認定

    Android デバイスで実行されているか 正規のアプリから送信されているか App Attest / Device Check Appleサーバーと連携し、完全性を担保する Device Check 主にデバイス、部分的にアプリの完全性を検証する App Attest 正規のiOSデバイスで実行されているか 正規のアプリから送信されているか ペイロードに改変が加えられていないか 引用: https://jp.imyfone.com/ 引用: https://www.apple.com/privacy/
  28. Firebase App Check 各PFの認証プロバイダーをサポート Apple: DeviceCheck または App Attest Android:

    Play Integrity API Web: reCAPTCHA Enterprise サードパーティの認証プロバイダや独自サービスも接続可 Firebaseサービスと連携 バックエンドリソースへのアクセスを伴うサービスで利用可 能 ex. Firebase Authentication, Cloud Firestore, Cloud Storage etc PFごとに対応しているSDKが豊富 iOS, Android, Web, Flutter, Unity, C++
  29. App Checkを使うことのメリット 導入と運用の簡素化 Integrity APIや App Attestを自前 で使う場合に比べて、プラット フォームAPIの呼び出しのコードを 書かなくて済む

    Token発行や検証部分の具体実装 がプロバイダ単位で差し替え可能 になる Firebaseサービスとの親和性 コンソールで設定するだけで正規 アプリからのリクエスト以外を防 止できる Token管理の簡素化 TokenのTTL設定・ローテーション リプレイ攻撃への対策 デバッグキー管理 nonce生成, 署名検証 クライアントはgetTokenを呼ぶだ けでいい サーバーはverifyTokenを呼ぶだけ でいい
  30. App Checkの特徴 13 チェックインリクエスト with App Check Tokenを送信 14 App

    CheckTokenを検証 自社サーバー AppCheckサーバー AppCheckサーバー
  31. App Checkを使う際の留意点 完全性検証に特化 Integrity APIをフル活用したい 場合は直接の利用が必要 単一障害点になる SDKがデバイス側のOSアップ デートに依存しやすい 動作検証が大変

    不具合にも遭遇しやすい 実運用にのせる場合、バイパ ス機構の用意も検討が必要 サービス障害時 SDKの不具合 クラシックリクエスト Integrity APIのプロバイダでは クラシックリクエストが利用 されている Token発行のレイテンシが 大きい 本来Integrity API Tokenの キャッシュは避けるべき App Checkトークンの形で 端末に永続化して再利用し てしまっている Quota消費が早くなる Integrity APIは 1日10000件 App Checkは内部にトークン のTTLを持っており、定期的に ローテーションされる ex. TTL1hなら30mで 想定より早く枯渇する可能性 がある
  32. サーバーリクエスト改ざんまとめ データ保護のための基礎対策を怠らない 暗号化や難読化、秘匿情報の管理は早い段階で見直しをし てみよう OSやライブラリのバージョン更新、日々頑張っていく デバイスやアプリの完全性を担保しよう Play Integrity APIやApp Attestを使って検証ができる

    Flutterでの利用の場合は特に実装が大変 Firebase App Checkを使えばかなり手軽に導入できる それでも不正とのイタチごっこ ポイントの不正取得の観点においては、かなり不正されづら くなったはず ただ、これまでに紹介した機能やサービスも完全に不正を 検知できるとは限らない 仰々しいセキュリティ対策だけでなく、サービス特性や機能 の特徴に応じた不正対策も重要
  33. 【おさらい】 今回の不正の脅威モデリング 1日で2日分のポイント獲得 23:55にチェックインして24:05に 再度チェックインする 1回来場するだけで2回分のポイン トを獲得する 位置情報の偽造 チェックインイベント開催中にデ バイスの位置情報を偽造

    競輪場にいたことにしてポイント を獲得する サーバーリクエストの改ざん チェックイン処理のコードや通信 を解析して差し替えてリクエスト 競輪場付近の位置情報を投げてポ イントを獲得する
  34. 今回の不正の脅威モデリングの対策まとめ 1日で2日分のポイント獲得 想定される正常なユーザーさんの ユースケースを元にして機能仕様 のアップデートを検討した 位置情報の偽造 位置情報のモックに関してはロ ケーションライブラリから返却さ れるisMockedの値を確認するよう にした

    位置情報が外部から差し替えられ る不正のケースを判定し、エラー に倒すようにした サーバーリクエストの改ざん セキュリティにおける基礎対策を 施し、処理の詳細が漏れづらくし た アプリやデバイスの完全性を保証 する仕組みを導入し、正常性判定 に活用するようにした
  35. まとめ セキュリティの重要性 セキュリティは一発アウトのリス クや事業的な収益にも影響するリ スクを孕んでいる 多層防御で考える 複数の対策を組み合わせることで 攻撃者側のコストメリットを下 げ、不正リスクを下げられる 予防しすぎないこと

    色々と大変になる 動作テストが難しくなる 処理が複雑になる 障害点が増え、バグリスクも上 がる リスクに対して必要十分な対策を 今回紹介したものは比較的コスパ がいいものなので、サービス特性 や重要度に合わせてぜひ検討して みてください!
  36. Special Thanks OWASP Mobile Application Security (MAS) モバイルアプリセキュリティの業界標準を定義 セキュリティ標準(OWASP MASVS)

    弱点リスト(OWASP MASWE) 包括的なテストガイド(OWASP MASTG) Android Developers公式 ドキュメントがとても丁寧 一般的なセキュリティ知識についても触れられている セキュリティチェックリストもあるので一読をおすすめします 引用: https://mas.owasp.org/ 引用: https://developer.android.com/