I have implemented server-side verification Google IAP purchase tokens. My mobile app send me this token as get it from Google.
A regular token looks like
minodojglppganfbiedlabed.AO-J1OyNtpooSraUdtKlZ_9gYs0o20ZF_0ryTNACmvaaaG5EwPX0hPruUdGbE3XejoXYCYzJA2xjjAxrDLFhmu9WC4fvTDNL-RDXCWjlHKpzLOigxCr1QhScXR8uXtX8R94iV6MmMHqD
but sometimes I get a short token like this
korpimulxmslxissnschtkdb
When I verify this token via Google Play Developer API: https://www.googleapis.com/androidpublisher/v2/applications/packageName/purchases/subscriptions/subscriptionId/tokens/token, for the short token I get a 404 error.
Where is the problem? Is it possible that this short token represents real transactions?
I have been receiving these same invalid tokens in our app with no idea of the reason for a while. The tokens have come in various formats, including 24 alpha characters (eg. glvnqnpjqslcagyimgxeuybk
), 15 digits (eg. 781871156762279
, see this question), and even tokens of proper length that have a slightly different format from valid ones (eg. xdavcuvdnniwwrhwemleqjdz.rSQozm...
see this question).
These are the error messages I have received from the in-app billing API for these various tokens at one time or another:
"code": 404, "message": "The purchase token was not found."
"code": 400, "message": "Invalid Value"
"code": 400, "message": "Your request is invalid for this subscription purchase."
The answer given by Marc Greenstock gave me an idea to try to reproduce the issue.
I tested two apps that claim to hack in-app purchases: Freedom, and Lucky Patcher, on a rooted device. The former did not work: though it detected that our app can make purchases, when I tried to make a fake one it told me that "this app's purchases cannot be faked". The latter one did work after some fiddling, however, and generated a short purchase token exactly as in the question. When I tried to verify the token via the in-app billing API, I received the same exact "invalid token" message as before.
I also started logging the root status of devices generating invalid tokens using this method. While this is not proof of anything, the fact that nearly all invalid tokens originated from rooted devices made me suspect foul play.
I believe the attack works as follows. Anyone who knows more about this please chime in!
Intent
which is meant for the legitimate service