craftcms/cms: GraphQL site-scope enforcement missing on entry create, "deleteEntry" without "siteId", and Category/Tag/Asset delete mutations
What fixes it
- 5.11.0craftcms/cms, composerGitHub
composer require "craftcms/cms:^5.11.0"
A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.
Description
Craft enforces GraphQL token site scope via MutationResolver::requireAllowedSite() (src/gql/base/MutationResolver.php), but at 5.10.13.2 it is invoked on only two code paths in the Entry mutation resolver and nowhere else. A GraphQL token scoped to site A can therefore mutate content belonging to site B:
- Entry create — the create branch of the save mutation never calls
requireAllowedSite(). Insrc/gql/resolvers/mutations/Entry.php, the site check sits inside the$canIdentify(update) branch at:282-284(if (isset($arguments['siteId'])) { $this->requireAllowedSite(...); }); the create branch at:303-305($entry = $elementService->createElement(EntryElement::class);) is reached with an attacker-suppliedsiteIdand no scope check. A site-A token creates entries directly in site B.
Impact
Cross-site content-integrity compromise via a least-privilege API token: a token issued to manage only site A's content can inject entries into site B and delete entries, categories, tags, and assets in site B (and across all sites for shared elements). Bounding note, verified dynamically: elements existing only in site B are not reachable, because element fetch is confined to the token’s allowed sites — impact is limited to creations into site B and deletes of elements that also exist in an allowed site.
Report ID: 1682
Text from GitHub Advisory Database
Affected versions 1
- craftcms/cms, composer>= 5.0.0, < 5.11.0GitHub