macOS system hardening configuration terminal output

macOS Hardening: Practical Security Configuration

macOS hardening guide covering FileVault, SIP, Gatekeeper, application firewall, Lockdown Mode, and Objective-See tools.

Sep 15, 2026
2 min read

Introduction

macOS is no longer a soft target by virtue of market share. Intel 471 documented roughly double the number of threat actors targeting Apple devices in 2023–2024 compared to the prior period, tracking both commodity infostealers and nation-state tooling. MacStealer and ShadowVault — both sold via dark web forums — harvest Keychain data, browser cookies, and documents from fully patched, modern Apple Silicon hardware. NotLockBit, a Go-written LockBit-style encryptor, demonstrated that ransomware deployment on macOS is no longer theoretical.

Apple's built-in defenses are genuinely strong: XProtect received 29 signature updates in 2024 alone, growing its rule set by 170%. T2 and Apple Silicon hardware-enforce code signing from the boot ROM up. But those controls only hold when SIP is intact, Gatekeeper is configured correctly, and software is current. The gap between "default macOS" and "hardened macOS" is not wide — it's a series of specific, verifiable configuration decisions.

This article documents those decisions as a practitioner's checklist: what to enable, what to disable, how to verify it, and where attackers look when defaults are left in place.

Authorization Required

This article describes defensive configuration for systems you own or are authorized to administer. Disabling SIP or modifying security baselines on systems without explicit authorization is unauthorized access in most jurisdictions. All verification commands are read-only unless otherwise noted.

Impact

Leaving macOS at default configuration exposes the following attack surface:

  • Credential theft via infostealer families (MacStealer, ShadowVault, Atomic Stealer) that target Keychain, browser credential stores, and session cookies
  • Persistence without detection through LaunchAgent/LaunchDaemon installation that survives reboots, undetected without persistence monitoring
  • Lateral movement enabled by open SSH, Screen Sharing, or Remote Management services running without awareness
  • SIP bypass through unpatched kernel extension vulnerabilities (CVE-2024-44243 is a recent example, patched December 2024)
  • Gatekeeper bypass on pre-Sequoia systems allowing unsigned code execution via Finder right-click without TCC prompt
  • Data exfiltration over covert outbound channels with no default outbound firewall blocking unexpected connections
  • Boot-level compromise on Intel Macs without a firmware password, allowing arbitrary boot media

Technical Details

Patch Cadence and XProtect

Apple pushes XProtect, MRT, and Gatekeeper Configuration Data updates silently via CloudKit, independent of full OS updates. On macOS 15 (Sequoia), this pipeline was redesigned to deliver updates more frequently than the OS release cycle. You can't rely on knowing when these fire — verify the current versions directly.

XProtect detects known malware signatures before execution. MRT (Malware Removal Tool) cleans known infections post-installation. Neither replaces behavioral detection, but both must be current. Missing a full macOS point release means missing firmware fixes, kernel patches, and security framework updates that XProtect signatures cannot compensate for.

Enterprise environments should use MDM (Jamf, Kandji, Mosyle) to enforce minimum OS version requirements and push updates on a defined SLA — typically 30 days for non-critical, 72 hours for actively exploited CVEs.

FileVault Full-Disk Encryption

FileVault uses XTS-AES-128 with a 256-bit key. On T2 and Apple Silicon, encryption and decryption are hardware-accelerated by the Secure Enclave, making the performance overhead negligible. The encryption key is derived from the user's login password and the hardware UID burned into the Secure Enclave — without both, decryption is not possible offline.

When FileVault is enabled, the recovery key is generated at setup. For managed deployments, the recovery key should be escrowed to MDM. For personal devices, Apple offers iCloud-based key recovery. Losing both the password and the recovery key means data is permanently unrecoverable — by design.

FileVault does not protect against a running system. A logged-in session with FileVault enabled is no different from any other running system. The protection model is specifically against offline disk access after theft or seizure.

Time Machine backup disks and external volumes require separate encryption. APFS encrypted volumes can be created natively; HFS+ encrypted volumes via Disk Utility. Unencrypted backups of an encrypted system negate the protection entirely.

System Integrity Protection (SIP)

SIP restricts modifications to /System, /usr, /bin, /sbin, and several other protected paths, even by root. It also prevents unsigned kernel extensions from loading, blocks runtime process injection into system processes, and enforces NVRAM protections. Disabling SIP requires booting into Recovery Mode — it cannot be disabled by a running process regardless of privileges.

