Skip to main content

Twig CVE-2026-46638

MEDIUM
Protection Mechanism Failure (CWE-693)
2026-05-21 https://github.com/twigphp/Twig GHSA-7fxw-r6jv-74c8
6.0
CVSS 4.0 · Vendor: https://github.com/twigphp/Twig
Share

Severity by source

Vendor (https://github.com/twigphp/Twig) PRIMARY
6.0 MEDIUM
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Primary rating from Vendor (https://github.com/twigphp/Twig) · only source for this CVE.

CVSS VectorVendor: https://github.com/twigphp/Twig

CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
X

Lifecycle Timeline

3
CVSS changed
Jul 14, 2026 - 22:22 NVD
6.0 (MEDIUM)
Source Code Evidence Fetched
May 21, 2026 - 22:03 vuln.today
Analysis Generated
May 21, 2026 - 22:03 vuln.today

DescriptionCVE.org

Description

The fix for CVE-2024-45411 / GHSA-6j75-5wfj-gh66 added an explicit $loaded->unwrap()->checkSecurity() call in CoreExtension::include() so that a template already cached in Environment::$loadedTemplates is re-checked when included with sandboxed = true.

The deprecated but still functional {% sandbox %}{% include ... %}{% endsandbox %} tag path was not updated: it compiles to enableSandbox(); yield from $this->load(...)->unwrap()->yield(...); disableSandbox(); with no checkSecurity() re-invocation. If the included template was loaded once outside the sandbox in the same Environment instance, its constructor (and therefore its compiled checkSecurity() call) already ran while isSandboxed() was false, so the tags/filters/functions allowlist enforced by SecurityPolicy::checkSecurity() is never applied.

An attacker who can author the included template gains access to every filter, function and tag registered in the environment, regardless of the sandbox policy.

Resolution

The compiled output of {% sandbox %}{% include %} now calls checkSecurity() on the loaded template, matching the behaviour of CoreExtension::include() with sandboxed = true.

Credits

Twig would like to thank Claude Mythos Preview (via Project Glasswing) for reporting the issue and providing the fix.

AnalysisAI

Sandbox policy bypass in Twig's deprecated {% sandbox %}{% include %} tag path allows template authors to access every filter, function, and tag registered in the environment, regardless of the configured SecurityPolicy. This is an incomplete fix for CVE-2024-45411 (GHSA-6j75-5wfj-gh66): the prior fix added an explicit checkSecurity() re-invocation in CoreExtension::include() but did not update the compiled output of the {% sandbox %}{% include %} syntax, leaving it without the same guard. Twig versions prior to 3.26.0 using this deprecated tag in applications that allow user-controlled template authorship are affected. No public exploit has been identified at time of analysis and the vulnerability is not listed in the CISA KEV catalog.

Technical ContextAI

Twig (pkg:composer/twig/twig) is a PHP templating engine that provides an optional sandbox mode enforced via a SecurityPolicy allowlist. The sandbox restricts which tags, filters, and functions a template may invoke, with enforcement performed in checkSecurity() on template load. Templates are cached in Environment::$loadedTemplates after their constructor runs; once cached, the constructor - and therefore its embedded checkSecurity() call - does not execute again. The prior fix for CVE-2024-45411 addressed this caching race in CoreExtension::include() by explicitly calling $loaded->unwrap()->checkSecurity() after retrieval from cache when sandboxed = true. However, the deprecated-but-functional {% sandbox %}{% include ... %}{% endsandbox %} tag compiles to enableSandbox(); yield from $this->load(...)->unwrap()->yield(...); disableSandbox(); with no corresponding checkSecurity() re-invocation. If the same Environment instance previously loaded the target template outside a sandboxed context, the cached compiled class will execute without the SecurityPolicy allowlist ever being applied. CWE-693 (Protection Mechanism Failure) accurately classifies this as a failure of the sandbox protection mechanism rather than a logic error in policy definition.

RemediationAI

Upgrade to Twig 3.26.0 or later, which corrects the compiled output of {% sandbox %}{% include %} to call checkSecurity() on the loaded template, matching the behaviour already enforced in CoreExtension::include() with sandboxed = true. The vendor-released patch is version 3.26.0 per GHSA-7fxw-r6jv-74c8. As an interim compensating control, applications can migrate away from the deprecated {% sandbox %}{% include %} syntax and use the include() function with the sandboxed = true parameter instead, which already applies the correct checkSecurity() re-invocation introduced by the CVE-2024-45411 fix. This workaround eliminates use of the vulnerable code path entirely but requires audit of all templates to confirm no remaining {% sandbox %}{% include %} usage. Restricting template authorship to fully trusted parties would reduce risk but does not constitute a fix. Advisory references: https://github.com/twigphp/Twig/security/advisories/GHSA-7fxw-r6jv-74c8 and https://symfony.com/cve-2026-46638.

Share

CVE-2026-46638 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy