From a29bf936e51dc3204ae49698b2b65b80c54c2280 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Sun, 13 Sep 2026 13:49:38 +0300 Subject: [PATCH] =?UTF-8?q?chore(caddy):=20security=20headers=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20meraocenka.ru=20+=20=D0=BE=D1=82=D0=BA=D0=BB?= =?UTF-8?q?=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20browse=20=D0=B2=20/previ?= =?UTF-8?q?ew?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit meraocenka.ru — публичный B2C-домен, не отдавал ни HSTS, ни защиту от встраивания во фрейм, ни X-Content-Type-Options/Referrer-Policy. Добавлен блок header: HSTS на 180 суток (без includeSubDomains/preload — оба флага практически необратимы, не все поддомены под контролем), X-Frame-Options: DENY + CSP frame-ancestors 'none' (старые клиенты + современный механизм), nosniff, strict-origin-when-cross-origin, плюс снятие Server/X-Powered-By. Полноценный CSP (default-src/script-src) — отдельная работа, здесь только периметр вокруг фрейма. Next.js (tradein-mvp/frontend) эти заголовки не выставляет — дублирования нет. handle_path /preview/* отдавал листинг каталога (file_server browse). Публичность самих макетов намеренная и задокументирована — убран только листинг, файлы по прямой ссылке продолжают отдаваться. Проверено: caddy validate --config apps.caddy --adapter caddyfile → Valid configuration (до и после правки, с учётом относительных import вида ../users.caddy.snippet — apps.caddy валиден только при монтировании родительского caddy/, не caddy/sites/ отдельно). Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01JY6iWDnGDthdvsMWgK1BMG --- caddy/sites/apps.caddy | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/caddy/sites/apps.caddy b/caddy/sites/apps.caddy index 1bc227e7..ca670588 100644 --- a/caddy/sites/apps.caddy +++ b/caddy/sites/apps.caddy @@ -184,10 +184,13 @@ gendsgn.ru { } # Static HTML mockups для review (audit alternatives). - # Public access — без auth (по запросу 2026-05-17). + # Public access — без auth (по запросу 2026-05-17) — это намеренно и + # менять НЕ надо. Но каталог не должен листингом отдавать список + # файлов случайному посетителю: без `browse` file_server продолжает + # отдавать сами файлы по прямой ссылке, просто без index-листинга. handle_path /preview/* { root * /srv/preview - file_server browse + file_server } # Trade-In UI preview — public CI surface (#801). Рендерит mock-фикстуру @@ -400,6 +403,36 @@ www.gendsgn.ru { meraocenka.ru { encode zstd gzip + # #3471 (security-headers follow-up): публичный B2C-домен без базовых + # security-заголовков. Позиция директивы в файле не важна — Caddyfile + # применяет директивы в фиксированном порядке (`header` идёт раньше + # `reverse_proxy`), не по строке в исходнике. + # + # Проверено: ни tradein-mvp/frontend (обслуживает этот домен, отдаёт + # `/trade-in/mera-public*`), ни его next.config.ts/middleware не + # выставляют ни один из этих заголовков — дублирования нет. + header { + # 180 суток (15552000s). НЕ ставить includeSubDomains и НЕ ставить + # preload — оба флага практически необратимы (браузеры кэшируют + # preload-список надолго, includeSubDomains ломает любой будущий + # HTTP-поддомен), а не все поддомены meraocenka.ru гарантированно + # под нашим контролем. Если это когда-нибудь понадобится — отдельное + # осознанное решение, не «улучшение по умолчанию». + Strict-Transport-Security "max-age=15552000" + # Запрет встраивания во фрейм: X-Frame-Options — для старых + # клиентов, которые не понимают CSP; frame-ancestors — современный + # механизм. Оба вместе, не один вместо другого. + X-Frame-Options "DENY" + Content-Security-Policy "frame-ancestors 'none'" + X-Content-Type-Options "nosniff" + Referrer-Policy "strict-origin-when-cross-origin" + # Не даём стеку светиться в ответе. Полноценный CSP + # (default-src/script-src/...) сюда намеренно НЕ входит — отдельная + # работа с риском сломать фронт, здесь только периметр вокруг фрейма. + -Server + -X-Powered-By + } + log { output file /var/log/caddy/meraocenka.ru.log } -- 2.45.3