Document DNS-rebind residual and prod-enablement egress hardening
The security docs claimed the in-browser SSRF filter (context.route/ routeWebSocket) re-applies "the same filtering" as the pre-fetch DNS check. That's inaccurate for hostnames: the browser-level filter only blocks literal private IPs and localhost/.local/.internal suffixes — it never re-resolves hostnames, so a same-hostname DNS-rebind (public IP on first resolve, private IP on a later request from inside browserless) is not closed at that layer. Correct the wording in the design spec and TECHNICAL.md, and add a prominent note to both the spec's deploy section and the plan's deploy notes: before flipping TOOLBOX_VISIBLE on prod, harden the browserless container's network egress (block 169.254.0.0/16 and RFC1918 ranges via host firewall or a dedicated internal docker network) to close the residual at the network layer. Also note that per-user limits currently count only successful generations — failed renders are uncapped, a bounded self-DoS risk worth a follow-up.
This commit is contained in:
@@ -1654,9 +1654,13 @@ git commit -m "Add browserless service to prod compose and document clean-pdf"
|
||||
1. В `.env` на Hoster.kz добавить `BROWSERLESS_TOKEN=<random>` (например `openssl rand -hex 24`) и при желании `PDF_MONTHLY_LIMIT`.
|
||||
2. Миграция на проде: выполняется как обычно при деплое (`prisma migrate deploy` в entrypoint — проверить, что `add_pdf_api_key` применилась: `docker exec -i lms-sb-db-1 psql -U lms_user -d lms_db -c '\d "PdfApiKey"'`).
|
||||
3. `docker pull ghcr.io/browserless/chromium` на Hoster.kz (интернет с сервера есть) + обновлённый compose.
|
||||
|
||||
> ⚠️ **Перед шагом 4 (включением `TOOLBOX_VISIBLE=true`) обязательно захардить сетевой egress контейнера `browserless` на проде** — заблокировать `169.254.0.0/16` (cloud-metadata) и RFC1918-диапазоны (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) на уровне хост-файрвола или выделенной internal-only docker-сети. Browser-level SSRF-фильтр (`context.route`/`context.routeWebSocket`) не резолвит DNS заново и не закрывает same-hostname DNS-rebind (публичный IP на первом резолве, приватный — на повторном запросе изнутри browserless); сетевой egress-блок — единственный слой, который закрывает этот остаточный риск. Подробности — «Безопасность»/«Деплой» в `docs/specs/20260706-clean-pdf-design.md`.
|
||||
|
||||
4. Инструмент останется невидимым, пока на проде не выставлен `TOOLBOX_VISIBLE=true` — это отдельное продуктовое решение. `/api/pdf` при этом уже будет работать — это ок (доступ гейтится платным enrollment), но анонсировать до включения тулбокса не нужно.
|
||||
5. Hot-standby Hetzner: подтянуть тот же compose (`/root/digital-household/lms-sb/docker-compose.prod.yml` обновится через git pull).
|
||||
6. После релиза: обновить SBT-карточку `SBT/00-Стек/Сервисы/lms.md` (раздел про тулбокс + новые env) через capture-knowledge.
|
||||
7. Follow-up (не блокирует релиз): месячный/burst-лимит сейчас считает только **успешные** генерации — неудачные попытки (таймаут, 5xx, зависший рендер) лимит не расходуют, потенциальный ограниченный self-DoS повторными запросами. Рассмотреть подсчёт попыток, а не только успехов, отдельной задачей.
|
||||
|
||||
## Самопроверка при завершении
|
||||
|
||||
|
||||
Reference in New Issue
Block a user