CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-62669

CVE-2026-62669: Critical Two-Factor Authentication Bypass in Grav CMS Login Plugin

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 3, 2026·8 min read·16 visits

Executive Summary (TL;DR)

A logical validation flaw in the Grav Login Plugin allows an attacker with valid primary credentials to out-of-band regenerate and read the victim's 2FA secret, successfully bypassing multi-factor protection.

CVE-2026-62669 is a critical Improper Authentication vulnerability (CWE-287) in the Grav Login Plugin for Grav CMS. Prior to version 3.8.11, the plugin's key rotation task failed to verify if a user session was fully authorized before regenerating and returning two-factor authentication (2FA) secrets. Consequently, an attacker possessing a victim's primary credentials could invoke this endpoint to replace the 2FA secret, retrieve the replacement, and bypass the MFA constraint entirely.

Vulnerability Overview

The Grav Login Plugin is a core extension for Grav CMS designed to manage administrative access, session validation, user profiles, and security mechanisms including Multi-Factor Authentication (MFA). It acts as the primary gatekeeper for the administrative dashboard, which exposes extensive site controls. The plugin implements Time-Based One-Time Password (TOTP) verification to secure administrative accounts.

This vulnerability, classified under CWE-287 (Improper Authentication), exists within the administrative controller task responsible for regenerating 2FA secrets. When a user authenticates, the system utilizes a two-stage process: validating the primary password, followed by a secondary TOTP challenge. During this secondary stage, the user is authenticated but not yet authorized.

The attack surface is exposed because the application handles administrative task routes before confirming that the user has completed the secondary authentication step. This logical flaw allows a partially authenticated session to trigger tasks reserved for fully authorized sessions. As a result, the protective boundaries of 2FA are weakened, exposing administrative sessions to complete hijack if primary credentials are compromised.

This flaw affects getgrav/grav-plugin-login versions prior to 3.8.11, as well as getgrav/grav installations prior to version 2.0.4. Because the Grav administrative dashboard provides direct facilities for theme modification, configuration changes, and file uploads, bypassing the login sequence yields total control over the server hosting the CMS environment.

Root Cause Analysis

To understand the root cause, it is necessary to examine how Grav CMS structures and serializes user sessions during login. When a user submits their correct username and password, Grav instantiates a user object and stores it in the global container under $this->grav['user']. At this specific execution point, the system evaluates the helper $user->exists() as true because a valid, matching database record was found.

However, because the account has 2FA enabled, the login controller does not yet grant full authorization. The login state explicitly declares the session as unauthorized, setting $user->authorized = false and redirecting the browser to the TOTP token prompt page. The server expects the user to submit a valid six-digit token before altering this authorization state flag to true.

The core architectural failure is in classes/Controller.php within the method taskRegenerate2FASecret(). The logic verified only whether the user session existed using $user->exists(), rather than checking if the user was fully authorized using $user->authorized === true. Because the attacker's session meets the existence condition immediately after inputting the correct primary password, the controller permits access to the secret regeneration logic.

Additionally, this endpoint lacked Cross-Site Request Forgery (CSRF) protection. The application did not require a cryptographically signed transaction nonce to authorize the secret regeneration. This allowed the administrative endpoint to be reached via GET requests, enabling attackers to execute cross-site request attacks on authenticated sessions.

Code Analysis

The code-level flaw resides in the Controller class of the Grav Login Plugin. In vulnerable versions, the method handling 2FA secret regeneration was implemented as follows:

