GHSA-VWG3-W8W3-PC79

Vulnerability from github – Published: 2026-08-19 19:32 – Updated: 2026-08-19 19:32
VLAI
Summary
Grav: .htaccess file extension rules bypass via case variation on case-insensitive filesystems
Details

Summary

The default .htaccess shipped with Grav (and the reference webserver-configs/htaccess.txt) contains security rules that block direct HTTP access to sensitive file types (.yaml, .yml, .php, .json, .twig, etc.) under user/ and system/vendor/ directories. However, these rules lack the [NC] (No Case) flag, making them case-sensitive. On case-insensitive filesystems (Windows/NTFS, macOS/HFS+, or Linux with Docker volumes mounted from Windows/macOS), an attacker can bypass these rules by requesting files with uppercase extensions (e.g., .YAML, .PHP, .JSON).

Affected Versions

  • Grav 2.0.1 (latest stable as of June 2026) — confirmed
  • Grav 1.7.x — likely affected (same .htaccess rules)
  • All versions shipping the current webserver-configs/htaccess.txt

Affected Component

File: .htaccess (root of Grav installation) Reference: webserver-configs/htaccess.txt

Affected Rules (lines 68, 70, 72)

# Line 68 — system/vendor file types
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|htm|shtml|shtm|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F]

# Line 70 — user file types
RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F]

# Line 72 — .md files globally
RewriteRule \.md$ error [F]

All three rules use [F] without [NC], making the extension match case-sensitive.

Steps to Reproduce

  1. Install Grav on a system with a case-insensitive filesystem:
  2. Windows (native WAMP/XAMPP)
  3. macOS (default HFS+)
  4. Docker on Windows/macOS with volume mounts (e.g., ./data:/var/www/html)

  5. Create or use any plugin that stores sensitive data in its YAML config (e.g., API keys): user/plugins/my-plugin/my-plugin.yaml

  6. Request the file with a case-varied extension: GET /user/plugins/my-plugin/my-plugin.YAML HTTP/1.1

  7. Expected: HTTP 403 Forbidden

  8. Actual: HTTP 200 OK — full file contents returned, including any API keys or sensitive configuration

Impact

  • Information disclosure: Plugin configuration files (.yaml) containing API keys, credentials, or sensitive settings can be read by unauthenticated users
  • Source code exposure: PHP source files can be downloaded (instead of executed) when requested with .PHP extension on some configurations
  • Configuration exposure: user/config/system.yaml, user/config/site.yaml, and other system configuration files are accessible

Fix

Add the [NC] flag to the three affected rules:

RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|htm|shtml|shtm|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F,NC]
RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F,NC]
RewriteRule \.md$ error [F,NC]

The [NC] flag makes the extension matching case-insensitive, covering .YAML, .Yaml, .PHP, .Json, etc.

Mitigating Factors

  • On native Linux with ext4 filesystem (case-sensitive), the attack does not work because Apache cannot resolve the uppercase filename to the actual file
  • Grav 2.0's Twig sandbox blocks access to plugins config subtree from page content, preventing SSTI-based config exfiltration
  • The user/accounts/, user/config/, and user/data/ folders have separate rules (line 62, 66) that block ALL file types regardless of extension — these are not affected

Environment

  • Grav: 2.0.1
  • PHP: 8.3
  • Apache: 2.4 with mod_rewrite
  • OS: Docker (php:8.3-apache) with volume mounted from Windows 10 (NTFS)
  • Tested: June 2026

Reporter

