About the Issues with Code Signing Checks in Little Snitch
A security vulnerability was recently disclosed by Josh Pitts, a security researcher at Okta. This vulnerability affects third-party macOS apps that check the code signatures of other apps by tricking them into treating a maliciously crafted fat binary as coming from Apple. You can read all the details about this in Josh’s blog post.
Because this also affects Little Snitch, Josh contacted us back in April with all the information we needed and enough time to fix this before he disclosed the issue this week. We also disclosed this as CVE-2018-10470.
Little Snitch started to verify the code signatures of apps and processes that use network connections in version 4, released almost a year ago in July 2017. Little Snitch versions 4.0 to 4.0.6 are affected by this vulnerability and Little Snitch 4.1 released yesterday fixes this issue.
Fortunately for us and our users, the consequences this has for Little Snitch are not as as bad as it first seems when reading the various headlines about this issue: What connections are allowed or denied by Little Snitch’s network filter is completely unaffected by this. The only thing that could happen is that Little Snitch would show inconsistent or incorrect information about an app’s code signature, but it would never actually allow connections that should not be allowed.
A Little More Detail
The issue discovered by Josh concerns fat binaries that contain code slices for multiple architectures (e.g. i386, x86_64, PowerPC) whereas the first architecture is signed correctly by Apple. When security tools would verify the code signature of such a fat binary, they would only check the first slice and assume that if that one is OK, the whole fat binary is OK. This means that they effectively ignore the code signature of all other slices, allowing attackers to put arbitrary code there.
What makes all this less of a problem for Little Snitch is that the actually relevant check happens in a kernel extension. Because the macOS kernel only knows about the code signatures of processes that are running, it only knows about the code signature of the correct slice. And since Little Snitch’s kernel extension uses this information to determine whether a running process has a valid code signature or not, it is completely unaffected by the issue discovered by Josh.
The parts of Little Snitch where this vulnerability manifests itself are Little Snitch Configuration, Network Monitor, and the connection alert. When these components try to verify the code signature of an app on disk, they will show incorrect information for the reasons outlined above. That’s bad, but still not as bad as you might think. Let’s play through what would happen here.
An Example
Let’s assume you have an universal app on your Mac that contains a maliciously crafted fat binary containing slices for two architectures. The first slice is signed by Apple and the second slice has no code signature. The second slice is being executed.
- You check the code signature of the app in Little Snitch Configuration and it incorrectly shows that the app is signed by Apple.
- You trust this incorrect information and create a rule that allows connections. This rule requires a valid code signature by Apple (unless you specifically opt-out of all code signature checks for that app).
- The app tries to connect.
- Little Snitch’s kernel extension sees that the rule requires a valid code signature by Apple. But the running process is based on the second slice of the fat binary and has no code signature. We call this a code signature mismatch.
- Little Snitch shows a connection alert that prominently notifies you about this mismatch. The default option in this alert is to deny any connection by the app.
The bottom line is that Little Snitch does not allow connections if you have a rule that requires a valid code signature, but the running process’ code signature does not match that.
It’s a bit different from the example above if you don’t have any rules for the app beforehand. Little Snitch will still show a connection alert for the maliciously crafted app and inform you with a big, yellow warning icon that the code signature of the running process is not valid.
In Conclusion
This issue shows once more that code signatures involve more complexity than just a cryptographic signature on a file. The code goes through many stages before it is actually executed by a CPU and the integrity of the signature must be preserved throughout all these stages. Little Snitch’s help chapter on code signature issues is a testimony to this.