feature: шум canvas с seed профиля — отпечатки профилей различаются (#89)

Минимальный init-script (src/api/js/canvas_noise.js): младший бит у ~1/64 непрозрачных
пикселей при toDataURL/toBlob/getImageData, детерминирован от seed профиля. Пустой
canvas не меняется, подменённые функции неотличимы по toString и length. Старые
профили получают seed, экран сохраняется.

Проверено: 4 профиля — 4 разных хеша canvas; Cloudflare 6/6 на новых профилях.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
protokeyandClaude Opus 5.5 committed 2026-10-13 21:02:21 +04:00
1 parent 4c8394eb4c
commit 9dc2c0b619
6 files changed
+176 -19

No files matched your search

+12 -4
View File
@@ -138,11 +138,19 @@ Cookie: session_id=<id> # необязательно, см. «Сесси
(`extra/user_data_dir/<session_id>`): cookies, localStorage и отпечаток сохраняются, повторно проходить Cloudflare
обычно не нужно. Без cookie или с некорректным значением (не UUID) запрос получает новый профиль.
Сессии изолированы друг от друга: у каждой свой профиль Chrome — cookies, localStorage, кэш.
Отпечаток профиля генерируется при первом запросе сессии и дальше не меняется (`robotex_session.json` в каталоге
профиля): размер экрана и `devicePixelRatio` десктопного Chrome на Linux из реального распределения (browserforge).
Применяется нативной эмуляцией Chrome, без JS-подмены (она ломала прохождение Cloudflare); DPR влияет и на хеш
canvas. Ограничение: canvas, WebGL и `hardwareConcurrency` у всех профилей одинаковые, поэтому примерно половина
профилей совпадает по отпечатку.
профиля):
* размер экрана и `devicePixelRatio` десктопного Chrome на Linux из реального распределения (browserforge) —
нативной эмуляцией Chrome;
* шум canvas: свой seed у каждого профиля, поэтому хеш canvas у профилей разный, а внутри профиля стабильный.
Меняется младший бит у редких непрозрачных пикселей при чтении canvas (`toDataURL`, `toBlob`, `getImageData`);
пустой canvas не меняется.
Остальное — WebGL, `hardwareConcurrency`, шрифты, UA — не подменяется: это родные значения Chrome, за маскировку
автоматизации отвечает Patchright. Полная JS-подмена отпечатка ломала прохождение Cloudflare.
User-Agent и размер окна запросом не задаются — это родные значения браузера (почему — [Usage.md](Usage.md#что-задаёт-сервис-а-не-клиент)).
Поле `user_agent` в запросе даёт `422`.