Privacy engineering · Browser internalsПриватность · Внутренности браузера

N0deZ3r0 — ALEX — privacy & browser-internals engineer

I make browsers stop introducing you to everyone you visit. Делаю так, чтобы браузер перестал представлять вас каждому сайту.

ALEX — privacy & browser-internals engineer. Anti-fingerprinting, patched Chromium, Windows telemetry. Everything MIT. ALEX — инженер приватности и внутренностей браузера. Анти-фингерпринтинг, патченый Chromium, телеметрия Windows. Всё под MIT.

01

AboutО себе

I work on the parts of the web that identify you without asking — canvas, WebGL, font metrics, timezone, screen geometry — and on making them report something else, consistently enough to survive cross-checking. A spoof that contradicts itself is worse than none: it makes you more distinctive, not less.

Занимаюсь теми частями веба, которые опознают вас, не спрашивая, — canvas, WebGL, метрики шрифтов, часовой пояс, геометрия экрана, — и тем, чтобы они сообщали что-то другое, причём согласованно, выдерживая перекрёстную проверку. Подмена, которая противоречит сама себе, хуже, чем её отсутствие: она делает вас более приметным, а не менее.

Fingerprint resistanceУстойчивость к отпечатку

Coherent profiles rather than scattered navigator overrides. Verified against CreepJS, BrowserLeaks, Pixelscan and AmIUnique.Согласованные профили вместо разрозненных переопределений navigator. Проверено на CreepJS, BrowserLeaks, Pixelscan и AmIUnique.

Patched Chromium and extensionsПатченый Chromium и расширения

When a flag is not enough, the patch series is. Manifest V3, WebAssembly cores, isolated and main-world injection.Когда флага недостаточно, в дело идёт серия патчей. Manifest V3, ядра на WebAssembly, внедрение в isolated и main world.

Windows privacy toolingИнструменты приватности для Windows

C# and PowerShell. Telemetry off — and still off after the next feature update, because something has to keep watching.C# и PowerShell. Телеметрия выключена — и остаётся выключенной после следующего крупного обновления, потому что кто-то должен за этим следить.

AutomationАвтоматизация

Job applications, latency checks, and the browser workflows worth writing down once.Отклики на вакансии, замеры задержки и те браузерные сценарии, которые стоит записать один раз.

02

Selected workИзбранное

One coherent invented machine — the same one in the window, in every frame and in every worker. A claim the layout can contradict produces a machine that cannot exist, which is rarer than the one you started from.Одна согласованная выдуманная машина — та же самая в окне, в каждом фрейме и в каждом воркере. Заявка, которую раскладка может опровергнуть, собирает машину, которой не бывает, а такая встречается реже исходной.

40 test suites40 сьютов 16 documented limits16 описанных пределов Manifest V3Manifest V3 JavaScript

Disables Microsoft's data collection, shows what has already been collected about this machine, and keeps checking on a schedule — because feature updates quietly restore what you turned off.Отключает сбор данных Microsoft, показывает, что об этой машине уже собрано, и продолжает проверять систему по расписанию — потому что крупные обновления тихо возвращают выключенное.

scheduled re-checkпроверка по расписанию .NET Framework 4.8.NET Framework 4.8 Windows 10 · 11Windows 10 · 11 C#

An instrument, not a blocker: a journal of which script read which fingerprinting surface, and outgoing beacons parsed field by field — "this is a hash of your email" instead of base64.Инструмент, а не блокировщик: журнал того, какой скрипт прочитал какую поверхность отпечатка, и исходящие маячки, разобранные по полям, — «это хеш вашей почты» вместо base64.

beacons decodedмаячки разобраны per-script journalжурнал по скриптам Manifest V3Manifest V3 JavaScript

Applies to hh.ru vacancies behind five layers of defence, so the site cannot profile the machine doing it — and surfaces what the page receives but never shows you.Откликается на вакансии hh.ru за пятью рубежами обороны, чтобы сайт не мог опознать машину, которая это делает, — и показывает то, что страница получает, но вам не показывает.

26 WASM functions26 функций WASM 32 trackers blocked32 трекера заблокированы 11 APIs intercepted11 API перехвачено JavaScript

Response time for any site from the Chrome toolbar. Type an address, get milliseconds. No account, no configuration, and ERROR instead of an invented number when a host is unreachable.Время отклика любого сайта прямо из панели Chrome. Ввели адрес — получили миллисекунды. Без регистрации, без настройки, и ERROR вместо выдуманного числа, когда узел недоступен.

median of samplesмедиана выборки no accountбез регистрации JavaScript

The same idea without an extension: one injected script that checks what you have already applied to, fills in the cover letter and turns the pages.То же самое без расширения: один внедряемый скрипт, который проверяет, куда вы уже откликнулись, заполняет сопроводительное письмо и листает страницы.

single injected scriptодин внедряемый скрипт no installбез установки JavaScript
03

Three in depthТри разбора

fingerprint-shield

