Does Apple really log every app you run? A technical look

November 14, 2020 • edited November 18, 2020

Apple’s launch of macOS Big Sur was almost immediately followed by server issues which prevented users from running third-party apps on their computers. While a workaround was soon found by people on Twitter, others raised some privacy concerns related to that issue.

What is OCSP?

OCSP stands for Online Certificate Status Protocol1. As the name implies, it is used to verify the validity of a certificate without having to download and scan large certificate revocation lists. macOS uses OCSP to make sure that the developer certificate hasn’t been revoked before an app is launched.

As Jeff Johnson explains in his tweet above, if macOS cannot reach Apple’s OCSP responder it skips the check and launches the app anyway - it is basically a fail-open behaviour. The problem is that Apple’s responder didn’t go down; it was reachable but became extremely slow, and this prevented the soft failure from triggering and giving up the check.

It is clear that this mechanism requires macOS to contact Apple before an app is launched. The sudden public awareness of this fact, brought about by Apple’s issues, raised some privacy concerns and a post from security researcher Jeffrey Paul2 became very popular on Twitter. He claims that

In the current version of the macOS, the OS sends to Apple a hash (unique identifier) of each and every program you run, when you run it.

That would be creepy indeed.

To make things worse, it is common for OCSP to use HTTP - I’m talking about good old plaintext HTTP on port 80, none of that HTTPS rubbish. There is usually a good reason for this, that becomes especially clear when the OCSP service is used for web browsers: preventing loops. If you used HTTPS for checking a certificate with OCSP then you would need to also check the certificate for the HTTPS connection using OCSP. That would imply opening another HTTPS connection and so on.

Of course while OCSP does not mandate encryption, it does require that responses are signed by the server. This still doesn’t solve the initial concern that anyone with a traffic analyzer on your network could eavesdrop every app you open and when you open it.

Diving deeper

Knowing some OCSP basics, more questions arise. OCSP is about checking certificates; why should this have anything to do with sending out hashes of apps you run? Does macOS really compute the hash of each executable at each launch? What about very large ones? That would take a significant amount of time; is it possible that nobody noticed? Maybe the hash is computed only once (e.g. the first time you run the app) and it is stored somewhere. But I’m not convinced and I think these claims needs more research.

Capturing a OCSP request is as easy as setting up an HTTP proxy or starting Wireshark. No HTTPS means no encryption, no certificate pinning, no problems whatsoever. I captured the following request while opening Firefox.

