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-75834

CVE-2026-75834: Input Sanitization Bypass leading to Stored XSS in Grav CMS

Alon Barad
Alon Barad
Software Engineer

Sep 17, 2026·6 min read·16 visits

Executive Summary (TL;DR)

A critical security bypass in Grav CMS's XSS safety gate allows attackers to inject and store arbitrary HTML/JavaScript by passing invalid UTF-8 bytes or oversized elements, triggering silent engine failures.

CVE-2026-75834 is a stored Cross-Site Scripting (XSS) vulnerability in Grav CMS core, caused by a design flaw in its input validation wrapper Security::detectXss(). Regular expressions using the PCRE UTF-8 /u modifier fail-open when encountering invalid UTF-8 sequences or when the PCRE JIT stack limit is exhausted, allowing authenticated users with page-editing privileges to save malicious HTML and scripts.

Vulnerability Overview

The flat-file Content Management System Grav relies on a central input validation library to inspect, block, and clean potential security threats before they write to disk. This mechanism, implemented in Security::detectXss(), targets user input across all editable page structures. Under standard settings, the scanner flags cross-site scripting (XSS) indicators before any modifications parse into the physical markdown pages.

Because the underlying engine inspects markup on the server side prior to database-free file writes, any validation failure represents an instantaneous bypass of the platform's editor permissions. The vulnerability surface is accessible to any authenticated user with page-creation or page-modification roles. This includes authors and editors who typically lack unrestricted script execution capabilities.

By leveraging specific design gaps in PHP's PCRE execution model, malicious payloads can navigate through these safety checks without setting off the system's defensive alerts. The resulting injection results in high-integrity stored scripts that target admin and visitor sessions.

Root Cause Analysis

The root cause lies in how Grav's validation logic evaluates the output of PHP's standard PCRE regular expression execution engine. Specifically, preg_match returns 0 if no matching threat patterns are located, and 1 if a matching pattern is caught. However, if the evaluation itself cannot complete due to internal engine limitations or data structure mismatches, the function returns the boolean value false.

The logic used to evaluate this output performed a loose truthiness check. Because PHP treats both 0 (clean) and false (processing error) as falsy values, any operational error inside preg_match was treated as an assurance that the evaluated input string contained zero threats. This architecture represents a classic fail-open state, where error handling falls back to the least restrictive option.

Two independent paths trigger this fail-open state. First, the inclusion of the /u (UTF-8) modifier on all regex pattern definitions forces preg_match to immediately reject inputs containing structurally invalid UTF-8 byte sequences. Second, recursive backtracking limits during the evaluation of oversized markup blocks trigger PCRE JIT stack limit errors, which similarly crash the evaluation and return false.

Code Analysis

The vulnerable implementation in system/src/Grav/Common/Security.php directly called preg_match inside a loop without checking for exact integer returns. Here is the conceptual vulnerable structure:

// Vulnerable evaluation logic in detectXss
foreach ($patterns as $name => $regex) {
    if (preg_match($regex, $string)) {
        return $name; // Threat flagged
    }
}
return null; // Treated as safe

The remediated approach resolves this by executing the validation within a specialized private helper, patternMatches. This function explicitly checks for strict boolean outcomes and defaults to a fail-closed response (true) if any matching errors occur. Below is the secure implementation:

private static function patternMatches(string $regex, string $subject): bool
{
    $result = preg_match($regex, $subject);
    if ($result !== false) {
        return (bool) $result;
    }
 
    if (preg_last_error() === PREG_JIT_STACKLIMIT_ERROR) {
        $jit = ini_get('pcre.jit');
        ini_set('pcre.jit', '0');
        $result = preg_match($regex[0] . '(?:)' . substr($regex, 1), $subject);
        ini_set('pcre.jit', (string) $jit);
        if ($result !== false) {
            return (bool) $result;
        }
    }
 
    // Fail closed if any other error (such as backtracking limits) occurs
    return true;
}

Exploitation Methodology

Exploitation requires an authenticated editor account or an API exposure that feeds user input into the Grav page parser. Attackers can leverage either the character encoding bypass or the JIT stack limit exhaustion vulnerability to deliver standard script vectors. The injection payload remains inactive on the server but is stored in its raw format inside the flat-file markdown content.