CVE-2024-44243 (patched December 2024, analyzed by Microsoft Security) demonstrated a SIP bypass through a vulnerable kernel extension. The attack required an existing kernel extension with a specific entitlement that Apple had granted to third-party software. This class of bug — entitlement abuse rather than kernel memory corruption — is the current SIP bypass surface. Keeping kext-loading restricted and applying OS patches promptly is the relevant mitigation.

SIP status is a pre-check in most macOS post-exploitation frameworks. A disabled SIP state is flagged as a high-value finding in any macOS security assessment.

Gatekeeper and Notarization

Gatekeeper validates code signatures and notarization status before allowing execution of downloaded files. Notarization requires Apple to have scanned the binary for known malware and confirm it's signed with a registered Developer ID. Gatekeeper checks occur at first-run and on subsequent launches if the binary has been modified.

macOS Sequoia (15.0) closed the most abused Gatekeeper bypass: the Finder right-click "Open" contextual menu no longer bypasses the TCC prompt for unsigned apps. Prior to Sequoia, this allowed a user to execute unnotarized software with a single right-click confirmation, which malware delivered via phishing reliably exploited. In Sequoia, the user must navigate to System Settings → Privacy & Security to explicitly allow unnotarized apps, which adds friction sufficient to stop most drive-by executions.

The spctl command-line tool manages Gatekeeper policy. spctl --assess -v /Applications/AppName.app evaluates whether Gatekeeper would allow execution. The assessment source (Developer ID Application, Mac App Store, notarized) is returned in the output.

Network Firewall and Outbound Controls

macOS ships with pf (packet filter) and a higher-level Application Firewall (socketfilterfw). The Application Firewall controls inbound connections per-application but has no outbound filtering capability. By default, the firewall is disabled on fresh installs.

Stealth mode, configurable via socketfilterfw, causes the system not to respond to ICMP probe packets or connection attempts on closed ports — the host appears offline to network scanners. This is meaningful noise reduction on untrusted networks.

Outbound filtering requires a third-party tool. LuLu (Objective-See) implements per-process outbound rules using the Network Extension framework. When an application makes its first outbound connection, LuLu presents a prompt. Approved rules persist; denied rules block all future attempts by that process. This visibility layer catches infostealers attempting to exfiltrate data and implants trying to reach C2 infrastructure — both behaviors that are otherwise silent by default.

Little Snitch provides similar functionality with a richer rule engine and traffic visualizer, at a licensing cost. For enterprise deployments, outbound filtering is typically handled at the network layer (proxy, next-gen firewall) rather than the endpoint, but host-based controls add defense-in-depth where network-level visibility is absent.

Persistence Monitoring with Objective-See Tools

macOS malware establishes persistence primarily via LaunchAgents (~/Library/LaunchAgents, /Library/LaunchAgents) and LaunchDaemons (/Library/LaunchDaemons). These plist files instruct launchd to execute a binary at login or system startup. Secondary persistence mechanisms include Login Items, kernel extensions, cron jobs, and shell profile modifications.

BlockBlock (Objective-See) monitors these persistence locations using kernel-level file system notifications. When any process writes a new persistent component, BlockBlock presents a prompt identifying the binary, its signing status, and the persistence mechanism. The user can allow or block the registration. Malware attempting to install a LaunchAgent is caught at write time, before the persistence is active.

KnockKnock enumerates all currently registered persistent items — LaunchAgents, LaunchDaemons, Login Items, kexts, browser extensions, and more — and checks each against VirusTotal. It's a point-in-time audit tool rather than a real-time monitor. Running KnockKnock periodically surfaces persistence that pre-dated BlockBlock installation or was installed through a mechanism BlockBlock didn't intercept.

OverSight monitors microphone and camera activation events. When any process activates the mic or camera, OverSight alerts with the process name and signing identity. This is relevant for detecting meeting-recording malware and RATs with audio/video collection capability. Note: OverSight's compatibility with the latest macOS versions should be verified before deployment in production environments.

User Account Hygiene

The macOS privilege model separates standard users from administrators. Administrator accounts can install software, modify system preferences, and run commands with sudo. Standard users cannot. Running daily workloads as an administrator means that a compromised process — a malicious email attachment, a trojanized app — immediately has admin privileges without requiring privilege escalation.

Create a dedicated admin account used only for administrative tasks. Use a standard account for all daily work. This limits the blast radius of most infostealer and trojan infections, which operate at the privilege level of the compromised user process.

