4

I have android app with subscription in-app purchase. Because I am using the subscription to deliver data from online service, I am using verification of purchase on server side via google play API (with purchase token the app send me after purchase). Majority of purchase tokens in my database are long alphanumeric strings, something like this :

djcbhbiertdkkotyuupnlmioppb.AO-J1Ozg0oasdfB3MAlWy-PihFE_nPVRMMfTW2_VPJt5KTKQA3CXNwyqweJAtUdIGTuOW9zEIIy-XS_4Un-a-Co6aEs__Adj1rZ4GtRxPKr04ph-l6nP2sU-w6e500YfTj5l0O8WEXF37yt

and these are verified OK. But from time to time I receive purchase tokens containing just 15 digits, like this :

781871156762279

And for these the result it always:

Google.GoogleApiException Google.Apis.Requests.RequestError
The purchase token was not found. [404]
Errors [
    Message[The purchase token was not found.] Location[token - parameter] Reason[purchaseTokenNotFound] Domain[global]
]

I did not find anything about this in documentation. Am I missing something? Or could it be these are "fake" purchases from some cracked version of my app? Thanks.

savanto
  • 4,470
  • 23
  • 40
rouen
  • 5,003
  • 2
  • 25
  • 48
  • Unless you have some mechanism in your app of checking the `classes.dex` file via an embedded SHA1 or MD5 hash, then it's hard to know whether your app has been cracked and/or the in-app token is a fake sent from the cracked version of your app. – ChuongPham Sep 16 '14 at 08:21

1 Answers1

3

I have received short purchase tokens in the same 15-digit format, and I believe that these are, in fact, attempts at fraudulent purchases.

It is not your app that is cracked. Rather, a user installs a special app onto a rooted device that performs a man-in-the-middle attack against your app, emulating the legitimate In-App Billing Service. When your app begins a purchase flow, this fraudulent app intercepts the purchase request, and returns a fake purchase token.

Apps that verify the token locally are vulnerable, because the same fraudulent app is used to verify the token.

Apps that send the token to the backend are probably safer, because the backend can make a request to the in-app billing API to verify the token independently. However, the app must wait for the backend verification to succeed before granting the user the purchased privileges.

Please see my other answer for more details on this attack.

Community
  • 1
  • 1
savanto
  • 4,470
  • 23
  • 40