クライアントアプリからの通信内容は秘匿にできない
クライアントアプリとは
クライアントアプリとは以下を指しています。
- Webアプリケーション(サイト)
- インストール型アプリケーション
- iOS/ Android/ macOS/ Windows/ Linuxなど
通信内容の盗み見
クライアントアプリがどんな通信をしているかは、パケットキャプチャツールを使うことURL Query
、HTTP Header
、HTTP 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には対応していません。
対策3-2 Android
AndroidではGoogle PlayがPlay Integrity API
という仕組みを提供しています。
対策3-3 Firebase
FirebaseではApp Checkという機能が用意されており、アクセスする際にApple PlatformであればApp Attest
を使用し、AndroidであればPlay Integrity API
を使ってくれます。
対策4(最新のOS、デバイスをサポート)
対策3のアプリの改ざんなどはOSレベルだけでなく、デバイス(CPU)レベルで対策がアップデートされています。
低いバージョンのOSや、古いCPUに脆弱性が発見され、アプリがそのOSやデバイスをサポートしていると、データを抜き取られやすくなってしまいます。
なので古いOS/デバイスをサポートしないことでセキュリティを高めることができます。
まとめ
クライアントアプリのソースコード、アプリの通信内容はユーザー本人に見られても問題ないように設計する。
- セキュアな値(API Keyなど)はクライアントアプリに持たない(ハードコーディング)
- リバースエンジニアリング出来てしまうため
- API Keyなどを使用する3rd Party APIを使用する場合、バックエンドを経由して、クライアントアプリには見えないようにする
- 通信内容は見えてしまうため
- 本人しか利用できないバックエンド EndPointはユーザー認証(JWT)を必須に
- 他人に個人情報などがアクセスされてしまうため
- 改ざんされたクライアントアプリからのリクエストは検知できるようにする
- 改ざんアプリにユーザー認証(JWT)を盗まれて、個人情報を盗まれてしまうため
- 古いOS/デバイスはサポートしない
Discussion