今回のエンジニアブログを担当する村田です。
前回の「iOSアプリ内課金(In-App Purchase)のはまりどころ」に引き続き、アプリ内課金に関する内容です。
2012年の夏、iOS5.1以前において脱獄不要でアプリ内課金が無料になってしまう脆弱性が見つかるというニュースがありました。iOS6のシェアが8割を超える今日、この脆弱性はどのようになっているのか。
実は、iOS5.1以前の端末では、依然としてこの脆弱性を利用して脱獄することなく無料でアプリ内課金を行うことが出来てしまいます。レシートの確認をAppleのサーバーに問い合わせているから大丈夫!では無いのが現状です。
この状況に対してAppleは放置している訳ではありません。Appleから対応内容が公開されております。
In-App Purchase Receipt Validation on iOS
上記ページ右上「Companion File」からダウンロードできるソースを利用すると、アプリ側で対応することができます。ソースについての補足として
- #warningの箇所は自分で実装する必要があります。
- KNOWN_TRANSACTIONS_KEYは、UserDefaultへのKey(Transaction IDの一意性チェックに用いている)になります。
- ITC_CONTENT_PROVIDER_SHARED_SECRETは、iTunes Connect上の該当アプリの「Manage In-App Purchases」の「View or generate a shared secret」リンクをクリックすることで生成できます。
ソースに記述されているとおり、レシート情報はbase64でデコードすることでチェックが可能です。ですので、全く何の対策を行っていない場合でも、アプリの修正・審査を待たずに、サーバー側に処理を追加することで即対応できる内容もあります。以下、追加する処理内容です。
- レシートデータをbase64デコード
- "purchase-info"のデータをbase64デコード
- 以下の項目をチェック
項目 チェック内容 product-id 使用しているProduct IDのいずれかと一致しているか bid Bundle IDと一致しているか
IDなどはアプリ側で持つよりサーバー側で保持する方が安全ですので、なるべくサーバー側でチェックできるように設計しておいた方が、今後新たな脆弱性が発見された場合でも、即対応できて良いと思います。