Pirated In App Purchases

I know this has been discussed in the past and the response has been that it is not a problem worth worrying about but I have had my game out for almost two weeks, had 18,000 hard earned downloads with the support of some Facebook marketing and have found that around 90% of the in app purchases are being hacked.  It wouldn’t worry me too much as I know a very small % of these hacked purchases would be actual purchases, however my game is ad-supported and one of the purchases removes the ads which means zero revenue from those users.  

From my research it looks like there is a pretty simple way to do IAP receipt validation in Objective-C but I haven’t found anything that works in Corona.  Has anyone successfully implemented this recently?  I would probably start with local verification as I don’t have a server (unless something like a bluhost could be set up to do it?).

Also, it seems that in most cases the device needs to be jailbroken to hack the IAP so perhaps a simple approach is to test for files that exist in a jailbroken phone and re-enable the ads if found and block the ability to buy IAP.  Again, I have found lots of code to do this in Objective-C but haven’t seen it for Corona.  I have pasted some sample code below.  Can anyone help me translate it?  I am not sure how to check the equivalent file paths in Corona.  Many thanks!

  • (BOOL)jailbroken
    {
    NSFileManager * fileManager = [NSFileManager defaultManager];
    return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];

NSURL* url = [NSURL URLWithString:@“cydia://package/com.example.package”];
return [[UIApplication sharedApplication] canOpenURL:url];
}

The problem is that app-hackers will easily be able to get around and deactivate most checks that you put into your code.

Unfortunately it doesn’t matter how difficult you make it. The only difference is that it may take 2 days for them to find a hack instead of 2 hours.

I’ve been down this path myself when I started making mobile apps, and nowadays I don’t bother.

In the code you posted above, they would just need to do a simple string search and replace it with a bogus string that never gets found. This would fall into a “2-minute-before-hacked” category.

Thanks for the reply.  I guess my thinking is that the majority of people have no idea what they are doing and are just following generic instructions on youtube on how to hack in-app purchases and if they don’t work they will move on.  I think that if you can block those people it will cover the majority and I would be willing to accept that the true hackers will always find a way.   

Given that the jailbreak check code is going to be pretty simple has anyone already done this and can share some code?

OK. I see your point.

You might be able to use lfs to check for certain existing directories/apps that are commonly found on jailbroken devices.

http://docs.coronalabs.com/api/library/lfs/index.html

I assume you store your IAP settings in a file? One suggestion is to calculate/store a hash for that file and check the hash on every start of your app. If the hash doesn’t match you reset your file to default settings.

LFS looks like it will do the job.  In the example they use “system.DocumentsDirectory” as the directory path.  Am I able to replace this with native iOS references, i.e. “/private/var/lib/apt/”?

I store my IAP settings as variables in an ice box.  I think that uses JSON and SQL but I don’t really understand that stuff.  I know when I try to open the ice file directly it shows up as a series of numbers that are not directly editable.  I assume a hacker would be able to easily convert this though?  How do I do the hash check - that sounds like a good idea.

Also - do you know if anyone has ever developed code to implement local verification of iOS IAP receipts?  It seems pretty simple in Objective-C but I am not sure how to do it in Corona.

Thanks for your help.

I’d assume you’d use the native iOS references directly with lfs, without the use of getPathForFile().

I know very little about Ice, as I’ve never used it. You could use GGData for storing your sensitive data as is has support for automatic hash generation/checking/restoration of hacked values.

https://github.com/GlitchGames/GGData

Validating IAP in Objective-C “local” is fairly simply but I can tell you that it doesn’t work, the only thing I have found that works is using a remote server to check the receipt on apples/googles servers.

For example: IAP->Call to your server->Your server calls Apple/Google->Validates the receipt->Your server calls back to your app.

It is the only thing I have done that can avoid the IAP hack, that and having a database of hack device id’s so even if they do manage to get by I have smart logic in place on the server to reset their coins to zero :slight_smile: Just because I am a nice guy like that :slight_smile:

@ingemar, it looks like GGData is the update version of ice as both are developed by the same person.  There is also an even newer version called “Crypt” which automatically encrypts and decrypts the saved items but it requires the OpenSSL plugin which needs a pro subscription and I only have basic so will have to stay with GGData.  Are you aware of any sample code for GGData?  I have worked through the project files in Github but I am not quite sure when to call “enableIntegrityControl” - it says do it before you add any values to the box which is fine for first run but what about after the game has been played a few times?

@Christopher, Thanks.  And for the server validation do you run your own server or is there a service that can host it for you?  Any chance you are able to share the Corona code that achieves this?

Here’s a blog post by fellow Corona developer Roaming Gamer on how to use GGData.

http://roaminggamer.com/2014/06/15/secure-data-storage-for-corona-sdk/

