PATCH parentId moves an element without checking permissions on the new parent
In plain terms
Moving an element in Studio is a PATCH request with { id, parentId }. The server checks whether the user may edit the element being moved. It does not check whether the user may put anything into the new parent.
The Studio tree hides the drop target when the user lacks the create permission on the folder (permission-helper.ts). That is a UI convenience only. The same request sent directly to the API goes through.
Where
src/Patcher/Service/PatchService.php, patchElement(): checks save on a data object only when field data is included, and publish on an asset. Nothing else.
src/Patcher/Adapter/ParentIdAdapter.php, patch(): calls setParentId() without any check.
src/Patcher/Adapter/KeyAdapter.php, patch(): same for setKey().
What goes wrong
- A user with edit rights on an element but no
create right on folder X can move the element into X.
- A data object moved without field data is not permission-checked at all beyond loading it.
- Bundles that build on PATCH (backend-power-tools
#757, child-assignments step) can only enforce this client-side today.
Expected
parentId in the payload: require create on the new parent, else ForbiddenException (403).
- Moving or renaming: require
settings on the element, matching the Studio tree's own drop gate, or document why publish is the intended permission.
- Apply the same check on the single-element path and on the job path (
count > 1).
Notes
- The adapters receive
$user, so the check fits into ParentIdAdapter::patch() and KeyAdapter::patch() directly, or centrally in PatchService::patchElement() before the adapter loop.
- Found while reviewing pimcore/backend-power-tools-bundle#757.
PATCH parentId moves an element without checking permissions on the new parent
In plain terms
Moving an element in Studio is a PATCH request with
{ id, parentId }. The server checks whether the user may edit the element being moved. It does not check whether the user may put anything into the new parent.The Studio tree hides the drop target when the user lacks the
createpermission on the folder (permission-helper.ts). That is a UI convenience only. The same request sent directly to the API goes through.Where
src/Patcher/Service/PatchService.php,patchElement(): checkssaveon a data object only when field data is included, andpublishon an asset. Nothing else.src/Patcher/Adapter/ParentIdAdapter.php,patch(): callssetParentId()without any check.src/Patcher/Adapter/KeyAdapter.php,patch(): same forsetKey().What goes wrong
createright on folder X can move the element into X.#757, child-assignments step) can only enforce this client-side today.Expected
parentIdin the payload: requirecreateon the new parent, elseForbiddenException(403).settingson the element, matching the Studio tree's own drop gate, or document whypublishis the intended permission.count > 1).Notes
$user, so the check fits intoParentIdAdapter::patch()andKeyAdapter::patch()directly, or centrally inPatchService::patchElement()before the adapter loop.