Хардненинг: доверие к X-Forwarded-For снимает throttle и портит аудит (F3) #58

Closed
opened 2026-09-13 16:17:42 +03:00 by Agent · 1 comment
Collaborator

Severity (предложение): High. Требует подтверждения на живом контуре (test-клон).

uvicorn запущен с --forwarded-allow-ips="*" (entrypoint.sh) → доверяет X-Forwarded-For от любого пира и берёт из него левое (клиентское) значение (ProxyHeadersMiddleware.get_trusted_client_address при always_trust). Caddy добавляет реальный IP справа, поэтому подставленное клиентом левое значение сохраняется и становится request.client.host (core/security.py:client_ip).

Оба ключа throttle (core/ratelimit.py) — login:{ip}:{nickname} и login-ip:{ip} — содержат этот IP, поэтому ротация X-Forwarded-For на каждый запрос полностью снимает лимит перебора пароля. Тот же IP пишется в audit_service → журнал источника подделывается.

Evidence: чтение кода uvicorn (левое значение при *) и deploy/vps/Caddyfile (append XFF). Полную эксплуатацию на живых контурах в рамках #25 не выполняли (без перебора на проде/тесте).

Рекомендация: доверять X-Forwarded-For только фактическому прокси (loopback / сеть туннеля) вместо *; на Caddy перезаписывать заголовок реальным пиром (header_up X-Forwarded-For {remote_host}) вместо append.

Обнаружено при работе над #25 (находка F3). Смежно с #56 (throttle) и следующей задачей о durability throttle.

**Severity (предложение): High.** Требует подтверждения на живом контуре (test-клон). uvicorn запущен с `--forwarded-allow-ips="*"` (`entrypoint.sh`) → доверяет `X-Forwarded-For` от **любого** пира и берёт из него **левое** (клиентское) значение (`ProxyHeadersMiddleware.get_trusted_client_address` при `always_trust`). Caddy добавляет реальный IP справа, поэтому подставленное клиентом левое значение сохраняется и становится `request.client.host` (`core/security.py:client_ip`). Оба ключа throttle (`core/ratelimit.py`) — `login:{ip}:{nickname}` и `login-ip:{ip}` — содержат этот IP, поэтому **ротация `X-Forwarded-For` на каждый запрос полностью снимает лимит перебора пароля**. Тот же IP пишется в `audit_service` → журнал источника подделывается. **Evidence:** чтение кода uvicorn (левое значение при `*`) и `deploy/vps/Caddyfile` (append XFF). Полную эксплуатацию на живых контурах в рамках #25 не выполняли (без перебора на проде/тесте). **Рекомендация:** доверять `X-Forwarded-For` только фактическому прокси (loopback / сеть туннеля) вместо `*`; на Caddy перезаписывать заголовок реальным пиром (`header_up X-Forwarded-For {remote_host}`) вместо append. Обнаружено при работе над #25 (находка F3). Смежно с #56 (throttle) и следующей задачей о durability throttle.
Agent added this to the 1.37 - смена аутентификации и смежный пен тест milestone 2026-09-13 16:17:42 +03:00
Agent added the Kind/Security label 2026-09-13 16:17:42 +03:00
Agent self-assigned this 2026-09-13 17:00:13 +03:00
Agent added the
Reviewed
Confirmed
1
label 2026-09-13 17:00:15 +03:00
Agent added the
Status
In Review
label 2026-09-13 17:25:29 +03:00
Author
Collaborator

F3 реализовано в PR #63 — #63

Caddy перезаписывает X-Forwarded-For реальным пиром (header_up ... {remote_host}), uvicorn --forwarded-allow-ips сужен с * до loopback + приватных сетей. Инфра backend-тестами не покрыть — живой перебор с подменой XFF проверяется на test-клоне (по вашему слову). Мёрж и закрытие — за вами.

F3 реализовано в PR #63 — https://gitea.arseniev.info/NotBigGhost/ForbiddenStarsApp/pulls/63 Caddy перезаписывает `X-Forwarded-For` реальным пиром (`header_up ... {remote_host}`), uvicorn `--forwarded-allow-ips` сужен с `*` до loopback + приватных сетей. Инфра backend-тестами не покрыть — **живой перебор с подменой XFF проверяется на test-клоне** (по вашему слову). Мёрж и закрытие — за вами.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: NotBigGhost/ForbiddenStarsApp#58