2

The application is an Android client for a remote service on which all users have accounts and can make purchases of non-consumable items. Each purchase is tied to the account they were purchased on. The current purchase scheme is as follows:

  1. The client initiates the purchase with the Google Play in-app billing service. The purchase request contains the payload which uniquely identifies the account.
  2. When the purchase is successfully completed, the client gets back the purchase data which contains the payload and the purchase token. Also it has a signature for the received data which is currently not checked though.
  3. The client sends the purchase token to the server. At this point it has to be authenticated.
  4. The server receives the purchase token. The server authenticates with the Google Play service using its service account key and receives the purchase data for the given token. The data contains the original payload and the information regarding the purchase.
  5. The server validates the purchase data: it is verified that the payload matches the currently logged in user id, the purchase is not yet consumed, and has successfully been paid for.
  6. If the verification is successful, it is marked that the client has purchased the product on the server and the client receives a confirmation, otherwise the client receives a rejection.

What could go wrong with this scheme? For instance, it worries me that the signature is not used anywhere. However, I don't see what use is in it if the server receives the data directly from Google Play. At worst, it can receive a wrong token, but the payload contains the user id, so the purchase will be rejected if it has been made for another account. Sending the same token twice is also useless since the product is non-consumable: it either has been purchased or hasn't. But maybe I'm missing something here or there is some other flaw I don't see?

1
+50

I don't understand what the question really is?

I suspect your question is more, what are the signature used for, if it's never verified. And I can say here what the signature is used for: The signature is used when you have no underlying account system, and also are not using Google Account system.

In that case, you receive the signed purchase data from the Google server into app. Now comes the problem that the user could tamper with it, say they could tamper to say they purchased something they didn't purchase.

You also have no UserID to validate against, so if you only used purchase token, user could share tokens with each other.

Here is what the signature is coming into play. When you receive the data from the app/client/user, you can verify that it's untampered with, before rendering access to paid services. Also, here you can supply a random nonce with your request, that is given in the response. Since the user can't get purchase data for any other purchase than his own purchases, this effectively prevents sharing of the premium content.

Adding purchase data validation on top of your scheme would make it even more secure, but in this case, it isn't neccessary as you are validating the token against UserID.

  • I just want to find out what weaknesses can be found in the whole scheme that's all. It's not just about the signature, I just thought that I was probably missing so at least there. By the way, if there are no server-side accounts, I doubt that the signature helps much because one can easily reverse-engineer client's code and make the signature check always return true. – Malcolm Aug 7 '16 at 7:09
  • @Malcolm: With server-side account I mean where the user needs a third-party account at your server. The signature validation is useful if you provide content from the server-side, but not requiring user to register for your service, eg anyone with a valid token and valid recent signature can get content off your server. In this case you are using a account (UserID) that is then matched against the user's Google Account. Then your proposed scheme is fine. – sebastian nielsen Aug 7 '16 at 22:13
  • OK, I'm giving the bounty to you for the effort of explaining the use cases of the signature. I assume that you don't see any weaknesses in the scheme, so that answers the question perfectly. Thanks! – Malcolm Aug 11 '16 at 20:51
1

You are right, I do not see any problem in this scheme either. If Google starts lying to your server about fictive purchases I doubt a signature would help, as at that point you'd need to completely switch payment providers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.