I was lucky enough to get a great tip from MalwareBytes’ Thomas Reed this week on the possibilities of code hijacking.
Thomas was kind enough to share details of a talk he gave at MacTech last year, in which he demonstrated how some 3rd party apps are susceptible to having their binaries replaced by a fake binary even when the original application is properly code signed with a valid developer’s signature.
The vulnerability lies not so much in the code signing itself, but in the mechanism for when and why it gets checked. In short, code signing is checked when an app is first launched, but after that, except in a few special situations, macOS’s security mechanisms pretty much ignore it. That means once an app has passed GateKeeper, it’s a ripe target for attackers to come in and replace the binary with one of their own.
In order to ensure the app on disk is still in fact the app that was downloaded and first launched, developers need to implement a check on each launch.
The key to it is what you specify in the entitlement constant. In this example, I’ve specified three things: that the code is signed by Apple, that is has the app’s bundle identifier and that it has the developer’s Team ID. Don’t forget to change my dummy values for your real ones in the code! You can get all these details for your app by running this in Terminal:
codesign --display -r- <path to your app>
With that information, the function verifies that the application in memory meets the requirements specified in the entitlement.
Call the function at some point after launch (e.g, when your main nib has loaded) and handle the boolean result appropriately. For example, if the function returns false, you might throw an alert like this one from DetectX Swift telling the user that the app is damaged and needs to be re-downloaded, and then terminate the app when they hit “OK”:
Let’s keep our code (and users!) safe everybody. 🙂
One of the things I find intrusive are the constant Swift Compiler warnings while I’m actually in the middle of writing a block of code (e.g, ‘…value was never used consider replacing…’). Well, yeah, it’s not been used *yet* …grrr!
However, turning off compiler warnings isn’t something I want to do either. It’s too easy to go into the build settings, turn them off, do a bit of coding, take a break, do a bit more coding…oh, three thousand lines later and I suddenly realize why Xcode hasn’t been correcting my mistakes all afternoon!
This script allows you to quickly and easily toggle the warnings from a hotkey, and just gives you a gentle reminder as to what you’ve done. Of course that won’t stop you forgetting, but assigning a hotkey for this script makes it painless to just turn warnings off and back on again as soon as you’ve got past whatever bit of code the compiler was complaining about.
Xcode unfortunately doesn’t have its own scripts menu, so in order to assign the script a hotkey, you’ll need to either make it into a Service with Automator or use a script runner like Red Sweater’s FastScripts.
display notification "Suppress Warnings was set to " & aVal with title "Swift Compiler - Warnings Policies"
tell application id "com.apple.dt.Xcode"
tell its front document
tell its front project
tell its front target
tell its build configuration "Debug"
set b to build setting "SWIFT_SUPPRESS_WARNINGS"
if b's value is "NO" then
set b's value to "YES"
set b's value to "NO"
my sendNotification(b's value)