Bläddra i källkod

docs: mark SEC_REVIEW F54 as fixed in 1ed16c0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chiappa 3 dagar sedan
förälder
incheckning
ea92c3d093
1 ändrade filer med 27 tillägg och 1 borttagningar
  1. 27 1
      doc/SEC_REVIEW.md

+ 27 - 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 (21 fixed, 21 open).
+> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (22 fixed, 20 open).
 
 ---
 
@@ -1777,6 +1777,32 @@
   path (the middleware reads only header or `getParsedBody()`); fine
   today, brittle for future PUT/PATCH endpoints with JSON.
 - **Severity: 1**
+- **Status:** Fixed. Two new layers on top of the existing
+  constant-time token compare:
+  1. **Same-origin gate.** State-changing requests with a present
+     `Origin` (or, when `Origin` is absent but `Referer` is present,
+     with a `Referer`) whose scheme+host+port doesn't match the
+     request URI's are refused with 403 BEFORE the token check, so a
+     cross-origin attacker who somehow exfiltrated the token cookie
+     still can't fire a same-token cross-origin POST.
+     `Origin: null` (sandboxed iframes / file:// pages) and the
+     "neither header present" branch fall through to the token-only
+     path — the curl/programmatic clients the test suite uses; modern
+     browsers always send `Origin` on POST/PUT/PATCH/DELETE.
+     Default ports (`:443` for https, `:80` for http) are normalised
+     out so `https://example.com` and `https://example.com:443`
+     compare equal.
+  2. **JSON body extraction.** `extractToken` now also reads
+     `csrf_token` from the JSON request body when
+     `Content-Type: application/json`, so a future fetch-with-JSON
+     PUT/PATCH endpoint inherits CSRF protection without a per-route
+     shim. Existing form-encoded and `X-CSRF-Token` header paths are
+     unchanged.
+  Regression tests in `ui/tests/Unit/Http/CsrfMiddlewareTest.php`:
+  cross-origin Origin → 403, same-origin Origin → 200,
+  Referer-fallback when Origin absent (same- and cross-origin),
+  `Origin: null` deferring to the token check, JSON-body token
+  accepted, JSON-body wrong token → 403.
 
 ### F55 — `e('html_attr')` in Alpine `x-data` JS-attribute
 - **File:** `ui/resources/views/pages/ips/detail.twig:166-171`