Even though there are like one million guides on how to secure macOS properly, I decided to throw in my 5c on this topic. In contrast to many other guides, I’d just like to provide you with the best practices that I also use. This one is about the essential things that I always do when getting a new Mac to provide better security while preserving almost all macOS features like iCloud document saving or Time Machine usage.
My threat model is more tailored towards security when accessing the device physically (leaving it at the hotel or a conference), preventing malware and protect against data loss. Privacy is not that much of a topic (at least in this article) although I’ll provide some privacy fixes as well. In general you should decide on your threat model before taking measures to secure your devices.
Some general words
As security advices can sometimes become esoteric really fast, all I can say is that this is only my approach which consists more of changing small things that help much rather then installing additional security software.
The least attack surface principle
Less is more. Remove software you don’t really need. Be careful about which application you use and how they work. If they start daemons in the background with high privileges and are not updated regularly, this might become a disaster. Don’t install hundreds of apps if you don’t need them anyway. At the time of writing, I have 18 applications installed on my Mac, none of this has background services running. I bet you have more.
Avoid apps known for their permanently discovered vulnerabilities like Flash, Acrobat Reader and Java. You’ll probably not need them, so just don’t install them.
Though this is much about preference, I try to work with the applications provided out-of-the-box. I don’t use any additional terminal or file explorer, I write my notes in Notes.app. Having as little additional software as possible means the least attack surface and the least maintenance effort.
When it comes to security, many people think installing additional software like malware protection or a firewall will solve all their problems. But while there sometimes might be some utility in using such software, it also exposes risks that are - when using your computer mindful - probably bigger than the advantages. Anti-malware software runs as
root. Often it exposes services to the outside world. For me this is already reason enough not to use it, leaving aside that the task of finding malicious software is not fully solvable anyhow and more unexperienced people tend to think less about what they do once they think they’re safe. macOS has tools like XProtect or pf which do the job for the most part.
I know many people use a personal firewall on macOS or the integrated one. I use neither the integrated firewall nor an additional software firewall like Little Snitch because by default macOS does not expose services that would really create vulnerable surface. You can check this by your own:
sudo lsof -i -P | grep -i "listen" | grep -v "localhost:"
To prevent apps from accessing the network, I use the macOS sandbox like described here: https://www.davd.eu/os-x-run-any-command-in-a-sandbox/.
If you’re in a hotel and you cannot trust the network connection provided by their network operator (which you can’t), use a proxy or VPN to masquerade your traffic. This way, only one connection to your endpoint is visible from the untrusted network. I use a SOCKS5 proxy via SSH to connect to my VPS and sometimes a IKEv2 VPN to one of my machines at home. This also solves the problem of DNS or TLS interception.
Though the Mac App Store is hated by almost everyone, it offers a safe way to get new software. All software from the MAS runs inside a sandbox (https://www.davd.eu/os-x-run-any-command-in-a-sandbox/) and is code-signed by the developer and therefore guaranteed to not be changed by anyone else.
In general I try to go with apps from the MAS first though sadly there are so many missing… Otherwise I install only apps which pass the Gatekeeper verification. You should think twice installing apps that are not signed (you’ll have to “right-click -> Open” anyway to even be able to install it).
The only incident I had over the last 10 years was a variant of the Proton malware that I got when I downloaded Handbrake (https://blog.malwarebytes.com/threat-analysis/mac-threat-analysis/2017/05/handbrake-hacked-to-drop-new-variant-of-proton-malware/). I was so sleepy that I even gave it my system password, which I would never do normally because I know that everything is installed in folders that are writable by my user and there’s no kexts or anything to load. The way this malware made it into Handbrake is that their download servers were pwned and someone just repackaged the Handbrake installer to contain the malware as well. Checking the checksum of the installer would have helped but at this time I used Homebrew to install most of my software and I assumed that a package manager that widely used and well-known provides some security measures like this. Turns out, checksum verification is optional per package (defined in the formula file) and if the package maintainer does not put any checksum, it is not checked and you are not even warned. If you want to only get packages that provide proper checksums, you have to enable it explicitly by setting an environment variable.
cat .zsh/ext/fix_homebrew_security.zsh export HOMEBREW_NO_INSECURE_REDIRECT=1 export HOMEBREW_CASK_OPTS=--require-sha
Some words on Homebrew
While Homebrew is a great package manager which is extremely flexible and provides almost anything you might want to install, it has some design flaws that might make your system vulnerable:
- Missing mandatory checksum verification (see above).
- It alters permissions of system directories (
/usr/local) that are in the
$PATHvariable by default (first item - highest priority), making it easy and almost invisible for any application to place malicious binaries on your system that are executed by the
$PATHlookup instead of the executables provided by the system. And as the directory ownerships are changed to your normal user, you won’t even get asked for your password.
echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/davd/n/bin/
So if you want to use Homebrew, don’t install it to
/usr/local but to your home directory, make sure it’s
bin directory is in the
$PATH on the very end and make sure to enforce checksum verification.
Personally, I run all the tools that I need on the CLI that are not installed on macOS by default in a Docker container - which at least gives me xhyve around it for some basic security.
After recognizing the malware I had on my device, I disconnected my machine from the network, reset all caches, reset my backup to the time before downloading the malware (read below), erased my storage and restored the backup. Afterwards I changed all my passwords of all services I use (good to have a password manager, right? ;-)), created a new SSH key-pair and exchanged it on all machines I have access to, just in case any data was gathered already. I would not feel safe to just rely on information which files to remove without diffing this by my own…
Proper backup strategies
The latest incidences show that ransomware becomes more popular. While I did not find any case where this occurred on macOS, it’s still possible. Having a Time Machine backup is a good idea but only if you do it right. Backing up to an external HDD that is always connected to your Mac will not help you much, the malware will just also encrypt your backup data. I thought about detaching my HDD and just attaching it from time to time but still the problem persists if you don’t recognize the malware immediately, which is likely.
Therefore I’m backing up to my NAS running netatalk (providing AFP for Time Machine backups). My NAS uses ZFS as a file-system which allows snapshots. I create regular snapshots of all volumes on my NAS. One could say it’s like backing up the backup. And as netatalk does not know anything about snapshots and does not provide a way to access them, also the ransomware can not access it. So my backup volume can stay attached to the machine all the time. And even if it gets encrypted, I can just revert to the last snapshot of the backup and I’m good to go.
I described how to setup netatalk for Time Machine backups here: https://www.davd.eu/posts-freebsd-time-machine-backup-server-with-netatalk/
Security measures provided by the OS
I often see discussions where someone tries to set up a network interface or sound device or whatever that requires additional kernel extensions (kext) to be loaded. Most of the time, for many “cheap” manufacturers, those kexts are not signed. Since 10.11 macOS has the System Integrity Protection (SIP) or rootless mode. This prevents userland software from writing to system directories that are not meant to be written by third parties. Since 10.13 Apple prevents loading kexts that are not signed properly. If you have a USB network interface that needs an additional kernel module (!?!) or has drivers that install to the wrong place or are not signed - sorry… don’t use such stuff.
While this all can be bypassed and people often are adviced do so, all those security measures like SIP, KEXT signing, XProtect/Gatekeeper are just here to make your system more secure, so embrace them - and leave them enabled.
Practical tips on securing macOS
Still there are some things you can do to provide additional security. Please note that none of those steps require additional software to be installed.
Please be aware that I am not responsible for you breaking your system when following this guide.
Reinstall macOS when getting a new device
First thing I always do is reinstalling macOS. And not because I think that it’s already infected when I get it but e.g. when buying an exhibition piece or a used device you don’t know what was done to the device before. Also reset SMC and clear NVRAM.
Enable full disk encryption
Next thing is enabling full disk encryption. This can be done on macOS from the “Security” system preferences pane in the “FileVault” tab. I never write down my recovery key or something like this because I can remember my password and have regular backups of my data in case I become oblivious.
Especially useful when having a portable device is enforcing hibernation instead of sleep to memory alongside with the deletion of the FileVault session keys when closing the lid:
sudo pmset -a destroyfvkeyonstandby 1 sudo pmset -a hibernatemode 25 sudo pmset -a powernap 0 sudo pmset -a standby 0 sudo pmset -a standbydelay 0 sudo pmset -a autopoweroff 0
Filter malicious hosts using the hosts file
To prevent loading known malicious sites that provide malware as well as directly blocking advertisements on the net and preventing social network foo from being loaded without having to install anything at all, I use StevenBlack’s hosts file https://github.com/StevenBlack/hosts in the malware+ads+social+fakenews+gambling flavour:
curl "https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-social/hosts" | sudo tee -a /etc/hosts
(Warning: This will override your existing hosts file)
Set a firmware password
A firmware password will prevent your machine booting from a different volume then the one integrated. This is useful for various cases including loss of your machine etc. This can only be reset at a Apple Store and as newer models have flash built-in without the possibility to exchange it, I don’t expect it to cause problems.
sudo firmwarepasswd -setpasswd -setmode command
However, be sure to remember that password, as otherwise you will be lost when resetting the device or when doing disaster recovery :-)
I assume this one is relatively self-explanatory. I added this on top of my
Host * PasswordAuthentication no ChallengeResponseAuthentication no HashKnownHosts yes UseKeyChain no
Ask for password immediately
When putting your device to sleep or the screensaver starts it makes sense to directly ask for a password when trying to wake it up again. So if you leave your device unattended, no one will be able to get in. This is especially useful when using it together with the FileVault advice from earlier in this guide.
defaults write com.apple.screensaver askForPassword -int 1 defaults write com.apple.screensaver askForPasswordDelay -int 0
Show real extensions
Having a executable pretending to be an image is bad… So make sure to always see what you got:
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
Disable crash reporter and diagnostics
I just always disable it because it drives me crazy:
defaults write com.apple.CrashReporter DialogType none
Read more on how to prevent diagnostics to be sent to Apple: https://github.com/fix-macosx/fix-macosx/wiki/Diagnostics-&-Usage-Data
Prevent applications from reading your terminal input
Both macOS Terminal and iTerm2 offer an option to enable “Secure keyboard entry”, which you should do to prevent other applications reading the keyboard input while using the terminal.
Update everything regularly
Last but not least, keep your stuff up-to-date.
- https://kryptera.se/assets/uploads/2014/10/WP_FileVault2.pdf (Mirror of the PDF on Apples servers, which is down)