CVE-2026-46640 - Twig macro-reference compilation RCE

Twig versions from 3.15.0 before 3.26.0 can compile attacker-controlled macro reference names into generated PHP source when a template uses dynamic attribute syntax against _self or an imported macro alias. A template author who can supply Twig source can inject PHP into the compiled template and execute it before sandbox checks run.

This is not a generic “Twig is installed” issue. The dangerous surface is an application that renders template source, theme fragments, CMS blocks, email templates, tenant templates, report templates, or plugin templates that can be influenced by users who are not trusted PHP developers.

When to use it

Use this recipe when a PHP repository depends on Twig and renders template source that can be edited, uploaded, previewed, imported, or generated by users, tenants, admins, support staff, integrations, plugins, or agents. It is especially important for CMS, ecommerce, email, reporting, theme, helpdesk, and low-code surfaces that treat Twig sandboxing as a security boundary.

Do not use it to render exploit templates. Use it to upgrade, clear compiled templates, audit template-author trust, and document whether secret rotation or template rollback is required.

Inputs

  • composer.json, composer.lock, Symfony/Laravel/Drupal/CMS integrations, container images, SBOMs, generated dependency reports, and deployment manifests that may resolve twig/twig.
  • Template render paths, Twig\Environment, createTemplate, SandboxExtension, SecurityPolicy, template upload/edit/preview features, and compiled template cache locations.
  • Ownership and trust classification for template authors: developers, admins, support, customers, tenants, marketplace plugins, integrations, or agents.
  • Deployment/runtime information for PHP-FPM, RoadRunner, FrankenPHP, Messenger/queue workers, warmed caches, image layers, and restart behavior.
  • Existing audit logs, template rollback process, and credential-rotation criteria when untrusted authors may have rendered templates.

Affected versions

  • Vulnerable package: twig/twig >=3.15.0, <3.26.0
  • Fixed package: twig/twig 3.26.0+
  • Preferred target: twig/twig 3.27.0+ to include the follow-up sandbox fixes published after the first 3.26.0 security release.
  • Affected syntax: _self.(<string>) and imported macro aliases using the dynamic-attribute parser path.
  • Required attacker capability: ability to supply or materially influence Twig template source.

Indicator-of-exposure

  • The repository depends on twig/twig in the affected range.
  • The application renders user-controlled or admin-controlled Twig source, not just developer-authored templates committed to the repository.
  • CMS, ecommerce, helpdesk, marketing, email, report, theme, plugin, low-code, automation, tenant-branding, or preview features allow template edits.
  • Twig sandboxing is treated as the security boundary between template authors and PHP code execution.
  • Long-lived workers, PHP-FPM pools, RoadRunner, FrankenPHP, Messenger workers, queues, or warmed template caches can keep compiled vulnerable templates after a package upgrade.

Quick checks:

rg -n "twig/twig|Twig\\Environment|SandboxExtension|SecurityPolicy|createTemplate|render\(|_self\.\(|import .* as|attribute\(|template|theme|email|cms|block|preview" .
composer show twig/twig
composer why twig/twig
rg -n "twig/twig|twig/cache|var/cache|compiled twig|createTemplate|SandboxExtension" composer.json composer.lock config src templates app resources . 2>/dev/null

Windows:

rg -n "twig/twig|Twig\\Environment|SandboxExtension|SecurityPolicy|createTemplate|render\(|_self\.\(|import .* as|attribute\(|template|theme|email|cms|block|preview" .
composer show twig/twig
composer why twig/twig
rg -n "twig/twig|twig/cache|var/cache|compiled twig|createTemplate|SandboxExtension" composer.json composer.lock config src templates app resources .

Do not render proof-of-concept templates, test PHP code execution, or dump template context values during triage. Template contexts often contain users, orders, tokens, feature flags, secrets, and internal service objects.

Remediation strategy

  • Upgrade every controlled twig/twig package, Composer lockfile, container layer, SBOM, dependency report, and deployment artifact to 3.26.0+.
  • Prefer 3.27.0+ when possible because multiple related Twig sandbox fixes followed the initial 3.26.0 release.
  • Clear compiled Twig caches and rebuild deployment images so stale generated PHP templates cannot remain loaded after the package upgrade.
  • Inventory every user-controlled template source and require explicit sandbox configuration, template-source ownership, and review for any template author who is not a trusted PHP developer.
  • Add a dependency guard that rejects vulnerable twig/twig versions and a safe regression test that exercises the local template-rendering path without executing injected PHP.
  • If upgrade is blocked, disable user-controlled template editing/rendering or restrict it to pre-reviewed templates until the package and compiled cache are fixed.
  • Review audit logs and rotate secrets exposed to the PHP runtime if untrusted template authors could render templates on a vulnerable deployment.

The prompt

You are remediating CVE-2026-46640 / GHSA-45vw-wh46-2vx8, a Twig
macro-reference compilation bug where dynamic attribute syntax on `_self` or an
imported macro alias can inject PHP into compiled templates before sandbox
checks run. Produce exactly one output:

- A reviewer-ready PR/change request that upgrades Twig, clears compiled
  template artifacts, hardens user-controlled template rendering, adds safe
  regression coverage, refreshes generated artifacts, and documents operator
  cleanup, or
- TRIAGE.md if this repository does not control an affected Twig runtime or any
  user-controlled Twig template rendering surface.

## Rules

- Scope only CVE-2026-46640 / GHSA-45vw-wh46-2vx8 and directly related Twig
  template rendering, sandbox, cache, and deployment controls.
