Firefox Kept a Secret Across Your Tor Identities: The IndexedDB Oversight
Source: lobsters
The researchers at Fingerprint published a finding that should give anyone relying on Tor Browser for genuine anonymity a reason to pause. They discovered that IndexedDB databases created during a Tor Browser session persist across “New Identity” operations, providing a stable cross-session identifier that survives what users reasonably expect to be a complete privacy reset. The mechanism is mundane once you understand it, but the consequences for people who actually depend on Tor are serious.
What New Identity Is Supposed to Do
Tor Browser’s “New Identity” feature, implemented through the Torbutton extension, is the nuclear option for resetting your anonymized session. When you trigger it, several things happen: all open tabs close, a new Tor circuit is negotiated (so your exit node changes), cookies are deleted, active logins are cleared, and the browser’s cache is flushed. The intent is that after New Identity, your browser looks like a fresh install to any site you visit. You get a new IP address from the Tor network and none of the session state that could tie your new browsing to your old browsing.
The operative word is “none.” The Torbutton source calls into Firefox’s nsIClearDataService interface, which exposes a clearData() method that accepts a bitmask of flags specifying what to clear. Cookies have their flag. Cache has its flag. Active logins, permissions, history: all flags. IndexedDB, it turns out, was not getting cleared reliably. The result is that a site can write a UUID to IndexedDB during one session, and after New Identity, that UUID survives intact, ready to be read back and matched to the same user.
The Storage Layer That Got Overlooked
IndexedDB is a transactional, object-oriented database API built into every modern browser. Unlike localStorage, which stores simple key-value string pairs and has a 5-10MB ceiling, IndexedDB supports arbitrary structured data, binary blobs, indexes, and cursor-based queries. It was designed for offline-capable web apps and progressive web apps that need to store substantial amounts of structured state client-side. Service workers rely on it heavily.
The API is origin-keyed, meaning a database created by https://example.com is isolated from anything https://other.com can access. That origin partitioning is the same model cookies use, which is why clearing mechanisms that work site by site tend to overlap. A call to indexedDB.deleteDatabase("my-db") removes a specific database for the current origin. Firefox exposes a clearData service that can clear storage by origin, by time range, or entirely.
The problem is that IndexedDB in Firefox lives on disk under a different storage path than cookies, and the clearing codepath that Torbutton invoked did not consistently include it. An attacker-controlled site does not need anything sophisticated. The tracking code is straightforward:
const request = indexedDB.open("_fprint", 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
db.createObjectStore("id", { keyPath: "k" });
};
request.onsuccess = (event) => {
const db = event.target.result;
const tx = db.transaction("id", "readwrite");
const store = tx.objectStore("id");
const read = store.get("uid");
read.onsuccess = () => {
if (read.result) {
// Existing user, even after New Identity
reportIdentifier(read.result.v);
} else {
const uid = crypto.randomUUID();
store.put({ k: "uid", v: uid });
reportIdentifier(uid);
}
};
};
This is roughly twenty lines of vanilla JavaScript. No fingerprinting heuristics, no timing attacks, no WebGL entropy collection. A deterministic, persistent, stable identifier that survives Tor circuit rotation because it never touches the network layer that Tor controls.
Why This Class of Bug Keeps Appearing
This is not the first time a browser storage mechanism has been weaponized as a supercookie, and the pattern of discovery follows a consistent arc. Browser vendors add a new storage API for legitimate purposes. The privacy implications of that API’s persistence model are addressed within the context of normal browsing, with features like “Clear browsing data” dialogs. Then someone checks whether that clearing mechanism is comprehensive from an adversarial perspective and finds a gap.
The HSTS supercookie attack from 2015 used HTTP Strict Transport Security headers to encode bits of a user identifier in the browser’s HSTS cache. Cache timing attacks have been used to detect whether a user has visited specific URLs. ETag headers can function as server-set cookies that survive cookie clearing. The Evercookie project from Samy Kamkar catalogued over a dozen storage vectors including localStorage, IndexedDB, Web SQL, sessionStorage, userData (Internet Explorer), PNG alpha channel caching, and more, cross-syncing an identifier across all of them so that clearing any subset still left recoverable state.
What makes the Tor Browser case more acute than typical browser privacy failures is that the people who rely on Tor are often not people for whom “my ad preferences persist between sessions” is the relevant threat model. Journalists communicating with sources, activists in repressive jurisdictions, and researchers accessing sensitive materials have concrete reasons to need session isolation. When a browser feature promises a clean break and fails to deliver one, the failure cost is not measured in targeted advertising.
Firefox’s Storage Architecture and the Clearing Problem
Firefox separates its persistent storage into several subsystems: the places database for history and bookmarks, the cookie and site permissions database, the network cache, and the “DOM storage” subsystem that encompasses localStorage and IndexedDB. These live in different directories under a Firefox profile and are managed by different components.
The nsIClearDataService interface, documented in the Firefox source, exposes flags like CLEAR_COOKIES, CLEAR_DOM_STORAGES, CLEAR_CACHE, and so on. The CLEAR_DOM_STORAGES flag is supposed to cover localStorage and IndexedDB together. The bug that Fingerprint identified is that under certain conditions, the IndexedDB clearing triggered by this flag was not actually removing the on-disk databases, or was doing so inconsistently across profile restarts.
Part of the complexity is that Firefox’s IndexedDB implementation uses a multi-process architecture. The database operations happen in a separate process from the browser UI, and there are shutdown-order constraints on when storage can be safely cleared. The Torbutton code calling into nsIClearDataService does so synchronously from the main process, and if the IndexedDB process has not completed its shutdown sequence, the clear operation can silently fail or clear only in-memory state while the disk files remain.
This is a recurring class of problem in browser architecture: operations that need to be atomic across multiple subsystems, where each subsystem has its own lifecycle and shutdown semantics. Cookies are simple to clear because they live in a single SQLite file that the main process owns directly. IndexedDB databases are a collection of files managed by a worker process, and “clear” means coordinating a deletion across that boundary.
Storage Partitioning as the Longer-Term Answer
The approach the browser privacy community has converged on, rather than trying to enumerate and clear every storage vector, is storage partitioning: keying storage not just by origin but by the top-level site as well. This means that tracker.com storing data while embedded in site-a.com gets a different storage bucket than when embedded in site-b.com, so cross-site tracking via storage is structurally broken rather than relying on clearing.
Firefox has been rolling out Total Cookie Protection since Firefox 86, which applies this double-keying to cookies. The extension to IndexedDB and other storage APIs under the “State Partitioning” umbrella has been progressing, but Tor Browser’s privacy requirements go further than what standard Firefox’s state partitioning provides. State partitioning prevents cross-site tracking by embedding but does not help if the first-party site itself is doing the tracking across New Identity operations.
For the New Identity case, partitioning does not help at all. The vulnerability is that one first-party session can read state written by a previous first-party session for the same origin. The fix has to be in the clearing path.
What Was Fixed and What to Check
The Tor Browser team addressed this by ensuring IndexedDB is fully included in the storage clearing that happens on New Identity. The fix involves waiting for the IndexedDB worker process to acknowledge the clear operation before the New Identity sequence completes, rather than fire-and-forget behavior that could leave databases on disk.
If you are running Tor Browser, the relevant thing to check is whether your version postdates the fix. The Tor Project publishes security advisories with version numbers for patched releases. Running an unpatched version means sites you visit can correlate your current session with sessions from before your last New Identity, even across different Tor circuits and different IP addresses.
For users who have been running an affected version and are concerned about accumulated identifiers, the safest remediation is to delete the Tor Browser profile entirely and reinstall, rather than relying on New Identity in a version that did not clear correctly. The identifier is on disk. New Identity that does not clear the disk does not help.
The Broader Takeaway for Browser Privacy Work
What this finding illustrates is that privacy guarantees built on clearing mechanisms are brittle in proportion to the number of independent storage subsystems in the browser. Every new storage API added to the web platform is a potential gap in the clearing logic, and closing each gap requires knowing that the API exists, understanding its persistence semantics, and ensuring the clearing operation is synchronous and confirmed rather than best-effort.
Tor Browser is arguably the most aggressively privacy-hardened browser in active use. It disables WebRTC, normalizes screen sizes, restricts JavaScript APIs that leak timing information, and has extensive custom patches on top of Firefox ESR. That an oversight in IndexedDB clearing could persist even in that environment is a useful data point about how difficult this problem is in practice, not a reason to conclude the broader effort is not worth making.
The Fingerprint research team did the right thing by reporting this responsibly and working with the Tor Project before publishing. The full write-up is worth reading for the specific reproduction steps and the version-by-version analysis of where the clearing behavior changed.