Firefox cookie database
Cookies in Firefox are stored in an SQLite format database found in the file cookies.sqlite in the currently-active user profile directory (exact path is system-dependent). Also, the write-ahead-logging and shared-memory files cookies.sqlite-wal and cookies.sqlite-shm are used, but the latter two are re-integrated into the main database file and deleted when you close the browser.
The structure is seen in this SQL command embedded in the file:
CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT, expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER, baseDomain TEXT, creationTime INTEGER)
Firefox Contextual Identity Project (Containers)
Firefox has implemented OriginAttributes in internal APIs to support features like Multi-Account Containers. Based on that, the same cookie name at the same host on the same path may return multiple values due to different originAttributes values (representing different containers).
As of Firefox 104 (released 2022-08-23), the cookies.sqlite schema is:
CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, originAttributes TEXT NOT NULL DEFAULT '', name TEXT, value TEXT, host TEXT, path TEXT, expiry INTEGER, lastAccessed INTEGER, creationTime INTEGER, isSecure INTEGER, isHttpOnly INTEGER, inBrowserElement INTEGER DEFAULT 0, sameSite INTEGER DEFAULT 0, rawSameSite INTEGER DEFAULT 0, schemeMap INTEGER DEFAULT 0, CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes))
Field Name | Type | Schema | Notes |
---|---|---|---|
id |
INTEGER |
PRIMARY KEY |
SQLite unique row ID |
originAttributes |
TEXT |
NOT NULL DEFAULT '' |
Values mapped to containers in conatiners.json . Some containers, like the one for extensions (userContextIdInternal.webextStorageLocal ), will always exist even if the Multi-Account Container or Firefox Container extensions are not installed.
|
name |
TEXT |
Cookie name | |
value |
TEXT |
Cookie value | |
host |
TEXT |
Hostname that owns the cookie | |
path |
TEXT |
Pathname at that host that owns the cookie | |
expiry |
INTEGER |
Cookie expiration in standard Unix timestamp format | |
lastAccessed |
INTEGER |
Cookie last accessed time in microseconds since the Unix epoch | |
creationTime |
INTEGER |
Cookie creation time in microseconds since the Unix epoch | |
isSecure |
INTEGER |
Send/receive cookie over HTTPS only. Set in Set-Cookie header | |
isHttpOnly |
INTEGER |
Access to the cookie via client-side script is prevented. Set in Set-Cookie header | |
inBrowserElement |
INTEGER |
DEFAULT 0 |
Legacy Firefox OS setting to create "cookie jars" |
sameSite |
INTEGER |
DEFAULT 0 |
Cookies should only be readable by the same site that set them. Set in Set-Cookie header |
rawSameSite |
INTEGER |
DEFAULT 0 |
"Preserve the 'on the wire' value [of the SameSite cookie, meaning the value found in the Set-Cookie header"] |
schemeMap |
INTEGER |
DEFAULT 0 |
[https://bugzilla.mozilla.org/show_bug.cgi?id=1638358#c0 Consider different "schemes" (meaning http vs https) to be different sites |
The CONSTRAINT
clause makes SQLite require the quadruple of name
, host
, path
, originAttributes
to be unique.
Datetime formats
There are 3 dateime fields: expiry, lastAccessed, and creationTime.
expiry
is stored in standard Unix timestamp format. In SQLite, this can be converted to a human-readable format with datetime("expiry", 'unixepoch')
.
However, lastAccessed
and creationTime
are in microseconds since the Unix epoch. To convert to a human-readable format in SQLite use datetime(("creationTime"/1000000),'unixepoch')
.