NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐘 Packagist
Not in CISA KEV

Grav has multiple RCE vectors: unsafe unserialize (x3), command injection in git clone, SSTI blocklist bypassGHSA-vj3m-2g9h-vm4p

Fix: getgrav/grav@5a12f9b

GHSA-vj3m-2g9h-vm4p is a OS Command Injection vulnerability in getgrav/grav. A fix is available for getgrav/grav — see the affected versions and patch details below.

Also known asCVE-2026-56700
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Nov 7, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • A successful exploit gives an attacker total control of the affected component, not partial access.
  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for GHSA-vj3m-2g9h-vm4p.

EPSS Exploitation Probability

via FIRST.org ↗
2.5%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs85th percentile — riskier than 85% of all scored CVEsHighest risk
1.18%1.80%2.41%3.03%1.7%2.5%Jul 26Oct 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected
🐘getgrav/grav

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

Description

Multiple RCE vectors were found in Grav CMS. Three are critical, two are high.

1. Unsafe unserialize() in JobQueue — direct RCE gadget (Critical)

system/src/Grav/Common/Scheduler/JobQueue.php:465 calls unserialize(base64_decode(...)) without restricting allowed_classes. The Job class has call_user_func_array($this->command, $this->args) in its execution path, which is a direct gadget chain — inject a serialized Job with command = 'system' and args = ['whoami'].

The same codebase actually has a Serializable trait that correctly restricts classes, so this inconsistency stands out.

2. Unsafe unserialize() in FileCache — arbitrary class instantiation (Critical)

system/src/Grav/Framework/Cache/Adapter/FileCache.php:75 does unserialize($value, ['allowed_classes' => true]). That true allows instantiation of any class. If an attacker can write to the cache directory (via any file write primitive), they get object injection → RCE.

3. Unsafe unserialize() in Session (High)

system/src/Grav/Common/Session.php:116 — same allowed_classes => true pattern on session data. Lower severity since session storage is typically more restricted.

4. Command injection in git clone (Critical)

system/src/Grav/Console/Cli/InstallCommand.php:150 — only $this->destination uses escapeshellarg(). The $data['branch'], $data['url'], and $data['path'] variables go directly into the shell command without escaping. Admin-accessible via plugin/theme installation.

5. SSTI blocklist bypass (High)

system/src/Grav/Common/Security.php:267-286 — cleanDangerousTwig() blocks twig_array_map and twig_array_filter but not twig_array_reduce. Also missing file_get_contents and fwrite from the dangerous function blocklist. An attacker who can inject Twig templates can bypass the security filter.

All five are independently exploitable. The unserialize issues are the most concerning since they don't require admin access if there's any file write primitive.

— ProScan AppSec | proscan.one


Maintainer note — fix applied (2026-04-24)

Fixed in Grav core on the 2.0 branch: commit c66dfeb5f (items #1, #2, #3, #4) and commit 38685ac25 + c66dfeb5f (item #5) — ships in 2.0.0-beta.2.

All five vectors addressed:

  1. Scheduler\JobQueue unsafe unserialize — serialized_job now carries a sibling serialized_job_hmac signed with Security::getNonceKey(). reconstructJob refuses to unserialize an item whose HMAC is missing/mismatched and falls through to the safe structured-fields rebuild. A tampered queue file can no longer smuggle a forged Job for direct RCE via Job::exec → call_user_func_array.
    → system/src/Grav/Common/Scheduler/JobQueue.php

  2. FileCache unsafe unserialize — same HMAC-integrity approach; see separate GHSA-gwfr-jfjf-92vv.
    → system/src/Grav/Framework/Cache/Adapter/FileCache.php

  3. Session::getFlashObject unsafe unserialize — payload now wrapped in a v2|<hmac>|<serialized> envelope; legacy/forged envelopes return null instead of triggering unserialize.
    → system/src/Grav/Common/Session.php

  4. InstallCommand git clone shell injection — branch, url, and path values read from user/.dependencies are now passed through escapeshellarg, with a -- separator before url/path to block option-injection (e.g. --upload-pack=evil).
    → system/src/Grav/Console/Cli/InstallCommand.php

  5. SSTI blocklist bypass — twig_array_reduce (the specific name called out) plus twig_array_some and twig_array_every added to cleanDangerousTwig's CALLABLE_DANGEROUS_NAMES alongside the existing twig_array_map/filter. More importantly, the new Twig content sandbox in 2.0.0-beta.2 blocks this class of attack at a different layer — see the sandbox work in 38685ac25.
    → system/src/Grav/Common/Security.php

Tests:

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐘Packagistgetgrav/gravall versions2.0.0-beta.2composer require getgrav/grav:^2.0.0-beta.2

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for getgrav/grav, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update getgrav/grav to 2.0.0-beta.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-vj3m-2g9h-vm4p is resolved across your whole dependency graph.

  3. Workarounds

    Stop passing untrusted input into the interpreter or shell: call the affected binary with an argument array rather than a composed command string, reject anything outside a strict allowlist of expected values, and run the component under an account that cannot reach beyond the work it legitimately does.

Frequently Asked Questions

Multiple RCE vectors were found in Grav CMS. Three are critical, two are high. **1. Unsafe unserialize() in JobQueue — direct RCE gadget (Critical)** `system/src/Grav/Common/Scheduler/JobQueue.php:465` calls `unserialize(base64_decode(...))` without restricting `allowed_classes`. The `Job` class has `call_user_func_array($this->command, $this->args)` in its execution path, which is a direct gadget chain — inject a serialized `Job` with `command = 'system'` and `args = ['whoami']`. The same codebase actually has a `Serializable` trait that correctly restricts classes, so this inconsistency s
O3 Security · Impact-Aware SCA

Is GHSA-vj3m-2g9h-vm4p in your dependencies?

Find it across Packagist, including transitive dependencies.

Grav has multiple RCE vectors: unsafe unserialize (x3),…