Safari

Safari Extensions

Overview

Safari extensions modify browser behaviour and can access browsing data, inject content into web pages, and intercept network requests. The list of installed extensions is recorded in Extensions.plist, which provides a forensic inventory of browser modifications. Extensions are relevant to investigations because they can serve as malware delivery vectors, privacy-invasive trackers, or indicators of user interests and habits.

Starting with macOS 10.15 (Catalina), Safari transitioned from the legacy .safariextz extension format to App Extensions distributed through the Mac App Store or as part of macOS apps. The Extensions.plist file records both legacy and modern extensions, though the available metadata differs between formats.

File Locations

FilePathFormat
Extension metadata~/Library/Safari/Extensions/Extensions.plistBinary Property List
Extension directory~/Library/Safari/Extensions/Directory

The Extensions.plist file may not exist if no extensions have ever been installed.

File Format

Extensions.plist is a binary property list containing a dictionary with an Installed Extensions key that holds an array of extension entries.

Plist Structure

Root (Dictionary)
  Installed Extensions (Array)
    [0] (Dictionary)
      Archive File Name (String)
      Bundle Directory Name (String)
      Enabled (Boolean)
    [1] (Dictionary)
      ...

Extension Entry Fields

KeyTypeDescription
Archive File NameStringOriginal extension archive filename (e.g., 1Password.safariextz)
Bundle Directory NameStringBundle identifier or directory name (e.g., com.agilebits.onepassword-safari)
EnabledBooleanWhether the extension is currently enabled

Additional keys may be present depending on the Safari version and extension type, but the three fields above are consistently available.

Key Fields for Analysis

  • Bundle Directory Name: Acts as the extension's unique identifier. For App Extensions, this is a reverse-DNS bundle identifier (e.g., com.agilebits.onepassword-safari). For legacy extensions, it may be a directory name. This field is the primary key for identifying the extension.
  • Archive File Name: The original installation archive name. For legacy extensions, this is the .safariextz filename. This can help identify the source of the extension.
  • Enabled: Indicates the current state. A disabled extension is installed but not active. Both enabled and disabled extensions are forensically relevant -- a disabled malicious extension may indicate the user discovered it.

Timestamps

Extensions.plist does not contain per-extension installation timestamps. To approximate when an extension was installed, examine:

  • The modification timestamp of Extensions.plist itself (reflects the last time any extension was added, removed, or toggled)
  • Filesystem creation and modification times of extension bundles in the Extensions/ directory
  • FSEvents records for changes to the Extensions/ directory

Analysis Notes

  • Malicious extensions: Browser extensions are a common malware delivery vector. Investigate any unfamiliar bundle identifiers. Cross-reference with known malicious extension databases.
  • Ad blockers and privacy tools: The presence of ad blockers (e.g., com.nicksinger.ABlocker), VPN extensions, or privacy tools may indicate the user's awareness of tracking and privacy concerns.
  • Password managers: Extensions like 1Password, LastPass, or Bitwarden indicate the user employs a password manager, which is relevant for credential investigations.
  • Developer tools: Extensions for web development (e.g., React DevTools, Web Inspector) may indicate the user has technical expertise.
  • Disabled extensions: Extensions that are installed but disabled (Enabled: false) may have been disabled by the user after noticing suspicious behaviour, or they may have been disabled by macOS security controls.
  • Extension count: An unusually high number of extensions may indicate careless installation habits, while a very clean extension list may indicate a security-conscious user.
  • Legacy vs App Extensions: After macOS 10.15, legacy .safariextz extensions stopped working. Their presence in Extensions.plist indicates they were installed before the transition.

Version Differences

VersionChange
macOS 10.12-10.14Legacy .safariextz format supported. Extensions Gallery available
macOS 10.15 (Catalina)Safari transitions to App Extensions only. Legacy extensions deprecated
macOS 13 (Ventura)Extension profiles introduced for per-profile extension configuration

The Extensions.plist format itself remains consistent, though the available extensions and their metadata may vary.

Tool Support

macfor

The browser.safari plugin reads Extensions.plist and emits browser_extension records with fields including bundle_id (from Bundle Directory Name), archive_file_name, enabled, and source_file. The raw plist file is also preserved in the evidence container.

Manual Analysis

# Convert to XML for inspection
plutil -convert xml1 -o - ~/Library/Safari/Extensions/Extensions.plist

# Quick list of installed extensions
python3 -c "
import plistlib
with open('Extensions/Extensions.plist', 'rb') as f:
    data = plistlib.load(f)
for ext in data.get('Installed Extensions', []):
    status = 'enabled' if ext.get('Enabled', False) else 'disabled'
    bundle = ext.get('Bundle Directory Name', 'unknown')
    archive = ext.get('Archive File Name', 'N/A')
    print(f'[{status}] {bundle} ({archive})')
"

Other Investigative Steps

  • Cross-reference bundle identifiers with the Mac App Store to identify the source application
  • Check the Extensions/ directory for the actual extension bundles and their Info.plist files, which contain additional metadata such as version, developer, and requested permissions
  • Review Unified Logs for extension-related events (subsystem com.apple.Safari)

References

Previous
Cookies