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

CVE-2026-75828: Stored Cross-Site Scripting (XSS) via Security Filter Bypass in Grav CMS

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 18, 2026·4 min read·26 visits

Executive Summary (TL;DR)

A parser-differential flaw in Grav CMS's detectXss() filter allows authenticated editors to bypass event-handler detection using unpaired quotes in unquoted attribute values, resulting in stored cross-site scripting.

CVE-2026-75828 is a critical stored cross-site scripting (XSS) vulnerability in the getgrav Grav CMS before version 2.0.15. The vulnerability resides in the detectXss() security filter mechanism, where parser-differential mismatches between the regular-expression-based server-side validation and browser HTML5 tokenization allow authenticated editors to bypass event-handler detection and inject arbitrary JavaScript execution vectors.

Vulnerability Overview

Grav CMS is a flat-file content management system that processes content via Markdown and HTML rendering. To ensure safety, Grav employs a centralized security class containing a detectXss() method designed to intercept malicious scripts, event handlers, and unauthorized XML namespaces.

The attack surface of Grav CMS includes markdown-enabled input fields, pages, and metadata accessible to authenticated administrative users and editors. In certain configurations, plugins may expose this filter to unauthenticated inputs, widening the risk vector.

The core of the vulnerability is a parser-differential bug classified under CWE-79. The input validation filter relies on regular expressions that fail to accurately predict the state-machine logic used by modern web browsers when encountering malformed HTML.

Root Cause Analysis

The root cause lies in how Security::detectXss() tracks quote pairs. The filter uses regex patterns to identify inline event handlers (such as onerror=) while attempting to ignore harmless occurrences of these sequences within valid quoted attribute strings.

In HTML5, a quote character only starts a quoted attribute state if it immediately follows an equals sign (e.g., attr="value"). An unanchored quote inside an unquoted attribute string (such as the double quote in src=x") is parsed by browsers as a literal character rather than a string delimiter. The browser remains in the unquoted attribute state, and subsequent characters like space and onerror= are parsed as new, independent attributes.

In contrast, the PHP regex parser used in detectXss() treats any quote character as the start of an enclosed string literal. Upon encountering the unpaired quote inside src=x", the engine searches for a matching closing quote, consuming the rest of the element, including the real malicious event-handler attribute. Because the handler is matched inside what the regex assumes is a benign string, validation succeeds.

Code Analysis

The vulnerable regular expression configuration in system/src/Grav/Common/Security.php used a generic matching sequence for quotes: (?:"[^"]"|'[^']'). This pattern matched quotes globally without checking if they were actually part of an attribute assignment.

Below is the code snippet comparing the vulnerable and patched regex patterns:

// Vulnerable configuration
'on_events' => '#<(?:"[^"]*"|\'[^']*\'|[^>"\'])*?(?:[\s\x00-\x20\"\u0027\/]|"[^"]*"|\'[^']*\')on\s*[a-z]+\s*=#iu',
 
// Patched configuration in 2.0.15
'on_events' => '#<(?:=\s*"[^"]*"|=\s*\'[^']*\'|[^>])*?(?:[\s\x00-\x20\"\u0027\/]|=\s*"[^"]*"|=\s*\'[^']*\')on\s*[a-z]+\s*=#iu',

The updated regex binds the quote character to an assignment pattern (=\s*) before allowing the parser to consume the content as a string literal. If the quote is not preceded by an equals sign, the parser falls back to matching it as an ordinary tag-body character, forcing the scanner to process the subsequent onerror event handler correctly.

Exploitation Methodology

An authenticated editor with permissions to modify site markdown files can insert the malformed payload through the administration panel. Once saved, the raw string is written directly to the flat-file database.

The parser divergence can be visualized in the following diagram:

The payload <img src=x" onerror="alert(document.domain)"> cleanly bypasses the regular expression filter while remaining completely syntactically functional in Chromium-based and Firefox browsers, resulting in arbitrary JavaScript execution when the page is viewed.

Impact Assessment

The impact of stored cross-site scripting in a CMS environment like Grav is significant. An attacker can hijack the sessions of administrative users who visit the compromised pages, leading to complete control over the application.

Session hijacking allows attackers to execute administrative actions, such as adding backdoor accounts, installing malicious plugins, or reading confidential environment configurations.

Given the flat-file nature of Grav, access to the administration panel translates directly to remote code execution (RCE) on the underlying server. Since administrators can write templates or execute PHP files through standard features, XSS represents a gateway to complete host compromise.

Remediation & Detection

Security administrators must update Grav installations to version 2.0.15 immediately. If an automatic update via the administration console is not possible, the command-line package manager can be used.

For legacy installations where upgrading the entire CMS is infeasible, the patches to system/src/Grav/Common/Security.php should be applied manually to anchor all quote validation steps to the = operator.

Temporary protections can be configured on web application firewalls (WAF) to intercept requests containing unquoted attributes containing internal quotes followed by script handles. An example detection signature has been verified for application-level proxies.

Fix Analysis (1)

Technical Appendix

CVSS Score
9.3/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N
EPSS Probability
0.34%
Top 72% most exploited

Affected Systems

Grav CMS

Affected Versions Detail

Product
Affected Versions
Fixed Version
grav
getgrav
< 2.0.152.0.15
AttributeDetail
CWE IDCWE-79
Attack VectorNetwork
CVSS Score9.3 (Critical)
EPSS Score0.00343
ImpactStored Cross-Site Scripting (XSS) leading to Session Hijacking / RCE
Exploit StatusProof of Concept
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 application does not neutralize or incorrectly neutralizes user-controlled input before it is placed in output that is used as a web page.

Known Exploits & Detection

GitHub Security AdvisoryOfficial advisory with details of the quote bypass vulnerability.

Vulnerability Timeline

Code patch committed to Grav repository
2026-07-30
Grav Core version 2.0.15 officially released containing the patch
2026-08-03
GitHub Security Advisory GHSA-vfmf-q6x9-cw96 published
2026-08-18
CVE-2026-75828 registered in the NVD
2026-08-18

References & Sources

  • [1]Grav GitHub Security Advisory
  • [2]VulnCheck Third-Party Advisory
  • [3]Grav Core Security Fix Commit
  • [4]Raw Git Patch Reference
  • [5]Official CVE Entry

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