- Treat template source, rendered output, template context objects, users,
  orders, email content, secrets, environment variables, API tokens, session
  data, logs, and generated PHP cache files as sensitive.
- Do not run exploit templates, inject PHP, call process functions, modify live
  templates, dump template contexts, or print generated PHP that contains
  application data.
- Do not remove Twig sandboxing, template review, authorization checks, audit
  logs, cache isolation, or tests to silence the advisory.
- Do not auto-merge.

## Steps

1. Inventory all Twig usage controlled by the repository: `composer.json`,
   `composer.lock`, Symfony bundles, Laravel/Drupal/CMS integrations,
   Dockerfiles, CI images, deployment manifests, SBOMs, generated dependency
   reports, template-cache directories, plugin/theme systems, email/report
   renderers, and local forks or patches.
2. Determine every resolved `twig/twig` version. A target is vulnerable if it
   resolves to `>=3.15.0, <3.26.0`.
3. Search for user-controlled template sources and sandbox boundaries:
   `Twig\Environment`, `createTemplate`, `SandboxExtension`, `SecurityPolicy`,
   template upload/edit/preview features, CMS blocks, themes, email templates,
   report builders, tenant templates, `_self.(`, `{% import %}`, dynamic
   attributes, and compiled template cache paths.
4. If Twig is absent, already fixed, or used only for developer-authored
   templates with no user-controlled source path, stop with `TRIAGE.md`
   listing checked files, resolved version, and why the RCE path is not
   exposed.
5. Upgrade all controlled Twig packages to `3.26.0+`; prefer `3.27.0+` unless
   compatibility testing requires the smaller fixed release. Refresh
   `composer.lock`, generated dependency reports, SBOMs, image metadata,
   deployment manifests, and docs that pin Twig.
6. Clear compiled templates and deployment caches:
   - remove stale Twig cache directories during deploy;
   - rebuild images or release artifacts that contain compiled Twig PHP;
   - restart long-lived PHP workers after deployment;
   - document cache locations that operators must clear outside the repo.
7. Harden user-controlled template rendering:
   - require authorization for template editing and preview;
   - keep untrusted templates in a sandbox with a minimal policy;
   - do not expose service containers, secrets, request/session objects, or
     privileged domain objects in template context;
   - separate trusted developer templates from tenant or admin-authored
     templates;
   - log template changes without logging sensitive rendered data.
8. Add safe regression coverage:
   - dependency policy rejects `twig/twig >=3.15.0, <3.26.0`;
   - user-controlled template rendering uses the sandboxed environment;
   - compiled template cache is cleared by deployment scripts or documented
     operator actions;
   - no test renders exploit payloads or executes PHP.
9. Add a PR body section named `CVE-2026-46640 operator actions` that states:
   - Twig versions before and after;
   - whether user-controlled Twig source exists and where;
   - whether sandboxing is global, source-policy based, or disabled;
   - which compiled template caches, workers, and images must be cleared or
     restarted;
   - whether untrusted template authors could access the vulnerable runtime;
   - whether secret rotation, audit-log review, or template rollback is needed;
   - which validation commands passed.
10. Run available validation: Composer install/check-platform-reqs, lockfile
    integrity, unit/feature tests, template-rendering tests with benign local
    fixtures, static analysis, lint, deployment rendering, image build, SBOM
    refresh, and dependency/security scans.
11. Use PR title:
    `fix(sec): remediate CVE-2026-46640 in Twig`.

## Stop conditions

- No affected Twig package, user-controlled template source, compiled cache, or
  deployment artifact is controlled by this repository.
- The Twig runtime is supplied by another application or platform owner; name
  the owner and required fixed version in `TRIAGE.md`.
- Upgrading Twig requires a broader PHP/framework migration or maintenance
  window the agent cannot schedule.
- Verification would require rendering exploit templates, injecting PHP,
  dumping template contexts, touching live customer 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 >=3.15.0, <3.26.0.
  • User-controlled Twig rendering is inventoried and either sandboxed, disabled, or documented as non-exposed with evidence.
  • Compiled Twig cache clearing and worker restarts are part of the deployment or operator notes.
  • Regression tests prove the fixed version and benign sandboxed rendering path without executing injected PHP.
  • PR notes cover template-author trust, context exposure, cache cleanup, and secret rotation criteria.

Watch for

  • Updating composer.json while composer.lock, container layers, SBOMs, or production images still install the vulnerable Twig version.
  • Assuming Twig sandboxing protects vulnerable versions from this CVE.
  • Forgetting compiled template caches or long-lived workers after a package upgrade.
  • Treating admin-authored CMS/email/theme templates as trusted when lower privilege users, tenants, support staff, or integrations can modify them.
  • Tests that only render committed templates and never exercise the user-controlled template path.

Output contract

Return one of:

  • A reviewer-ready PR/change request that upgrades twig/twig to 3.26.0+ or preferably 3.27.0+, clears compiled template artifacts, hardens user-controlled template rendering, adds safe dependency and sandbox tests, refreshes generated artifacts, and documents operator cleanup.
  • TRIAGE.md when no controlled affected Twig runtime, user-controlled template source, compiled cache, or deployment artifact exists.

The output must list Twig versions before/after, user-controlled template surfaces, sandbox/context policy, cache and worker restart actions, validation commands, and secret-rotation or log-review criteria. It must not render exploit templates, inject PHP, dump template contexts, expose generated PHP with sensitive data, or touch live customer templates.

References