
Lehrreiche evercookie-Demo, die zeigt, wie Browser-Speicher und HTTP-Cache-Techniken einen Besucher dauerhaft wiedererkennen können.
Eine lehrreiche Demonstration, wie Websites dich dauerhaft identifizieren – und warum "Cookies löschen" nicht mehr ausreicht.
ubercookie pflanzt eine einzelne zufällige ID in 12 verschiedene Browser-Speichervektoren auf einmal ein. Bei jedem Besuch liest es alle aus, ermittelt einen Konsens und schreibt die ID überall wieder zurück. Lösche einen beliebigen Speicher – oder sogar alle deine Cookies – und die Überlebenden stellen sie still wieder her. Die Seite zeigt dir in klarer Sprache, wo genau deine ID versteckt ist und wie oft sie deinen Browser bereits erkannt hat.
Es ist die gleiche Idee wie Samy Kamkars klassisches evercookie – hier als offenes, transparentes Lehrmittel gebaut, das sich auf das Wiederherstellen von Speicher und die Persistenz von Supercookies konzentriert.
[!IMPORTANT] Dieses Projekt verfolgt den Besucher absichtlich, um Bewusstsein zu schaffen. Es verwendet nur Erstanbieter-Techniken, speichert lediglich eine zufällige ID, Besuchszahlen, erste/letzte Zeitstempel und Quell-Labels zur Wiederherstellung, teilt nichts mit Dritten und bietet einen echten "Vergiss mich"-Button. Nutze es nicht, um Menschen ohne ihr Wissen oder ihre Zustimmung zu verfolgen – das wäre das Gegenteil des Zwecks. Siehe Ethik.
| Vektor | Art | Benötigt JS? | Aus JS löschbar? | Was es lehrt |
|---|---|---|---|---|
document.cookie | client | yes | yes | Der Basistracker |
localStorage | client | yes | yes | Überlebt Cookie-Löschungen |
sessionStorage | client | yes | yes | Redundanz pro Tab |
IndexedDB | client | yes | yes | Eine ganze DB, die man vergisst zu löschen |
Cache API (caches) | client | yes | yes | Programmierbarer Speicher, getrennt von den obigen |
window.name | client | yes | yes | Überlebt Navigationen |
| OPFS (Origin Private File System) | client | yes | yes | Ein sandboxed Dateisystem, das manuelle Bereinigungen übersehen |
| Service Worker + Cache | client | yes | yes | Hintergrundskript stellt die ID erneut bereit, sogar offline |
Server-Cookie (HttpOnly) | server | no | über Server | Für JS unsichtbar, wird trotzdem bei jeder Anfrage gesendet |
| ETag-Supercookie | server | no | nur Cache leeren | ID wird in If-None-Match zurückgespiegelt |
| Last-Modified-Supercookie | server | no | nur Cache leeren | ID ist im Datum der gecachten Ressource kodiert |
| HTTP-Cache (eingebettetes ID-Skript) | server | no | nur Cache leeren | ID in eine immutable gecachte Datei eingebacken |
Darüber hinaus fordert die Seite beim Browser persistenten Speicher an (navigator.storage.persist()), der die IndexedDB-/Cache-/Service-Worker-/OPFS-Kopien von der automatischen Räumung ausnimmt – was sie noch schwerer zu entfernen macht.
Die drei cache-basierten Vektoren sind der Höhepunkt der Persistenz: Sie leben im HTTP-Cache des Browsers, sodass JavaScript (einschließlich unseres eigenen "Vergiss mich") sie nicht löschen kann – nur das Leeren des Browser-Caches schafft das. So kehrt die ID von den Toten zurück.
Eine ausführliche Beschreibung der implementierten Speichervektoren sowie die Idee des HSTS-Supercookies, die noch in dieses Projekt passt, findest du in docs/techniques.md.
ubercookie/
├── backend/ FastAPI — serverseitige Vektoren + das Beobachtungsprotokoll (SQLite)
│ └── app/
│ ├── main.py Endpunkte: /api/visit, /api/whoami, /api/etag-id,
│ │ /api/lastmod-id, /api/cache-id.js, /api/clear-cookie,
│ │ /api/forget
│ ├── store.py "Wir haben diesen Browser N-mal gesehen"-Speicher
│ └── ids.py Erstellen/Validieren der 32-stelligen hexadezimalen Tracking-ID
└── frontend/ Vanilla JS + Vite — das Dashboard und die Client-Vektoren
└── src/ubercookie/
├── index.js Orchestrator: lesen → Konsens → wiederherstellen → melden
└── vectors/ Ein eigenständiges Modul pro Speichervektor
So funktioniert ein Besuch (frontend/src/ubercookie/index.js):
HttpOnly-Cookie setzt.Erfordert Python ≥ 3.11 (mit uv) und Node ≥ 18.
make install # Backend-Abhängigkeiten (uv) + Frontend-Abhängigkeiten (npm)
# dann in zwei Terminals:
make backend # FastAPI auf http://localhost:8000
make frontend # Vite auf http://localhost:5173 (proxed /api → :8000)
Öffne http://localhost:5173 und beobachte, wie du getrackt wirst. Öffne DevTools, lösche einige Speicher, klicke auf Neu scannen und sieh zu, wie sie wieder auftauchen.
Einzeiler für beide Server gleichzeitig:
./scripts/dev.sh
make build # → frontend/dist
cd backend && uv run uvicorn app.main:app --port 8000
# öffne http://localhost:8000
Beide von einer einzigen Herkunft aus zu bedienen, ist die originalgetreueste Einrichtung, da die Cache-/ETag-Vektoren von echtem same-origin HTTP-Caching abhängen.
make test # Backend-Pytest (serverseitige Vektorlogik + Beobachtungsprotokoll)
make build # Frontend-Produktionsbuild
Die Backend-Tests prüfen die serverseitigen Vektoren und das Beobachtungsprotokoll. Das Browserverhalten muss noch mit einem echten Browser überprüft werden, da mehrere Vektoren vom Origin-Speicher, Service Workern und HTTP-Caching abhängen.
Dies ist ein defensives / bewusstseinsbildendes Werkzeug. In das Design eingebaute Richtlinien:
Bitte behalte jeden Fork im gleichen Geist: Verwende ihn, um Menschen beizubringen, wie Tracking funktioniert, damit sie sich selbst schützen können, nicht um sie heimlich zu verfolgen.
MIT – siehe LICENSE.