browserforensics
Back to all articles

Browser extensions forensics (Chrome & Firefox)

2026-06-21 · 3 min

Installed extensions are an under-used source of both intent and risk. A malicious or sideloaded extension can read every page the user visits, exfiltrate cookies, or inject scripts — and unlike a dropped binary, it survives reboots and rides along with profile sync. The list of what was installed, when, with which permissions, and from where is recorded in plain JSON. You just have to know which file to open.

Chrome / Edge: Preferences and Secure Preferences

Chromium records each extension under the extensions.settings object inside the profile's Preferences and Secure Preferences files (both JSON). Every extension is keyed by its 32-character id:

FieldMeaning
manifest.name / manifest.versionDisplay name and version
manifest.permissionsRequested capabilities (e.g. tabs, cookies, <all_urls>)
install_timeWebKit/Chrome microseconds since 1601-01-01 UTC
stateEnabled (1) or disabled (0)
from_webstoretrue = Web Store; false = sideloaded/dev

Secure Preferences additionally carries a protection.macs tree — HMACs over selected preference values, including extension entries. Chrome uses these to detect off-browser tampering (an attacker silently adding an extension by editing the file). Mismatched or missing MACs are themselves an indicator: either the entry was hand-edited, or it was written by a process that did not have the seed to recompute the MAC.

The extension's actual code lives separately, on disk:

…\<profile>\Extensions\<id>\<version>\

Pull the manifest.json and background/content scripts from there when you need to read what the extension actually does, not just what it declared.

Firefox: extensions.json

Firefox keeps its inventory in extensions.json at the profile root. Each add-on entry gives you:

FieldMeaning
idAdd-on identifier (often an email-style or UUID id)
defaultLocale.nameDisplay name
versionInstalled version
typeextension, theme, dictionary, …
activeCurrently enabled or not
installDateUnix epoch milliseconds
sourceURIWhere the add-on was installed from

sourceURI is the high-value field: addons.mozilla.org means the official store, while a file:// path or an arbitrary HTTPS host points to a sideloaded or enterprise-pushed add-on — a classic persistence and data-theft vector.

Reading the forensic signal

  • Permissions = capability. <all_urls> plus cookies or webRequest means the extension could read and exfiltrate anything the browser sees. Triage by capability, not by name.
  • Source = provenance. from_webstore: false (Chrome) or a non-AMO sourceURI (Firefox) flags sideloading — common in IR for credential stealers and ad-injectors that never touched a store review.
  • Install time = timeline. Feed install_time / installDate into your master timeline; an extension appearing minutes after a phishing click or a fresh logon is a strong lead. See browser timestamp formats for the microseconds-since-1601 vs Unix-ms conversions.
  • State. A disabled extension is still evidence — it was installed deliberately at some point and may have been left behind after use.

In the tool

BrowserForensics parses Chrome Preferences and Secure Preferences (both the profile metadata and the extensions.settings block) and Firefox extensions.json into sortable tables — id, name, version, permissions, source, install time, and enabled state — entirely in your browser, with no upload. That makes it quick to spot the one entry with <all_urls> and a file:// source among twenty benign theme add-ons.

Further reading