How Evercookie Achieves Unbreakable Browser Persistence
This article explains the evercookie technique, detailing its multi‑dimensional storage methods—from standard cookies and Flash to IndexedDB and HSTS—showing how data can survive typical browser clean‑ups and how it can be applied for long‑term client identifiers.
0 Introduction
Front‑end persistence means storing data permanently on the client so that it is hard to delete or can be restored after deletion. The data is often called “zombie data”. This article introduces one such method—evercookie.
1 Evercookie Overview
Evercookie was created by Samy Kamkar, a white‑hat hacker and security researcher. It is a set of JavaScript APIs designed to persist cookies even after the user clears standard cookies, Flash cookies, etc., by restoring data from multiple storage dimensions.
2 Evercookie Principle
2.1 Core Idea
Data is written to many browser storage vectors; when reading, any vector that still contains the data can be used to reconstruct the original value. This makes the data extremely difficult for ordinary users to remove and allows automatic recovery of cleared data.
2.2 Storage Dimensions
Standard HTTP Cookie : Stored in
document.cookie. Easily cleared by the browser or JavaScript.
Flash Cookie (Local Shared Object) : Stored in a Flash LSO file. Example code:
<code>shared = sharedobject.getlocal("evercookie");
if (everdata) {
var newdata = everdata.split("=");
var str = shared.data.cookie;
var results = str.split("&");
var i = 0;
while (i < results.length) {
var elem = results[i].split("=");
if (elem[0] != newdata[0]) {
everdata = everdata + ("&" + results[i]);
}
i++;
}
shared.data.cookie = everdata.replace("\\", "\\\\");
shared.flush();
}
flash.external.ExternalInterface.call("_evercookie_flash_var", shared.data.cookie);
</code>localStorage : HTML5 API for permanent local storage, accessible across the same origin.
sessionStorage : Similar to localStorage but cleared when the browsing session ends.
globalStorage : Firefox‑only permanent storage (supported from Firefox 48).
openDatabase (WebSQL) : Deprecated HTML5 database API for large structured data.
IndexedDB : Built‑in NoSQL‑style database for permanent client‑side storage.
Image Cache : Data encoded as pixels in a generated PNG; retrieved by drawing the image onto a canvas and reading pixel values.
ETag : Data stored in the HTTP ETag header; retrieved via conditional requests (If‑None‑Match).
Web Cache : Uses HTTP caching mechanisms to persist data.
Silverlight : Client‑side storage via a Silverlight plug‑in and .xap files.
Java Applet Local Storage : Stores data in local files via JNLP‑launched applets.
IE userData : IE‑specific storage using XML/HTML attributes (up to ~640 KB per domain).
window.name : Persists a string across page navigations; often used for cross‑domain communication.
<a> visited state : Leverages the browser’s visited link styling to encode bits of data.
HSTS : Stores bits in the Strict‑Transport‑Security header across multiple domains. Example PHP implementation:
<code><?php
$is_ssl = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443;
if (isset($_GET['SET'])) {
if ($is_ssl) {
header('Strict-Transport-Security: max-age=31536000');
header('Content-type: image/png');
echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAgAAAAJCAIAAACAMfp5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVBhXY/z//z8DNsAEpTHAkJJgYAAAo0sDD8axyJQAAAAASUVORK5CYII=');
} else {
$redirect = "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("Location: $redirect");
}
die();
}
if (isset($_GET['DEL'])) {
if ($is_ssl) {
header('Strict-Transport-Security: max-age=0');
} else {
$redirect = "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("Location: $redirect");
}
die();
}
if ($is_ssl) {
header('Content-type: image/png');
echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAgAAAAJCAIAAACAMfp5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVBhXY/z//z8DNsAEpTHAkJJgYAAAo0sDD8axyJQAAAAASUVORK5CYII=');
die();
} else {
header('X-PHP-Response-Code: 404', true, 404);
}
?>
</code>2.3 Reading Data
Evercookie does not return the first value it finds; it collects data from all configured dimensions and selects the most reliable result, which helps prevent corruption but introduces asynchronous latency for some vectors (e.g., databases, ETag).
3 Application
Using evercookie for persistence allows data to survive aggressive cookie clearing, enabling long‑term identifiers for analytics, fraud detection, and other risk‑assessment scenarios. It can be a powerful tool for front‑end risk control systems.
4 Summary
Evercookie is essentially a collection of storage tricks that write and read data across many browser vectors. While it offers impressive resilience, some methods (like HSTS) have high overhead, and data retrieval can be asynchronous, so choose vectors based on your specific use case.
Tencent IMWeb Frontend Team
IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.