Summary
Bulk operations in multiple controllers skip permission checks that single-item operations correctly enforce, allowing any authenticated backend user to perform destructive operations without proper authorization.
Findings
1. UsersController::deleteList() — No permission check (CRITICAL)
Any authenticated backend user can bulk-delete users via DELETE /backend/users/ without can-delete-users permission. Compare with deleteItem() which correctly checks hasPermissions() — classic 1-of-N pattern.
2. FailedJobsController::updateList() — No permission check (CRITICAL)
Bulk job updates via PUT/PATCH /backend/vaah/failedjobs/ skip authorization.
3. FailedJobsController::listAction() — No permission check (CRITICAL)
Bulk actions via ANY /backend/vaah/failedjobs/action/{action} skip authorization.
4-5. BatchesController::listAction() + deleteList() — No permission check (CRITICAL)
Bulk batch operations and deletion skip authorization. JobsController has the same pattern on listAction, deleteList, deleteItem, and itemAction.
Root Cause
Single-item operations correctly check hasPermissions() before proceeding, but bulk operations skip this check entirely. The authorization pattern exists in the codebase — it's just not applied consistently to bulk endpoints.
Recommended Fix
Add the same hasPermissions() check used in single-item operations to all bulk operation methods.
Summary
Bulk operations in multiple controllers skip permission checks that single-item operations correctly enforce, allowing any authenticated backend user to perform destructive operations without proper authorization.
Findings
1. UsersController::deleteList() — No permission check (CRITICAL)
Any authenticated backend user can bulk-delete users via
DELETE /backend/users/withoutcan-delete-userspermission. Compare withdeleteItem()which correctly checkshasPermissions()— classic 1-of-N pattern.2. FailedJobsController::updateList() — No permission check (CRITICAL)
Bulk job updates via
PUT/PATCH /backend/vaah/failedjobs/skip authorization.3. FailedJobsController::listAction() — No permission check (CRITICAL)
Bulk actions via
ANY /backend/vaah/failedjobs/action/{action}skip authorization.4-5. BatchesController::listAction() + deleteList() — No permission check (CRITICAL)
Bulk batch operations and deletion skip authorization. JobsController has the same pattern on listAction, deleteList, deleteItem, and itemAction.
Root Cause
Single-item operations correctly check
hasPermissions()before proceeding, but bulk operations skip this check entirely. The authorization pattern exists in the codebase — it's just not applied consistently to bulk endpoints.Recommended Fix
Add the same
hasPermissions()check used in single-item operations to all bulk operation methods.