You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Closes the rest of the Tier-1 unauth/authz advisories from the 2026-04
batch:
- GHSA-gwfr-jfjf-92vv: Framework\Cache\Adapter\FileCache now HMAC-signs
every payload (sha256, key from Security::getNonceKey()) and verifies
on read. Tampered, forged, or pre-upgrade files are treated as cache
misses and unlinked instead of being unserialized. New on-disk format
v2\n<expires>\n<key>\n<hmac>\n<serialized>; existing caches rebuild
transparently. (Adapter isn't currently in Grav's main cache path —
Symfony's FilesystemAdapter is — but the class is reachable to plugin
authors so the hardening is defensive.)
- GHSA-vj3m-2g9h-vm4p (5-part advisory):
* #1 Scheduler\JobQueue: serialized_job blob now carries a sibling
serialized_job_hmac field; reconstructJob refuses to unserialize an
item whose HMAC missing/mismatches and falls through to the safe
structured-fields rebuild. Closes the Job::exec → call_user_func_array
direct RCE gadget chain.
* #2 FileCache: same fix as GHSA-gwfr above.
* #3 Session::getFlashObject: payload is now wrapped in
"v2|<hmac>|<serialized>"; legacy/forged envelopes return null instead
of triggering unserialize.
* #4 InstallCommand git clone: branch/url/path coming from
user/.dependencies are now escapeshellarg'd, with a "--" separator
before url/path to block option-injection (e.g. --upload-pack=evil
in path).
* #5 cleanDangerousTwig: twig_array_reduce (advisory call-out) plus
twig_array_some/twig_array_every added to CALLABLE_DANGEROUS_NAMES.
Two new test files (FileCacheSecurityTest, UnserializeIntegritySecurityTest)
covering 13 cases between them; CleanDangerousTwigTest extended with the
new twig_array_* entries. Full unit suite: 645 tests, 2447 assertions.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,6 +13,8 @@
13
13
*[security] Fixed unauthenticated path traversal in `FormFlash` (GHSA-hmcx-ch82-3fv2): `session_id` and `unique_id` now pass through a strict allowlist before being used to build on-disk paths, preventing arbitrary directory creation via the `__form-flash-id` parameter.
14
14
*[security] Fixed salt disclosure via sandboxed Twig (GHSA-3f29-pqwf-v4j4): the HMAC key used for CSRF nonces and admin rate-limit hashing has moved out of Config into `user/config/security-private.php` (blocked from web access by the default `user/*.php` htaccess rule), so `{{ grav.config.get('security.salt') }}` no longer leaks it. Existing sites are migrated automatically on first request — existing nonces and sessions survive the upgrade.
15
15
*[security] Hardened the new-user uniqueness guard in `UserObject::save` (GHSA-rr73-568v-28f8): `strpos(..., '@@')` replaced with `str_contains` (the old form was falsy when the transient-key marker was at position 0, silently bypassing the check) and the check now runs for every `FlexStorageInterface` backend rather than only `FileStorage`. A low-privileged user with `admin.users.create` can no longer disrupt a super-admin account by submitting the admin's username through the "add user" form.
16
+
*[security] Added HMAC integrity to `Framework\Cache\Adapter\FileCache` (GHSA-gwfr-jfjf-92vv): every cache payload is signed with `Security::getNonceKey()` on write and verified on read; tampered, attacker-planted, or pre-upgrade files are treated as cache misses and removed instead of being unserialized. The on-disk format is now versioned (`v2\n<expires>\n<key>\n<hmac>\n<serialized>`); existing caches rebuild transparently on first read.
17
+
*[security] Closed GHSA-vj3m-2g9h-vm4p (5-part advisory): (#1) `JobQueue` now HMAC-signs the `serialized_job` blob — a tampered queue file can no longer smuggle a forged `Job` for direct RCE via `Job::exec → call_user_func_array`; legitimate items still execute via the structured-fields fallback. (#3) `Session::getFlashObject` now wraps its payload in a versioned HMAC envelope, refusing to unserialize legacy/forged values. (#4) `InstallCommand` git-clone arguments (`branch`, `url`, `path` from `user/.dependencies`) now go through `escapeshellarg`, with a `--` separator before url/path to block option-injection. (#5) `twig_array_reduce` (plus `twig_array_some`/`twig_array_every`) added to `cleanDangerousTwig`'s callable blocklist alongside the existing `twig_array_map`/`filter`. (#2) was the same FileCache issue addressed by GHSA-gwfr above.
0 commit comments