CVE-2026-24425 - Twig SourcePolicyInterface callback bypass

Twig versions 2.16.* and >=3.9.0, <3.26.0 can fail to enforce sandbox callback restrictions when sandboxing is enabled by SourcePolicyInterface instead of globally. In affected versions, callback-accepting filters can treat the current execution as non-sandboxed and allow non-Closure PHP callables in sort, filter, map, and reduce.

The risky application shape is a PHP product that lets users author or edit Twig templates and uses a source policy to decide which template names or sources should be sandboxed. A fixed package is necessary, but reviewers should also verify that the application is not exposing privileged PHP callables, service objects, or sensitive context objects to untrusted template authors.

When to use it

  • A PHP application resolves an affected twig/twig version and uses sandboxed or user-controlled templates.
  • SourcePolicyInterface, custom loaders, template previews, CMS blocks, themes, or email/report templates influence whether sandboxing applies.
  • Template contexts may expose service containers, request/session objects, filesystem clients, database handles, or other privileged objects.
  • You need a bounded PR or triage note that upgrades Twig and proves the template sandbox boundary.

Inputs

  • composer.json, composer.lock, framework integrations, Dockerfiles, deployment manifests, SBOMs, and generated dependency reports.
  • Template loader, source policy, sandbox extension, security policy, preview, cache, include/import/embed, and user-template code.
  • Template context object inventory and owner-approved narrowing rules.
  • Available Composer, unit/feature, template-rendering, static analysis, image, SBOM, and dependency scan commands.

Affected versions

  • Vulnerable package: twig/twig 2.16.* and twig/twig >=3.9.0, <3.26.0
  • Fixed package: twig/twig 3.26.0+
  • Preferred target: twig/twig 3.27.0+ to include later related sandbox fixes.
  • Affected sandbox mode: sandboxing enabled through SourcePolicyInterface, not a globally enabled sandbox.
  • Affected filters: sort, filter, map, and reduce when supplied a non-Closure callback.

Indicator-of-exposure

  • The repository depends on twig/twig in the affected range.
  • Code references SourcePolicyInterface, custom Twig loaders, per-template sandbox decisions, or source-name based sandboxing.
  • Users, tenants, admins, CMS editors, theme authors, plugin authors, or automation workflows can provide Twig template source.
  • Template context exposes PHP objects whose methods, string conversion, or callbacks could reach secrets, files, database records, service containers, or network clients.
  • Tests or docs assume source-policy sandboxing is equivalent to global sandboxing for callback filters.

Quick checks:

rg -n "twig/twig|SourcePolicyInterface|SandboxExtension|SecurityPolicy|sort\(|filter\(|map\(|reduce\(|Closure|callable|createTemplate|template source|theme|cms|email" .
composer show twig/twig
composer why twig/twig
rg -n "SourcePolicyInterface|SandboxExtension|SecurityPolicy|sort\(|filter\(|map\(|reduce\(|twig/twig" composer.json composer.lock config src templates app resources tests . 2>/dev/null

Windows:

rg -n "twig/twig|SourcePolicyInterface|SandboxExtension|SecurityPolicy|sort\(|filter\(|map\(|reduce\(|Closure|callable|createTemplate|template source|theme|cms|email" .
composer show twig/twig
composer why twig/twig
rg -n "SourcePolicyInterface|SandboxExtension|SecurityPolicy|sort\(|filter\(|map\(|reduce\(|twig/twig" composer.json composer.lock config src templates app resources tests .

Do not render attacker-controlled templates, test arbitrary PHP callables, or print template contexts during triage.

Remediation strategy

  • Upgrade every controlled twig/twig package, lockfile, image, SBOM, generated dependency report, and deployment artifact to 3.26.0+.
  • Prefer 3.27.0+ when compatibility allows, because Twig published additional sandbox hardening after 3.26.0.
  • If the application still supports Twig 2.16.x, treat that branch as needing a framework/runtime migration or a product decision; there is no fixed 2.x version in the advisory.
  • Keep source-policy sandboxing only if the source policy is deterministic, fail-closed, covered by tests, and not bypassed by alternate loaders, includes, embeds, previews, imports, or cache keys.
  • Remove privileged objects and broad service containers from untrusted template contexts. Pass narrow view models instead.
  • Add regression checks that fail on vulnerable Twig versions and assert that untrusted template sources are rendered through the intended sandbox path.

The prompt

You are remediating CVE-2026-24425 / GHSA-2q52-x2ff-qgfr, a Twig sandbox
bypass where `SourcePolicyInterface` based sandboxing can fail to reject
non-Closure callbacks passed to `sort`, `filter`, `map`, or `reduce`. Produce
exactly one output:

- A reviewer-ready PR/change request that upgrades Twig, verifies source-policy
  sandboxing and template context boundaries, adds safe regression coverage,
  refreshes generated artifacts, and documents operator cleanup, or
- TRIAGE.md if this repository does not control affected Twig dependencies or
  a source-policy sandboxed template rendering surface.

## Rules

- Scope only CVE-2026-24425 / GHSA-2q52-x2ff-qgfr and directly related Twig
  source-policy sandbox and callback-filter controls.
- Treat template source, template context objects, rendered content, users,
  orders, database records, service containers, environment variables, secrets,
  sessions, logs, and compiled template caches as sensitive.
