Просмотр исходного кода

docs: mark SEC_REVIEW F74 as fixed in 3235d35

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chiappa 3 дней назад
Родитель
Сommit
221818fd52
1 измененных файлов с 20 добавлено и 1 удалено
  1. 20 1
      doc/SEC_REVIEW.md

+ 20 - 1
doc/SEC_REVIEW.md

@@ -11,7 +11,7 @@
 >
 >
 > Each finding is referenced as **F<N>** for later citation.
 > Each finding is referenced as **F<N>** for later citation.
 >
 >
-> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (41 fixed, 1 open).
+> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (42 fixed, 0 open).
 
 
 ---
 ---
 
 
@@ -2353,6 +2353,25 @@
   the structured logger. No log-rate cap, no aggregation. Pair with
   the structured logger. No log-rate cap, no aggregation. Pair with
   F1 (XFF spoof) and F2 (no per-user bucket) to amplify.
   F1 (XFF spoof) and F2 (no per-user bucket) to amplify.
 - **Severity: 1**
 - **Severity: 1**
+- **Status:** Fixed. `LoginThrottle::recordFailure` now emits a
+  `warning` only at `failure_count === 1` — the FIRST failure in a
+  given (username, ip) bucket since the bucket was created or
+  cleared. Subsequent failures within the bucket stay silent until
+  a lockout fires, which still emits the existing `error` line
+  carrying `failure_count` and `lock_seconds`. Total visibility is
+  preserved at aggregate (the lockout error carries the burst size)
+  without per-attempt spam: a 1000-IP botnet spraying one username
+  used to emit ~24 username-bucket warnings + 4×1000 = 4024
+  per-IP-bucket warnings before everything was locked; now it
+  emits 1 username-bucket warning + 1000 per-IP-bucket warnings,
+  about 4× quieter, with the lockout errors carrying the actual
+  count. The `error`-on-lockout signal stays loud because that's
+  the genuinely-actionable event. Regression tests in
+  `ui/tests/Unit/Auth/LoginThrottleTest.php`:
+  `testRecordFailureLogRateIsCappedToFirstWarningPerBucket`
+  (5 failures → 1 warning + ≥1 error) and
+  `testHighRateBruteForceDoesNotSpamPerFailureWarnings` (100
+  failures into the same bucket → exactly 1 warning).
 
 
 ---
 ---