Google Play は、ユーザーとデベロッパーの両方の安全性を確保することに尽力しています。収益性の高いアプリビジネスを構築するには、信頼できるプラットフォームが不可欠です。信頼できるプラットフォームとは、悪意のあるユーザーからプロアクティブに防御することで、投資収益率を確保できるプラットフォームです。
このドキュメントでは、課金の統合に対する攻撃を防止し、アプリの不正使用による影響を低減するための推奨事項について説明します。
保護を強化する
次の API とツールは、アプリのリスクを軽減できます。
- Voided Purchases API: 無効な注文へのアクセスを取り消します。
- 難読化されたアカウント ID: 短期間に複数のデバイスで同じアカウントを使用して購入が行われたかどうかを検出するのに役立ちます。
- バックエンド消費: Purchases.products:consume などのツールは、ビジネス ロジックを安全なバックエンドに移行し、クライアントサイドの改ざんを防ぎます。これらのプラットフォーム API を使用するだけでなく、次のベスト プラクティスを採用して、不正アクセスに対する統合のセキュリティを強化してください。
位置情報のなりすましを防止する
Google Play には、悪意のあるユーザーが偽の位置情報を使用して地域間の通貨の差を利用したり(位置情報のスプーフィングとも呼ばれます)、定期購入のプロモーションやインセンティブを不正使用したり、ギフトカード詐欺を試みたりすることを防ぐための保護機能が組み込まれています。
機密性の高いロジックをバックエンドに移動する
機密性の高いデータとロジックは、アプリの設計で許容できる限り、自分で管理するバックエンド サーバーに移動します。フロントエンド デバイス上にあるデータとロジックが多いほど、変更や改ざんといった攻撃を受ける可能性が高まります。
たとえばオンラインのチェスゲームでは、フロントエンドから送信される駒の動きを信用せずに、すべての動きをバックエンドで検証する必要があります。
さらに、脆弱性やセキュリティ上の問題が見つかった場合、システムの設計によっては、デバッグ、修正、アップデートのデプロイをフロントエンドよりもバックエンドで行うほうが簡単な場合があります。
利用権を付与する前に購入を確認する
機密性の高いデータとロジックをバックエンドで処理すべき特別なケースの 1 つは、購入の確認と承認です。ユーザーが購入した後、以下の操作を行う必要があります。
- 対応する purchaseToken をバックエンドに送信します。つまり、すべての購入ですべての purchaseToken 値の記録を保持する必要があります。
- 現在の購入の purchaseToken 値が、以前のどの purchaseToken 値とも一致しないことを確認します。purchaseToken はグローバルに一意であるため、この値はデータベースの主キーとして安全に使用できます。
- Google Play Developer API で Purchases.products:get または Purchases.subscriptionsv2:get エンドポイントを使用して、購入が正当であることを Google で確認します。
- 購入が正当であり、過去に使用されたことがない場合は、アプリ内アイテムや定期購入に対する利用権を安全に付与できます。
- 定期購入に関しては、Purchases.subscriptionsv2:get で linkedPurchaseToken が設定された場合、データベースから linkedPurchaseToken を削除し、linkedPurchaseToken に付与されている利用権を取り消して、複数のユーザーが同じ購入を行うことができないようにする必要もあります。
- 購入ステータスが PURCHASED の場合にのみ利用権を付与し、PENDING の購入を正しく処理してください。CANCELED の購入が急増している場合は、購入ステータスがまだ PENDING のときに利用権を付与している可能性があります。詳細については、保留中の取引の処理をご覧ください。
利用権を付与した後、消費型アイテムを使用および承認する場合は、安全なバックエンド サーバーで Play Developer API の Purchases.products:consume を使用します。非消費型アイテムまたは定期購入を承認するには、安全なバックエンド サーバーの Purchases.products:acknowledge または Purchases.subscriptions:acknowledge のいずれかの Play Developer API エンドポイントを呼び出します。承認は、ユーザーに購入の利用権が付与されたことを Google Play に通知するために必須です。利用権を付与したら、すぐに購入を承認する必要があります。
購入の承認または消費は、アプリを介してクライアントサイドでも処理できますが、サーバーサイドの API を使用した方が、ネットワーク接続の障害、悪意のあるアクティビティといった問題に対する保護を強化できます。たとえば、ユーザーがアプリのアイテムを購入したものの、購入の検証中にネットワーク接続が切断されたとします。サーバーサイドの承認を使用していなければ、このような場合、ユーザーがアプリに再度ログインしないと承認プロセスが完了しない可能性があります。ユーザーが 3 日以内に再度ログインしなかった場合は購入が承認されないため自動的に払い戻しが行われます。サーバーサイドの承認では、サーバーは Google Play から購入有効の通知を受け取るとすぐに承認を送信するので、このようなケースを防止できます。
購入の承認と消費についての詳細は、購入を処理するをご覧ください。
ロックフリー コンテンツを保護する
悪意のあるユーザーによってロックフリー コンテンツが再配信されるのを防ぐために、APK ファイル内にバンドルしないようにします。代わりに、次のいずれかを行います。
- コンテンツ フィードなどのリアルタイム サービスを使ってコンテンツを配信する。 リアルタイム サービスを利用してコンテンツを配信することで、コンテンツを最新の状態に維持することもできます。
- コンテンツの配信にリモート サーバーを使用します。リモート サーバーやリアルタイム サービスからコンテンツを配信すると、ロックフリー コンテンツをデバイスのメモリや SD カードに保存できます。SD カードに保存する場合には、必ずコンテンツを暗号化し、デバイス固有の暗号鍵を使用してください。
取り消し済みの購入を検出して処理する
「取り消し済みの購入」とは、キャンセル、取り消し、またはチャージバックが行われた購入です。取り消し済みの購入でアプリ内アイテムやその他のコンテンツをユーザーに付与したことがある場合は、Voided Purchases API を使用して、購入が取り消された理由と、回収可能な関連コンテンツを取得できます。
アプリ内アイテムの購入と定期購入は、以下のような、さまざまな理由で取り消されることがあります。
- ユーザー、デベロッパー、Google のいずれかによって購入がキャンセルされた(承認されずに自動的にキャンセルされた購入を含む)。定期購入の場合、これは、定期購入自体のキャンセルではなく、定期購入の購入をキャンセルしたことを表します。
- 購入がチャージバックされた。
アプリ デベロッパーがユーザーの注文のキャンセルまたは払い戻しを行い、コンソールで「取り消し」オプションを有効にした。取るべき対応は、購入が取り消された理由に基づき、ユーザーの以前の行動データも考慮して決定することができます。そこで、次のうち 1 つ以上を実装することをおすすめします。
回収を行う: 購入が取り消された場合、未使用のアイテムを回収して、それらが購入されなかったようにすることができます。たとえば、ゲーム内通貨の購入が取り消された場合、ユーザーにすでに付与された通貨を回収できます。ユーザーがすでに通貨を使ってしまった場合は、通貨の残高をマイナスに設定し、通貨の残高がプラスになるまでアプリのアクティビティと今後の購入を制限することを検討してください。
複数回の違反警告を実装する: 違反が初めてのユーザーに対しては控えめな措置(アプリ内での警告の表示など)に留め、違反を繰り返すユーザーに対しては厳しい措置を取ることを検討してください。
購入を一時的に無効にする: 複数回の違反警告を実装する場合と同様に、購入が取り消された理由を詳しく調査できるようになるまで、購入を取り消したユーザーの購入を無効にすることを検討します。
アプリへのアクセスを一時的または永続的に拒否する: 悪意のあるアクティビティが繰り返し行われる極端なケースでは、アプリへのアクセスを一時的または永続的に拒否することを検討してください。
Voided Purchases API を頻繁に呼び出す: 取り消し済みの購入が 1 つ以上検出された場合、Voided Purchases API を頻繁に呼び出して、ユーザーが購入アイテムを消費する前に回収することを検討してください。Voided Purchases API の割り当てについて詳しくは、Voided Purchases API のドキュメントをご覧ください。
不正行為が行われる前に Google が検出できるようにする
不正行為の中には、悪意のあるユーザーが複数の Google アカウントとアプリ内アカウントを作成して、自分のアクティビティを隠すというものがあります。
BillingFlowParams のビルダーで setObfuscatedAccountId メソッドと setObfuscatedProfileId メソッドを使用すると、Google が Google アカウントをアプリ内アカウントにマッピングできるようになります。
Google はこのデータを使用して不審な行動を検出し、一部の不正なトランザクションを完了前にブロックします。
商標と著作権の侵害に対する措置
リモート サーバーでコンテンツの配信や管理を行っている場合、ユーザーがコンテンツにアクセスするたびに、アプリでロックフリー コンテンツの購入ステータスを確認するようにします。これにより、必要に応じて利用を取り消し、侵害行為を最小限に抑えることができます。自分のコンテンツが Google Play 上で再配信されているのを見つけた場合、速やかに断固たる措置を講じる必要があります。詳しくは、著作権ヘルプセンターの著作権に関するよくある質問をご覧ください。