GitHub Advisoryadvisory · Packagist

GHSA-7fxw-r6jv-74c8 Twig: `{% sandbox %}{% include %}` skips checkSecurity() on cached templates (incomplete fix for CVE-2024-45411)

MEDIUM Published 2026-05-21 Modified 2026-05-21 Official page ↗
Aliases
CVE-2026-46638
Ecosystem
Packagist
Packages
twig/twig
Severity
Moderate
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H
Weaknesses
CWE-693
Reviewed
2026-05-21

Affected packages

• Packagist twig/twig: < 3.26.0 → fixed in 3.26.0

Description

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.

Related

Alias · CVE (1)

Weakness · CWE (1)

  • CWE-693 Protection Mechanism Failure weakness

References