CVE-2026-79990
moderateSite-scope authorization bypass in Craft CMS GraphQL entry mutations
CVE-2026-79990 is an authorization bypass (CWE-639) in the GraphQL API of Craft CMS: the saveEntry and deleteEntry mutation resolvers read the siteId argument directly from user input instead of routing it through ArgumentManager::prepareArguments(), the function that enforces each GraphQL schema's allowed-sites filter via array_intersect. Because of this, a client authenticating with a token scoped to one site can supply a different siteId in a mutation and create, modify, or delete entries on that other site without any site-scope check; the query path is unaffected because it does call prepareArguments(). An attacker needs only a low-privilege, site-scoped GraphQL token, gaining unauthorized write access to content in other sites of a multi-site installation (CVSS 4.0: 8.7 High, network vector, low privileges required). Only Craft CMS installations that expose the GraphQL API and use tokens or schemas scoped to a subset of their configured sites are affected; single-site installs or tokens already permitted to access all sites are not impacted. No public proof-of-concept exists, the issue is not in CISA KEV, and EPSS assigns a 0.3% probability of exploitation within 30 days (17th percentile), so exploitation is not currently known.
What to do: Check whether your Craft CMS deployment exposes the GraphQL endpoint and whether any schemas or tokens are scoped to a subset of the install's sites; until patched, treat such tokens as able to write to any site in the install, review entry logs for unexpected cross-site changes, and consider temporarily restricting mutation access. Upgrade to the patched Craft CMS release identified in the vendor advisory (fixed version not given in the provided data).
| Craft (Pixel & Tonic) Craft CMS (GraphQL API) | — |
Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.
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.
- Weakness
- CWE-639
- Vector
- CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
In the news0 stories
No ingested article mentions this CVE yet.