Summary
Grav CMS contains an authorization bypass in the flex accounts backend that can let an authenticated backend operator alter protected group or account permissions through specially formatted field names. An operator with account-management access but without super-administrator rights may use this behavior to grant admin.super to an account or group they control.
Affected context
The issue occurs in Grav CMS versions using the affected group and account blueprints together with the flex accounts backend. Risk depends on an authenticated operator having permission to manage users while lacking the higher-privilege admin.super permission, and on submitted account data being processed through dotted property paths before authorization rules are fully enforced.
Exploit preconditions
- Attack surface: Authenticated Grav backend flex accounts functionality
- Required access: An account with
admin.usersor comparable account-management privileges, but withoutadmin.super - Trigger point: Updating an account or group through submitted blueprint fields
- Why exploitation is possible: A flat dotted key can bypass an exact-path blueprint access check, survive filtering, and later be reconstructed as a privileged nested property during object updates
Why this happens
The vulnerability results from inconsistent handling of structured field names across authorization and persistence layers. The blueprint access map evaluates the submitted field using its exact path, while later processing interprets dotted notation as a nested property and writes the reconstructed value. This mismatch allows a field that was not authorized as a nested path to affect a protected permission. The behavior maps to CWE-639: Authorization Bypass Through User-Controlled Key, because attacker-controlled key structure influences which authorization-controlled property is modified.
Potential impact
- An authorized backend operator could grant
admin.superto their own account - An operator could elevate a group they belong to
- The attacker may gain control of Grav configuration and administrative settings
- The attacker could install or modify plugins and themes
- The attacker could access file-management capabilities and other accounts
- The compromise could enable persistent application or content tampering
General mitigation guidance
Mitigation generally focuses on applying authorization consistently to the canonical representation of every property before persistence.
Common defensive patterns include:
- Normalize dotted and nested property paths before access checks and filtering
- Reject keys whose ancestor path is disabled or explicitly ignored by validation policy
- Use allowlisted field paths rather than relying on exact submitted-key matches
- Enforce server-side privilege checks immediately before writing authorization-sensitive fields
- Prevent lower-privileged operators from modifying their own effective role or group memberships
- Apply least privilege to backend accounts and separate user-management from role-management capabilities
- Record and review changes to administrator permissions and group membership
How teams detect issues like this
Organizations can detect this class of issue through:
- Static analysis and code review of path normalization, nested-property setters, and authorization-map lookups
- Tests that submit equivalent nested and dotted representations of protected fields
- Regression tests verifying that disabled or ignored ancestor paths cannot be written
- Review signals where filtering and authorization occur before a later parser reconstructs object structure
- Runtime audit monitoring for unexpected grants of administrator or super-administrator permissions
- Policy enforcement requiring explicit authorization checks for sensitive role and group fields

