twigphp/twig · Security

Twig: Arbitrary PHP code execution via `_self.(<string>)` macro-reference compilation

GHSA ID
GHSA-45vw-wh46-2vx8
CVE ID
CVE-2026-46640
Severity
high
Published
Updated
CVSS v4
8.7 · CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

Description

Description

The obj.(expr) dynamic-attribute syntax (added in 3.15.0 as the replacement for the deprecated attribute() function) lets the attribute be an arbitrary expression. When the receiver is _self (or any {% import %} alias) and the parenthesised expression is a string literal, DotExpressionParser short-circuits to the macro-call path and concatenates the attacker-controlled string into a MacroReferenceExpression name with no identifier validation. MacroReferenceExpression::compile() then emits that name raw into the generated PHP source.

An attacker who can supply template source can inject arbitrary PHP into the compiled template and execute it at template-load time, before checkSecurity() is ever called. This is a complete bypass of SandboxExtension, including a globally-enabled sandbox with an empty SecurityPolicy allowlist.

Resolution

The parser now validates that the dynamic attribute resolves to a valid macro identifier before routing through MacroReferenceExpression, and the macro-reference compiler emits the name through a properly escaped path.

Credits

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

CWEs

References