Auto-login must be disabled. A physical attacker with boot access and auto-login enabled bypasses authentication entirely. The Guest user account should be disabled unless the device serves a specific kiosk or shared-access function.

For Apple ID, two-factor authentication is mandatory. Apple ID recovery access can unlock devices and reset FileVault via iCloud, so a compromised Apple ID with no 2FA is equivalent to physical access. Hardware security keys (YubiKey via USB-C or NFC) are supported as 2FA for Apple ID as of iOS 16.3/macOS 13.2.

mSCP Compliance Baselines

Apple's macOS Security Compliance Project (mSCP) provides NIST SP 800-219-based configuration profiles, audit scripts, and remediation guidance maintained by Apple engineers. The project maps controls to NIST 800-53, DISA STIGs, and CIS Benchmarks. Organizations required to meet FISMA, FedRAMP, or CIS Level 1/2 compliance can use mSCP-generated profiles deployed via MDM.

For non-enterprise environments, the CIS macOS Benchmark is available publicly and covers the highest-impact settings without requiring MDM infrastructure. Key CIS Level 1 controls include: disable auto-login, require password after screensaver, enable FileVault, enable firewall, disable Remote Login, disable Bluetooth if unused, enable Gatekeeper.

MDM enforcement (Jamf, Kandji, Mosyle) provides the strongest compliance posture: configuration profiles are applied at enrollment, settings drift is detected and remediated automatically, and device compliance status is reportable. MDM-enrolled devices can also enforce minimum OS version, require FileVault escrow, and restrict which applications can be installed.

Attack Tools

The following tools are used to assess macOS security posture in authorized engagements.

Gatekeeper Assessment
# Check Gatekeeper global policy
spctl --status

# Assess a specific application
spctl --assess -v /Applications/Firefox.app

# List all developer ID exceptions (apps allowed despite policy)
spctl --list

# Remove a specific rule (by rule number from --list output)
spctl --remove --rule 1

Expected output for a properly signed app:

/Applications/Firefox.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: Mozilla Corporation (43AQ936H96)
Application Firewall Management
# Check firewall status
/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate

# Enable the firewall
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on

# Enable stealth mode
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on

# Block all incoming connections (strictest setting)
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setblockall on

# List apps with firewall rules
/usr/libexec/ApplicationFirewall/socketfilterfw --listapps
SIP Status Check
# Check SIP status (requires Terminal, not Recovery)
csrutil status
# Expected: System Integrity Protection status: enabled.

# Check individual SIP protections (macOS 11+)
csrutil status --verbose
# Shows: filesystem, kext, nvram, dtrace, debug protections individually

# Disabling SIP requires Recovery Mode boot:
# csrutil disable  -- DO NOT run unless explicitly required
Baseline Audit with osquery
# Check FileVault status
osqueryi "SELECT * FROM disk_encryption;"

# List LaunchAgents and LaunchDaemons
osqueryi "SELECT name, path, disabled FROM launchd;"

# Check SIP status
osqueryi "SELECT * FROM sip_config;"

# List login items
osqueryi "SELECT * FROM startup_items;"

# Check firewall state
osqueryi "SELECT * FROM alf;"

# Users with admin privileges
osqueryi "SELECT uid, username, shell FROM users WHERE uid < 500 OR gid = 80;"

Detection

macOS generates security-relevant events across several log sources. Unified Logging (log show, log stream) is the primary collection mechanism.

EventLog SourceQuery / Event ID
SIP disabledSecurity subsystemlog show --predicate 'subsystem == "com.apple.MobileFileIntegrity"'
LaunchAgent installedFile system eventsESF / BlockBlock alert on ~/Library/LaunchAgents write
Unsigned kext loadkernellog show --predicate 'process == "kextd"' --info
Gatekeeper blockGK subsystemlog show --predicate 'subsystem == "com.apple.gatekeeper"'
TCC accessTCC daemonlog show --predicate 'subsystem == "com.apple.TCC"'
SSH loginauth.log / OpenSSH/var/log/auth.log or log show --predicate 'process == "sshd"'
Firewall blockALFlog show --predicate 'process == "socketfilterfw"'

For enterprise detection, Santa (Google) provides binary allowlisting with centralized logging — every execution decision (ALLOW/DENY) is logged with binary hash, signing identity, and user. JAMF Protect and CrowdStrike Falcon for Mac ingest Endpoint Security Framework (ESF) events and map them to MITRE ATT&CK. ESF is Apple's kernel-level API for observing process, file, and network events; it requires a system extension with specific entitlements, making it unsuitable for ad hoc use but the correct foundation for commercial EDR solutions.

