fix(tradein/browser): куки клались на поддомен и вечно держали QRATOR-загрузчик (#3261) #3262

Merged
lekss361 merged 3 commits from fix/browser-cookie-domain-and-fonts into main 2026-08-29 22:53:21 +00:00
Owner

Закрывает #3261.

Что было

Сайдкар инжектил куки на домен из url карточки — для ekaterinburg.domclick.ru это .ekaterinburg.domclick.ru. Настоящие куки площадки живут на .domclick.ru (видно в записи ручной сессии 29.08: .domclick.ru qrator_jsid2, .domclick.ru qrator_jsr).

Куки поддомена родительские не заменяют, а сосуществуют с ними: как только площадка выдаёт свежий qrator_jsid2 на .domclick.ru, браузер шлёт в одном запросе две куки с этим именем, и первой — более специфичную, нашу протухшую. QRATOR читает её и держит страницу на 274-байтном загрузчике, рукопожатие не завершается никогда.

Замер

Прод-сайдкар против пропатченного, один и тот же снимок кук из БД, одни и те же узлы, чередование плеч, свежий контекст на пробу. Прогон повторён с обратным порядком узлов и плеч — выиграли те же узлы, так что это не эффект очерёдности:

плечо результат
прод (куки на поддомен) 0 из 8
патч (куки на .domclick.ru) 4 из 8 (узлы 1 и 9 — 2 из 2 каждый; 10 и 11 отказывают в любом плече)

Отдельно изолированы шрифты — третьим плечом собран образ только со шрифтами на прод-овском server.py:

плечо результат
прод 0 из 4
только шрифты 0 из 4
шрифты + домен кук 3 из 4

Чинит именно домен кук. Шрифты сами по себе не дают ничего.

Локальный контроль в тот же час: через те же узлы с камуфоксом на машине разработчика 3 из 4 узлов отдавали карточки (426 КБ / 384 КБ / 867 КБ), пока прод отказывал на всех четырёх, — то есть пул был живой, отказывал сервер.

Шрифты

Прод-контейнер нёс 8 файлов / 3 семейства (только DejaVu) при камуфоксе с os="windows" — браузер, называющий себя Windows, но не знающий Arial/Times New Roman/Calibri, ловится перечислением шрифтов. Добавлены метрически совместимые Liberation/Carlito/Caladea. С отказами Домклика это, как показано выше, не связано — правка про правдоподобие отпечатка, отдельная нестыковка.

Проверка сборки смотрит не на число файлов, а на алиасы: первая версия требовала ≥30 файлов и покраснела на фактических 20 — порог был угадан. Теперь гейт проверяет, что fc-match Arial → Liberation Sans и так по всем пяти алиасам.

Ограничение, принятое сознательно

_cookie_domain берёт два последних лейбла. Для example.co.uk это дало бы .co.uk, но все площадки проекта — в зонах первого уровня (domclick.ru, avito.ru, cian.ru, yandex.ru); тащить publicsuffix-список ради гипотетического случая дороже, чем он стоит. Оговорено в докстринге.

Тесты

Новый test_server_cookie_domain.py (8 проверок). Три существующих теста закрепляли ровно то поведение, которое оказалось багом (.ekaterinburg.domclick.ru / .www.avito.ru / .realty.yandex.ru) — переведены на новый контракт, докстринги объясняют почему. Прогон сайдкара целиком: 206 passed.

Закрывает #3261. ## Что было Сайдкар инжектил куки на домен из url карточки — для `ekaterinburg.domclick.ru` это `.ekaterinburg.domclick.ru`. Настоящие куки площадки живут на `.domclick.ru` (видно в записи ручной сессии 29.08: `.domclick.ru qrator_jsid2`, `.domclick.ru qrator_jsr`). Куки поддомена родительские **не заменяют, а сосуществуют** с ними: как только площадка выдаёт свежий `qrator_jsid2` на `.domclick.ru`, браузер шлёт в одном запросе две куки с этим именем, и первой — более специфичную, нашу протухшую. QRATOR читает её и держит страницу на 274-байтном загрузчике, рукопожатие не завершается никогда. ## Замер Прод-сайдкар против пропатченного, один и тот же снимок кук из БД, одни и те же узлы, чередование плеч, свежий контекст на пробу. Прогон повторён с **обратным** порядком узлов и плеч — выиграли те же узлы, так что это не эффект очерёдности: | плечо | результат | |---|---| | прод (куки на поддомен) | **0 из 8** | | патч (куки на `.domclick.ru`) | **4 из 8** (узлы 1 и 9 — 2 из 2 каждый; 10 и 11 отказывают в любом плече) | Отдельно изолированы шрифты — третьим плечом собран образ **только со шрифтами** на прод-овском `server.py`: | плечо | результат | |---|---| | прод | 0 из 4 | | только шрифты | **0 из 4** | | шрифты + домен кук | **3 из 4** | Чинит именно домен кук. Шрифты сами по себе не дают ничего. Локальный контроль в тот же час: через те же узлы с камуфоксом на машине разработчика 3 из 4 узлов отдавали карточки (426 КБ / 384 КБ / 867 КБ), пока прод отказывал на всех четырёх, — то есть пул был живой, отказывал сервер. ## Шрифты Прод-контейнер нёс 8 файлов / 3 семейства (только DejaVu) при камуфоксе с `os="windows"` — браузер, называющий себя Windows, но не знающий Arial/Times New Roman/Calibri, ловится перечислением шрифтов. Добавлены метрически совместимые Liberation/Carlito/Caladea. **С отказами Домклика это, как показано выше, не связано** — правка про правдоподобие отпечатка, отдельная нестыковка. Проверка сборки смотрит не на число файлов, а на алиасы: первая версия требовала ≥30 файлов и покраснела на фактических 20 — порог был угадан. Теперь гейт проверяет, что `fc-match Arial` → Liberation Sans и так по всем пяти алиасам. ## Ограничение, принятое сознательно `_cookie_domain` берёт два последних лейбла. Для `example.co.uk` это дало бы `.co.uk`, но все площадки проекта — в зонах первого уровня (domclick.ru, avito.ru, cian.ru, yandex.ru); тащить publicsuffix-список ради гипотетического случая дороже, чем он стоит. Оговорено в докстринге. ## Тесты Новый `test_server_cookie_domain.py` (8 проверок). Три существующих теста закрепляли ровно то поведение, которое оказалось багом (`.ekaterinburg.domclick.ru` / `.www.avito.ru` / `.realty.yandex.ru`) — переведены на новый контракт, докстринги объясняют почему. Прогон сайдкара целиком: **206 passed**.
lekss361 added 3 commits 2026-08-29 22:51:33 +00:00
Сайдкар инжектил куки на домен из url карточки — для
ekaterinburg.domclick.ru это `.ekaterinburg.domclick.ru`. Настоящие куки
площадки живут на `.domclick.ru` (видно в записи ручной сессии 29.08:
`.domclick.ru qrator_jsid2`, `.domclick.ru qrator_jsr`).

Куки поддомена родительские не заменяют, а сосуществуют с ними: как
только площадка выдаёт свежий `qrator_jsid2` на `.domclick.ru`, браузер
шлёт в одном запросе ДВЕ куки с этим именем, и первой — более
специфичную, нашу протухшую. QRATOR читает её и держит страницу на
274-байтном загрузчике, рукопожатие не завершается никогда.

Замер 29.08, узел 10, чередование, свежий контекст на пробу:
куки на поддомене — 0 успехов из 3 (все три ровно 274 байта),
те же куки на `.domclick.ru` — 3 из 3.

Заодно шрифты в образе сайдкара: контейнер нёс 8 файлов / 3 семейства
(только DejaVu) при заявленном camoufox `os="windows"`. Добавлены
метрически совместимые Liberation/Carlito/Caladea + `fc-cache` и
build-time проверка. С текущими отказами Домклика это НЕ связано —
правка про правдоподобие отпечатка, не про этот баг.

Тестов пока нет сознательно: правка ждёт подтверждения на сервере на
отдохнувшем пуле.
Первая версия требовала >=30 файлов в fc-list и покраснела на фактических
20 — порог был взят из головы, а не измерен. Значение имеет не число
файлов (оно зависит от того, что притащили соседние пакеты), а то, что
запрос Arial отдаёт метрически совместимый шрифт. Проверяем ровно это,
по всем пяти алиасам.

Замер образа 30.08: 20 файлов, 5 семейств (Liberation Sans/Serif/Mono,
Carlito, Caladea); Arial→Liberation Sans, Times New Roman→Liberation
Serif, Courier New→Liberation Mono, Calibri→Carlito, Cambria→Caladea.
test(tradein/browser): домен инжектируемых кук — регистрируемый, не хост из url
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 1m27s
18ae509f98
Новый test_server_cookie_domain.py: схлопывание поддомена, хост из двух
лейблов без изменений, оба места инъекции зовут одну функцию.

Три существующих теста закрепляли как раз то поведение, которое оказалось
багом (.ekaterinburg.domclick.ru / .www.avito.ru / .realty.yandex.ru), —
переведены на новый контракт, докстринги объясняют почему.

Прогон сайдкара целиком: 206 passed.
lekss361 merged commit 046b0282d5 into main 2026-08-29 22:53:21 +00:00
lekss361 deleted branch fix/browser-cookie-domain-and-fonts 2026-08-29 22:53:22 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3262
No description provided.