- Do not run exploit callbacks, render attacker templates, test callable-based
  PHP execution, mutate live templates, dump template contexts, or print secrets.
- Do not remove sandboxing, source policies, authorization, audit logs, or
  tests to silence the advisory.
- Do not auto-merge.

## Steps

1. Inventory all Twig usage controlled by this repository: `composer.json`,
   `composer.lock`, Symfony/Laravel/Drupal/CMS integrations, Dockerfiles,
   deployment manifests, CI images, SBOMs, generated dependency reports,
   template loaders, source policies, user-template features, and local forks.
2. Determine every resolved `twig/twig` version. A target is vulnerable if it
   resolves to `2.16.*` or `>=3.9.0, <3.26.0`.
3. Search for source-policy sandboxing and callback filters:
   `SourcePolicyInterface`, `SandboxExtension`, `SecurityPolicy`,
   `setSecurityPolicy`, `enableSandbox`, custom loaders, `sort`, `filter`,
   `map`, `reduce`, `Closure`, `callable`, `createTemplate`, template previews,
   CMS blocks, themes, and email/report templates.
4. If Twig is absent, fixed, globally sandboxed without source-policy use, or
   only renders developer-authored templates, stop with `TRIAGE.md` listing the
   checked files, resolved version, and exposure rationale.
5. Upgrade all controlled Twig dependencies to `3.26.0+`; prefer `3.27.0+`
   unless the application requires the smaller fixed target. Refresh
   `composer.lock`, images, deployment artifacts, SBOMs, generated dependency
   reports, and docs that pin Twig.
6. If the project is pinned to Twig 2.16.x, stop with `TRIAGE.md` unless the
   repository can migrate to a fixed Twig 3.x line safely in this PR.
7. Verify or patch the sandbox boundary:
   - source-policy decisions are deterministic and fail closed;
   - untrusted template sources cannot avoid the source policy through alternate
     loaders, cache keys, includes, imports, embeds, previews, or aliases;
   - callback-accepting filters are not granted arbitrary PHP callables;
   - template contexts expose narrow view models, not service containers,
     database handles, request/session objects, filesystem clients, or secrets.
8. Add safe regression coverage:
   - dependency policy rejects affected Twig versions;
   - untrusted template sources use the source-policy sandbox;
   - benign templates using `sort`, `filter`, `map`, and `reduce` still work
     with allowed closures;
   - non-closure callback attempts are rejected in tests without executing PHP
     callables or printing sensitive context.
9. Add a PR body section named `CVE-2026-24425 operator actions` that states:
   - Twig versions before and after;
   - whether `SourcePolicyInterface` is used and where;
   - which user-controlled template surfaces exist;
   - whether template contexts expose privileged objects and what was narrowed;
   - whether compiled template caches or workers must be cleared/restarted;
   - whether audit review or secret rotation is needed;
   - which validation commands passed.
10. Run available validation: Composer install/check-platform-reqs, lockfile
    integrity, unit/feature tests, benign template-rendering tests, static
    analysis, lint, deployment rendering, image build, SBOM refresh, and
    dependency/security scans.
11. Use PR title:
    `fix(sec): remediate CVE-2026-24425 in Twig source policies`.

## Stop conditions

- No affected Twig package, source-policy sandbox, user-controlled template
  source, or deployment artifact is controlled by this repository.
- The Twig runtime or template subsystem is owned by another team; name the
  owner and required fixed version in `TRIAGE.md`.
- The project requires Twig 2.16.x and cannot move to a fixed 3.x release in
  this PR.
- Verification would require rendering exploit templates, executing arbitrary
  PHP callables, dumping template contexts, mutating live templates, or exposing
  secrets.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Verification - what the reviewer looks for

  • No controlled Composer lockfile, package manifest, image, SBOM, or generated dependency report resolves twig/twig 2.16.* or twig/twig >=3.9.0, <3.26.0.
  • Source-policy sandbox usage is inventoried and covered by tests.
  • Untrusted template contexts do not expose broad service containers, request objects, filesystem handles, database clients, or secrets.
  • Callback-filter regression tests do not execute arbitrary PHP callables.
  • PR notes cover source-policy behavior, cache cleanup, worker restarts, and audit or rotation criteria.

Output contract

  • Reviewer-ready PR upgrading controlled Twig dependencies to 3.26.0+ preferably 3.27.0+, with refreshed generated artifacts.
  • Safe regression coverage for source-policy sandbox decisions, callback-filter rejection, and benign template behavior.
  • Reviewer notes that identify user-controlled template surfaces, narrowed contexts, cache cleanup, worker restarts, and audit or rotation criteria.
  • TRIAGE.md when the repository does not control an affected Twig runtime or cannot safely leave Twig 2.16.x.

Watch for

  • Updating Composer constraints without refreshing composer.lock, images, SBOMs, or generated reports.
  • Assuming source-policy sandboxing has the same behavior as global sandboxing on vulnerable Twig versions.
  • Leaving user-template preview endpoints or alternate template loaders outside the source policy.
  • Passing rich domain objects or service containers into untrusted templates.
  • Writing exploit-style tests that execute PHP callables instead of asserting safe rejection.

References