Validate your in-app purchase receipts
By Miha Hribar | | 3 minute read
I’ve been keeping an eye on the Russian hack reported a while ago. Recently I wanted to see how widespread the hack was on Toshl for iPhone and was startled by what I saw.
About 30% of all in-app purchases on
— Miha Hribar (`mihahribar) August 28, 2012`toshl are attempts using the Russian hack from a couple of weeks ago. Validate your receipts.
I did take into account the number of duplicated requests by folks that tried the same hack a couple of times, but still it appears that the hack is more widespread than I first thought. Toshl was not affected by the hack, because we do our receipt validation on the server-side, but seeing the number of attempts piqued my curiosity.
How the hack works
Since I am a registered iOS developer this line is a prerequisite: “The first rule of iOS hacks is you do not talk about iOS hacks”. But in the spirit of learning and better protecting your apps in the future, some research is warranted. Here is what this hack does at a high level:
- Installs a new Certificate Authority (CA) which enables the hacker to install a certificate that fools
StoreKit
into thinking it is connecting to the correct App Store server. - When a new in-app purchase request is made, instead of going to Apple servers, a custom DNS redirects the request to a fake server which returns a valid receipt for every request.
How to protect yourself client side
When the hack was detected Apple quickly notified it’s developers, amending the documentation and releasing this sample code. The main points for avoiding this hack seem to be:
- Make sure the SSL certificate used to connect to the App Store server is valid.
- Make sure the information returned from validation matches the information in the SKPayment object - check that the
product_id
is one you are expecting. - Make sure the new transactions have a unique
transaction_id
.
The documentation states that the hack does not work in iOS6, so I guess all the verification steps have been included in StoreKit
itself, which makes you wonder why this was not done in the first place.
How to protect yourself server side
Having the receipt verified server-side does not make you completely immune to the hack. While you are connecting to the correct server for verification (unless your network was compromised as well), the receipt returned from the fake App Store server is in fact a valid transaction that can be restored, so additional steps need to be taken:
- Make sure the information returned from validation matches the information in the SKPayment object - check that the
product_id
is one you are expecting. - Make sure the new transactions have a unique
transaction_id
. This step is required if the hack is modified for your application and the restorable payment is one that was in fact captured by your application.
Conclusion
Since it will take a couple of years before all iOS 5.x versions are gone from this world, SSL verification will remain a key for preventing this hack on the client side and keeping track of the product_id
and tranaction_id
on the server side.