Skip to main content
Vulnerability Database/CVE-2026-100669

CVE-2026-100669: Grav CMS Information Disclosure Vulnerability

CVE-2026-100669 is an information disclosure flaw in Grav CMS that allows attackers to bypass access controls through case manipulation on IIS servers. This post explains its technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-100669 Overview

CVE-2026-100669 is a sensitive file disclosure vulnerability in the Grav flat-file content management system (CMS) prior to version 2.0.25. The shipped webserver-configs/web.config sample for Internet Information Services (IIS) sets ignoreCase="false" on every URL Rewrite deny rule. On case-insensitive NTFS volumes, an unauthenticated remote attacker can alter the case of a path segment or file extension to bypass access-control rules. The IIS static file handler then resolves and returns the underlying file, exposing configuration secrets or account password hashes.

Critical Impact

Unauthenticated remote attackers can retrieve sensitive Grav configuration files and credential stores from IIS-hosted deployments by varying path case (for example, GET /user/CONFIG/system.YAML).

Affected Products

  • Grav CMS versions prior to 2.0.25 when served by IIS using the bundled webserver-configs/web.config
  • Grav CMS versions prior to 2.0.25 when served by lighttpd using the bundled webserver-configs/lighttpd.conf (lower risk on case-sensitive filesystems)
  • Deployments on Apache (.htaccess), nginx, Caddy, and the PHP built-in server are not affected

Discovery Timeline

  • 2026-09-26 - CVE-2026-100669 published to the National Vulnerability Database (NVD)
  • 2026-09-30 - Last updated in NVD database

Technical Details for CVE-2026-100669

Vulnerability Analysis

The weakness is tracked as CWE-178: Improper Handling of Case Sensitivity. Grav ships IIS configuration samples whose URL Rewrite deny rules match request paths case-sensitively. These rules protect sensitive directories such as user/config, user/accounts, user/data, user/pages, system, and vendor. Because IIS runs on NTFS, which is case-insensitive by default, the file system resolves /user/CONFIG/system.YAML to the same file as /user/config/system.yaml. The rewrite deny filter, however, treats the two paths as distinct and permits the altered request.

Successful exploitation can disclose Grav site configuration, account password hashes stored under user/accounts, and other secrets written to protected directories. Whether a bypassed file is actually returned depends on IIS MIME registration. .json files are served by default, while .yaml and .yml return HTTP 404.3 on a stock IIS unless a YAML MIME mapping has been added by the operator.

Root Cause

Each <match> element in webserver-configs/web.config (user_sensitive_folders, user_accounts, user_data, user_error_redirect, user_pages, system, vendor, ignore_folders) explicitly sets ignoreCase="false", overriding the IIS default of ignoreCase="true". The rules are implemented as URL Rewrite matches rather than <requestFiltering> entries, so there is no case-insensitive fallback. The same class of gap exists in webserver-configs/lighttpd.conf, whose user/(config|env), directory, script-extension, root-file, and dotfile rules lack the (?i) regex modifier.

Attack Vector

The attack vector is unauthenticated, remote, and requires no user interaction. An attacker issues an HTTP GET request for a protected resource with one or more characters in the path or extension changed to an uppercase variant. The rewrite deny rule fails to match, control falls through to the IIS static file handler, and the handler resolves the actual file on NTFS. The attacker can enumerate variants programmatically against known Grav paths such as /user/accounts/, /user/config/, and /user/data/.

See the GitHub Security Advisory GHSA-pg8v-xw58-frq8 and the VulnCheck Advisory for Grav Vulnerability for complete technical details.

Detection Methods for CVE-2026-100669

Indicators of Compromise

  • IIS access log entries requesting Grav-protected paths with mixed or uppercase segments, for example GET /user/CONFIG/system.YAML or GET /User/Accounts/admin.YAML.
  • Successful HTTP 200 responses for requests targeting /user/accounts/, /user/config/, /user/data/, /system/, or /vendor/ on IIS-hosted Grav sites.
  • Repeated path-casing permutations against the same resource from a single source address, consistent with automated bypass enumeration.

Detection Strategies

  • Parse IIS W3C logs for request URIs that match Grav sensitive directory names case-insensitively but do not match them case-sensitively, and alert when the response code is 200.
  • Baseline legitimate Grav traffic and flag requests whose path case differs from canonical lowercase routes used by the application.
  • Hash and monitor the deployed web.config and lighttpd.conf for drift against the Grav 2.0.25 reference files.

Monitoring Recommendations

  • Forward IIS and lighttpd access logs to a central analytics platform and retain them long enough to support retroactive hunting after disclosure.
  • Monitor outbound reads of files under user/accounts/, user/config/, and user/data/ on the Grav host for anomalous access patterns.
  • Track administrator logins to Grav after this CVE is remediated, in case account password hashes were previously disclosed and cracked offline.

How to Mitigate CVE-2026-100669

Immediate Actions Required

  • Upgrade Grav to version 2.0.25 or later on all affected deployments.
  • After upgrade on IIS or lighttpd hosts, re-copy the corrected web.config or lighttpd.conf sample from the 2.0.25 release; the .htaccess installer heal does not touch these files.
  • Rotate all Grav administrator passwords and any secrets stored under user/config or user/data, assuming prior disclosure.
  • Review historical IIS access logs for case-varied requests against Grav sensitive directories.

Patch Information

The issue is fixed in Grav 2.0.25. The corrected webserver-configs/web.config sets ignoreCase="true" on the affected URL Rewrite <match> elements, and webserver-configs/lighttpd.conf applies the (?i) modifier to the equivalent regex rules. Because the upgrade routine does not overwrite existing web.config or lighttpd.conf files, operators must manually replace them with the 2.0.25 sample versions. Refer to the GitHub Security Advisory GHSA-pg8v-xw58-frq8 for the authoritative fix commit.

Workarounds

  • Edit the deployed web.config and set ignoreCase="true" on every URL Rewrite <match> element in each deny rule.
  • Add the (?i) case-insensitive modifier to the equivalent regex rules in lighttpd.conf.
  • Remove any YAML MIME mapping from IIS so that .yaml and .yml requests return 404.3 rather than file contents, reducing exposure of the most sensitive files.
  • Where feasible, migrate the Grav deployment to Apache, nginx, Caddy, or the PHP built-in server, none of which are affected by this bypass.
bash
# Example: enforce case-insensitive match on an IIS URL Rewrite deny rule
# in webserver-configs/web.config (fixed form shipped in Grav 2.0.25)
<rule name="user_sensitive_folders" stopProcessing="true">
  <match url="^user/(config|accounts|data)/" ignoreCase="true" />
  <action type="CustomResponse" statusCode="403" statusReason="Forbidden" />
</rule>

# Example: case-insensitive regex in webserver-configs/lighttpd.conf
url.access-deny = ( "(?i)/user/(config|env)", "(?i)/user/accounts", "(?i)/vendor" )

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.