Summary
Security audit identified 8 vulnerabilities (4 CRITICAL, 3 HIGH, 1 MEDIUM) across V1/V2/V3 APIs and Prod controllers. The dominant pattern is 1-of-N authorization inconsistency.
Findings
CRITICAL
-
V1 API Story Manipulation Missing Auth — ControllerProvider/Api/V1.php:254-267 — POST addrecords, DELETE delrecords, POST setcover only have ensureJsonContentType but missing ensureCanAccessToRecord/ensureCanModifyRecord. Compare to GET story at line 245 which correctly has auth. Any OAuth user can manipulate any story.
-
V2 API Quarantine Missing Auth Entirely — Controller/Api/LazaretController.php — quarantineItemDeleteAction, quarantineItemAddAction, quarantineItemEmptyAction have zero ACL checks. Any OAuth user can delete/add/empty quarantine items.
-
V3 Subdefs Service ACL Commented Out + SSRF — Controller/Api/V3/V3SubdefsServiceController.php:89-97 — ACL check explicitly commented out. Also fetches user-supplied URLs via Guzzle (SSRF) with SSL verification disabled.
-
V3 Subdefs Callback Arbitrary File Write — V3SubdefsServiceController.php:38-71 — Copies uploaded file using user-controlled filename from $request->get('file_info')['filename'] with no path traversal sanitization.
HIGH
-
Prod Lazaret Cross-Collection IDOR — Controller/Prod/LazaretController.php:72-97 — getElement()/thumbnailElement() fetch items by ID without per-item has_right_on_base() check. Middleware only checks CANADDRECORD on any base.
-
Prod Lazaret emptyLazaret Missing CSRF — LazaretController.php:218-234 — No CSRF validation while addElement() and denyElement() in same controller DO check CSRF. 1-of-N inconsistency.
-
V1 API sendAssetsInQueue Missing Auth — V1.php:292 — POST /upload/enqueue/ has no ACL check. Compare to addRecordAction which checks has_right_on_base().
MEDIUM
- Prod Printer Missing Auth Middleware —
ControllerProvider/Prod/Printer.php:39 — Uses createCollection() instead of createAuthenticatedCollection(). All other Prod controllers use authenticated variant.
Root Cause
V1/V2/V3 APIs evolved separately. Authorization checks not consistently applied across endpoint groups. Story manipulation and quarantine endpoints added without matching sibling authorization patterns.
Recommended Fix
Add ensureCanAccessToRecord/ensureCanModifyRecord before-filters to story endpoints. Add has_right_on_base() ACL checks to quarantine controllers. Uncomment V3 ACL check. Sanitize filenames with basename().
Found during a systematic open-source security audit.
Summary
Security audit identified 8 vulnerabilities (4 CRITICAL, 3 HIGH, 1 MEDIUM) across V1/V2/V3 APIs and Prod controllers. The dominant pattern is 1-of-N authorization inconsistency.
Findings
CRITICAL
V1 API Story Manipulation Missing Auth —
ControllerProvider/Api/V1.php:254-267— POST addrecords, DELETE delrecords, POST setcover only haveensureJsonContentTypebut missingensureCanAccessToRecord/ensureCanModifyRecord. Compare to GET story at line 245 which correctly has auth. Any OAuth user can manipulate any story.V2 API Quarantine Missing Auth Entirely —
Controller/Api/LazaretController.php—quarantineItemDeleteAction,quarantineItemAddAction,quarantineItemEmptyActionhave zero ACL checks. Any OAuth user can delete/add/empty quarantine items.V3 Subdefs Service ACL Commented Out + SSRF —
Controller/Api/V3/V3SubdefsServiceController.php:89-97— ACL check explicitly commented out. Also fetches user-supplied URLs via Guzzle (SSRF) with SSL verification disabled.V3 Subdefs Callback Arbitrary File Write —
V3SubdefsServiceController.php:38-71— Copies uploaded file using user-controlled filename from$request->get('file_info')['filename']with no path traversal sanitization.HIGH
Prod Lazaret Cross-Collection IDOR —
Controller/Prod/LazaretController.php:72-97—getElement()/thumbnailElement()fetch items by ID without per-itemhas_right_on_base()check. Middleware only checks CANADDRECORD on any base.Prod Lazaret emptyLazaret Missing CSRF —
LazaretController.php:218-234— No CSRF validation whileaddElement()anddenyElement()in same controller DO check CSRF. 1-of-N inconsistency.V1 API sendAssetsInQueue Missing Auth —
V1.php:292— POST/upload/enqueue/has no ACL check. Compare toaddRecordActionwhich checkshas_right_on_base().MEDIUM
ControllerProvider/Prod/Printer.php:39— UsescreateCollection()instead ofcreateAuthenticatedCollection(). All other Prod controllers use authenticated variant.Root Cause
V1/V2/V3 APIs evolved separately. Authorization checks not consistently applied across endpoint groups. Story manipulation and quarantine endpoints added without matching sibling authorization patterns.
Recommended Fix
Add
ensureCanAccessToRecord/ensureCanModifyRecordbefore-filters to story endpoints. Addhas_right_on_base()ACL checks to quarantine controllers. Uncomment V3 ACL check. Sanitize filenames withbasename().Found during a systematic open-source security audit.