iosapp-storereceipt-validation

Validate App Store Receipt: Local vs Server


This is for tvOS but the same would apply for iOS too. This concerns in-app purchase subscriptions (auto-renewable).

Apple says:

Warning Do not call the App Store server verifyReceipt endpoint from your app. You can't build a trusted connection between a user’s device and the App Store directly, because you don’t control either end of that connection, which makes it susceptible to a man-in-the-middle attack.

If I use my own server, how is a man-in-the-middle any harder to do? My server will send the receipt to Apple, get all the internal fields as a response but will eventually have to send a valid/invalid response back to my app that anyone could forge with a man-in-the-middle system.

So why is using an intermediate server so much better?


Solution

  • There isn’t supposed to send back a response with valid/invalid result. You should build your API architecture considering subscription benefits: backend makes a decision what content a client app will have.

    For example, you have an app with video library. Some videos are free, other available only with subscription. Backend has to send json where each video has a flag isAvailable (true/false). If a content is available, json will have URL for playing. Otherwise, there isn’t any URLs in JSON for non subscribing user, he would have only option to subscribe.

    Only backend validates a subscription receipt and decides how much content user get. Client doesn’t know anything about user’s subscription and depends only on JSON from a server. If someone tried to hack you, they would get nothing without subscription. In addition, you can use SSL pinning for protection from Man-in-the-Middle attacks (of course, it’s not ultimate solution, but you can make hacker’s lives much more harder).