A day after the Mac App Store was launched, people are reporting that it has been cracked. There are two separate stories here, a vapourware circumvention of the FairPlay DRM used to generate the receipts and a report that certain apps aren’t validating the receipts properly. We can ignore the first case for the moment: it’s important, and if it’s true then Apple needs to fix it (and co-ordinate updating the validation code with us third-party developers). But for the moment, it’s more important that developers are implementing the protections that are in place in their applications – it’s those applications that are supposed to be protected.
Let’s skip, for the moment, the question of whether DRM or anti-cracking mechanisms are ethically right, worthwhile, or how much effort you want to put into them. Apple have done most of the legwork, in providing a vendor-signed receipt that’s part of your signed app bundle. What you need to do is:
- Check whether you have a receipt
- Check whether Apple signed the receipt you have
- Check whether the receipt is valid for your product
- Check whether the receipt is valid for this version of your product
- Check whether the receipt is valid for this computer
That’s it in a nutshell. Of course, some nutshells surround very big and complex nuts, and that’s true in this case:
- There’s some good example code for receipt validation at github/roddi/ValidateStoreReceipt, if you’re going to use it then don’t just paste it wholesale. If everyone uses the same code then it’s super-easy for someone to detect and strip that code from each instance.
- Check at runtime, as well as before startup. If you just check at startup, then all an attacker needs to do is patch main() to jump straight into NSApplicationMain() and your app runs for free.
- Code obfuscation is not a very effective tool. Having worked in anti-virus, I know it’s much easier to classify code based on what it does than what it is, and it’s quite easy to find the code that opens the receipt file, or calls exit(173). That said, some of the commercial obfuscation companies offer a guaranteed service, so you can still protect your revenue after the app gets cracked.
- Update I have been advised privately and seen in a blog post that people are recommending hard-coding their app bundle IDs and version numbers into the binary rather than using Info.plist, because that file can be edited. Well, so can the app binary…and in either case you’d need to re-sign the product with a valid certificate to continue, because Apple have used the kill flag:
heimdall:~ leeg$ codesign -dvvvv /Applications/Twitter.app/ Executable=/Applications/Twitter.app/Contents/MacOS/Twitter Identifier=com.twitter.twitter-mac Format=bundle with Mach-O universal (i386 x86_64) CodeDirectory v=20100 size=12452 flags=0x200(kill) hashes=616+3 location=embedded CDHash=8e0736639d79a108a5a1ebe89f928d1da0d49d94 Signature size=4169 Authority=Apple Mac OS Application Signing Authority=Apple Worldwide Developer Relations Certification Authority Authority=Apple Root CA Info.plist entries=21 Sealed Resources rules=4 files=78 Internal requirements count=2 size=344
Changing a hard-coded string in a binary file is not difficult. You can of course obfuscate the string, but the motivated cracker still finds the point where the comparison is made (particularly easily if you use NSStrings). Really, how far you want to go depends on how much you’re willing to spend.
Of course, Fuzzy Aliens Ltd has already been implementing receipt validation for customers, so if this is too hard for you or you don’t have the time… 😉
A last word on publicising receipt-validation vulnerabilities
You and I both make our living by selling software, or by selling services to people who sell software. Crowing on the interwebs about how this application or that application doesn’t validate its receipts properly is not cool, because you are shitting on your own doorstep. There is no public benefit to public disclosure that class of vulnerability, because DRM is not a user security feature. Don’t do that. Send the developer a private message explaining your findings. Give them a chance to put extra effort into protecting their product, if that’s what they want to do.