Sisnetic

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "getgrav/grav"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.0.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-62673"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-178"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-19T19:32:38Z",
    "nvd_published_at": "2026-08-19T16:18:20Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\nThe default `.htaccess` shipped with Grav (and the reference `webserver-configs/htaccess.txt`) contains security rules that block direct HTTP access to sensitive file types (`.yaml`, `.yml`, `.php`, `.json`, `.twig`, etc.) under `user/` and `system/vendor/` directories. However, these rules lack the `[NC]` (No Case) flag, making them case-sensitive. On case-insensitive filesystems (Windows/NTFS, macOS/HFS+, or Linux with Docker volumes mounted from Windows/macOS), an attacker can bypass these rules by requesting files with uppercase extensions (e.g., `.YAML`, `.PHP`, `.JSON`).\n\n## Affected Versions\n\n- Grav 2.0.1 (latest stable as of June 2026) \u2014 confirmed\n- Grav 1.7.x \u2014 likely affected (same `.htaccess` rules)\n- All versions shipping the current `webserver-configs/htaccess.txt`\n\n## Affected Component\n\nFile: `.htaccess` (root of Grav installation)\nReference: `webserver-configs/htaccess.txt`\n\n## Affected Rules (lines 68, 70, 72)\n\n```apache\n# Line 68 \u2014 system/vendor file types\nRewriteRule ^(system|vendor)/(.*)\\.(txt|xml|md|html|htm|shtml|shtm|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F]\n\n# Line 70 \u2014 user file types\nRewriteRule ^(user)/(.*)\\.(txt|md|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F]\n\n# Line 72 \u2014 .md files globally\nRewriteRule \\.md$ error [F]\n```\n\nAll three rules use `[F]` without `[NC]`, making the extension match case-sensitive.\n\n## Steps to Reproduce\n\n1. Install Grav on a system with a case-insensitive filesystem:\n   - Windows (native WAMP/XAMPP)\n   - macOS (default HFS+)\n   - Docker on Windows/macOS with volume mounts (e.g., `./data:/var/www/html`)\n\n2. Create or use any plugin that stores sensitive data in its YAML config (e.g., API keys):\n   ```\n   user/plugins/my-plugin/my-plugin.yaml\n   ```\n\n3. Request the file with a case-varied extension:\n   ```\n   GET /user/plugins/my-plugin/my-plugin.YAML HTTP/1.1\n   ```\n\n4. **Expected**: HTTP 403 Forbidden\n5. **Actual**: HTTP 200 OK \u2014 full file contents returned, including any API keys or sensitive configuration\n\n## Impact\n\n- **Information disclosure**: Plugin configuration files (`.yaml`) containing API keys, credentials, or sensitive settings can be read by unauthenticated users\n- **Source code exposure**: PHP source files can be downloaded (instead of executed) when requested with `.PHP` extension on some configurations\n- **Configuration exposure**: `user/config/system.yaml`, `user/config/site.yaml`, and other system configuration files are accessible\n\n## Fix\n\nAdd the `[NC]` flag to the three affected rules:\n\n```apache\nRewriteRule ^(system|vendor)/(.*)\\.(txt|xml|md|html|htm|shtml|shtm|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F,NC]\nRewriteRule ^(user)/(.*)\\.(txt|md|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F,NC]\nRewriteRule \\.md$ error [F,NC]\n```\n\nThe `[NC]` flag makes the extension matching case-insensitive, covering `.YAML`, `.Yaml`, `.PHP`, `.Json`, etc.\n\n## Mitigating Factors\n\n- On native Linux with ext4 filesystem (case-sensitive), the attack does not work because Apache cannot resolve the uppercase filename to the actual file\n- Grav 2.0\u0027s Twig sandbox blocks access to `plugins` config subtree from page content, preventing SSTI-based config exfiltration\n- The `user/accounts/`, `user/config/`, and `user/data/` folders have separate rules (line 62, 66) that block ALL file types regardless of extension \u2014 these are not affected\n\n## Environment\n\n- Grav: 2.0.1\n- PHP: 8.3\n- Apache: 2.4 with mod_rewrite\n- OS: Docker (php:8.3-apache) with volume mounted from Windows 10 (NTFS)\n- Tested: June 2026\n\n## Reporter\n\nSisnetic",
  "id": "GHSA-vwg3-w8w3-pc79",
  "modified": "2026-08-19T19:32:38Z",
  "published": "2026-08-19T19:32:38Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/getgrav/grav/security/advisories/GHSA-vwg3-w8w3-pc79"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-62673"
    },
    {
      "type": "WEB",
      "url": "https://github.com/getgrav/grav/commit/8c9d1e7b6fd66ecea80a4bc3783fd41d36e22fb1"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/getgrav/grav"
    },
    {
      "type": "WEB",
      "url": "https://github.com/getgrav/grav/releases/tag/2.0.4"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Grav: .htaccess file extension rules bypass via case variation on case-insensitive filesystems"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…