In the invalid UTF-8 attack vector, the attacker inserts a single bad byte (such as hex \x80) immediately before a functional HTML element. When the security validation layer parses this input, the internal regular expressions fail immediately. The engine returns false, causing the system to write the page content to disk. When the page is subsequently requested by a client, the browser decodes the malformed byte sequence into a Unicode replacement character (such as U+FFFD) and executes the remaining HTML and JavaScript normally.

In the JIT stack exhaustion attack vector, the attacker provides a highly nested or padded tag structure. The recursive validation expressions run out of JIT stack memory, generating a PREG_JIT_STACKLIMIT_ERROR. The regex matching halts, returns false, and permits the storing of the script payload. Upon page render, the browser disregards the excessive padding and executes the accompanying javascript attribute.

Impact Assessment

The impact of a stored Cross-Site Scripting vulnerability in a Content Management System like Grav is high. Because administrative actions in the dashboard can be executed via client-side requests, a successfully injected script targeting an administrator can automate high-privilege activities. This includes creating new admin users, altering configurations, or utilizing system-level integrations to compromise the hosting environment.

Furthermore, because the payload executes in the browsers of ordinary site visitors, it can be used for session hijacking, drive-by malware delivery, or phishing campaigns. The scope change metric in CVSS v3.1 (S:C) highlights this transition, indicating that the vulnerability allows the compromise of resources beyond the security boundaries of the target platform.

The vulnerability holds a CVSS v3.1 base score of 5.4. While it requires low privileges (PR:L), the potential for administrative takeover elevated by administrative views changes the practical threat landscape to a high risk level in typical production environments.

Remediation & Mitigation Guidance

The recommended remediation path is to upgrade the Grav core system to version 2.0.14 or later. This version contains the fully patched Security::detectXss logic, replacing raw evaluation checks with robust fail-closed mechanics and handling invalid UTF-8 transformations safely at the entry point.

If instant upgrades are not feasible, teams should apply the code changes in the official patch commit 5192316f5bf0f033636f43561829d7fc13a4ab64. Administrators can also implement a Web Application Firewall (WAF) or local validation rules to strip malformed character byte strings (such as isolated non-ASCII characters) and restrict input sizes on page update endpoints.

To identify historical indicators of compromise, security teams should execute binary scans across the user/pages/ folder. Files failing UTF-8 compilation or containing excessively long HTML structures paired with Javascript event keywords should be flagged and manually validated.

Official Patches

getgravRemediation commit on GitHub

Fix Analysis (1)

Technical Appendix

CVSS Score
5.4/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
EPSS Probability
0.18%
Top 92% most exploited

Affected Systems

Grav CMS Core

Affected Versions Detail

Product
Affected Versions
Fixed Version
grav
getgrav
< 2.0.142.0.14
AttributeDetail
CWE IDCWE-79
Attack VectorNetwork (Authenticated Page-Edit Permissions Required)
CVSS v3.1 Score5.4 (Medium)
EPSS Score0.00182 (0.18% Probability)
ImpactStored Cross-Site Scripting (XSS) / Account Takeover
Exploit StatusProof of Concept (PoC) documented
CISA KEV StatusNot listed

MITRE ATT&CK Mapping

T1189Drive-by Compromise
Initial Access
T1185Browser Session Hijacking
Collection
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The software does not neutralize or incorrectly neutralizes user-controlled input before placing it in output that is served to other users, allowing malicious scripts to execute.

Vulnerability Timeline

Vulnerability reported to Grav maintainers
2026-07-25
Code patch drafted by core developers
2026-07-26
Unit tests verified, code modifications finalized, and version 2.0.14 tagged
2026-07-27
Advisory published under identifier GHSA-q2j8-x8hf-63ch and CVE assigned
2026-08-18

References & Sources

  • [1]GitHub Security Advisory GHSA-q2j8-x8hf-63ch
  • [2]VulnCheck Security Advisory
  • [3]Remediation Commit

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

•1 day ago•CVE-2026-118777
4.8

CVE-2026-118777: Prototype Pollution in Forge HTTP Client Cookie Management

CVE-2026-118777 is a prototype pollution vulnerability (CWE-1321) in the Forge JavaScript cryptography and networking library (distributed on npm as node-forge) prior to version 1.4.1. The flaw resides in the forge.http client subsystem, where incoming HTTP cookie names and paths parsed from Set-Cookie response headers are stored directly into standard JavaScript objects without key validation or property isolation. By returning crafted Set-Cookie headers containing keys such as __proto__ or constructor, a malicious HTTP server can inject arbitrary properties into Object.prototype, attach attributes to the global Object constructor, or delete built-in prototype methods to cause an application-wide denial of service.

