Thursday, December 22, 2016

Encoding? Compression? You tell me...

In HTTP, there are two ways to specify compression of the content:

  • Content-Encoding:gzip
  • Transfer-Encoding:gzip
Amazing discovery of the day: command-line cURL, as of v.7.21.6, recognizes both, while the cURL functions in PHP, as of PHP 5.3.3, only respect the former.

Tuesday, December 20, 2016

Strikes again

Just a few days after I wrote about the in-app purchase simulator, someone tried it again. Not that they've succeeded; the server-side order signature check caught it. But the device-side check didn't. I'm really wondering how'd they do that.

Here's the first step: I'm going to try reimplementing the signature check by hand, and see if the fake order passes that. I suspect the IAP simulator taps into Java's built-in Signature.verify() method, making it return a hard-coded true. It wouldn't know about my homegrown implementation, obviously.

The signature algorithm that Google Play uses is well known, it's SHA1 with RSA. Normally, I'd be the first one to recommend against building your own crypto primitives, but in this case, it's probably justified, at least as the first step to counteract the fraud. I can probably still use the built-in SHA1, just need to reimplement the RSA portion. The latter is a bunch of BigInteger arithmetic.




Friday, December 2, 2016

Google Play fraud

I have a freemium Android app on the Google Play store. It's free to download, but there's a paid subset of functionality. To unlock it, one may download a separate app ("The License App"), or pay with an in-app purchase (IAP).

Such a scheme is open to many avenues of abuse. I'll try to outline some of those, and discuss the ways to combat them.