I run my own server and the server side is all .net with sql 2014 which is where all the magic happens, the corona code is simple it is just a network.request “post” receipt (on ios) and the json data (on google) my server then calls up google or apple to verify the receipt then returns with a json string that is parsed and if validated = true then it credits whatever the inapp is otherwise it just shows a dialog that says problem with iap make sure you are connected to google (or itunes depending).

This stops most middleman attacks which accounts for about 90% of all iap hacks because what they do is pretend to be apple or google and return with a valid receipt but when you have your server check apple or google to see if it is a valid receipt it will come back with bogus because they never actually submitted anything.

I am not aware of a service that can do this, mostly because it requires setting up certificates etc. on your server that have to be passed to google and itunes but would be a cool service :slight_smile:

The problem is that app-hackers will easily be able to get around and deactivate most checks that you put into your code.

Unfortunately it doesn’t matter how difficult you make it. The only difference is that it may take 2 days for them to find a hack instead of 2 hours.

I’ve been down this path myself when I started making mobile apps, and nowadays I don’t bother.

In the code you posted above, they would just need to do a simple string search and replace it with a bogus string that never gets found. This would fall into a “2-minute-before-hacked” category.

Thanks for the reply.  I guess my thinking is that the majority of people have no idea what they are doing and are just following generic instructions on youtube on how to hack in-app purchases and if they don’t work they will move on.  I think that if you can block those people it will cover the majority and I would be willing to accept that the true hackers will always find a way.   

Given that the jailbreak check code is going to be pretty simple has anyone already done this and can share some code?

OK. I see your point.

You might be able to use lfs to check for certain existing directories/apps that are commonly found on jailbroken devices.

http://docs.coronalabs.com/api/library/lfs/index.html

I assume you store your IAP settings in a file? One suggestion is to calculate/store a hash for that file and check the hash on every start of your app. If the hash doesn’t match you reset your file to default settings.

LFS looks like it will do the job.  In the example they use “system.DocumentsDirectory” as the directory path.  Am I able to replace this with native iOS references, i.e. “/private/var/lib/apt/”?

I store my IAP settings as variables in an ice box.  I think that uses JSON and SQL but I don’t really understand that stuff.  I know when I try to open the ice file directly it shows up as a series of numbers that are not directly editable.  I assume a hacker would be able to easily convert this though?  How do I do the hash check - that sounds like a good idea.

Also - do you know if anyone has ever developed code to implement local verification of iOS IAP receipts?  It seems pretty simple in Objective-C but I am not sure how to do it in Corona.

Thanks for your help.

I’d assume you’d use the native iOS references directly with lfs, without the use of getPathForFile().

I know very little about Ice, as I’ve never used it. You could use GGData for storing your sensitive data as is has support for automatic hash generation/checking/restoration of hacked values.

https://github.com/GlitchGames/GGData

Validating IAP in Objective-C “local” is fairly simply but I can tell you that it doesn’t work, the only thing I have found that works is using a remote server to check the receipt on apples/googles servers.

For example: IAP->Call to your server->Your server calls Apple/Google->Validates the receipt->Your server calls back to your app.

It is the only thing I have done that can avoid the IAP hack, that and having a database of hack device id’s so even if they do manage to get by I have smart logic in place on the server to reset their coins to zero :slight_smile: Just because I am a nice guy like that :slight_smile:

@ingemar, it looks like GGData is the update version of ice as both are developed by the same person.  There is also an even newer version called “Crypt” which automatically encrypts and decrypts the saved items but it requires the OpenSSL plugin which needs a pro subscription and I only have basic so will have to stay with GGData.  Are you aware of any sample code for GGData?  I have worked through the project files in Github but I am not quite sure when to call “enableIntegrityControl” - it says do it before you add any values to the box which is fine for first run but what about after the game has been played a few times?

@Christopher, Thanks.  And for the server validation do you run your own server or is there a service that can host it for you?  Any chance you are able to share the Corona code that achieves this?

Here’s a blog post by fellow Corona developer Roaming Gamer on how to use GGData.

http://roaminggamer.com/2014/06/15/secure-data-storage-for-corona-sdk/

I run my own server and the server side is all .net with sql 2014 which is where all the magic happens, the corona code is simple it is just a network.request “post” receipt (on ios) and the json data (on google) my server then calls up google or apple to verify the receipt then returns with a json string that is parsed and if validated = true then it credits whatever the inapp is otherwise it just shows a dialog that says problem with iap make sure you are connected to google (or itunes depending).

This stops most middleman attacks which accounts for about 90% of all iap hacks because what they do is pretend to be apple or google and return with a valid receipt but when you have your server check apple or google to see if it is a valid receipt it will come back with bogus because they never actually submitted anything.

I am not aware of a service that can do this, mostly because it requires setting up certificates etc. on your server that have to be passed to google and itunes but would be a cool service :slight_smile: