
Demo educativa dell'evercookie che mostra come le tecniche di archiviazione del browser e di cache HTTP possano re-identificare persistentemente un visitatore.
Una dimostrazione educativa di come i siti web ti identificano in modo persistente — e perché "cancellare i cookie" non è più sufficiente.
ubercookie inserisce un singolo id casuale in 12 diversi vettori di archiviazione del browser contemporaneamente. Ogni volta che visiti, li legge tutti, prende un consenso e riscrive l'id ovunque. Cancella un qualsiasi archivio — o anche tutti i cookie — e i sopravvissuti lo ri-generano silenziosamente. Il sito ti mostra, in linguaggio chiaro, esattamente dove si nasconde il tuo id e quante volte ha riconosciuto il tuo browser.
È la stessa idea alla base del classico evercookie di Samy Kamkar — realizzato qui come strumento didattico aperto e trasparente incentrato sulla ri-generazione dello storage e sulla persistenza dei supercookie.
[!IMPORTANT] Questo progetto traccia il visitatore apposta, per consapevolezza. È solo first-party, memorizza solo un id casuale, conteggi di visite, timestamp di primo/ultimo accesso ed etichette di fonte di recupero, non condivide nulla con terze parti e include un vero pulsante "Dimenticami". Non riutilizzarlo per tracciare persone senza la loro conoscenza o consenso — è l'opposto dello scopo. Vedi Etica.
| Vettore | Tipo | Richiede JS? | Cancellabile da JS? | Cosa insegna |
|---|---|---|---|---|
document.cookie | client | sì | sì | Il tracciante di base |
localStorage | client | sì | sì | Sopravvive alla cancellazione dei cookie |
sessionStorage | client | sì | sì | Ridondanza per scheda |
IndexedDB | client | sì | sì | Un intero database che la gente dimentica di cancellare |
Cache API (caches) | client | sì | sì | Archivio programmabile, separato dai precedenti |
window.name | client | sì | sì | Persiste tra le navigazioni |
| OPFS (Origin Private File System) | client | sì | sì | Un filesystem in sandbox che le pulizie manuali saltano |
| Service Worker + Cache | client | sì | sì | Script in background che ri-serve l'id, anche offline |
Cookie server (HttpOnly) | server | no | via server | Invisibile a JS, inviato comunque ad ogni richiesta |
| Supercookie ETag | server | no | solo svuotamento cache | Id rimandato in If-None-Match |
| Supercookie Last-Modified | server | no | solo svuotamento cache | Id codificato nella data della risorsa cacheata |
| Cache HTTP (script con id incorporato) | server | no | solo svuotamento cache | Id incorporato in un file cacheato immutable |
Oltre a questi, la pagina chiede al browser l'archiviazione persistente (navigator.storage.persist()), che esenta le copie IndexedDB / Cache / Service Worker / OPFS dall'evizione automatica — rendendole ancora più difficili da eliminare.
I tre vettori basati su cache sono il colpo di scena della persistenza: vivono nella cache HTTP del browser, quindi JavaScript (incluso il nostro "Dimenticami") non può eliminarli — solo svuotare la cache del browser lo fa. È così che l'id risorge.
Una descrizione completa dei vettori di archiviazione implementati, più l'idea del supercookie HSTS che ancora si adatta a questo progetto, si trova in docs/techniques.md.
ubercookie/
├── backend/ FastAPI — vettori lato server + il registro delle osservazioni (SQLite)
│ └── app/
│ ├── main.py endpoint: /api/visit, /api/whoami, /api/etag-id,
│ │ /api/lastmod-id, /api/cache-id.js, /api/clear-cookie,
│ │ /api/forget
│ ├── store.py memoria "abbiamo visto questo browser N volte"
│ └── ids.py crea/valida l'id di tracciamento esadecimale a 32 caratteri
└── frontend/ Vanilla JS + Vite — la dashboard e i vettori client
└── src/ubercookie/
├── index.js orchestratore: leggi-tutti → consenso → ri-genera → report
└── vectors/ un modulo auto-contenuto per ogni vettore di archiviazione
Come funziona una visita (frontend/src/ubercookie/index.js):
HttpOnly.Richiede Python ≥ 3.11 (con uv) e Node ≥ 18.
make install # backend deps (uv) + frontend deps (npm)
# then, in two terminals:
make backend # FastAPI on http://localhost:8000
make frontend # Vite on http://localhost:5173 (proxies /api → :8000)
Apri http://localhost:5173 e guardati mentre vieni tracciato. Apri DevTools, elimina alcuni archivi, premi Re-scan e guardali ri-generarsi.
Comando unico per entrambi i server contemporaneamente:
./scripts/dev.sh
make build # → frontend/dist
cd backend && uv run uvicorn app.main:app --port 8000
# open http://localhost:8000
Servire entrambi da una singola origine è la configurazione più fedele, perché i vettori cache/ETag dipendono dal reale caching HTTP stessa-origine.
make test # backend pytest (logica vettori lato server + registro osservazioni)
make build # build frontend produzione
I test del backend verificano i vettori lato server e il registro osservazioni. Il comportamento del browser necessita ancora di un browser reale per la verifica perché diversi vettori dipendono dallo storage di origine, dai Service Worker e dal caching HTTP.
Questo è uno strumento difensivo / di consapevolezza. Linee guida integrate nel design:
Per favore, mantieni qualsiasi fork nello stesso spirito: usalo per insegnare alle persone come funziona il tracciamento in modo che possano difendersi, non per tracciarle di nascosto.
MIT — vedi LICENSE.