Firefox
Firefox
Overview
Mozilla Firefox is a Gecko-based browser with a forensically distinct architecture from both Safari and Chrome. It stores artifacts in a profile-based directory structure, uses SQLite databases with Mozilla-specific schemas, and employs a custom JSONLZ4 compression format for session data. Firefox is often favoured by privacy-conscious users and is widely deployed in enterprise environments through its ESR (Extended Support Release) channel.
Firefox uses PRTime timestamps (microseconds since the Unix epoch, 1970-01-01 00:00:00 UTC) for most of its SQLite databases, a unique places.sqlite database that unifies browsing history and bookmarks, and a custom JSONLZ4 format for session recovery files.
Supported Variants
macOS can host multiple Firefox installations, each with its own profile directory:
| Variant | Application Path | Data Path |
|---|---|---|
| Firefox (Stable) | /Applications/Firefox.app | ~/Library/Application Support/Firefox/ |
| Firefox Developer Edition | /Applications/Firefox Developer Edition.app | ~/Library/Application Support/Firefox Developer Edition/ |
| Firefox Nightly | /Applications/Firefox Nightly.app | ~/Library/Application Support/Firefox Nightly/ |
Cache data is stored separately:
~/Library/Caches/Firefox/Profiles/{profiledir}/cache2/
Profile System
Firefox uses a profile-based architecture where each profile is a self-contained directory with its own databases, configuration, and extension data. Profiles are registered in a profiles.ini file at the root of the Firefox data directory.
profiles.ini Format
[General]
StartWithLastProfile=1
Version=2
[Profile0]
Name=default-release
IsRelative=1
Path=Profiles/a1b2c3d4.default-release
Default=1
[Profile1]
Name=work
IsRelative=1
Path=Profiles/e5f6g7h8.work
[Install308046B0AF4A39CB]
Default=Profiles/a1b2c3d4.default-release
Locked=1
Key fields:
- Name: The human-readable profile name.
- Path: Directory path (relative to the Firefox base directory if
IsRelative=1, or absolute). - IsRelative: Whether
Pathis relative (1) or absolute (0). Almost always 1. - Default: Whether this is the default profile (1 = default).
- [InstallXXX]: Maps a Firefox installation hash to its default profile. The
Locked=1flag indicates the profile is locked to that installation.
Profile directory names follow the pattern {random8chars}.{profilename} (e.g., a1b2c3d4.default-release).
INI Profile Parser
The macfor collector uses a Go INI parser (gopkg.in/ini.v1) to enumerate profiles. The parser iterates over [ProfileN] sections, resolves relative paths against the Firefox base directory, and also checks [InstallXXX] sections for installation-to-profile mappings. If no profile has Default=1, the parser falls back to the [Install] section's Default path, and finally to a single-profile heuristic.
Profile Directory Structure
~/Library/Application Support/Firefox/
+-- profiles.ini # Profile registry
+-- installs.ini # Installation mapping
+-- Profiles/
+-- a1b2c3d4.default-release/ # Profile directory
+-- places.sqlite # History, bookmarks, downloads
+-- places.sqlite-wal # Write-ahead log
+-- places.sqlite-shm # Shared memory
+-- favicons.sqlite # Site icons (Firefox 55+)
+-- cookies.sqlite # Cookies
+-- formhistory.sqlite # Form autofill
+-- permissions.sqlite # Site permissions
+-- content-prefs.sqlite # Per-site preferences
+-- webappsstore.sqlite # DOM localStorage
+-- logins.json # Encrypted credentials
+-- key4.db # NSS key database
+-- cert9.db # Certificates
+-- prefs.js # User preferences
+-- extensions.json # Extension metadata
+-- extensions/ # Installed extensions (XPI files)
+-- sessionstore-backups/
| +-- recovery.jsonlz4 # Current session
| +-- recovery.baklz4 # Session backup
| +-- previous.jsonlz4 # Previous session
+-- storage/
+-- default/ # Extension storage
+-- moz-extension+++{id}/
Artifact Database Files
| Artifact | File | Format | Key Tables |
|---|---|---|---|
| History & Bookmarks | places.sqlite | SQLite | moz_places, moz_historyvisits, moz_bookmarks |
| Favicons | favicons.sqlite | SQLite | moz_icons, moz_pages_w_icons |
| Cookies | cookies.sqlite | SQLite | moz_cookies |
| Form History | formhistory.sqlite | SQLite | moz_formhistory |
| Permissions | permissions.sqlite | SQLite | moz_perms |
| Content Prefs | content-prefs.sqlite | SQLite | prefs, groups |
| DOM Storage | webappsstore.sqlite | SQLite | webappsstore2 |
Timestamps
Firefox uses PRTime for most database timestamps: microseconds since 1970-01-01 00:00:00 UTC.
PRTime value: 1706234567000000
Conversion: 1706234567000000 / 1000000 = 1706234567 (Unix seconds)
Result: 2024-01-25T22:22:47Z
Exceptions:
- Cookie expiry (
moz_cookies.expiry): Unix timestamp in seconds. - Login timestamps (
logins.json): Unix milliseconds. - Session timestamps (
recovery.jsonlz4): Unix milliseconds. - Permission modification time (
moz_perms.modificationTime): Unix milliseconds.
JSONLZ4 Format
Firefox uses a Mozilla-specific LZ4 compression format for session files and some configuration files (e.g., search.json.mozlz4, addonStartup.json.lz4).
Binary Structure
| Offset | Size | Description |
|---|---|---|
| 0 | 8 bytes | Magic header: mozLz40\x00 (ASCII + null byte) |
| 8 | 4 bytes | Original (decompressed) size, little-endian uint32 |
| 12 | N bytes | LZ4-compressed data (block format, not frame format) |
Decompression requires LZ4 block decompression (not the more common frame format). The macfor collector caps decompressed output at 100 MB to prevent memory exhaustion from malicious or corrupt files.
Affected Files
| File | Location | Content |
|---|---|---|
recovery.jsonlz4 | sessionstore-backups/ | Current session state |
recovery.baklz4 | sessionstore-backups/ | Session backup |
previous.jsonlz4 | sessionstore-backups/ | Previous session |
search.json.mozlz4 | Profile root | Search engine configuration |
addonStartup.json.lz4 | Profile root | Extension startup state |
Version Differences
| Firefox Version | Key Changes |
|---|---|
| Firefox 55 | Favicons moved from places.sqlite to separate favicons.sqlite |
| Firefox 57 (Quantum) | Legacy XUL/XPCOM add-ons deprecated; WebExtensions only |
| Firefox 62 | moz_origins table added to places.sqlite |
| Firefox 78 (ESR) | key4.db replaces key3.db for NSS key storage |
| Firefox 91 (ESR) | Storage improvements |
| Firefox 102 (ESR) | Minimum supported target for current tooling |
| Firefox 115 (ESR) | source and triggeringPlaceId columns added to moz_historyvisits |
| Firefox 128+ | Current release channel |
Collection Order
The macfor Firefox collector processes artifacts in this order for each profile:
profiles.ini(metadata, per variant)places.sqlite(history, bookmarks, downloads -- from same database)cookies.sqliteformhistory.sqlitepermissions.sqlitelogins.json+key4.db(credential metadata)extensions.jsonsessionstore-backups/(JSONLZ4 session files)prefs.js
For each SQLite database, the collector copies the database along with its WAL and SHM files, then opens a read-only copy to parse records without modifying the original.
Tool Support
| Tool | Firefox Support |
|---|---|
| macfor | Full collection and parsing (Pro module) |
| Autopsy | Firefox history, cookies, bookmarks via Autopsy modules |
| AXIOM | Full Firefox artifact support |
| Hindsight (Obsidian Forensics) | Primarily Chromium; limited Firefox |
| DB Browser for SQLite | Manual inspection of all SQLite databases |
| firefed | Specialised Firefox forensics tool |
| plaso/log2timeline | Firefox history, cookies, downloads parsers |