Receipt Validation

Does Corona validate the receipt that is returned from Apple/Google or do I need to do that? I am dealing with one time in app purchases, but I have heard of programs that basically send fake receipts when apps attempt to contact the store.

I found this info on the apple website regarding the problem: https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateLocally.html#//apple_ref/doc/uid/TP40010573-CH1-SW2

But it occurred to me that the store* api might already be handling this since it would be a problem that everyone would have.

You have to validate them.

Rob

Is the event.transaction the receipt sent by Apple or is that something that is derived from the receipt?

I tried to iterate over event.transaction with a generic for loop and print its contents and that didn’t work. This suggests that it isn’t a LUA table. I’m a little confused about what it is. I’m also confused about how I can pull data out of it by using dot notation, like transaction.receipt. It’s basically acting like an object but Apple doesn’t send you an object it sends data encoded with ANS.1.

I’m still on the step of verifying that the receipt came from Apple by checking the signature on the receipt.

Ok, it just occurred to me that the event.transaction is probably the parsed receipt. Is that right? If that is the case, all I need to do is see if the transaction.productIdentifier is one of my products. Is that right?

If you look at the docs (for instance: http://docs.coronalabs.com/api/library/store/purchase.html) you will see that event.transaction is a lua table with the following members:

.state

.productIdentifer

.receipt

.identifer

.date

Google IPA V3 might return more, but those are the core items.  State will be something like"purchased", “cancelled”, etc.  .productIdentifier is the unique item ID you gave to the store to ID.   .receipt is a big long Base64 encoded string of binary data if my memory is correct.   You can save that receipt when you get it and the compare it later using standard Lua string comparators to see if they are the same.

Rob

I read the documentation, the question I am asking is not in the documentation. I did what is in the documentation, I implemented and tested making in app purchases in my app, it works. That is not the problem.

 

If you look at this video you will see that apparently there is a way to trick apps into giving you in app purchases:

 

 

I am trying to fight this.

 

The link in my first post is Apple’s explanation of how to verify if the receipt is valid or fraud. However, it requires C code to process the receipt which I don’t know how to do. The reason I use Corona is largely because I don’t know how to program in a lower level language like C. Furthermore, it seems kind of pointless to write security code in Lua because Lua is fairly easy to decompile and read.

 

One of the key reasons to be a Pro Subscriber is to have access to the in app purchases api. It doesn’t really help to enable me to create a store that has no lock on the door. I have a dead bolt lock on my house but I didn’t make it. I bought it. I even installed it, but I didn’t make it. I want the same kind of relationship with Corona. I will install the lock, but I need Corona to make it.

 

What I’m asking for is instructions on how to lock the door to my new store when using Corona SDK.

The method in the video requires jail broken phones to work.  I don’t know what % of phones are jail broken, but it’s probably not all that high.  I’ll ask Engineering to see what can be done.

Rob

For it to work with any app it would have to be faking a receipt. There is no way they are getting specific information about every app.

Apple says they sign their receipts in a way that would be hard to fake. It is possible that these people have been able to fake the signing but it is more likely that receipts are not being properly scrutinized by the app after they are returned. Especially since the comments below the video say it doesn’t work on all apps.

I noticed that they instruct the user to cancel the transaction when they get to the point of purchase. They are probably intercepting the purchase request, decoding it, getting the product ID and then building a quick and dirty fake receipt and sending it back to the app to see if they can trick it.

I googled around and it seems that the most common answer to how many phones are jailbroken are around 10%.  Of that 10%, only a portion 10% is going to be trying to get things for free.  It’s an effort vs. gain issue.  Anyway I’ve asked Engineering.  One early response was Android based and there the receipt is validated against the license key that you provide in the config.lua.

Rob

You have to validate them.

Rob

Is the event.transaction the receipt sent by Apple or is that something that is derived from the receipt?

I tried to iterate over event.transaction with a generic for loop and print its contents and that didn’t work. This suggests that it isn’t a LUA table. I’m a little confused about what it is. I’m also confused about how I can pull data out of it by using dot notation, like transaction.receipt. It’s basically acting like an object but Apple doesn’t send you an object it sends data encoded with ANS.1.

I’m still on the step of verifying that the receipt came from Apple by checking the signature on the receipt.

Ok, it just occurred to me that the event.transaction is probably the parsed receipt. Is that right? If that is the case, all I need to do is see if the transaction.productIdentifier is one of my products. Is that right?

If you look at the docs (for instance: http://docs.coronalabs.com/api/library/store/purchase.html) you will see that event.transaction is a lua table with the following members:

.state

.productIdentifer

.receipt

.identifer

.date

Google IPA V3 might return more, but those are the core items.  State will be something like"purchased", “cancelled”, etc.  .productIdentifier is the unique item ID you gave to the store to ID.   .receipt is a big long Base64 encoded string of binary data if my memory is correct.   You can save that receipt when you get it and the compare it later using standard Lua string comparators to see if they are the same.

Rob

I read the documentation, the question I am asking is not in the documentation. I did what is in the documentation, I implemented and tested making in app purchases in my app, it works. That is not the problem.

 

If you look at this video you will see that apparently there is a way to trick apps into giving you in app purchases:

 

 

I am trying to fight this.

 

The link in my first post is Apple’s explanation of how to verify if the receipt is valid or fraud. However, it requires C code to process the receipt which I don’t know how to do. The reason I use Corona is largely because I don’t know how to program in a lower level language like C. Furthermore, it seems kind of pointless to write security code in Lua because Lua is fairly easy to decompile and read.

 

One of the key reasons to be a Pro Subscriber is to have access to the in app purchases api. It doesn’t really help to enable me to create a store that has no lock on the door. I have a dead bolt lock on my house but I didn’t make it. I bought it. I even installed it, but I didn’t make it. I want the same kind of relationship with Corona. I will install the lock, but I need Corona to make it.

 

What I’m asking for is instructions on how to lock the door to my new store when using Corona SDK.

The method in the video requires jail broken phones to work.  I don’t know what % of phones are jail broken, but it’s probably not all that high.  I’ll ask Engineering to see what can be done.

Rob

For it to work with any app it would have to be faking a receipt. There is no way they are getting specific information about every app.

Apple says they sign their receipts in a way that would be hard to fake. It is possible that these people have been able to fake the signing but it is more likely that receipts are not being properly scrutinized by the app after they are returned. Especially since the comments below the video say it doesn’t work on all apps.

I noticed that they instruct the user to cancel the transaction when they get to the point of purchase. They are probably intercepting the purchase request, decoding it, getting the product ID and then building a quick and dirty fake receipt and sending it back to the app to see if they can trick it.

I googled around and it seems that the most common answer to how many phones are jailbroken are around 10%.  Of that 10%, only a portion 10% is going to be trying to get things for free.  It’s an effort vs. gain issue.  Anyway I’ve asked Engineering.  One early response was Android based and there the receipt is validated against the license key that you provide in the config.lua.

Rob