GET /ocsp-devid01/ME4wTKADAgEAMEUwQzBBMAkGBSsOAwIaBQAEFDOB0e%2FbaLCFIU0u76%2BMSmlkPCpsBBRXF%2B2iz9x8mKEQ4Py%2Bhy0s8uMXVAIIBseUIWx6qTA%3D HTTP/1.1
Host: ocsp.apple.com
Accept: */*
User-Agent: com.apple.trustd/2.0
Accept-Language: it-it
Accept-Encoding: gzip, deflate
Connection: keep-alive

I should also add that after closing Firefox and opening it again, no requests were made. This is reasonable, and indicates that certificate checking isn’t performed at each launch but only after it hasn’t been performed for a certain period of time.

The request is a very simple GET that contains the payload as a base64-encoded string. The actual binary data can be easily dumped to a file:

echo 'ME4wTKADAgEAMEUwQzBBMAkGBSsOAwIaBQAEFDOB0e/baLCFIU0u76+MSmlkPCpsBBRXF+2iz9x8mKEQ4Py+hy0s8uMXVAIIBseUIWx6qTA=' | base64 --decode > output.bin

We obtain an 80-byte-long payload that looks nothing like a hash. Sure enough, it isn’t. We can use OpenSSL to extract readable information from the binary file.

openssl ocsp -text -reqin output.bin
OCSP Request Data:
    Version: 1 (0x0)
    Requestor List:
        Certificate ID:
          Hash Algorithm: sha1
          Issuer Name Hash: 3381D1EFDB68B085214D2EEFAF8C4A69643C2A6C
          Issuer Key Hash: 5717EDA2CFDC7C98A110E0FCBE872D2CF2E31754
          Serial Number: 06C794216C7AA930

Update: November 18, 2020

While the payload itself is not a hash, we can see that it does contain two hashes: Issuer Name Hash and Issuer Key Hash. I’ll take care of them later, but meanwhile you can easily verify by yourself that those are static values that never change between applications.

It is clear that the trustd service on macOS doesn’t send out a hash of the apps you launch. Instead, it just sends information about some certificate - as we would certainly expect after understanding what OCSP is in the first place.

Well, this does not solve the problem, does it? If each app has a unique certificate, then it would still be possible to create a table that associates each serial number to the corresponding app, and thus this would still be a privacy concern. Let’s check if this is the case.

Developer certificates…

First of all I would like to determine from which certificate this information comes from. I used Apple’s codesign utility to extract certificates from the Firefox app in order to look for matching data.

codesign -d --extract-certificates /Applications/Firefox.app

This command results in several files being created with names codesign0, codesign1, etc. The first one is the leaf certificate, while others belong to the certificate chain up until the root. codesign0 should be what we are looking for, and once again we can use OpenSSL to extract some info about it.

openssl x509 -inform der -in codesign0 -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 488521955867797808 (0x6c794216c7aa930)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=Developer ID Certification Authority, OU=Apple Certification Authority, O=Apple Inc., C=US
        Validity
            Not Before: May  8 19:08:58 2017 GMT
            Not After : May  9 19:08:58 2022 GMT
        Subject: UID=43AQ936H96, CN=Developer ID Application: Mozilla Corporation (43AQ936H96), OU=43AQ936H96, O=Mozilla Corporation, C=US
        ...

Check the serial number we got (0x6c794216c7aa930) and compare it with the payload of the OCSP request. We have a match! This proves that OCSP requests actually send out information about the app developer certificate.

Update: November 18, 2020

At this point we can easily understand the meaning of Issuer Name Hash and Issuer Key Hash in the OCSP request payload and why they never change. The keyword here is “Issuer”. Who issues developer certificates? Apple, of course. And in fact those are, respectively, a hash of Apple’s certificate name and of Apple’s certificate key.

…and their generality

“So what?” you might ask. Well, developer certificates aren’t unique for each app. Once again, don’t take my word for it. We can quickly verify this by checking the certificate of a different app from Mozilla, say Thunderbird.

codesign -d --extract-certificates /Applications/Thunderbird.app
openssl x509 -inform der -in codesign0 -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 488521955867797808 (0x6c794216c7aa930)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=Developer ID Certification Authority, OU=Apple Certification Authority, O=Apple Inc., C=US
        Validity
            Not Before: May  8 19:08:58 2017 GMT
            Not After : May  9 19:08:58 2022 GMT
        Subject: UID=43AQ936H96, CN=Developer ID Application: Mozilla Corporation (43AQ936H96), OU=43AQ936H96, O=Mozilla Corporation, C=US
        ...

That’s exactly the same certificate used for Firefox (of course it is!). So Jeffrey Paul’s analysis isn’t quite accurate - at least for what concerns these parts (emphasis mine).

The OS sends to Apple a hash (unique identifier) of each and every program you run, when you run it.

[An IP address] allows for a table that has the following headings: Date, Time, Computer, ISP, City, State, Application Hash

[This means that Apple knows] what apps you open there, and how often. They know when you open Premiere over at a friend’s house on their Wi-Fi, and they know when you open Tor Browser in a hotel on a trip to another city.

macOS does actually send out some opaque3 information about the developer certificate of those apps, and that’s quite an important difference on a privacy perspective.

A word about notarization

I would like to clarify something that is probably at the root of this misunderstanding. In fact, there exists a situation where macOS can actually send Apple the hash of an executable, and that is when Gatekeeper checks if a notarization ticket exists on Apple’s servers upon first launch, in case the ticket isn’t stapled to the app4.

This has nothing to do with OCSP. It happens under specific circumstances and the check is performed via a secure (HTTPS) endpoint located at api.apple-cloudkit.com. During this process, a pop-up with a progress bar is shown to the user.

About blocking OCSP

As you probably have already learned during Apple’s OCSP responder outage, you can block OCSP requests in several ways, the most popular ones being Little Snitch5 and editing your /etc/hosts file. Personally, I wouldn’t suggest doing that as it prevents an important security feature from working.

Now that you know the actual facts, if you think your privacy is put at risk by this feature more than having potential undetected malware running on your system, go ahead. Otherwise, don’t bother.

If you use macOS Big Sur, blocking OCSP might not be as trivial. Before crying conspiracy, however, keep in mind that common users are generally not able to fully understand and evaluate the impact of disabling such a complex and delicate security feature on their computer.

TL;DR

  • No, macOS does not send Apple a hash of your apps each time you run them.
  • You should be aware that macOS might transmit some opaque3 information about the developer certificate of the apps you run. This information is sent out in clear text on your network.
  • You shouldn’t probably block ocsp.apple.com with Little Snitch or in your hosts file.

  1. https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol ↩︎

  2. https://sneak.berlin/20201112/your-computer-isnt-yours/ ↩︎

  3. The term opaque means the information is just a reference that requires external context in order to be meaningful. In other words, it is not possible to infer anything useful just by looking at it. ↩︎ ↩︎

  4. https://eclecticlight.co/2020/08/28/how-notarization-works/ ↩︎

  5. https://obdev.at/products/littlesnitch/index.html ↩︎

macosappleprivacy
Share this post:

SPID and Google Authenticator: When Interoperability Is Intentionally Impeded

Vulnerabilities in ATM Milano's mobile app