|
@@ -1099,6 +1099,23 @@
|
|
|
logged-in Viewer can hit `?page=999999&page_size=200` to force
|
|
logged-in Viewer can hit `?page=999999&page_size=200` to force
|
|
|
scans repeatedly.
|
|
scans repeatedly.
|
|
|
- **Severity: 2**
|
|
- **Severity: 2**
|
|
|
|
|
+- **Status:** Fixed in `3a2564d`. `AuditController::list` now bounds every
|
|
|
|
|
+ free-form filter (`action`, `entity_type`, `entity_id`,
|
|
|
|
|
+ `subject_kind`, `subject_id`) to `MAX_FILTER_LENGTH = 128` chars and
|
|
|
|
|
+ rejects any computed offset above `MAX_OFFSET = 10 000` with 400
|
|
|
|
|
+ `validation_failed` (`{"page": "pagination depth exceeded; use `to=`
|
|
|
|
|
+ to cursor into older rows"}`). The cap is large enough to
|
|
|
|
|
+ comfortably page through human-driven browsing (offset 10 000
|
|
|
|
|
+ covers 200 pages of 50 or 50 pages of 200) but bounds the
|
|
|
|
|
+ `LIMIT n OFFSET huge` worst case the finding describes. The
|
|
|
|
|
+ request-time `COUNT(*)` cost is bounded by the same gate — once a
|
|
|
|
|
+ Viewer can't drive offsets past 10 k, the count's cost is bounded
|
|
|
|
|
+ by the WHERE-clause's selectivity instead of by attacker choice;
|
|
|
|
|
+ the per-token admin rate limit added under F29 caps how often a
|
|
|
|
|
+ Viewer can issue these counts. Regression tests in
|
|
|
|
|
+ `api/tests/Integration/Admin/AuditLogControllerTest.php`
|
|
|
|
|
+ (`testOversizedFilterRejected`, `testDeepOffsetRejected`,
|
|
|
|
|
+ `testDeepOffsetAtBoundaryAccepted`).
|
|
|
|
|
|
|
|
### F32 — Admin list endpoints execute N+1 enrichment lookups per page row
|
|
### F32 — Admin list endpoints execute N+1 enrichment lookups per page row
|
|
|
- **Files:** `api/src/Application/Admin/IpsController.php:84-86, 187-190`,
|
|
- **Files:** `api/src/Application/Admin/IpsController.php:84-86, 187-190`,
|