Affected versions
Twig versions <3.26.0 are affected by this security issue.
The issue has been fixed in Twig 3.26.0.
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
We would like to thank Claude Mythos Preview (via Project Glasswing) for reporting the issue and providing the fix.