Chrome MV3 · v2.5.31 · JavaScript + WebAssembly
The problemЗадача

A spoof that contradicts itself is worse than none. Scattered navigator overrides leave a machine whose claims the layout can disprove — and the contradiction itself becomes the fingerprint, rarer than the one you started from.Подмена, которая противоречит сама себе, хуже, чем её отсутствие. Разрозненные переопределения navigator оставляют машину, чьи заявки раскладка может опровергнуть, — и само противоречие становится отпечатком, более редким, чем исходный.

What I builtЧто построил

Ten main-world modules, ~15 500 lines, that assemble one invented machine and keep it identical in the window, in every frame and in every worker — across 20 Web API interfaces: Navigator, Screen, Canvas and OffscreenCanvas, WebGL and WebGL2, TextMetrics, FontFaceSet, MediaCapabilities, NetworkInformation, Date, Intl. Workers are built from a blob so the patch reaches them too. The shipped bundle and the dynamic tables are both generated, and the UI carries 215 strings in each of two locales.Десять модулей main world, ~15 500 строк, которые собирают одну выдуманную машину и держат её одинаковой в окне, в каждом фрейме и в каждом воркере — по 20 интерфейсам Web API: Navigator, Screen, Canvas и OffscreenCanvas, WebGL и WebGL2, TextMetrics, FontFaceSet, MediaCapabilities, NetworkInformation, Date, Intl. Воркеры собираются из blob, чтобы патч доезжал и туда. Бандл и динамические таблицы генерируются, интерфейс — по 215 строк в каждой из двух локалей.

How it is verifiedЧем проверено

64 suites, 1 646 assertions. 941 timezone assertions are checked against the ICU that Node bundles, which is why Node is pinned to the exact patch release 24.19.0 — a tzdata update changes the measurement, and once did, turning the build red with no change to the code. A static-parity suite fails if the generated bundle on disk has drifted from its modules. The browser set drives 26 pages through Playwright against a real Chromium with the extension loaded. Nightly, the whole set runs three times and writes a flake ledger: before that, conclusions were drawn one run at a time, and a single unchanged commit produced 12, 0, 2, 4 and 0 red suites.64 сьюта, 1 646 проверок. 941 утверждение о часовых поясах сверяется с ICU, вшитым в Node, — поэтому Node запинен до точного патча 24.19.0: обновление tzdata меняет измерение, и однажды уже уронило сборку без единой правки кода. Отдельный сьют падает, если сгенерированный бандл на диске отстал от модулей. Браузерный набор гоняет 26 страниц через Playwright на живом Chromium с загруженным расширением. Ночью весь набор проходит трижды и пишет журнал флаки-тестов: до него выводы делались по одиночным прогонам, и один неизменный коммит выдавал 12, 0, 2, 4 и 0 красных сьютов.

And a Limits section: sixteen things it knowingly does not close, each with the measurement behind it — 16 cores against 18, Europe/Berlin against Europe/Moscow — numbered, and referenced from the code and the audit page so the numbers never shift.И раздел «Пределы»: шестнадцать пунктов, которые заведомо не закрыты, каждый с измерением — 16 ядер против 18, Europe/Berlin против Europe/Moscow — пронумерованных, и код со страницей аудита ссылаются на эти номера, поэтому они не сдвигаются.

64suitesсьюта
1 646assertionsпроверки
941tz assertionstz-утверждения
16known limitsописанных пределов

Win11Privacy

Windows 10 · 11 · C# / WinForms · .NET Framework 4.8 · PowerShell
The problemЗадача

Telemetry you turned off stays off only until the next feature update quietly puts it back. A script run once cannot notice that; something has to keep watching.Выключенная телеметрия остаётся выключенной только до следующего крупного обновления, которое тихо вернёт её обратно. Скрипт, запущенный один раз, этого не заметит — кто-то должен продолжать следить.

What I builtЧто построил

Split in two: a 269 KB PowerShell engine that owns the system — 99 HKLM and 52 HKCU keys, 7 services, 10 scheduled tasks, every setting declared together with its rollback — and 10 200 lines of C# on top of it. No external dependencies: csc.exe compiles it directly, so a release is one portable exe. Bilingual interface, 141 KB of it in the string table alone.Разделено на две части: движок на PowerShell в 269 КБ, который владеет системой — 99 ключей HKLM и 52 HKCU, 7 служб, 10 запланированных задач, каждая настройка описана вместе с откатом, — и 10 200 строк C# поверх него. Без внешних зависимостей: csc.exe собирает напрямую, поэтому релиз — один переносимый exe. Интерфейс на двух языках, одна таблица строк на 141 КБ.

How it is verifiedЧем проверено

