Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-25497

CVE-2026-25497: Craft CMS GraphQL Privilege Escalation

CVE-2026-25497 is a privilege escalation vulnerability in Craft CMS GraphQL API that allows authenticated users to modify assets across unauthorized volumes. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-25497 Overview

CVE-2026-25497 is a Privilege Escalation vulnerability affecting Craft CMS, a platform for creating digital experiences. The flaw exists in Craft CMS's GraphQL API and allows an authenticated user with write access to one asset volume to escalate their privileges and modify or transfer assets belonging to any other volume, including restricted or private volumes to which they should not have access.

The saveAsset GraphQL mutation validates authorization against the schema-resolved volume but fetches the target asset by ID without verifying that the asset belongs to the authorized volume. This authorization bypass enables unauthorized cross-volume asset modification and transfer, potentially compromising sensitive digital assets across an organization's entire Craft CMS deployment.

Critical Impact

Authenticated attackers can bypass volume-level access controls to modify or transfer assets from restricted and private volumes, leading to unauthorized data access, data manipulation, and potential data exfiltration.

Affected Products

  • Craft CMS versions 4.0.0-RC1 to before 4.17.0-beta.1
  • Craft CMS versions 5.0.0 to before 5.9.0-beta.1
  • Craft CMS version 5.8.22 and earlier (stable releases)

Discovery Timeline

  • 2026-02-09 - CVE-2026-25497 published to NVD
  • 2026-02-09 - Last updated in NVD database

Technical Details for CVE-2026-25497

Vulnerability Analysis

This vulnerability is classified as CWE-639: Authorization Bypass Through User-Controlled Key. The core issue lies in how the GraphQL API's saveAsset mutation handles authorization checks for asset operations. When processing a mutation request, the system correctly validates whether the authenticated user has permissions for the volume specified in the GraphQL schema. However, the actual asset retrieval occurs via a separate lookup using the asset ID parameter, which does not include a secondary validation to confirm the retrieved asset belongs to the volume the user is authorized to access.

This disconnect between authorization validation and resource retrieval creates a classic Insecure Direct Object Reference (IDOR) pattern within the GraphQL context. An attacker with legitimate write access to Volume A can craft a mutation targeting an asset ID belonging to Volume B (a restricted volume), and the system will permit the operation because authorization was checked against Volume A while the action is performed on Volume B's asset.

Root Cause

The root cause is a missing authorization check in the asset resolution logic within the GraphQL mutation handler. The saveAsset mutation in src/gql/resolvers/mutations/Asset.php validates user permissions based on the schema-defined volume context but fails to verify that the asset ID provided in the request actually belongs to that authorized volume before performing modifications.

Attack Vector

The attack is network-based and requires low-privilege authentication. An attacker needs:

  1. Valid credentials to authenticate with the Craft CMS instance
  2. Write access to at least one asset volume (even a low-privilege public volume)
  3. Knowledge of asset IDs in target restricted volumes (obtainable through enumeration or information disclosure)

The attacker crafts a malicious GraphQL mutation specifying their authorized volume in the schema context while targeting an asset ID from a restricted volume. The system authorizes the request based on the attacker's legitimate volume access, then retrieves and modifies the target asset without validating volume ownership.

php
// Security patch in src/gql/resolvers/mutations/Asset.php
// Source: https://github.com/craftcms/cms/commit/ac7edf868c1a81fd9c4dc49d3b3edf1cce113409

             if (!$asset) {
                 throw new Error('No such asset exists');
             }
+
+            if ($asset->volumeId !== $volume->id) {
+                $this->requireSchemaAction('volumes.' . $asset->getVolume()->uid, 'save');
+            }
         } else {
             $this->requireSchemaAction('volumes.' . $volume->uid, 'create');

The fix adds a critical check: after retrieving an asset by ID, the code now verifies whether the asset's volume ID matches the authorized volume. If not, it requires explicit authorization for the asset's actual volume, preventing cross-volume privilege escalation.

Detection Methods for CVE-2026-25497

Indicators of Compromise

  • GraphQL mutation requests to the saveAsset endpoint that reference asset IDs outside the user's authorized volumes
  • Unexpected asset modifications or transfers in restricted volumes by users who should not have access
  • Audit logs showing users performing operations on volumes not assigned to their permission groups

Detection Strategies

  • Monitor GraphQL API logs for saveAsset mutations and correlate asset IDs with the requesting user's volume permissions
  • Implement anomaly detection for cross-volume asset operations that violate expected access patterns
  • Review Craft CMS access logs for authenticated users performing bulk asset operations or accessing multiple volumes in rapid succession

Monitoring Recommendations

  • Enable detailed GraphQL query logging to capture mutation parameters and user context
  • Set up alerts for asset modifications in high-value or restricted volumes
  • Implement file integrity monitoring on asset storage directories to detect unauthorized changes

How to Mitigate CVE-2026-25497

Immediate Actions Required

  • Upgrade Craft CMS to version 4.17.0-beta.1 or later for the 4.x branch
  • Upgrade Craft CMS to version 5.9.0-beta.1 or later, or stable release 5.8.22 or later for the 5.x branch
  • Review asset volume permissions and audit recent asset modifications for signs of unauthorized access
  • Consider temporarily disabling GraphQL API access for untrusted users until the patch is applied

Patch Information

The vulnerability has been patched in Craft CMS versions 4.17.0-beta.1 and 5.9.0-beta.1. A stable release patch is available in version 5.8.22. The fix adds proper volume ownership validation when processing asset mutations through the GraphQL API. For detailed patch information, see the GitHub Security Advisory and the commit changes.

Workarounds

  • Restrict GraphQL API schema permissions to minimize the number of users with write access to any asset volume
  • Implement network-level access controls to limit GraphQL endpoint exposure to trusted networks only
  • Use custom middleware or firewall rules to validate asset IDs in mutations against user permissions before requests reach Craft CMS
bash
# Configuration example - Disable GraphQL API temporarily in config/general.php
# Add or modify the following setting:
'enableGraphqlIntrospection' => false,
# For complete API disable (if not required):
'enableGql' => false,

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.