CVE-2026-65603 Overview
CVE-2026-65603 is a privilege escalation vulnerability [CWE-269] in the Grav Login plugin (grav-plugin-login) affecting versions <= 3.8.11. The flaw resides in the authenticated profile self-update handler processUserProfile(), invoked via the update_user task. Unlike the registration handler, this handler fails to strip privilege fields (groups, access) from user-submitted form data before persisting them to the user account backend. A low-privilege authenticated attacker can submit crafted form data such as access[admin][super]=true to elevate their account to super-admin. Post-exploitation impact includes admin panel access, scheduler abuse leading to remote code execution, and arbitrary Twig template evaluation. The issue is fixed in version 3.8.12.
Critical Impact
Authenticated users can escalate to super-admin, gain admin panel access, and achieve remote code execution through scheduler abuse and Twig evaluation.
Affected Products
- Grav CMS Login plugin (grav-plugin-login) versions <= 3.8.11
- Deployments where plugins.login.user_registration.fields includes groups or access
- Instances using the default regular / DataUser account backend
Discovery Timeline
- 2026-07-22 - CVE-2026-65603 published to NVD
- 2026-07-22 - Last updated in NVD database
Technical Details for CVE-2026-65603
Vulnerability Analysis
The Grav Login plugin exposes a self-service profile update handler that accepts POST data from authenticated users. The handler persists submitted form fields directly to the user account file without filtering privileged attributes. Administrators who extend plugins.login.user_registration.fields with entries like groups or access inadvertently allow those fields to be submitted through the profile update flow. The registration handler correctly strips these attributes, but the update path does not apply the same allowlist. This inconsistency is the core defect enabling vertical privilege escalation from a standard user to super-admin.
Root Cause
The root cause is an absent server-side allowlist in processUserProfile() for privilege-related keys. The handler trusts client-controlled form data and writes groups and access structures back to the DataUser object. Because Grav evaluates the access.admin.super attribute to grant administrative rights, any value the attacker sets in that key is honored on the next authorization check. The fix in version 3.8.12 introduces the same field-stripping logic used during registration.
Attack Vector
An attacker registers or logs into an existing low-privilege account on the target Grav site. The attacker then submits a POST request to the profile update endpoint containing crafted body parameters such as access[admin][super]=true and optional groups[]=admins. On the next request, the account is treated as super-admin. The attacker can then reach /admin, register a scheduler job to execute arbitrary shell commands, or use Twig template evaluation to run PHP code within the Grav process.
See the GitHub Security Advisory and the VulnCheck Advisory on Grav Plugin for the vendor technical writeup.
Detection Methods for CVE-2026-65603
Indicators of Compromise
- POST requests to the profile update endpoint containing access[ or groups[ parameter names from non-admin sessions.
- Modifications to user YAML files under user/accounts/ that add an access.admin.super: true block for previously unprivileged users.
- New or modified entries in user/config/scheduler.yaml that invoke shell commands or unusual binaries.
- Unexpected Twig template renders or admin panel logins from accounts not previously granted administrative rights.
Detection Strategies
- Monitor web access logs for authenticated POST requests to update_user task URLs where the request body contains privilege field names.
- Perform integrity monitoring of files under user/accounts/ to alert on any change adding access or groups keys.
- Correlate admin panel authentication events with prior profile-update activity from the same user identifier.
Monitoring Recommendations
- Enable verbose logging in Grav and forward logs to a centralized SIEM for retention and query.
- Alert on any successful /admin session established by an account that recently submitted a profile update.
- Track scheduler configuration changes and Twig rendering errors as secondary indicators of post-exploitation activity.
How to Mitigate CVE-2026-65603
Immediate Actions Required
- Upgrade grav-plugin-login to version 3.8.12 or later on every Grav instance.
- Audit all user account files under user/accounts/ for unauthorized access.admin.super or groups entries and revoke privileges as needed.
- Rotate credentials and invalidate active sessions for any account that shows signs of tampering.
- Review user/config/scheduler.yaml for unauthorized jobs and remove them.
Patch Information
The vendor released the fix in grav-plugin-login version 3.8.12. Install the update through the Grav admin panel or via the CLI command bin/gpm update login. Refer to the GitHub Security Advisory for full remediation guidance.
Workarounds
- Remove groups and access from plugins.login.user_registration.fields in the Login plugin configuration until the patch is applied.
- Disable self-service profile updates by restricting the update_user route at the web server or reverse proxy layer for non-admin users.
- Switch to an alternative account backend that enforces server-side privilege field filtering if patching cannot be completed immediately.
# Configuration example - restrict privilege fields in Login plugin config
# user/config/plugins/login.yaml
user_registration:
enabled: true
fields:
- username
- email
- password
- fullname
# Do NOT include 'groups' or 'access' here
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