163 behaviour checks on the engine. The step that matters runs on a live Windows runner: it applies the whole set of settings to the machine, rolls it back, and fails the build if the system did not return to the state it started in — the only check that catches a rollback which silently does nothing. Around it: engine syntax, version consistency across the sources, translation completeness, a separately compiled self-test that walks the UI pages, checksums, and the winget manifest.163 проверки поведения движка. Главный шаг идёт на живом Windows-раннере: применяет весь набор настроек к машине, откатывает и роняет сборку, если система не вернулась в исходное состояние, — единственная проверка, которая ловит откат, тихо не сделавший ничего. Вокруг: синтаксис движка, сверка версий по всем исходникам, полнота перевода, отдельно собираемый self-test, прогоняющий страницы интерфейса, контрольные суммы и манифест winget.

163engine checksпроверки движка
151registry keysключа реестра
17services & tasksслужб и задач
11CI stepsшагов CI

X-ray-for-web

Chrome MV3 · v0.1.0 · JavaScript
The problemЗадача

Blockers tell you something was stopped. They do not tell you who read your canvas, or what exactly left in that beacon. An instrument has to answer both — without becoming the reason the page is slow.Блокировщики сообщают, что что-то остановлено. Они не говорят, кто прочитал ваш canvas и что именно ушло в маячке. Прибор должен отвечать на оба вопроса — и не стать сам причиной того, что страница тормозит.

What I builtЧто построил

67 wrapped surfaces, split into four cost classes by call frequency, each with its own stack-capture policy: cold ones always, hot ones for the first 8 per surface and a counter after that. Class D — offsetWidth and offsetHeight — is deliberately left alone: fonts are fingerprinted through it, but so is every layout, and wrapping a getter read on every size query breaks the page. A hard budget of 1 200 stack captures per document caps the cost regardless of how hard the page pokes. Beacons are decoded by declarative parsers — GA4, Meta Pixel, Yandex Metrica and Webvisor — each with its own benchmark fixture.67 обёрнутых поверхностей, разбитых на четыре класса стоимости по частоте вызова, у каждого своя политика снятия стека: холодные — всегда, горячие — первые 8 на поверхность, дальше счётчик. Класс D — offsetWidth и offsetHeight — намеренно не трогается: через него снимают отпечаток шрифтов, но его же дёргает любая раскладка, и обёртка на геттере, читаемом при каждом запросе размера, ломает страницу. Жёсткий бюджет в 1 200 снятий стека на документ ограничивает цену независимо от того, насколько сильно страница дёргает. Маячки разбираются декларативными парсерами — GA4, Meta Pixel, Яндекс.Метрика и Вебвизор — у каждого свой бенч-фикстура.

How it is verifiedЧем проверено

The budget numbers are measured, not guessed, with the method and the baseline written down: 18.1 µs for a cold call with a stack capture, 21.7 ms for the full 1 200-capture budget, 0.155 µs for a hot measureText. Nine test files, 2 800 lines. host_permissions ships empty and site access is asked for optionally — a tool about privacy should not take rights by default. Fourteen limits documented, including the font coverage that leaving class D alone costs it.Числа бюджета измерены, а не взяты с потолка, с методикой и базой: 18,1 мкс на холодный вызов со снятием стека, 21,7 мс на полный бюджет из 1 200 снятий, 0,155 мкс на горячий measureText. Девять файлов тестов, 2 800 строк. host_permissions отдаётся пустым, доступ к сайтам запрашивается опционально — инструмент про приватность не должен брать права по умолчанию. Четырнадцать пределов описаны, включая неполное покрытие шрифтов, которым оплачен отказ от класса D.

67surfacesповерхностей
18.1 µsper captureна снятие
1 200capture budgetбюджет снятий
14known limitsописанных пределов
04

StackСтек

LanguagesЯзыки
JavaScript · TypeScript · C# · C++ · Python
Runtime and buildСреда и сборка
WebAssembly · Node.js · .NET Framework 4.8 · PowerShell · Bash
TargetsЦели
Chromium · Chrome extensions (Manifest V3) · Windows 10 and 11расширения Chrome (Manifest V3) · Windows 10 и 11
ToolingИнструменты
Git · GitHub Actions · Visual Studio · VS Code
05

How the repositories shipКак устроены репозитории

CI
GitHub Actions on every repository — build, lint and tests before a release exists.GitHub Actions в каждом репозитории — сборка, линт и тесты раньше, чем появится релиз.
EN · RU
Documentation and interfaces in both languages, following the browser.Документация и интерфейсы на двух языках, по настройке браузера.
SECURITY.md
A disclosure policy and issue templates, so a report has somewhere to go.Политика раскрытия и шаблоны задач, чтобы сообщению было куда прийти.
MIT
Everything public, everything permissive. No telemetry in tooling about telemetry.Всё открыто и разрешительно. Никакой телеметрии в инструментах против телеметрии.
06

ContactКонтакты

Privacy isn't a setting. It's an engineering budget. Приватность — это не галочка. Это статья инженерного бюджета.

The fastest way to reach me is an issue on any of the repositories — they all carry templates and a security policy. Быстрее всего — issue в любом из репозиториев: везде есть шаблоны и политика безопасности.