Skip to main content
EPSS 0.4%top 65%

CVE-2026-74907: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') in getgrav grav

0
High
Published: 09/17/2026 (09/17/2026, 20:43:16 UTC)
Source: CVE Database V5
Vendor/Project: getgrav
Product: grav

Description

**Verified against:** `getgrav/grav` devel branch, `GRAV_VERSION = "2.0.15"`, file `index.php ## Title Unauthenticated Path Traversal via Missing Directory-Boundary Check in `plugin-asset-map.php` Static Asset Server (`index.php`) ## Product / Affected Versions - Product: `getgrav/grav` - File: `index.php` (top-level front controller, runs before Grav itself boots) - Confirmed present in: devel branch, 2.0.15 - **Precondition:** requires `user/config/plugin-asset-map.php` to exist and contain at least one route-prefix mapping ,this is an opt-in mechanism (per the code comment: "Fast static asset serving for plugins that bundle SPA apps"). No core mechanism generates this file automatically; it's created by a plugin that opts into this fast-path. **Not reachable on a stock Grav install with no such plugin.** Where reachable, it requires zero authentication. ## CWE CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') , specific mechanism: a path-prefix containment check performed with plain string comparison (`str_starts_with`) instead of a directory-boundary-aware comparison, allowing escape into any sibling path whose name happens to extend the base directory's name as a string. ## Description `index.php` implements a fast-path static file server that runs *before* Grav's own routing/security stack, gated on the presence of an asset-map file: ```php $assetMapFile = __DIR__ . '/user/config/plugin-asset-map.php'; if (is_file($assetMapFile)) { $assetMap = require $assetMapFile; foreach ($assetMap as $routePrefix => $diskPath) { if (str_starts_with($path, $routePrefix)) { $relPath = substr($path, strlen($routePrefix)); $filePath = __DIR__ . '/' . ltrim($diskPath, '/') . $relPath; $realFile = realpath($filePath); $realBase = realpath(__DIR__ . '/' . ltrim($diskPath, '/')); if ($realFile && $realBase && str_starts_with($realFile, $realBase) && is_file($realFile)) { // ... serves $realFile directly, with Content-Type inferred from extension readfile($realFile); exit; } } } } ``` `realpath()` correctly resolves `..` sequences, so a naive `../../etc/passwd`-style traversal that leaves the filesystem entirely is blocked (it wouldn't share the `$realBase` string prefix). **But the containment check itself, `str_starts_with($realFile, $realBase)`, has no directory-boundary awareness** it's a plain string-prefix test, not "is `$realFile` inside the `$realBase` directory." Any resolved path whose string representation merely *begins with* the same characters as `$realBase` passes, including sibling directories that extend the base directory's name (`assets` → `assets-secret`, `assets.bak`, `assets_old`, `assets2`, etc.) a very common real-world directory-naming pattern (backup dirs, versioned dirs, disabled/legacy dirs sitting alongside the active one). ## Live Proof of Concept **Setup:** the exact code block above, extracted verbatim from `index.php`, executed with PHP 8.3.6 against a realistic directory layout (a plugin's active `assets/` dir sitting next to an unrelated `assets-secret/` dir containing a fake secret): ``` user/plugins/myplugin/assets/app.js <- intended, public user/plugins/myplugin/assets-secret/config.php <- NOT intended to be served user/config/plugin-asset-map.php: return ['/myplugin-assets' => 'user/plugins/myplugin/assets']; ``` **Legitimate request** (`/myplugin-assets/app.js`): ``` realFile: '/home/claude/grav-poc/user/plugins/myplugin/assets/app.js' realBase: '/home/claude/grav-poc/user/plugins/myplugin/assets' >>> WOULD SERVE FILE <<< >>> Content: public asset content ``` **Traversal request** (`/myplugin-assets/../assets-secret/config.php`): ``` realFile: '/home/claude/grav-poc/user/plugins/myplugin/assets-secret/config.php' realBase: '/home/claude/grav-poc/user/plugins/myplugin/assets' >>> WOULD SERVE FILE <<< >>> Content: SECRET_API_KEY=sk_live_totally_secret_12345 ``` `str_starts_with('.../assets-secret/config.php', '.../assets')` evaluates `true` because `assets-secret` literally begins with the characters `assets` there is no separator-boundary check (e.g. requiring `$realBase . '/'` as the actual prefix) to prevent this. ## Trust-boundary framing (per Grav's own SECURITY.md) This code path requires **no Grav account** , it runs before Grav even initializes, directly off the raw request path. Per Grav's own stated criteria: *"An unauthenticated attacker can achieve RCE, exfiltrate site data, or gain admin-equivalent control. No Grav account required"* → this matches the **CRITICAL** bar exactly, for any deployment where the `plugin-asset-map.php` mechanism is in active use. ## Suggested Fix Append a trailing directory separator before the prefix comparison, or use a proper containment check: ```php if ($realFile && $realBase && ( $realFile === $realBase || str_starts_with

CVSS v4.0

Score 8.2high

Attack Vector
Network
Attack Complexity
High
Attack Requirements
Present
Privileges Required
None
User Interaction
None
Vuln. Confidentiality
High
Vuln. Integrity
None
Vuln. Availability
None
Subsq. Confidentiality
None
Subsq. Integrity
None
Subsq. Availability
None
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N

Affected software

getgrav

grav

Affected versions
>=0 <2.0.15
GitHub Actionsmore threats →ai
getgrav/grav
pkg:github/getgrav/grav
Affected versions
<2.0.15

Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.

AI-Powered Analysis

Machine-generated threat intelligence

AILast updated: 09/11/2026, 23:18:22 UTC

Technical Analysis

CVE-2026-74907 describes a path traversal vulnerability in Grav CMS prior to version 2.0.15. The vulnerability exists in the static asset server code within index.php, which uses string prefix matching to validate requested paths instead of enforcing directory boundaries. This improper validation enables attackers without authentication to access files outside the intended asset directory by exploiting directory names that extend the base path string, such as requesting 'assets-secret' when 'assets' is the configured base directory.

Potential Impact

An unauthenticated attacker can exploit this vulnerability to read files located in sibling directories outside the intended restricted directory. This could lead to unauthorized disclosure of sensitive files on the server.

Mitigation Recommendations

Upgrade Grav to version 2.0.15 or later, where this path traversal vulnerability has been fixed. No other mitigation guidance is provided; applying the official patch is the recommended remediation.

Pro Console: star threats, build custom feeds, automate alerts via Slack, email & webhooks.Upgrade to Pro

Technical Details

Data Version
5.2
Assigner Short Name
VulnCheck
Date Reserved
2026-08-17T10:48:45.738Z
Cvss Version
4.0
State
PUBLISHED

Threat ID: 6a844364c6e8be03322294a8

Added to database: 08/18/2026, 11:35:00 UTC

Last enriched: 09/11/2026, 23:18:22 UTC

Last updated: 10/02/2026, 07:10:08 UTC

Views: 62

Community Reviews

0 reviews

Crowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.

Sort by
Loading community insights…

Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.

Actions

PRO

Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.

Please log in to the Console to use AI analysis features.

Need more coverage?

Upgrade to Pro Console for AI refresh and higher limits.

For incident response and remediation, OffSeq services can help resolve threats faster.

Latest Threats

Breach by OffSeqOFFSEQFRIENDS — 25% OFF

Check if your credentials are on the dark web

Instant breach scanning across billions of leaked records. Free tier available.

Scan now
OffSeq TrainingCredly Certified

Lead Pen Test Professional

Technical5-day eLearningPECB Accredited
View courses