Browse Source

docs: mark SEC_REVIEW F37 as fixed in f2a81ad

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chiappa 4 days ago
parent
commit
436e670c5a
1 changed files with 20 additions and 1 deletions
  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.
 >
-> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (4 fixed, 38 open).
+> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (5 fixed, 37 open).
 
 ---
 
@@ -1287,6 +1287,25 @@
   `password_get_info()` and refuse to enable local-admin if the
   algorithm is below threshold.
 - **Severity: 1**
+- **Status:** Fixed. `App\App\Config::validateOrExit` (called from
+  `Bootstrap::run()` before `Container::build()`) now refuses to boot
+  when `LOCAL_ADMIN_ENABLED=true` and the configured
+  `LOCAL_ADMIN_PASSWORD_HASH` is anything other than Argon2id or
+  bcrypt with cost ≥ 12 (new `Config::BCRYPT_MIN_COST` constant). The
+  algorithm is read via `password_get_info()`, so unknown / legacy
+  formats (`$1$…` md5-crypt, `$5$…` sha256-crypt, plain text, base64
+  noise) all collapse into the rejection branch with the same
+  human-readable message pointing the operator at
+  `password_hash('…', PASSWORD_ARGON2ID)`. argon2i is also rejected
+  because it doesn't meet the SEC_REVIEW threshold even though
+  `password_hash` accepts it. Tests: bypass the validator (the
+  `Bootstrap::container()` test path is unchanged), so existing
+  fixtures continue to use Argon2id without ceremony. Regression
+  tests in `ui/tests/Unit/App/ConfigTest.php` cover Argon2id-accept,
+  bcrypt-cost-12-accept, bcrypt-cost-4-reject, argon2i-reject,
+  md5-crypt-reject, plain-string-reject, empty-string-reject, and
+  the "local admin disabled, hash not checked" branch (operators who
+  run OIDC-only don't have to invent a strong dummy hash).
 
 ### F38 — Disabled local-admin returns 404 *before* throttle, allowing unrestricted hammering
 - **File:** `ui/src/Auth/LocalLoginController.php:60-62`