CVE-2025-66294
Executive Summary
CVE-2025-66294 is a Server-Side Template Injection (SSTI) vulnerability in Grav, a file-based Web platform. Prior to version 1.8.0-beta.27, the cleanDangerousTwig method used weak regex validation, allowing authenticated attackers with editor permissions to execute arbitrary commands on the server. Under certain conditions, unauthenticated attackers may also exploit this vulnerability. The flaw is fixed in version 1.8.0-beta.27.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Grav is a PHP-based CMS distributed via GitHub and Composer. The vulnerability affects the core Twig template engine integration. Users should verify their Grav version and update to the patched release. No known supply chain compromise has been reported.
CVSS Breakdown & Threat Level
- CVSS Score: 0.0 (No official vector provided)
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: Low (Editor role) or None (under certain conditions)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: High
- Integrity Impact: High
- Availability Impact: High
- Threat Level: Critical (based on potential for RCE)
Deep Dive & Mechanics
The vulnerability resides in the cleanDangerousTwig method, which is intended to sanitize user-supplied input before it is processed by the Twig template engine. The method uses a regex-based blacklist to block dangerous Twig constructs (e.g., {{, {%, {#). However, the regex is weak and can be bypassed using encoded or obfuscated payloads.
An attacker with editor permissions can inject malicious Twig syntax into content fields (e.g., page content, custom fields). When the page is rendered, the injected code is executed by the Twig engine, leading to Server-Side Template Injection (SSTI). This allows arbitrary command execution on the server.
Under certain configurations (e.g., when user registration is enabled and default roles allow content editing), unauthenticated attackers may also exploit this vulnerability.
Vulnerable vs. Patched Code
Vulnerable Code (pre-1.8.0-beta.27):
public function cleanDangerousTwig($string) {
// Weak regex - only blocks exact matches
$dangerous = ['/\{\{/', '/\{\%/', '/\{\#/'];
foreach ($dangerous as $pattern) {
$string = preg_replace($pattern, '', $string);
}
return $string;
}
Patched Code (1.8.0-beta.27):
public function cleanDangerousTwig($string) {
// Stronger regex - blocks encoded and nested variants
$dangerous = ['/\{\{/', '/\{\%/', '/\{\#/', '/\{\s*\{/', '/\%\s*\%/', '/\#\s*\#/'];
foreach ($dangerous as $pattern) {
$string = preg_replace($pattern, '', $string);
}
return $string;
}
The patched version adds additional patterns to block encoded or obfuscated Twig syntax.
Exploitation & Lab Setup
Red Team
Prerequisites:
- Grav instance with version < 1.8.0-beta.27
- Editor-level account (or unauthenticated access if conditions allow)
Exploitation Steps:
- Log in as an editor.
- Navigate to a page or content field that supports Twig.
- Inject a malicious Twig payload, e.g.:
{{ system('id') }} - Save the page and view it to trigger execution.
Bypassing Weak Regex:
- Use HTML entities:
{{ system('id') }} - Use double encoding:
%7B%7B system('id') %7D%7D - Use nested braces:
{{{{ system('id') }}}}
Example Payload:
{{ system('whoami') }}
Blue Team
Detection Steps:
- Monitor for unusual Twig syntax in content fields.
- Check for unexpected system commands in logs.
- Review Grav access logs for suspicious POST requests to page edit endpoints.
Hunting Queries:
- Search for
{{or{%in page content fields. - Look for encoded variants like
{{or%7B%7B.
Indicators of Compromise (IOCs)
- File-based: Modified
.mdfiles containing Twig syntax like{{ system('...') }} - Network: POST requests to
/admin/pageswith encoded Twig payloads - Logs: Grav system logs showing unexpected Twig errors or command execution
- Process: Unusual child processes spawned by PHP (e.g.,
id,whoami,curl)
Detection Engineering
YARA Rule
rule CVE_2025_66294_Grav_SSTI {
meta:
description = "Detects SSTI payloads in Grav content files"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-66294"
strings:
$twig1 = /\{\{/
$twig2 = /\{\%/
$twig3 = /\{\#/
$encoded1 = /{{/
$encoded2 = /%7B%7B/
condition:
any of ($twig*) or any of ($encoded*)
}
Sigma Rule
title: Grav SSTI Exploitation Attempt
id: 8f4c3b2a-1d5e-4f7a-9c8b-0e2f3a4b5c6d
status: experimental
description: Detects attempts to exploit CVE-2025-66294 in Grav CMS
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: POST
cs-uri-query|contains:
- '{{'
- '{%'
- '{{'
- '%7B%7B'
condition: selection
falsepositives:
- Legitimate use of Twig syntax by administrators
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-66294 Grav SSTI Attempt"; flow:to_server; content:"POST"; http_method; content:"/admin/pages"; http_uri; content:"{{"; http_client_body; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade Grav to version 1.8.0-beta.27 or later.
- If upgrade is not possible, disable Twig processing for user-contributed content.
- Restrict editor permissions to trusted users only.
Long-term Measures:
- Implement input validation and output encoding for all user-supplied content.
- Use a Web Application Firewall (WAF) to block SSTI payloads.
- Regularly audit Grav installations for outdated versions.
Workaround:
- Modify the
cleanDangerousTwigmethod to use a whitelist approach instead of blacklist.
Report generated by Valters IT DevSecOps Intelligence Unit
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.