fix(caddy): периметр МЕРЫ — секрет убран из анонимного пути, чанки закрытого контура не раздаются с meraocenka #3340

Merged
bot-backend merged 2 commits from fix/3324-mera-perimeter into main 2026-09-02 12:48:52 +00:00
Collaborator

Refs #3324, периметр-пункты 1 и 3 (п.2 — 401-оракул в rbac.py — отдельно, после мержа #3331).

П.3 — мёртвый секрет в анонимном пути (убран)

Доказательство мёртвости: X-Internal-Auth-Secret читается ровно в одном месте (rbac.py:300), в ветке, достижимой только при непустом X-Authenticated-User — а оба Caddy-хопа срезают этот заголовок header_up -X-Authenticated-User. Пара «имя + секрет» через Caddy прийти не может по построению → инжектированный секрет не сравнивался никогда. Задуман для внутрисетевого dual-mode (QA-смоуки изнутри gendesign_shared несут оба заголовка сами, мимо Caddy) — эта проверка в rbac.py не тронута. Второй потребитель (вебхук GlitchTip) берёт секрет из query — не задет.

Убрано из handle /trade-in/api/* и @tradein; caddy adapt | grep -c Internal-Auth-Secret → 0. Follow-up: docker-compose.prod.yml:756 всё ещё кладёт секрет в env Caddy-контейнера, которому он больше не нужен.

П.1 — чанки закрытого контура (отсечены path-матчером)

Замер на живом проде: лендингу нужны chunks/app/layout-*, error-*, chunks/app/mera-public/* и общие хэш-чанки; каталоги закрытых маршрутов различимы в путях буквально (app/admin/, app/team/, app/scrapers/, v2, history). Матчер path_regexp ^/trade-in/_next/static/chunks/app/[^/]+/ минус mera-publicrespond 404, срабатывает раньше reverse_proxy (подтверждено adapted JSON).

Ограничение названо честно: блок убирает КОД, но не имена — webpack-карта нужна лендингу и остаётся; полное закрытие = split build (отдельная задача).

  • scripts/smoke-mera-perimeter.sh — смоук периметра.

Валидация

caddy adapt локальным caddy 2.11.3 — конфиг адаптируется; на проде перед репортом: docker exec gendesign-caddy-1 caddy validate.

Прод-приёмка после deploy-caddy (сделаю)

  • curl https://meraocenka.ru/trade-in/_next/static/chunks/app/admin/page-x.js → 404 с телом 0 байт (было 404/9 от Next — различает тело, не код);
  • layout-чанк лендинга → 200;
  • bash scripts/smoke-mera-perimeter.sh;
  • лог tradein-backend без новых «без валидного X-Internal-Auth-Secret»; caddy adapt | grep -c → 0.
Refs #3324, периметр-пункты 1 и 3 (п.2 — 401-оракул в rbac.py — отдельно, после мержа #3331). ## П.3 — мёртвый секрет в анонимном пути (убран) Доказательство мёртвости: `X-Internal-Auth-Secret` читается ровно в одном месте (`rbac.py:300`), в ветке, достижимой только при непустом `X-Authenticated-User` — а оба Caddy-хопа срезают этот заголовок `header_up -X-Authenticated-User`. Пара «имя + секрет» через Caddy прийти не может по построению → инжектированный секрет не сравнивался никогда. Задуман для внутрисетевого dual-mode (QA-смоуки изнутри `gendesign_shared` несут оба заголовка сами, мимо Caddy) — эта проверка в rbac.py не тронута. Второй потребитель (вебхук GlitchTip) берёт секрет из query — не задет. Убрано из `handle /trade-in/api/*` и `@tradein`; `caddy adapt | grep -c Internal-Auth-Secret` → 0. Follow-up: `docker-compose.prod.yml:756` всё ещё кладёт секрет в env Caddy-контейнера, которому он больше не нужен. ## П.1 — чанки закрытого контура (отсечены path-матчером) Замер на живом проде: лендингу нужны `chunks/app/layout-*`, `error-*`, `chunks/app/mera-public/*` и общие хэш-чанки; каталоги закрытых маршрутов различимы в путях буквально (`app/admin/`, `app/team/`, `app/scrapers/`, `v2`, `history`). Матчер `path_regexp ^/trade-in/_next/static/chunks/app/[^/]+/` минус `mera-public` → `respond 404`, срабатывает раньше reverse_proxy (подтверждено adapted JSON). Ограничение названо честно: блок убирает КОД, но не имена — webpack-карта нужна лендингу и остаётся; полное закрытие = split build (отдельная задача). + `scripts/smoke-mera-perimeter.sh` — смоук периметра. ## Валидация `caddy adapt` локальным caddy 2.11.3 — конфиг адаптируется; на проде перед репортом: `docker exec gendesign-caddy-1 caddy validate`. ## Прод-приёмка после deploy-caddy (сделаю) - `curl https://meraocenka.ru/trade-in/_next/static/chunks/app/admin/page-x.js` → 404 с телом 0 байт (было 404/9 от Next — различает тело, не код); - layout-чанк лендинга → 200; - `bash scripts/smoke-mera-perimeter.sh`; - лог tradein-backend без новых «без валидного X-Internal-Auth-Secret»; `caddy adapt | grep -c` → 0.
bot-backend added 1 commit 2026-09-02 12:42:55 +00:00
fix(caddy): снять мёртвый internal-секрет с анонимного пути и чанки закрытого контура с публичного домена
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 11s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
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
177207223b
#3324, п.3: Caddy на gendsgn.ru инжектил X-Internal-Auth-Secret в каждый
анонимный запрос /trade-in/api/* и /trade-in/* (хоп во фронт). Сравнение
недостижимо по построению: backend читает этот заголовок только в
legacy trusted-header ветке rbac.py, и только после непустого
X-Authenticated-User, который тот же самый хоп строкой ниже удаляет.
Второй потребитель секрета (вебхук GlitchTip) берёт его из query-параметра.
Защита от подделки заголовков внутри gendesign_shared — проверка в rbac.py,
она не тронута; инжект работал в обратную сторону, раздавая секрет наружу.

#3324, п.1: meraocenka.ru раздавал анонимам постраничные чанки App Router
чужих маршрутов (chunks/app/{admin,team,scrapers,...}/) — код закрытого
контура с именами внутренних ручек. Матчер отсекает 404-ом «есть подкаталог,
и он не mera-public»; лэндингу нужны только chunks/app/<файл>.js и
chunks/app/mera-public/* (замер на проде). Карта чанков в webpack-*.js
остаётся — имена файлов по-прежнему читаются, полное разделение = split build.

Регресс-тесты в smoke-mera-perimeter.sh отличают 404 Caddy (пустое тело) от
404 Next и отдельно проверяют, что статика лэндинга жива.
Light1YT added 1 commit 2026-09-02 12:47:38 +00:00
fix(caddy): исключить _not-found из фильтра чанков закрытого контура
All checks were successful
CI Trade-In / changes (pull_request) Successful in 13s
CI / changes (pull_request) Successful in 16s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
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
5d9ff13dae
Ревью #3340: `chunks/app/_not-found/` — внутренняя страница Next, а не
маршрут продукта; фильтр её глушил, и клиентская навигация по битому href
падала в error-boundary вместо честного «не найдено». Закрытого кода она
не несёт. Заодно в комментарии матчера явно зафиксировано, что
`static/css/app/<маршрут>/*` оставлен без фильтра сознательно — тот же
класс «имена, а не код», потолок уже задекларирован.
bot-backend merged commit 6883a46ecd into main 2026-09-02 12:48:52 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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#3340
No description provided.