{"id":2737,"date":"2012-07-22T20:33:10","date_gmt":"2012-07-22T23:33:10","guid":{"rendered":"http:\/\/brockerhoff.net\/blog\/?p=2737"},"modified":"2012-07-22T21:47:43","modified_gmt":"2012-07-23T00:47:43","slug":"checking-receipts-on-os-x","status":"publish","type":"post","link":"https:\/\/brockerhoff.net\/blog\/2012\/07\/22\/checking-receipts-on-os-x\/","title":{"rendered":"Checking receipts on OS X"},"content":{"rendered":"<p>Recently someone figured out an <a href=\"http:\/\/arstechnica.com\/security\/2012\/07\/ios-in-app-purchase-service-hacked\/\" target=\"_blank\">attack against in-app purchasing on iOS<\/a>. Only a few days later Apple, with commendable speed, put up a page detailing how to counter this crack by <a href=\"https:\/\/developer.apple.com\/library\/ios\/#releasenotes\/StoreKit\/IAP_ReceiptValidation\/_index.html#\/\/apple_ref\/doc\/uid\/TP40012484\" target=\"_blank\">implementing better receipt checking<\/a>.<\/p>\n<p>Now there&#8217;s news that <a href=\"http:\/\/www.forbes.com\/sites\/adriankingsleyhughes\/2012\/07\/21\/ios-in-app-purchase-hack-extended-to-include-mac-app-store-apps\/\" target=\"_blank\">a similar attack also works on OS X<\/a>. For this, users have to install two bogus certificates, point their DNS at the cracker&#8217;s server, and run an auxiliary application while making the in-app purchase; this builds an apparently valid receipt inside the application bundle. (Of course this means that the user is trusting those certificates, that server <em>and<\/em> that application to be otherwise innocuous &#8211; not a good policy! And it asks you for your admin password while you&#8217;re connected to that server, too&#8230;)<\/p>\n<p>So how to implement better receipt checking on the Mac? The details are different, in that OS X in-app receipts are stored inside the application bundle, inside the application&#8217;s original receipt from the Mac App Store. Furthermore this receipt has a known format and is signed by 3 certificates:<\/p>\n<ul>\n<li>&#8220;Mac App Store Receipt Signing&#8221; (SHA1:\u00a04A 7B 3A 17 00 A4 DA 4A D4 EA 43 3A 83 61 43 2E CF 1C A1 AF)<\/li>\n<li>&#8220;Apple Worldwide Developer Relations Certificate&#8221; (SHA1:\u00a009 50 B6 CD 3D 2F 37 EA 24 6A 1A AA 20 DF AA DB D6 FE 1F 75)<\/li>\n<li>and the &#8220;Apple Root CA&#8221; (SHA1:\u00a061 1E 5B 66 2C 59 3A 08 FF 58 D1 4A E2 24 52 D1 98 DF 6C 60)<\/li>\n<\/ul>\n<p>the latter can be found, of course, inside every Mac user&#8217;s System Keychain. All this was easily obtained with my <a href=\"\/RB\/AppCheckerLite\" target=\"_blank\">RB App Checker Lite<\/a> utility (ahem). \ud83d\ude42<\/p>\n<p>Apple&#8217;s <a href=\"https:\/\/developer.apple.com\/library\/mac\/#releasenotes\/General\/ValidateAppStoreReceipt\/_index.html\" target=\"_blank\">currently recommended receipt verification code<\/a>, however, does not contain any recommendation to check the certificates used to sign the receipt; it does check if the receipt is for that particular application (otherwise people would just copy a receipt from another app) and if the receipt was generated on that particular computer (otherwise one could just copy the app from a friend&#8217;s computer).<\/p>\n<p>No doubt Apple will now recommend to all OS X developers that their receipt verification codes also check the certificates &#8211; and in fact, that&#8217;s what my apps are already doing. The certificates are, after all, available from the same parsing process recommended in the above link. At the very least, I recommend obtaining the SHA1 fingerprints of all 3 certificates (openssl has a SHA1() function for that) and checking them against the list above. And once that&#8217;s done, obtaining the app&#8217;s own signing certificates, and checking them, is also advisable, even if the app is signed with a Developer ID.<\/p>\n<p>I&#8217;m not giving specific code examples here, to avoid people copy&amp;pasting it into their apps and offering a clear path to hacking the binary. The usual precautions to make binary hacking more difficult (though it&#8217;ll never be impossible) apply, of course.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently someone figured out an attack against in-app purchasing on iOS. Only a few days later Apple, with commendable speed, put up a page detailing how to counter this crack by implementing better receipt checking. Now there&#8217;s news that a similar attack also works on OS X. For this, users have to install two bogus [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,19],"tags":[43,23],"class_list":["post-2737","post","type-post","status-publish","format-standard","hentry","category-dev","category-software","tag-app-store","tag-mac"],"featured_image_src":null,"author_info":{"display_name":"Rainer Brockerhoff","author_link":"https:\/\/brockerhoff.net\/blog\/author\/rbrockerhoff\/"},"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1q3Zc-I9","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/brockerhoff.net\/blog\/wp-json\/wp\/v2\/posts\/2737","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/brockerhoff.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brockerhoff.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brockerhoff.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/brockerhoff.net\/blog\/wp-json\/wp\/v2\/comments?post=2737"}],"version-history":[{"count":0,"href":"https:\/\/brockerhoff.net\/blog\/wp-json\/wp\/v2\/posts\/2737\/revisions"}],"wp:attachment":[{"href":"https:\/\/brockerhoff.net\/blog\/wp-json\/wp\/v2\/media?parent=2737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brockerhoff.net\/blog\/wp-json\/wp\/v2\/categories?post=2737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brockerhoff.net\/blog\/wp-json\/wp\/v2\/tags?post=2737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}