What Is IndexedDB Fingerprinting? β Definition and How It Works
Learn how IndexedDB is used for persistent identity, why databases() leaks history, and how partitioning changed it.
IndexedDB fingerprinting uses the browser's structured storage database β its availability, its behaviour, and what it already contains β for identification and persistence.
1. Two Distinct Uses
As a persistence mechanism. IndexedDB stores a written identifier that survives page reloads, tab closes, and browser restarts β a cookie alternative that is less commonly cleared by users who clear cookies.
As a fingerprinting surface. Its availability, quota behaviour, and error characteristics vary by browser and configuration.
The first is the more consequential in practice: IndexedDB is a favoured place to keep an identity precisely because it survives cleanup that removes cookies.
2. Database Enumeration Leaks History
const dbs = await indexedDB.databases(); // where supported
// [{name: "...", version: 1}, ...]
This lists databases for the current origin. Within a partition it reveals what this origin has stored before β so a returning visitor is distinguishable from a first-time one without reading any value.
For automation the reading is direct: an empty database list means a fresh profile, every single time. Real browsers accumulate databases from the sites they visit.
3. Availability and Behaviour Vary
| Condition | Observable |
|---|---|
| Private browsing | Restricted, sometimes in-memory only |
| Storage blocked | Open requests fail |
| Quota exhausted | Writes fail with a quota error |
| Third-party context | Partitioned, or unavailable |
| Some hardened configurations | API missing entirely |
An indexedDB.open() that throws or is blocked is unusual for an ordinary desktop session, which makes the error path itself a signal.
4. Storage Partitioning Changed the Game
Historically an embedded third party could read the same IndexedDB across every parent site, making it an excellent cross-site tracking vector.
Modern browsers partition storage by top-level site, so the same third party gets a separate storage bucket per parent. That largely closes cross-site tracking through IndexedDB while leaving same-site persistence intact.
The consequence for detection: a browser that does share storage across partitions is behaving in a way current browsers do not, which is itself detectable. So disabling partitioning to simplify automation is visible.
5. Quota as an Environment Probe
navigator.storage.estimate() reports a quota derived from disk space, and IndexedDB writes fail against it. That makes quota an indirect measure of the host: a tiny quota suggests a constrained container, an enormous one a server volume.
Testing the failure point is slow and conspicuous, so this is more commonly read from the estimate than probed by writing.
6. The Pristine-Profile Problem Again
The dominant automation signal here is the same one storage fingerprinting exposes: a brand-new profile has no databases, no cached data, and near-zero usage. No real browser looks like that.
The mitigation is the same: persistent profiles, one per identity, reused across runs so ordinary residue accumulates. A profile that has actually browsed looks browsed.
7. Practical Guidance
- Use persistent profiles rather than a fresh one per run.
- Do not clear IndexedDB between requests in a session; browsers do not.
- Do not disable storage partitioning to make automation easier β it is observable.
- Provision adequate disk in containers if quota realism matters.
- Treat the profile directory as a credential, since it holds identity and session state.
- Clear on a schedule to bound growth, not per run.
8. Summary
IndexedDB fingerprinting uses storage availability, quota, error behaviour, and database enumeration, and IndexedDB is a favoured identity-persistence mechanism because it survives cookie clearing.
Storage partitioning has largely closed its cross-site tracking use, and the main automation tell is a pristine profile with no databases and zero usage β so reuse persistent per-identity profiles rather than wiping storage, and do not disable partitioning, because unpartitioned behaviour is itself anomalous.