I am currently implementing Android in-app payments, and am wondering what attack vectors I should look out for.

I have a simple application to view server-generated content. I want to allow the user to buy additional access in-app, and would like to know how to communicate a successful transaction to the server.

A quick summary of how Android in-app payments work:

  • The app sends the user to Android Market with the product to buy
  • The app is informed by the Market when the transaction is finished.
  • The app requests transaction information using a nonce.
  • Google sends a response to the app with the transaction record, repeating the nonce, signed with a developer-specific private key.
  • The app can check the data using the nonce and the signature (+ public key).
  • [update]: Android transactions always include a timestamp, and my app adds a GUID to identify the client. (both are in the signed transaction record)

More info here: http://developer.android.com/guide/market/billing/index.html

My current plan is to sent the full transaction record to the server, and check against the public key on the server.

Some questions I have:

  • Is my plan inherently flawed?
  • Is it preferable to generate and check the nonce server-side as well? Why is that nonce used anyway?
  • Is it necessary (preferable) to use HTTPS when communicating with the server?

I'm not protecting private or top-secret data, but I don't want to make it easy for an attacker.

  • Verification is not a web service API, it is a Android market IN_APP_NOTIFY broadcast intent. How can you verify the same on the server side?
    – Gopinath
    Dec 6, 2011 at 7:01
  • @Gopinath: The IN_APP_NOTIFY requests signed transaction information, you have to send that to the server yourself. The verification of the signature can happen wherever you want, right? Or did you mean something else?
    – beetstra
    Dec 6, 2011 at 12:36
  • May be that information gets tampered or some hacker can send similar messages. How can I ensure on my server that the sent information is valid using Google's checkout or Android makert web API. How do we validate that again on the server?
    – Gopinath
    Dec 7, 2011 at 7:16
  • You don't need Google's help on the server. Google signs the request, and you send the request as-is to your server. You check the signature on the server, and if the message is modified, the signature won't be valid.
    – beetstra
    Dec 7, 2011 at 12:09

1 Answer 1


The possible flaw I see is what you ask in your second question. It is preferable to double check everything server side and treat anything done on a client (even if coming from your own app) as untrusted. In this particular case I don't see an inherent issue, but client-side only checks open the door if a flaw is discovered down the road.

The nonce acts like a salt on the transaction, similar to how *nix systems store passwords. The nonce is used to add entropy to the value that is encrypted with your key, largely eliminating the chance that two transactions are encrypted and result in the same signature, and other similar cryptographic attacks.

I, as a paranoid, would say it is necessary to communicate in HTTPS when you're talking about money changing hands. With cleartext transmission, what's to stop me from intercepting full transaction records at my starbucks and sending them in as my own transactions, among other nasty actions?

  • Thanks for your answer; I have included a unique client ID in the transaction (GUID), which should lessen the impact of intercepting transactions, but I see your point. I accept :)
    – beetstra
    May 30, 2011 at 18:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .