|
|
@@ -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 (4 fixed, 23 open), 42 sev-1.
|
|
|
+> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (5 fixed, 22 open), 42 sev-1.
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -268,6 +268,24 @@
|
|
|
`consumeNext()` path is currently safe (`AuthRequiredMiddleware`
|
|
|
controls the source), but `setNext()` itself is unrestricted.
|
|
|
- **Severity: 2**
|
|
|
+- **Status:** Fixed in `55156c5`. `SessionManager::isSafeRedirectPath()`
|
|
|
+ accepts only same-origin paths (must start with `/`; second char must
|
|
|
+ not be `/` or `\`; no control chars including CR/LF/NUL).
|
|
|
+ `SessionManager::safeNextOrDefault()` returns the candidate iff safe,
|
|
|
+ else a hard-coded literal default. `setNext()` and `consumeNext()` also
|
|
|
+ drop unsafe values silently as defence-in-depth so any future caller
|
|
|
+ is safe even without the helper. `AllowlistController::delete` and
|
|
|
+ `ManualBlocksController::delete` now route the `next` form field
|
|
|
+ through `safeNextOrDefault`, so a malicious value falls back to the
|
|
|
+ resource list rather than redirecting the operator to the attacker
|
|
|
+ URL. Regression tests: `SessionManagerTest` data-provider truth table
|
|
|
+ for `isSafeRedirectPath` plus `testSetNextDropsUnsafeValueSilently`,
|
|
|
+ `testConsumeNextRejectsPreviouslyStoredUnsafeValue`,
|
|
|
+ `testSafeNextOrDefaultUsesDefaultOnUnsafeOrMissing`; integration
|
|
|
+ tests in `CrudPagesTest`
|
|
|
+ (`testManualBlockDeleteRejectsOpenRedirectInNext`,
|
|
|
+ `testManualBlockDeleteHonoursSafeNext`,
|
|
|
+ `testAllowlistDeleteRejectsOpenRedirectInNext`).
|
|
|
|
|
|
### F11 — Service-token impersonation accepts any user id with no allow-list, no active-status gate
|
|
|
- **Files:** `api/src/Infrastructure/Http/Middleware/ImpersonationMiddleware.php:38-77`,
|