Firefox

Firefox Saved Passwords

Overview

Firefox stores saved login credentials in logins.json, a JSON file within each profile directory. Usernames and passwords are encrypted using Mozilla's NSS (Network Security Services) library, with encryption keys stored in key4.db. An optional master password adds an additional layer of protection.

Forensic analysis of saved logins focuses on metadata rather than credential recovery: which sites have saved credentials, when they were created and last used, how frequently they were used, and which sites have password saving explicitly disabled. The macfor collector never attempts to decrypt passwords.

File Locations

FilePathDescription
Saved logins~/Library/Application Support/Firefox/Profiles/{profile}/logins.jsonEncrypted credentials
Key database~/Library/Application Support/Firefox/Profiles/{profile}/key4.dbNSS encryption keys
Certificate DB~/Library/Application Support/Firefox/Profiles/{profile}/cert9.dbCertificate storage

All three files should be collected together to preserve the complete credential artifact set.

File Format

logins.json Structure

{
  "nextId": 15,
  "logins": [
    {
      "id": 1,
      "hostname": "https://github.com",
      "httpRealm": null,
      "formSubmitURL": "https://github.com/session",
      "usernameField": "login",
      "passwordField": "password",
      "encryptedUsername": "MDIEEPgA...",
      "encryptedPassword": "MDoEEPgA...",
      "guid": "{abc12345-def6-7890-abcd-ef1234567890}",
      "encType": 1,
      "timeCreated": 1685620800000,
      "timeLastUsed": 1706227200000,
      "timePasswordChanged": 1701388800000,
      "timesUsed": 47
    }
  ],
  "version": 1,
  "disabledHosts": [
    "https://bank.example.com"
  ],
  "potentiallyVulnerablePasswords": []
}

Top-Level Fields

FieldDescription
nextIdNext ID to be assigned to a new login entry
loginsArray of saved login entries
versionFile format version (typically 1)
disabledHostsHostnames where user chose "Never save" when prompted
potentiallyVulnerablePasswordsIDs of passwords flagged as potentially compromised

Login Entry Fields

FieldDescription
idUnique integer identifier
hostnameOrigin URL (e.g., https://github.com)
httpRealmHTTP authentication realm (null for form-based logins)
formSubmitURLForm action URL (empty for HTTP auth)
usernameFieldHTML name attribute of the username input
passwordFieldHTML name attribute of the password input
encryptedUsernameBase64-encoded, NSS-encrypted username
encryptedPasswordBase64-encoded, NSS-encrypted password
guidGlobally unique identifier (for Firefox Sync)
encTypeEncryption type (1 = SDR encryption via NSS)
timeCreatedWhen credential was first saved (Unix milliseconds)
timeLastUsedWhen credential was last used for autofill (Unix milliseconds)
timePasswordChangedWhen the password was last updated (Unix milliseconds)
timesUsedNumber of times the credential was used for autofill

Key Fields for Analysis

FieldForensic Significance
hostnameWhich services the user has accounts on
formSubmitURLLogin form endpoint (can reveal custom/internal applications)
usernameField / passwordFieldField names that may identify the application framework
timeCreatedWhen the user first saved this credential
timeLastUsedMost recent autofill usage
timePasswordChangedWhen password was last rotated
timesUsedFrequency of use (indicates active vs dormant accounts)
disabledHostsSites where user explicitly declined password saving

Timestamps

Login timestamps use Unix milliseconds (milliseconds since 1970-01-01 UTC), which differs from the PRTime format used in SQLite databases.

timeCreated = 1685620800000
Unix seconds = 1685620800000 / 1000 = 1685620800
Result = 2023-06-01T12:00:00Z

A value of 0 means the timestamp was not recorded.

Analysis Notes

Credential Inventory

Enumerate all sites with saved credentials to build a service inventory:

  • The hostname list reveals which web services the user accesses.
  • Cross-reference with browsing history to determine active vs. dormant accounts.
  • The formSubmitURL may reveal internal corporate applications or staging environments.

Temporal Analysis

The three timestamps (timeCreated, timeLastUsed, timePasswordChanged) provide a credential lifecycle:

  • timeCreated: When the user first trusted Firefox with this password.
  • timeLastUsed: Last confirmed active use of the account.
  • timePasswordChanged: Last password rotation. If this equals timeCreated, the password has never been changed.
  • Gap analysis: A long gap between timeCreated and timePasswordChanged may indicate stale credentials.

Disabled Hosts

The disabledHosts array lists sites where the user clicked "Never save" when Firefox offered to save credentials. This is forensically relevant because:

  • It confirms the user logged into these sites.
  • It may indicate sites the user considers particularly sensitive (banking, healthcare).
  • The decision to not save implies awareness of credential security.

Encryption Details

Firefox uses Mozilla NSS (Network Security Services) for credential encryption:

  • key4.db: SQLite database containing encrypted master key material.
  • Encryption type 1 (SDR): Secret Decoder Ring encryption, the standard method.
  • Master Password: If set, adds an additional PKCS#5 encryption layer. Without the master password, offline decryption requires significantly more effort.
  • The collector collects key4.db alongside logins.json to preserve the complete encryption context for offline analysis tools.

Potentially Vulnerable Passwords

The potentiallyVulnerablePasswords array contains IDs of logins that Firefox Lockwise has flagged as potentially compromised (e.g., via breach monitoring). The presence of entries here indicates the user received breach notifications.

Useful Queries on Parsed Records

Since logins.json is JSON rather than SQLite, analysis is performed on the parsed output:

  • Sites with most logins used: Sort by timesUsed descending.
  • Recently created credentials: Sort by timeCreated descending.
  • Stale accounts: Filter where timeLastUsed is older than a threshold.
  • Never-changed passwords: Filter where timePasswordChanged == timeCreated.

Version Differences

VersionChange
Firefox 78key4.db replaces key3.db for NSS key storage
Firefox 76+Firefox Lockwise breach monitoring integration
Firefox 79+potentiallyVulnerablePasswords field added

The logins.json format has been stable since its introduction. Older Firefox versions (pre-32) used a signons.sqlite database instead, but this is well outside the supported version range.

Tool Support

ToolCapability
macforMetadata extraction from logins.json, key4.db collection, no decryption (Pro module)
firefox_decryptOpen-source Python tool for decrypting Firefox passwords (requires key4.db + optional master password)
firepwdPython NSS credential decryptor
AXIOMAutomated Firefox credential extraction and analysis
NetworkMinerCan extract saved credentials from Firefox profile data

References

Previous
Form History