GHSA-gwfr-jfjf-92vv
High · 8.8Grav has Insecure Deserialization in File Cache
CVSS
8.8
EPSS
—
Published
May 5, 2026
CISA due date
—
The record
# Insecure Deserialization in File Cache - **Severity:** High - **CWE:** CWE-502 - **Location:** `system/src/Grav/Framework/Cache/Adapter/FileCache.php` - **Sink:** `unserialize($value, ['allowed_classes' => true])` ## Affected version(s) - **Affected:** `>= 1.7.44` and `<= 1.7.49.5` (verified in current codebase and changelog-covered releases). - **Fixed:** No upstream fix identified in the reviewed branch at the time of analysis. - **Notes:** Earlier `1.7.x` releases may also be affected, but were not fully back-traced in this review. ## Notes `allowed_classes => true` allows object instantiation and does not constrain classes. ## PoC (Primitive Demonstration) ### Preconditions - Local PHP runtime. - Goal is to validate the deserialization primitive used in cache retrieval. ### Steps ```bash php -r ' class CacheWakeup { public function __wakeup(){ file_put_contents("/tmp/grav_filecache_poc.txt", "wakeup"); } } $payload = serialize(new CacheWakeup()); unserialize($payload, ["allowed_classes" => true]); echo file_exists("/tmp/grav_filecache_poc.txt") ? "FILECACHE_UNSERIALIZE_TRIGGERED\n" : "FILECACHE_UNSERIALIZE_NOT_TRIGGERED\n"; ' ``` ### Expected Result - Output contains: `FILECACHE_UNSERIALIZE_TRIGGERED`. ### Interpretation This reproduces the same unsafe primitive used by `FileCache::doGet()`: `unserialize($value, ['allowed_classes' => true])`. If cache files are attacker-tampered, object magic methods may execute. ## Exploit Preconditions - Cache file poisoning/tampering capability. ## Recommendation - Avoid object deserialization in cache payloads. - Use non-object formats and integrity protection for cache files. --- ## Maintainer note — fix applied (2026-04-24) Fixed in Grav core on the `2.0` branch: commit [`c66dfeb5f`](https://github.com/getgrav/grav/commit/c66dfeb5f) — will ship in **2.0.0-beta.2**. **What changed:** `Framework\Cache\Adapter\FileCache` now HMAC-signs every cache payload with `Security::getNonceKey()` on write, and verifies the HMAC on read. Tampered, forged, or pre-upgrade files are treated as cache misses and unlinked instead of being unserialized. The on-disk format is now versioned: ``` v2 <expires> <key> <hmac-hex> <serialized> ``` Existing caches rebuild transparently on first read. Note that `Framework\Cache\Adapter\FileCache` isn't wired into Grav's main cache path — Symfony's `FilesystemAdapter` is — but the class is reachable by plugin and downstream consumers, so the hardening applies defensively.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|
Related vulnerabilities
- CVE-2026-7317 A vulnerability was found in Grav CMS up to 1.7.49.5/2.0.0-beta.1. Same vulnerability
- CVE-2026-114724 Roundcube Webmail before 1.6.20 and 1.7.x before 1.7.5 contains an object injection… CWE-502
- CVE-2026-112081 A vulnerability was determined in hankcs HanLP up to 2.1.0-beta.64. CWE-502
- CVE-2026-96745 Deserialization of untrusted data in the command monitoring support of the MongoDB PHP… CWE-502
- CVE-2026-62107 Unauthenticated PHP Object Injection in Masteriyo - LMS <= 3.4.0 versions. CWE-502
- CVE-2026-62103 Unauthenticated PHP Object Injection in Everest Forms <= 3.6.0 versions. CWE-502
- CVE-2026-62105 Unauthenticated PHP Object Injection in ThemeREX Addons < 2.45.0 versions. CWE-502
- CVE-2026-73699 FileRun before 2026.3.0 contains a PHP object injection vulnerability that allows… CWE-502