
ブラウザストレージとHTTPキャッシュ技術が、訪問者を永続的に再識別できる仕組みを示す教育用 evercookie デモ。
ウェブサイトがどのようにしてあなたを永続的に識別するのか——そして「Cookieを消せばいい」がもはや通用しない理由を示す、教育用デモです。
ubercookie は、単一のランダムIDを12種類のブラウザストレージベクターに同時に埋め込みます。訪問のたびにすべてを読み取り、合意を取って、IDをすべての場所に書き戻します。どこか1つのストアを消しても——あるいはCookieを全部消しても——生き残ったストアが静かに 復活 させます。このサイトは、あなたのIDがどこに隠れているのか、どのくらい頻繁にブラウザを認識したのかを、平易な言葉で正確に表示します。
これは Samy Kamkar の古典的な evercookie と同じ発想を、ストレージの復活とスーパークッキーの永続性に焦点を当てた、オープンで透明な教材として構築したものです。
[!IMPORTANT] このプロジェクトは、啓発のために意図的に訪問者を追跡します。ファーストパーティのみを使用し、ランダムなID・訪問回数・初回/最終アクセス時刻・復元元ラベルだけを保存し、第三者とは一切共有しません。また、実際に動作する 「Forget me」 ボタンが付属しています。人の同意なしに追跡する目的に流用しないでください——それは本プロジェクトの趣旨に反します。倫理を参照してください。
| ベクター | 種類 | JS必要? | JSから消去可能? | 学べること |
|---|---|---|---|---|
document.cookie | クライアント | はい | はい | 基本のトラッカー |
localStorage | クライアント | はい | はい | Cookie消去後も生存する |
sessionStorage | クライアント | はい | はい | タブごとの冗長性 |
IndexedDB | クライアント | はい | はい | 消し忘れがちなDB全体 |
Cache API (caches) | クライアント | はい | はい | 上記とは別のプログラム可能なストア |
window.name | クライアント | はい | はい | ナビゲーションをまたいで持続する |
| OPFS (Origin Private File System) | クライアント | はい | はい | 手動クリーンアップでは消せないサンドボックス化ファイルシステム |
| Service Worker + Cache | クライアント | はい | はい | バックグラウンドスクリプトがIDを再提供、オフラインでも |
サーバーCookie (HttpOnly) | サーバー | いいえ | サーバー経由 | JSからは不可視、すべてのリクエストで送信される |
| ETagスーパークッキー | サーバー | いいえ | キャッシュ削除のみ | If-None-Match でIDがエコーバックされる |
| Last-Modifiedスーパークッキー | サーバー | いいえ | キャッシュ削除のみ | キャッシュ済みリソースの日時にIDが埋め込まれる |
| HTTPキャッシュ (ID埋め込みスクリプト) | サーバー | いいえ | キャッシュ削除のみ | immutable なキャッシュファイルにIDが焼き込まれる |
これらに加えて、ページはブラウザに永続ストレージ(navigator.storage.persist())を要求します。これにより、IndexedDB / Cache / Service Worker / OPFS のコピーが自動削除の対象から除外され、さらに剥がしにくくなります。
キャッシュベースの3つのベクターが永続性の核心です。これらはブラウザのHTTPキャッシュ内に存在するため、JavaScript(私たち自身の「Forget me」を含む)では削除 できません——ブラウザのキャッシュを消すだけです。それがIDが死からよみがえる仕組みです。
実装済みストレージベクターの完全な解説と、このプロジェクトに当てはまるHSTSスーパークッキーのアイデアは、docs/techniques.md にあります。
ubercookie/
├── backend/ FastAPI — server-side vectors + the observation log (SQLite)
│ └── app/
│ ├── main.py endpoints: /api/visit, /api/whoami, /api/etag-id,
│ │ /api/lastmod-id, /api/cache-id.js, /api/clear-cookie,
│ │ /api/forget
│ ├── store.py "we've seen this browser N times" memory
│ └── ids.py mint/validate the 32-hex tracking id
└── frontend/ Vanilla JS + Vite — the dashboard and the client vectors
└── src/ubercookie/
├── index.js orchestrator: read-all → consensus → respawn → report
└── vectors/ one self-contained module per storage vector
訪問の仕組み(frontend/src/ubercookie/index.js):
HttpOnly Cookieを設定します。Python ≥ 3.11(uv 付き)と 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)
http://localhost:5173 を開いて、自分が追跡されるのを確認してください。DevToolsを開き、いくつかのストアを削除して Re-scan を押すと、復活する様子がわかります。
両サーバーを一度に起動するワンライナー:
./scripts/dev.sh
make build # → frontend/dist
cd backend && uv run uvicorn app.main:app --port 8000
# open http://localhost:8000
両方を1つのオリジンから配信するのが最も忠実な構成です。cache/ETagベクターは、実際の同一オリジンHTTPキャッシュに依存するためです。
make test # backend pytest (server-side vector logic + observation log)
make build # frontend production build
バックエンドのテストは、サーバーサイドのベクターと観察ログを検証します。ブラウザの挙動は、複数のベクターがオリジンストレージ・Service Worker・HTTPキャッシュに依存するため、実際のブラウザでの確認が依然として必要です。
これは防御 / 啓発のためのツールです。設計に組み込まれたガイドライン:
フォークする場合も同じ精神を守ってください: 人々が自分を守れるよう追跡の仕組みを教えるために使い、秘かに追跡するために使わないでください。
MIT — LICENSE を参照してください。