[Investigation] Подтвердить public auth perimeter и admission budget #73

Open
opened 2026-10-11 21:47:21 +03:00 by codex-bot · 2 comments
Owner

Problem

В app и supplied Nginx нет auth rate limit; loopback frontend предполагает внешний HTTPS proxy, его controls неизвестны. Login/register выполняют bcrypt work. Реальная public exploitation/CPU exhaustion не подтверждена.

Expected Behavior

Известна trusted proxy/exposure chain и существующий admission budget; новый limiter появляется только при доказанном gap.

Evidence

Audit date 2026-10-11; 13, RISK-008. Backend revision 0ad84ff4f0b4712abc7e69dc299856f14af6eadd, frontend c8821200ce699dab1ce65360d1968d5877a2e78b; Confidence Medium; Verification status runtime-unverified.
Affected: auth.controller.ts:55–79; auth.service.ts:19–78; frontend/docker/nginx.conf:20–33; actual external proxy config не предоставлен.

Scope

In scope

Пассивный private deployment input и network exposure review; explicit KEEP/FIX decision.

Out of scope

Production brute-force/load test, публикация proxy credentials/IP/user data, automatic CAPTCHA/Redis/account lockout.

Proposed Approach

Проверить bypass paths/client-IP trust и upstream existing limits. При gap выбрать smallest existing boundary budget; distributed account guessing отдельно от IP limit, без attacker-controlled lockout.

Acceptance Criteria

  • Реальная доступность auth/bypass paths и trusted client-IP chain подтверждены обезличенным evidence.
  • Для limits есть конкретный KEEP либо bounded remediation с owner и проверяемым rejection/recovery outcome.
  • При code fix isolated rejected requests не выполняют bcrypt/upstream work, access восстанавливается по budget; generic errors/dummy hashing сохранены.

Verification

Static approved proxy input; isolated auth boundary tests только при gap/code change. P0/P1 vulnerability не заявлять из отсутствующего input.

Dependencies

Требуется фактическая private proxy/exposure configuration от deployment owner; отдельный Issue в deploy автоматически не создаётся.

Traceability

Campaign WealthLedger/main#23 . Finding RISK-008. WealthLedger/backend — auth behavior owner, deployment evidence внешний; T38.

<!-- wealthledger-audit:2026-10-11:auth-perimeter --> ## Problem В app и supplied Nginx нет auth rate limit; loopback frontend предполагает внешний HTTPS proxy, его controls неизвестны. Login/register выполняют bcrypt work. Реальная public exploitation/CPU exhaustion не подтверждена. ## Expected Behavior Известна trusted proxy/exposure chain и существующий admission budget; новый limiter появляется только при доказанном gap. ## Evidence Audit date `2026-10-11`; [13](https://git.personal.ksv741.ru/WealthLedger/main/src/commit/d07fbfabb1295780952a554185989d2d5b5c8349/audits/2026-10-11/reports/13-reliability-and-security-report.md), RISK-008. Backend revision `0ad84ff4f0b4712abc7e69dc299856f14af6eadd`, frontend `c8821200ce699dab1ce65360d1968d5877a2e78b`; Confidence Medium; Verification status runtime-unverified. Affected: [auth.controller.ts:55–79](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/0ad84ff4f0b4712abc7e69dc299856f14af6eadd/src/modules/auth/presentation/auth.controller.ts#L55-L79); auth.service.ts:19–78; frontend/docker/nginx.conf:20–33; actual external proxy config не предоставлен. ## Scope ### In scope Пассивный private deployment input и network exposure review; explicit KEEP/FIX decision. ### Out of scope Production brute-force/load test, публикация proxy credentials/IP/user data, automatic CAPTCHA/Redis/account lockout. ## Proposed Approach Проверить bypass paths/client-IP trust и upstream existing limits. При gap выбрать smallest existing boundary budget; distributed account guessing отдельно от IP limit, без attacker-controlled lockout. ## Acceptance Criteria - [ ] Реальная доступность auth/bypass paths и trusted client-IP chain подтверждены обезличенным evidence. - [ ] Для limits есть конкретный KEEP либо bounded remediation с owner и проверяемым rejection/recovery outcome. - [ ] При code fix isolated rejected requests не выполняют bcrypt/upstream work, access восстанавливается по budget; generic errors/dummy hashing сохранены. ## Verification Static approved proxy input; isolated auth boundary tests только при gap/code change. P0/P1 vulnerability не заявлять из отсутствующего input. ## Dependencies Требуется фактическая private proxy/exposure configuration от deployment owner; отдельный Issue в deploy автоматически не создаётся. ## Traceability Campaign https://git.personal.ksv741.ru/WealthLedger/main/issues/23 . Finding RISK-008. WealthLedger/backend — auth behavior owner, deployment evidence внешний; T38.
codex-bot added this to the Technical Audit Remediation — 2026-10-11 milestone 2026-10-11 21:47:21 +03:00
codex-bot added the
Priority
Medium
3
audit/2026-10-11kind/investigation
labels 2026-10-11 21:47:21 +03:00
ksv741 was assigned by hermes-agent 2026-10-12 00:04:20 +03:00
hermes-agent added this to the WealthLedger — Delivery Board project 2026-10-12 00:04:20 +03:00
hermes-agent added Kind/Investigation and removed kind/investigation labels 2026-10-12 00:04:20 +03:00
Author
Owner

