Aug 7, 2026·5 min read·2 visits
Authenticated users can exfiltrate sensitive environment variables by abusing sequential evaluation of environment parsing and sandboxed Twig templates.
An authenticated information disclosure vulnerability in Craft CMS allows high-privilege administrators to extract sensitive environment variables, including the CRAFT_SECURITY_KEY and database credentials, using a blind error-based template injection attack within element select condition rules.
In Craft CMS, authenticated administrators or users with access to the Control Panel can configure element select condition rules. These rules utilize input parameters such as elementId in Craft 4 or elementIds in Craft 5 to dynamically filter and select specific content assets or entries.
A previous vulnerability fix, CVE-2026-31857 (GHSA-fp5j-j7j4-mcxc), attempted to secure this input channel by enforcing the use of a sandboxed Twig template rendering engine when processing user-defined inputs. This sandbox was designed to prevent remote code execution via Server-Side Template Injection (SSTI).
Despite the sandbox protection, GHSA-596P-6JV8-775V introduces a validation bypass in the template processing pipeline. An authenticated attacker can exploit the sequence in which inputs are resolved to perform a blind error-based injection attack, ultimately exfiltrating sensitive environment variables from the server config.
The root cause of this vulnerability lies in a sequence-of-operations flaw where environment variable interpolation occurs before sandboxed template rendering.
When evaluating the condition rule parameters, the application first passes the input string to the App::parseEnv() helper method. This method automatically processes and interpolates environment variables or secrets matching patterns like $ENV_VAR or ${ENV_VAR}.
Immediately following this environment variable interpolation, the resulting string is rendered as a Twig template via renderSandboxedObjectTemplate(). Because the secrets are inserted directly into the string before rendering, Twig parses the resolved secret values as part of the executable template context rather than as plain, non-evaluable text literals.
Although the Twig engine operates within a restricted sandbox that blocks dangerous PHP functions and classes, an attacker can still write standard control flow statements. By crafting conditional statements that check individual characters of the interpolated environment variables, the attacker can trigger runtime execution exceptions based on whether a specific condition is met.
In vulnerable versions of Craft CMS 4 (pre-4.18.2), the vulnerable flow is located in src/base/conditions/BaseElementSelectConditionRule.php within the getElementId method:
public function getElementId(bool $parse = true): int|string|null
{
if ($parse && is_string($this->_elementId)) {
// Step 1: Interpolate environment variables into the string
$elementId = App::parseEnv($this->_elementId);
if ($this->condition instanceof ElementCondition && isset($this->condition->referenceElement)) {
$referenceElement = $this->condition->referenceElement;
} else {
$referenceElement = new stdClass();
}
// Step 2: Pass the interpolated string to the template engine
return Craft::$app->getView()->renderSandboxedObjectTemplate($elementId, $referenceElement);
}
return $this->_elementId;
}The implementation in Craft CMS 5 (pre-5.10.6) reflects the same logical design flaw inside the modified array handler getElementIds:
public function getElementIds(bool $parse = true): array|string
{
if ($parse && is_string($this->_elementIds)) {
// Step 1: Interpolation occurs first
$elementIds = App::parseEnv($this->_elementIds);
if ($this->condition instanceof ElementCondition && isset($this->condition->referenceElement)) {
$referenceElement = $this->condition->referenceElement;
} else {
$referenceElement = new stdClass();
}
// Step 2: The output of step 1 is compiled
$elementIds = Craft::$app->getView()->renderSandboxedObjectTemplate($elementIds, $referenceElement);
return array_values(array_filter(array_map(
fn(string $elementId) => (int)trim($elementId),
explode(',', $elementIds),
)));
}
return $this->_elementIds;
}The vulnerability is resolved in the updated releases by adding strict regex checks. If environment variable interpolation alters the initial string, additional Twig templating execution is completely bypassed unless the original input is a simple environment variable format matching /^\$\{?\w+\}?$/.
An attacker with Control Panel access can exploit this vulnerability using a blind error-based template injection technique. This requires crafting a payload that dynamically evaluates a character of the target variable and triggers a standard PHP runtime error on a match.
The attacker inputs the following payload into a condition rule text field:
{% if "${CRAFT_SECURITY_KEY}"|slice(0, 1) == "a" %}{{ 1/0 }}{% endif %}When the server processes this rule, App::parseEnv() resolves ${CRAFT_SECURITY_KEY} into its actual plaintext value. The Twig compilation engine then evaluates the comparison expression:
{{ 1/0 }}. This produces a DivisionByZeroError, resulting in an HTTP 500 Internal Server Error returned to the attacker.By programmatically adjusting the slice index and testing different characters, an automated script can reconstruct sensitive keys character-by-character.
A successful exploit allows the exfiltration of core secrets. The main target of such an attack is the CRAFT_SECURITY_KEY, which is responsible for signing cookies, sessions, and security tokens. Gaining access to this key allows attackers to forge administrative sessions, perform object injection, and potentially escalate permissions to remote code execution.
Additionally, secondary variables such as CRAFT_DB_PASSWORD (database credentials), API keys, and SMTP server passwords can be exfiltrated. This introduces risks of lateral movement and complete compromise of external databases or connected cloud environments.
While this attack requires authenticated access with permissions to define element condition rules, it presents a substantial risk in multi-tenant installations, delegated administration frameworks, or instances compromised via minor entry points.
To remediate this vulnerability, administrators must update Craft CMS installations to the patched versions immediately.
The official patch mitigates the flaw by implementing validation checks. The application checks if the environment-resolved string differs from the original. If a change is detected, it only permits rendering if the string contains a single, simple environment variable format without complex syntax structures or Twig delimiters.
If immediate updates are not possible, administrators should restrict Control Panel access to trusted personnel and closely monitor database tables and configuration files for unexpected Twig delimiters inside condition rules.
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Craft CMS Pixel & Tonic | >= 4.0.0-RC1, <= 4.18.1 | 4.18.2 |
Craft CMS Pixel & Tonic | >= 5.0.0-RC1, <= 5.10.5 | 5.10.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-1336 |
| Attack Vector | Network |
| CVSS v4.0 | 5.1 |
| Impact | Partial Information Disclosure |
| Exploit Status | Proof-of-Concept |
| Privileges Required | High (Admin Access) |
| CISA KEV Status | No |
Improper Neutralization of Special Elements Used in a Template Engine
An authorization bypass vulnerability in Craft CMS allows unauthenticated or low-privileged users to query and obtain sensitive time-series user registration counts and demographic metrics. This is due to a missing authorization check inside the actionGetNewUsersData endpoint of the ChartsController class.
A protocol-parsing vulnerability in the pure-Python HTTP/2 library 'h2' (versions <= 4.4.0) allows unauthenticated remote attackers to perform HTTP Request Smuggling (CWE-444). The vulnerability exists because the library does not validate the uniqueness of 'Host' headers in incoming HTTP/2 request streams. When an upstream gateway parses such requests and downgrades them to HTTP/1.1 for internal backend servers, the resulting stream contains duplicate Host headers, which leads to parsing inconsistency and potential bypass of security filters.
An information disclosure vulnerability in Craft CMS allows users with administrative or non-sandboxed template-authoring privileges to read arbitrary system and configuration files. The issue stems from an incomplete class instantiation blocklist in the Twig template extension, which omitted PHP's built-in SplFileObject class.
An authorization bypass vulnerability in Craft CMS allows authenticated control panel users with low privileges to reorder global sets. This alters structure and writes to the project configuration database schema without administrative rights.
Prior to versions 10.9.8 and 11.16.1, Mermaid is vulnerable to prototype pollution via its deep-merge utility function assignWithDepth. This helper is invoked by public configuration-setting interfaces, specifically mermaid.initialize, mermaidAPI.setConfig, and mermaidAPI.updateSiteConfig. Because assignWithDepth recursively merges developer-provided properties into Mermaid's internal configuration state without proper sanitization, an attacker who can control or influence the configuration payload can corrupt the global Object.prototype. This vulnerability can lead to security bypasses, cross-site scripting (XSS), or execution flow modifications in applications using vulnerable Mermaid integrations.
A high-severity path traversal vulnerability exists in Traefik's Kubernetes Ingress NGINX provider. The flaw resides in the RewriteTarget middleware, which is auto-generated when an Ingress resource specifies the `nginx.ingress.kubernetes.io/rewrite-target` annotation. This allows remote, unauthenticated attackers to bypass route-level authentication and access restricted downstream endpoints by exploiting a parser differential.