Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

Commit bb8cd7f

Browse files
committed
fix(security): UrnController::bulk — cap input list at 1000
Each URN triggers parse → register find → schema find → object find (~4 DB round-trips per item). Without a cap a caller can post 100k URNs and force ~400k DB round-trips per request. Today the route is effectively admin-only via the absence of @NoAdminRequired, so impact is limited; a future relaxation would convert the missing cap into a direct DoS lever. Reject with 422 above 1000. Refs: #1419 review (concern 3) — discussion_r3187494464
1 parent ea0b5d5 commit bb8cd7f

1 file changed

Lines changed: 13 additions & 0 deletions

File tree

lib/Controller/UrnController.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,19 @@ public function bulk(?array $urns=null): JSONResponse
149149
return new JSONResponse(['error' => 'urns array is required'], Http::STATUS_BAD_REQUEST);
150150
}
151151

152+
// SECURITY: cap the input list. Each URN triggers a parse →
153+
// register find → schema find → object find chain, so a 100k
154+
// input list = ~400k DB round-trips per request. Currently this
155+
// route is effectively admin-only via the absence of
156+
// @NoAdminRequired, but a future relaxation would convert the
157+
// missing cap directly into a DoS lever.
158+
if (count($urns) > 1000) {
159+
return new JSONResponse(
160+
['error' => 'Too many URNs (max 1000 per request)', 'count' => count($urns)],
161+
Http::STATUS_UNPROCESSABLE_ENTITY
162+
);
163+
}
164+
152165
$resolved = $this->urnService->resolveBulk($urns);
153166

154167
return new JSONResponse(

0 commit comments

Comments
 (0)