Решение владельца (2026-11-05): только nginx limit_req; регистрацию оставить открытой. Внешняя HTTPS proxy chain и trusted client-IP неизвестны, поэтому per-client IP limit и claims о реальной публичной доступности не подтверждены. Кодовая цепочка: frontend nginx публикуется через loopback в supplied compose, backend не публикует host port; возможный внешний путь и bypass вне этих configs не проверены. Backend login/register вызывают bcrypt cost 12; неизвестный login использует dummy hash; generic login error остаётся. В frontend/nginx подготовлен общий (не IP) бюджет 2r/s + burst 5 для POST login/register, 429 до upstream. Изолированный тест на двух контейнерах: 6 POST проходят к upstream (upstream ответил 502, так как тестовый nginx не слушает :3000), следующие 6 — 429; через 4 сек снова пропуск к upstream (502). GET login и POST logout вне лимита. Следствие: один клиент может исчерпать общую квоту; дополнить per-client budget только после проверки trust chain. Frontend owner Issue #155. В backend изменений нет; #73 закрывать после проверки на реальном прокси/деплое.

Решение владельца (2026-11-05): только nginx `limit_req`; регистрацию оставить открытой. Внешняя HTTPS proxy chain и trusted client-IP неизвестны, поэтому per-client IP limit и claims о реальной публичной доступности не подтверждены. Кодовая цепочка: frontend nginx публикуется через loopback в supplied compose, backend не публикует host port; возможный внешний путь и bypass вне этих configs не проверены. Backend login/register вызывают bcrypt cost 12; неизвестный login использует dummy hash; generic login error остаётся. В frontend/nginx подготовлен общий (не IP) бюджет 2r/s + burst 5 для POST login/register, 429 до upstream. Изолированный тест на двух контейнерах: 6 POST проходят к upstream (upstream ответил 502, так как тестовый nginx не слушает :3000), следующие 6 — 429; через 4 сек снова пропуск к upstream (502). GET login и POST logout вне лимита. Следствие: один клиент может исчерпать общую квоту; дополнить per-client budget только после проверки trust chain. Frontend owner Issue #155. В backend изменений нет; #73 закрывать после проверки на реальном прокси/деплое.
Author
Owner

Code mitigation shipped to frontend develop via frontend PR #156 (commit 668f2ef), frontend#155 closed. nginx -t, isolated 429/refill and frontend CI run 1956 green. Investigation remains OPEN: real external HTTPS proxy chain, trusted client-IP forwarding and whether there are auth bypass paths outside supplied compose have not been supplied/verified; production exposure/recovery cannot be asserted from repo-only evidence. Current shared admission budget is not per-client and may be exhausted by one requester.

Code mitigation shipped to frontend `develop` via frontend PR #156 (commit `668f2ef`), frontend#155 closed. `nginx -t`, isolated 429/refill and frontend CI run 1956 green. Investigation remains OPEN: real external HTTPS proxy chain, trusted client-IP forwarding and whether there are auth bypass paths outside supplied compose have not been supplied/verified; production exposure/recovery cannot be asserted from repo-only evidence. Current shared admission budget is not per-client and may be exhausted by one requester.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: WealthLedger/backend#73