🗝️

クライアントアプリからの通信内容は秘匿にできない

に公開

クライアントアプリとは

クライアントアプリとは以下を指しています。

  • Webアプリケーション(サイト)
  • インストール型アプリケーション
    • iOS/ Android/ macOS/ Windows/ Linuxなど

通信内容の盗み見

クライアントアプリがどんな通信をしているかは、パケットキャプチャツールを使うことURL QueryHTTP HeaderHTTP Body(Payload)などが見れるため、その中にAPI Keyが入っているとユーザーにAPI Keyを取得されてしまいます。

ネットワークに乗る前の通信内容をキャプチャできるため、https(SSL)でも防げません。

Proxyman, Wireshark, Charles, ブラウザのDeveloper Toolなどで通信内容のキャプチャが可能です。

ここで言及している問題はインストールしたユーザーがユーザー自身の通信内容を見れることです。
第三者が通信内容を見れるものではありません。


ソースコードの漏洩

Webアプリケーションの場合、ソースコード(HTML/ JavaScriptなど)がユーザーにそのまま見えているため、API Keyなどがソースコードに入っていると、そのまま見えてしまいます。

インストール型アプリケーションは配布形式がソースコードからコンパイル/ビルドされた実行ファイル/コンテンツが配布されるため、直接は見れないが、実行ファイル/コンテンツはリバースエンジニアリングをされソースコードが見えてしまいます。

通信の再現(リプレイ)攻撃

もしユーザーAの個人情報を取得するというAPIをアプリが使っている場合、この通信をキャプチャしてAPI Keyを取得して、別のユーザーBの個人情報も見れてしまいます。

curl -H "Authorization: Bearer SECRET_API_KEY" https://api.???.com/user?id=user_a_id
curl -H "Authorization: Bearer SECRET_API_KEY" https://api.???.com/user?id=user_b_id

攻撃の例

  • 他人のSNSに投稿する
  • 他人のIDで商品を購入する

通信内容を秘匿にすることはできない

ユーザーのネットワークを使用する限り通信内容を秘匿にすることはできません。
なので見られても問題ないように構築することが重要です。

施設などの共有WiFiでは、WiFiに通信内容が載った時点でhttps(SSL)で暗号化されているので、ここで上げている問題とは別です。
https://qiita.com/ockeghem/items/c6a3602d2c2409f89fbb

対策1(アプリとAPIの間にバックエンドを挟む)

上記のようにすることで、クライアントがAPI Keyを持たずに、バックエンドがAPI Keyを持つので、ユーザーにはセキュアな情報を見せないでデータを連携することができます。

しかしユーザー認証が無いので、誰でも個人情報取得や、購入などが出来てしまいます。
ユーザー認証が必要がない商品検索なのであればバックエンドを挟むだけで問題ありません。

対策2(ユーザー認証/認可を追加)

ユーザー情報をリクエストする場合、ユーザーはログインする必要があります。
そのログインの際にユーザーIDを持ったJWT(JSON Web Token)をバックエンドで秘密鍵で発行して、ユーザーのクライアントアプリに渡します。

このJWTは他の人には発行できないため、このJWTをユーザー情報を取得するAPIに渡すことで、本人のみ個人情報を取得することが可能です。

対策3(インストール型アプリの改ざん検知)

クライアントアプリのコードが書き換えられた偽アプリをユーザーが使ってしまい、そのアプリでログインしてしまうとJWTを第三者に取られてしまい、個人情報を取られてしまう可能性があります。

しかしいくつかのプラットフォームではOS/デバイスレベルで改ざんを検知することで対策可能です。

対策3-1 Apple Platform (iOS / iPadOS/ watchOS/ tvOS/ visionOS)

Apple Platformではコード署名とApp Attestという仕組みがあり、正規のアプリからのリクエスト化が判別できるようになっています。
macOSには対応していません。

https://developer.apple.com/documentation/devicecheck/establishing-your-app-s-integrity

対策3-2 Android

AndroidではGoogle PlayがPlay Integrity APIという仕組みを提供しています。

https://developer.android.com/google/play/integrity/overview

対策3-3 Firebase

FirebaseではApp Checkという機能が用意されており、アクセスする際にApple PlatformであればApp Attestを使用し、AndroidであればPlay Integrity APIを使ってくれます。

https://firebase.google.com/docs/app-check

対策4(最新のOS、デバイスをサポート)

対策3のアプリの改ざんなどはOSレベルだけでなく、デバイス(CPU)レベルで対策がアップデートされています。
低いバージョンのOSや、古いCPUに脆弱性が発見され、アプリがそのOSやデバイスをサポートしていると、データを抜き取られやすくなってしまいます。
なので古いOS/デバイスをサポートしないことでセキュリティを高めることができます。

まとめ

クライアントアプリのソースコード、アプリの通信内容はユーザー本人に見られても問題ないように設計する。

  1. セキュアな値(API Keyなど)はクライアントアプリに持たない(ハードコーディング)
    • リバースエンジニアリング出来てしまうため
  2. API Keyなどを使用する3rd Party APIを使用する場合、バックエンドを経由して、クライアントアプリには見えないようにする
    • 通信内容は見えてしまうため
  3. 本人しか利用できないバックエンド EndPointはユーザー認証(JWT)を必須に
    • 他人に個人情報などがアクセスされてしまうため
  4. 改ざんされたクライアントアプリからのリクエストは検知できるようにする
    • 改ざんアプリにユーザー認証(JWT)を盗まれて、個人情報を盗まれてしまうため
  5. 古いOS/デバイスはサポートしない

Discussion