Amit Schendel
Amit Schendel
7 views•10 min read
•1 day ago•CVE-2026-118775
3.7

CVE-2026-118775: ASN.1 OID First Arc Truncation and Ambiguity in node-forge

CVE-2026-118775 (GHSA-4642-5mcj-2rqw) is an integer overflow and validation flaw in the ASN.1 serialization module of Forge (node-forge) prior to version 1.4.1. The asn1.oidToDer() function fails to validate the range of the first two arcs of an Object Identifier (OID) and truncates the packed initial subidentifier to a single 8-bit integer. Applications that perform policy checks on untrusted OID strings before encoding them into Distinguished Encoding Rules (DER) format can be tricked into emitting DER bytes that correspond to a completely different, restricted OID.

Amit Schendel
Amit Schendel
8 views•10 min read
•1 day ago•CVE-2026-119194
7.5

CVE-2026-119194: Algorithmic Complexity Denial of Service in pyasn1 Schemaless ASN.1 Decoder

CVE-2026-119194 is an algorithmic complexity vulnerability (CWE-407) in the pyasn1 library for Python, affecting versions 0.3.3 through 0.6.4. The flaw resides in the schemaless decoding routine ConstructedPayloadDecoderBase._decodeComponentsSchemaless used across BER, CER, and DER codecs. By sending an ASN.1 container populated with child components whose tag identifiers are separated by multiples of CPython's integer hash modulus (sys.hash_info.modulus), an unauthenticated attacker can force worst-case hash collisions in an unbounded Python set, degrading decoding performance from O(N) to O(N^2) and causing a Denial of Service (DoS).

Alon Barad
Alon Barad
7 views•9 min read
•1 day ago•CVE-2026-119195
7.5

CVE-2026-119195: Quadratic-Time Denial of Service in pyasn1 BER/CER/DER Decoders

CVE-2026-119195 is an algorithmic complexity vulnerability (CWE-407) in the pyasn1 library for Python, affecting all versions prior to 0.6.5. When decoding constructed strings or indefinite-length ANY types across BER, CER, and certain DER code paths, the payload decoders repeatedly concatenate incoming fragments onto an immutable bytes object using the += operator. Because Python bytes objects cannot be resized in-place, each fragment iteration allocates a new buffer and copies all previously accumulated bytes, resulting in quadratic O(N^2) time and memory copy complexity. An unauthenticated remote attacker can supply a highly fragmented ASN.1 stream to exhaust CPU cycles and stall application worker threads.

Amit Schendel
Amit Schendel
8 views•10 min read
•1 day ago•CVE-2026-119197
7.5

CVE-2026-119197: Quadratic Algorithmic Complexity Denial of Service in pyasn1 REAL Mantissa Decoder

An algorithmic complexity vulnerability (CWE-407) in pyasn1 versions prior to 0.6.5 allows unauthenticated attackers to cause a Denial of Service (DoS) via crafted ASN.1 payloads. The flaw resides in the binary-encoded ASN.1 REAL mantissa deserialization routine within RealPayloadDecoder.valueDecoder. By performing iterative byte-string slicing and repeated bitwise shifts on a growing arbitrary-precision integer, the decoder exhibits quadratic time and memory allocation complexity relative to the mantissa length. Supplying a BER-, CER-, or DER-encoded payload with a large REAL mantissa causes excessive CPU consumption and blocks application worker processes.

Amit Schendel
Amit Schendel
7 views•10 min read
•1 day ago•CVE-2026-119196
7.5

CVE-2026-119196: Quadratic CPU Consumption in pyasn1 Constructed BIT STRING Decoding

A vulnerability classified under CWE-407 (Inefficient Algorithmic Complexity) exists in the pyasn1 library prior to version 0.6.5. When parsing constructed ASN.1 BIT STRING payloads under BER, CER, or schema-driven DER encoding rules, the BitStringPayloadDecoder repeatedly shifts and copies the entire accumulated bit value for each incoming fragment. Processing inputs with a large number of small constructed fragments induces quadratic CPU consumption, allowing unauthenticated remote attackers to cause a denial of service via resource exhaustion during the initial decoding phase.

Alon Barad
Alon Barad
8 views•10 min read