Remediation

Apply these settings in order of impact.

Patching

  • Enable automatic macOS updates: System Settings → General → Software Update → Automatic Updates (all options on)
  • For MDM: enforce minimum OS version with a 30-day grace period for non-critical releases, 72 hours for actively exploited CVEs

FileVault

Enable FileVault via CLI (requires sudo)
sudo fdesetup enable -user $(whoami)
# Outputs recovery key — store this securely before proceeding

SIP — verify only, do not disable

Verify SIP
csrutil status
# Must return: System Integrity Protection status: enabled.

Gatekeeper

Set Gatekeeper to require notarization
# Allow apps from App Store and identified developers only
sudo spctl --master-enable
# Verify
spctl --status
# Expected: assessments enabled

Application Firewall

Enable firewall with stealth mode
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on

Disable Unnecessary Services

Disable remote services
# Disable Remote Login (SSH)
sudo systemsetup -setremotelogin off

# Disable Remote Management (ARD/VNC)
sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -deactivate -stop

# Verify no unexpected listeners
sudo lsof -i -P -n | grep LISTEN

User Account Hygiene

Disable auto-login and guest account
# Disable auto-login
sudo defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser -bool false

# Disable guest user
sudo defaults write /Library/Preferences/com.apple.loginwindow GuestEnabled -bool false

# Require password immediately after screensaver
defaults write com.apple.screensaver askForPasswordDelay -int 0

Lockdown Mode — enable only for high-risk users (journalists, executives, targets of nation-state actors)

System Settings → Privacy & Security → Lockdown Mode → Turn On Lockdown Mode

Lockdown Mode disables: JIT compilation in Safari, wired device connections when locked, configuration profiles (unless MDM-enrolled before enabling), message attachment previews, and several communication features. Per-site and per-app exceptions can be configured in Sequoia via System Settings → Lockdown Mode.

Objective-See Tools

Install Objective-See tools via Homebrew
# LuLu — outbound firewall
brew install --cask lulu

# BlockBlock — persistence monitor
brew install --cask blockblock

# KnockKnock — persistence audit
brew install --cask knockknock

After installing BlockBlock, run KnockKnock once to enumerate all existing persistent items and verify there are no unknown entries before relying on real-time monitoring going forward.

Verification

Run these checks to confirm the hardening state of a system.

Full Hardening Verification Script
#!/bin/bash
echo "=== macOS Hardening Verification ==="

# SIP
echo -n "[SIP] "; csrutil status

# FileVault
FV=$(fdesetup status 2>/dev/null)
echo "[FileVault] $FV"

# Firewall
FW=$(/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate 2>/dev/null)
echo "[Firewall] $FW"

# Stealth Mode
SM=$(/usr/libexec/ApplicationFirewall/socketfilterfw --getstealthmode 2>/dev/null)
echo "[Stealth Mode] $SM"

# Gatekeeper
GK=$(spctl --status 2>/dev/null)
echo "[Gatekeeper] $GK"

# Auto-login
AL=$(defaults read /Library/Preferences/com.apple.loginwindow autoLoginUser 2>/dev/null || echo "disabled")
echo "[Auto-login] $AL"

# Guest user
GU=$(defaults read /Library/Preferences/com.apple.loginwindow GuestEnabled 2>/dev/null || echo "0")
echo "[Guest user enabled] $GU (0=disabled)"

# Remote Login
RL=$(sudo systemsetup -getremotelogin 2>/dev/null)
echo "[Remote Login] $RL"

# Screensaver password delay
PD=$(defaults read com.apple.screensaver askForPasswordDelay 2>/dev/null || echo "unknown")
echo "[Screensaver password delay (seconds)] $PD"

# XProtect version
XP=$(defaults read /Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Info.plist CFBundleShortVersionString 2>/dev/null)
echo "[XProtect version] $XP"

# Current OS version
sw_vers

Expected output on a hardened system:

[SIP] System Integrity Protection status: enabled.
[FileVault] FileVault is On.
[Firewall] Firewall is enabled. (State = 1)
[Stealth Mode] Stealth mode enabled
[Gatekeeper] assessments enabled
[Auto-login] disabled
[Guest user enabled] 0 (0=disabled)
[Remote Login] Remote Login: Off
[Screensaver password delay (seconds)] 0

References

MITRE ATT&CK Techniques

Tools Documentation

Next Steps

On this page