// Vulnerable Implementation in classes/Controller.php
public function taskRegenerate2FASecret()
{
    /** @var UserInterface $user */
    $user = $this->grav['user'];
 
    if ($user->exists()) {
        /** @var TwoFactorAuth $twoFa */
        $twoFa = $this->grav['login']->twoFactorAuth();
        $secret = $twoFa->createSecret();
        // ... saves the secret to user configuration and outputs JSON

The patched version modifies this evaluation gate to strictly check both existence and session authorization state:

// Patched Implementation in classes/Controller.php
public function taskRegenerate2FASecret()
{
    /** @var UserInterface $user */
    $user = $this->grav['user'];
 
    // Require a fully authorized session, not merely an existing one.
    // Gating on exists() alone let an unauthorized attacker overwrite and read the secret.
    if ($user->exists() && $user->authorized === true) {
        /** @var TwoFactorAuth $twoFa */
        $twoFa = $this->grav['login']->twoFactorAuth();
        $secret = $twoFa->createSecret();
        // ...

Furthermore, the patch hardened the routing flow in login.php to prevent CSRF exploitation. It enforces that regenerate2FASecret requests must use the HTTP POST method and include a valid security nonce:

// Hardening routing gate in login.php
case 'regenerate2FASecret':
    if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST'
        || !isset($post['login-form-nonce'])
        || !Utils::verifyNonce($post['login-form-nonce'], 'login-form')) {
        $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'info');
        return;
    }
    break;

In the frontend template 2fa_secret.html.twig, a CSRF token helper was injected to supply the required validation parameter:

{# Injection in templates/forms/fields/2fa_secret/2fa_secret.html.twig #}
<div class="danger twofa-wrapper">
    <button class="button button-small" data-2fa-regenerate><i class="fa fa-refresh"></i> Regenerate</button>
    {{ nonce_field('login-form', 'login-form-nonce')|raw }}
</div>

This multi-layered patch ensures that the secret-rotation action is inaccessible during the incomplete, pre-authorization login phase and blocks any unauthorized state transitions.

Exploitation & Attack Flow

Exploiting this flaw requires that the attacker has already obtained the victim's correct primary credentials (username and password). The attack does not bypass the initial password verification phase. Instead, it targets the subsequent step where the system relies on TOTP to prevent unauthorized login attempts from actors who have acquired the password.

First, the attacker authenticates using the known credentials, which causes the target server to initialize a session cookie and prompt for the 2FA token. The attacker extracts this session cookie from the HTTP response headers. At this point, the session state satisfies the $user->exists() condition but does not have the authorized flag set.

Next, the attacker submits an out-of-band POST request targeting /admin/task:login.regenerate2FASecret, appending the captured session cookie. Because the application evaluates only the existence of the session user, it processes the request, overwrites the user's authenticating secret in the database, and returns the new base32 secret inside the JSON response body:

POST /admin/task:login.regenerate2FASecret HTTP/1.1
Host: target-grav.local
Cookie: grav-site-xxxx=attacker_captured_cookie
Content-Type: application/x-www-form-urlencoded
 
login-form-nonce=dummy_or_ignored

Response:

{
  "status": "success",
  "secret": "KVKVE43VNZSXIYTM",
  "image": "data:image/png;base64,..."
}

The attacker inputs the extracted secret (KVKVE43VNZSXIYTM) into a local generator tool to calculate the active six-digit token. Finally, the attacker submits this token to the standard 2FA verification page, satisfying the challenge and gaining full control of the administrative panel.

Impact Assessment

The technical impact of CVE-2026-62669 is highly severe. It allows a complete bypass of multi-factor authentication, which is often deployed as a primary control to protect highly privileged administrative accounts. Bypassing this control results in an immediate breakdown of the zero-trust boundary surrounding administrative access.

Once inside the Grav CMS administrative interface, the attacker has unrestricted administrative rights. The administrative panel provides functionality to edit page content, change site-wide configurations, create new high-privilege users, and modify installed extensions. Attackers can leverage these features to execute arbitrary code on the underlying host, typically by uploading malicious PHP webshells or modifying active theme templates to execute system commands.

The CVSS v3.1 base score of 7.4 reflects high confidentiality and integrity impact. The Attack Complexity is classified as High because the exploit cannot be performed entirely blindly; the attacker must already possess the victim's correct primary authentication credentials. No user interaction or special privileges are required.

While there is no evidence of active, automated exploitation in the wild, the simple logic required to execute this bypass makes it highly attractive for targeted attacks or persistent threat campaigns. The exposure of Grav administrative interfaces on the public internet makes immediate remediation critical.

Remediation & Detection Guidance

The primary remediation for this vulnerability is upgrading the Grav Login Plugin to version 3.8.11 or later. Organizations running Grav CMS must also ensure the core package is updated to version 2.0.4 or higher to ensure full compatibility with the patched authentication and session-handling methods.

If immediate patching is not feasible, temporary mitigation can be achieved at the network layer. Security teams should deploy Web Application Firewall (WAF) or reverse-proxy rules to block any incoming HTTP requests that contain the path pattern task:login.regenerate2FASecret or /task/login.regenerate2FASecret. This path should be restricted strictly to trusted administrative IP addresses.

Detection should focus on monitoring web server logs for anomalous administrative traffic. Search access logs for any POST requests targeting the task:login.regenerate2FASecret endpoint that do not originate from the expected administrative profile configuration sub-paths (e.g., /admin/user/). Requests hitting this endpoint immediately following a login attempt indicate an exploit attempt.

Furthermore, system administrators should audit configuration files for unauthorized modifications. Periodically verify user configuration files under user/config/accounts/ to confirm that the twofa_secret fields have not been modified unexpectedly. Any sudden desynchronization of user authenticators should be flagged and investigated immediately as a potential account takeover incident.

Fix Analysis (1)

Technical Appendix

CVSS Score
7.4/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
EPSS Probability
0.39%
Top 68% most exploited

Affected Systems

Grav CMS CoreGrav Login Plugin

Affected Versions Detail

Product
Affected Versions
Fixed Version
grav-plugin-login
getgrav
< 3.8.113.8.11
grav
getgrav
< 2.0.42.0.4
AttributeDetail
CWE IDCWE-287
Attack VectorNetwork
CVSS Score7.4 (High)
EPSS Score0.00386
ImpactTwo-Factor Authentication Bypass
Exploit StatusProof-of-Concept
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1078Valid Accounts
Initial Access
T1190Exploit Public-Facing Application
Initial Access
CWE-287
Improper Authentication

The software does not prove, or insufficiently proves, that a user is who they claim to be.

Vulnerability Timeline

Remediation patch pushed to source repository
2026-06-26
GitHub Security Advisory GHSA-7mgc-c7pq-3rr3 published
2026-08-19
NVD indexes and analyzes CVE-2026-62669
2026-08-19

References & Sources

  • [1]GitHub Security Advisory GHSA-7mgc-c7pq-3rr3
  • [2]Grav Commit 5d1b722298cb
  • [3]Grav Login Plugin Release 3.8.11
  • [4]Grav CMS Release 2.0.4
  • [5]Wiz Vulnerability Database Details

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•2 minutes ago•CVE-2026-109619
9.2

CVE-2026-109619: Remote Code Execution in PHP Core via Stale Global State Memory Corruption (PHP2Shell)

CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.

Alon Barad
Alon Barad
1 views•6 min read
•5 minutes ago•CVE-2026-113721
4.5

CVE-2026-113721: Unsafe Link Resolution in virtualenv File Generation

In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.

Amit Schendel
Amit Schendel
1 views•5 min read
•9 days ago•CVE-2026-87697
8.8

CVE-2026-87697: Untrusted Deserialization in .NET PresentationCore Clipboard Handling

A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.

Alon Barad
Alon Barad
31 views•5 min read
•9 days ago•CVE-2026-70007
8.8

CVE-2026-70007: Out-of-Bounds Write Vulnerability in .NET Framework and WPF Subsystem

An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.

Amit Schendel
Amit Schendel
19 views•6 min read
•10 days ago•CVE-2026-70186
7.5

CVE-2026-70186: ASP.NET Core Denial of Service Vulnerability via Framework Deadlock

ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.

Amit Schendel
Amit Schendel
18 views•5 min read
•10 days ago•CVE-2026-70035
8.8

CVE-2026-70035: Insecure Deserialization Remote Code Execution in Microsoft .NET Framework and .NET Runtime

CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.

Amit Schendel
Amit Schendel
24 views•6 min read