Description
Craft CMS GraphQL entry mutation resolvers (saveEntry, deleteEntry) read siteIddirectly from$argumentswithout passing throughArgumentManagerprepareArguments(), which is the function that enforces site-scope filtering via array_intersect against the GraphQL schema’s allowed sites. The query path (ElementResolverprepareElementQuery) correctly calls prepareArguments()`, so queries to unauthorized sites return empty. But mutations bypass this entirely — an attacker with a token scoped to Site A can create, modify, or delete entries in Site B by passing siteId in the mutations argument.
Affected products
| Vendor | Product | Affected | Fixed |
|---|---|---|---|
| craftcms | cms | 5.0.0-RC1 – < 5.10.13 | 5.10.13 |
References
- https://www.hckrt.com/hacktivity/HCKRT-B5BSMM third-party-advisory technical-description mitigation
- https://github.com/craftcms/cms/releases/tag/5.10.13 release-notes
- https://github.com/craftcms/cms product
- https://github.com/craftcms/cms/security/advisories/GHSA-4mgp-5vf2-7c9m third-party-advisory