Sep 17, 2026·8 min read·2 visits
A missing security decorator in Grav's group blueprint allowed delegated admin users to assign themselves super-admin privileges, leading to potential remote code execution.
CVE-2026-75837 is a critical privilege escalation vulnerability affecting the Grav Flat-File Content Management System (CMS) in versions prior to 2.0.14. Due to a missing security guard on the access field within the core Flex group blueprint configuration file (system/blueprints/user/group.yaml), a delegated administrative operator can submit a crafted payload to elevate their permissions to super-administrator, which can then be leveraged to achieve remote code execution.
The Grav Flat-File Content Management System (CMS) relies on YAML-based configurations known as blueprints to dynamically manage schemas, form structures, and access permissions. In Grav, administrative users are assigned various granular privileges, such as the ability to manage user accounts and groups (admin.users). This design allows for delegated administration where specific operators can handle lower-level user management tasks without obtaining full administrative control over the entire system.
CVE-2026-75837 identifies a critical flaw in how Grav handles privilege management within its user group configuration blueprints. Specifically, the core Flex group blueprint configuration file failed to declare appropriate security controls over its permission mapping field. Consequently, an administrative operator with delegated access can bypass intended privilege boundaries by directly injecting permissions into the group configuration.
This security vulnerability represents a classic privilege escalation scenario (CWE-269), wherein a low-privileged administrative user elevates their access level to that of a system-wide super-administrator (admin.super). Once an attacker achieves super-admin status, they can access sensitive features of the Grav administrative interface, such as custom Twig template rendering and task scheduling. These features can be exploited to execute arbitrary code on the underlying host, translating the privilege escalation into an interactive system compromise.
The underlying mechanism behind Grav's administrative security is the blueprint schema processor. When a form is submitted to modify user or group attributes, the backend engine processes the request using BlueprintSchema::filterArray(). This filtering step is responsible for validating, sanitizing, and casting input data before it is written to the flat-file database on the disk. To prevent unauthorized modifications, the engine relies on security decorators defined directly within the YAML blueprints.
During input processing, the schema engine executes Blueprint::dynamicSecurity(). This helper function evaluates security guards attached to individual fields. If a field configuration contains the property security@: admin.super, the dynamic security helper checks whether the currently authenticated user possesses the admin.super privilege. If the user does not have this privilege, the helper marks the field as validate.ignore. This instruction forces the validation engine to discard the field from the submitted input payload, rendering unauthorized modifications ineffective.
In versions of Grav prior to 2.0.14, the core blueprint for user groups (system/blueprints/user/group.yaml) omitted the security@: admin.super guard on the access field. Although the sibling blueprint for user accounts (account.yaml) correctly implemented this security restriction on its group and access fields, the group blueprint did not. The access field in group.yaml was configured with check_authorize: false, which only governed visualization rules within the administration panel's Twig templates and did not enforce server-side validation. Because the backend validation loop found no security decorator on the access property, it allowed the data to pass into the final configuration file unfiltered.
To understand how the flaw manifests, analyze the differences in blueprint definitions before and after the application of the official security patch. The vulnerable blueprint definition in system/blueprints/user/group.yaml was structured as follows:
access:
type: permissions
check_authorize: false
label: PLUGIN_ADMIN.PERMISSIONSIn this configuration, there is no server-side security constraint associated with the access property. An administrative user with the admin.users permission could manipulate the request payload to append arbitrary access fields. During execution, the following diagram illustrates how the request flows through the insecure pipeline:
To resolve this issue, the patch introduced in commit 5192316f5bf0f033636f43561829d7fc13a4ab64 inserts the security@ directive under the access block. Below is the updated and annotated blueprint configuration:
access:
# A group's access map is granted to every member, so writing it is a
# super-only capability — same as the account form's groups/access fields.
# `check_authorize` below only drives how the classic admin renders the
# permission rows; `security@` is what actually strips the field from a
# non-super's submitted data via Blueprint::dynamicSecurity(), so without
# it an `admin.users` operator could save `admin.super: true` onto a group
# they belong to and escalate. (GHSA-xhfv-7758-r9hx)
security@: admin.super
type: permissions
check_authorize: false
label: PLUGIN_ADMIN.PERMISSIONSWith this change, Blueprint::dynamicSecurity() detects the security@: admin.super property. When a user lacking the admin.super privilege submits a form containing group access modifications, the helper evaluates the restriction, identifies the missing privilege, and dynamically marks the access parameter as ignored. This prevents the unauthorized permissions from being written to disk, ensuring that non-super operators cannot elevate their status or that of any groups they control.
Exploitation of CVE-2026-75837 requires the attacker to have already acquired credentials or session access for an account with the admin.users permission. This permission allows the user to manage accounts and user groups. From this position, the attacker can leverage the missing validation check on group blueprints to escalate their privileges to super-admin.
First, the attacker identifies a group they belong to or creates a new group that they can assign to their own account. Using an HTTP interception proxy or by directly constructing a network request, the attacker triggers an update to the target user group. The request structure is modified to include the access[admin][super] parameter, mapping it to a value of true:
POST /admin/flex-objects/user-groups/ops HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Cookie: grav-admin-session=...
_csrf_token=1a2b3c4d5e...&groupname=ops&readableName=Operations&access%5Badmin%5D%5Bsuper%5D=trueWhen the Grav backend receives this payload, it processes the request and executes the blueprint validation. Since the system/blueprints/user/group.yaml file on the vulnerable server does not restrict the access field, the payload is successfully validated and written to the corresponding group configuration file on disk. The output file, typically stored at user/config/groups.yaml or within the flex directories, then contains the updated privilege map:
groupname: ops
readableName: Operations
access:
admin:
super: true
login: trueBecause the attacker is a member of the updated group, Grav dynamically merges the group permissions into the attacker's active session profile. This immediately elevates the attacker's privileges to admin.super. With super-admin privileges, the attacker gains the ability to execute administrative tasks, configure plugins, edit scheduled tasks, or exploit the built-in Twig template processor to execute arbitrary system commands on the hosting server.
The security impact of CVE-2026-75837 is classified as critical, receiving a CVSS v3.1 base score of 9.1 and a CVSS v4.0 score of 9.3. The primary driver of this high severity is the direct path from delegated administrative access to complete host compromise. By escalating privileges to admin.super, an attacker successfully bypasses the logical isolation of administrative roles within the CMS.
Once super-admin status is attained, the scope of the attack expands beyond the CMS itself. In a standard Grav deployment, a super-administrator can modify system configurations, manage file uploads, and define scheduled tasks. Additionally, the administrative interface allows the execution of Twig templates. Since Twig template processing can be leveraged to execute arbitrary PHP code, the privilege escalation directly leads to remote code execution (RCE) under the context of the web server user (e.g., www-data).
The vulnerability has an EPSS score of 0.00339, which indicates a low probability of immediate, automated exploitation in the wild, largely because exploitation requires pre-existing administrative credentials with the admin.users privilege. However, in enterprise environments or multi-tenant setups where administrative roles are strictly segregated, the vulnerability represents a significant risk, as it completely invalidates the security boundaries established between different administrative tiers.
The most effective remediation is upgrading the Grav installation to version 2.0.14 or later, which contains the official patch. The update modifies the default blueprint file for user groups to enforce proper security validations, preventing non-super administrators from submitting modified access maps.
If upgrading the entire CMS is not immediately possible due to production constraints, administrators can apply a manual hotfix. To do so, locate the file system/blueprints/user/group.yaml within the Grav installation directory. Open the file in a text editor, find the access field definition, and insert the security@: admin.super property. The modified section must match the following structure:
access:
security@: admin.super
type: permissions
check_authorize: false
label: PLUGIN_ADMIN.PERMISSIONSAfter saving the changes, clear the Grav cache to ensure the system compiles the updated blueprint definitions. This can be accomplished by executing the command bin/grav clear-cache via the command-line interface. Additionally, security teams should audit existing user and group configurations to identify unauthorized permissions. Inspect the files in user/config/groups.yaml and the flex objects directory for any instances of admin.super: true assigned to groups that are not intended to possess full administrative control.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
grav getgrav | < 2.0.14 | 2.0.14 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-269 |
| Attack Vector | Network |
| CVSS v3.1 | 9.1 (Critical) |
| EPSS Score | 0.00339 (Percentile: 27.20%) |
| Exploit Status | PoC |
| KEV Status | Not Listed |
The software does not properly assign, modify, track, or validate privileges for an actor, creating opportunities for privilege escalation.
CVE-2026-76461 is a critical, unauthenticated, remotely exploitable SQL Injection (SQLi) vulnerability in the email parsing engine of Cisco AsyncOS Software for Cisco Secure Email Gateway (SEG). An unauthenticated remote attacker can exploit this vulnerability by transmitting a specially crafted email message containing malicious SQL statements directly through an affected gateway.
CVE-2026-72819 is a high-severity Remote Code Execution (RCE) vulnerability in Grav CMS before version 2.0.13. The vulnerability lies in the validation of dynamic data providers (callbacks) within the Flex Objects plugin settings and blueprints, allowing administrative users to bypass validation checks via array-notation callables. This validation failure enables administrative users to execute arbitrary PHP classes and methods, including the GPM Installer unZip routine, leading to full remote code execution on the server.
Steeltoe, a popular framework for building cloud-native .NET applications, contains a critical data-exposure flaw in its HttpExchanges actuator endpoint before version 4.3.0. When explicitly configured to include query strings, the system records and stores sensitive values (such as OAuth tokens and credentials) in memory and application debug logs without sanitization, exposing them to unauthorized network actors.
A logic verification vulnerability in `@libp2p/peer-store` (part of the `js-libp2p` ecosystem) allows unauthenticated remote attackers to bypass identity verification and poison a victim node's peer store database with arbitrary network multiaddresses. This occurs because `consumePeerRecord()` fails to ensure that the signature's identity matches the inner record payload's identity.
Improper neutralization of input during web page generation in Grav CMS allows authenticated users with page modification privileges to execute stored Cross-Site Scripting (XSS) attacks. The flaw exists in AudioMediaTrait and VideoMediaTrait where media source URLs are concatenated directly into HTML templates without proper escaping.
A directory traversal vulnerability exists in the Junrar archive extraction library prior to version 7.6.1. When extracting crafted RAR archives, the library allows unauthorized directory creation outside the designated destination root due to improper path normalization during directory creation.