
Образовательная демонстрация evercookie, показывающая, как методы хранения в браузере и кэширования HTTP могут постоянно повторно идентифицировать посетителя.
Демонстрация того, как веб-сайты постоянно вас идентифицируют — и почему «очистить куки» больше недостаточно.
ubercookie помещает один случайный идентификатор в 12 различных хранилищ браузера одновременно. При каждом посещении он читает их все, находит консенсус и перезаписывает идентификатор обратно повсюду. Очистите любое хранилище — или даже все куки — и уцелевшие молча восстановят его. Сайт показывает вам простым языком, где именно прячется ваш идентификатор и как часто он узнавал ваш браузер.
Это та же идея, что и в классическом evercookie Сэми Камкара — реализованная здесь как открытое, прозрачное учебное пособие, посвящённое восстановлению хранилищ и стойкости суперкуков.
[!IMPORTANT] Этот проект намеренно отслеживает посетителя для повышения осведомлённости. Он использует только first-party данные, хранит только случайный идентификатор, количество посещений, временные метки первого/последнего визита и метки источника восстановления, не передаёт ничего третьим лицам и предоставляет настоящую кнопку «Забудьте меня». Не используйте его для отслеживания людей без их ведома или согласия — это противоречит цели. См. Этика.
| Вектор | Тип | Нужен JS? | Очищаем из JS? | Что показывает |
|---|---|---|---|---|
document.cookie | клиентский | да | да | Базовый трекер |
localStorage | клиентский | да | да | Переживает очистку кук |
sessionStorage | клиентский | да | да | Резервирование на вкладку |
IndexedDB | клиентский | да | да | Целая БД, которую забывают очистить |
Cache API (caches) | клиентский | да | да | Программируемое хранилище, отдельное от остальных |
window.name | клиентский | да | да | Сохраняется при переходах |
| OPFS (Origin Private File System) | клиентский | да | да | Песочница файловой системы, которую пропускают ручные очистки |
| Service Worker + Cache | клиентский | да | да | Фоновый скрипт повторно отдаёт идентификатор, даже офлайн |
Серверная кука (HttpOnly) | серверный | нет | через сервер | Невидима для JS, но отправляется с каждым запросом |
| ETag суперкук | серверный | нет | только очистка кеша | Идентификатор возвращается в If-None-Match |
| Last-Modified суперкук | серверный | нет | только очистка кеша | Идентификатор закодирован в дате кешированного ресурса |
| HTTP-кеш (скрипт со встроенным id) | серверный | нет | только очистка кеша | Идентификатор вшит в immutable кешированный файл |
Вдобавок ко всему, страница запрашивает у браузера постоянное хранилище (navigator.storage.persist()), что освобождает копии в IndexedDB / Cache / Service Worker / OPFS от автоматического удаления — делая их ещё более сложными для избавления.
Три кешевых вектора — это ключ к стойкости: они живут в HTTP-кеше браузера, поэтому JavaScript (включая нашу кнопку «Забудьте меня») не может их удалить — только очистка браузерного кеша. Именно так идентификатор возвращается из мёртвых.
Полное описание реализованных векторов хранения, а также идея HSTS-суперкука, которая всё ещё подходит для этого проекта, находится в docs/techniques.md.
ubercookie/
├── backend/ FastAPI — серверные векторы + журнал наблюдений (SQLite)
│ └── app/
│ ├── main.py эндпоинты: /api/visit, /api/whoami, /api/etag-id,
│ │ /api/lastmod-id, /api/cache-id.js, /api/clear-cookie,
│ │ /api/forget
│ ├── store.py память «мы видели этот браузер N раз»
│ └── ids.py создание/валидация 32-символьного hex-идентификатора
└── frontend/ Vanilla JS + Vite — панель управления и клиентские векторы
└── src/ubercookie/
├── index.js оркестратор: читать всё → консенсус → восстановить → отчитаться
└── vectors/ по одному самодостаточному модулю на каждый вектор хранения
Как происходит посещение (frontend/src/ubercookie/index.js):
HttpOnly-куку.Требуется Python ≥ 3.11 (с uv) и Node ≥ 18.
make install # зависимости бэкенда (uv) + фронтенда (npm)
# затем в двух терминалах:
make backend # FastAPI на http://localhost:8000
make frontend # Vite на http://localhost:5173 (проксирует /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
# откройте http://localhost:8000
Обслуживание обоих из одного источника — наиболее точная настройка, поскольку векторы кеша/ETag зависят от реального HTTP-кеширования в рамках одного источника.
make test # pytest бэкенда (логика серверных векторов + журнал наблюдений)
make build # сборка фронтенда для продакшна
Тесты бэкенда проверяют серверные векторы и журнал наблюдений. Поведение браузера всё ещё требует реального браузера для проверки, поскольку несколько векторов зависят от хранилища источника, Service Workers и HTTP-кеширования.
Это оборонительный / обучающий инструмент. Правила, заложенные в дизайн:
Пожалуйста, сохраняйте тот же дух в любых форках: используйте его, чтобы обучать людей, как работает отслеживание, чтобы они могли защитить себя, а не для скрытой слежки за ними.
MIT — см. LICENSE.