Twig is your injection surface: four template-injection advisories in 14 days
I almost scrolled past the first one. "Moderately critical," needs an editor account — I shrugged and closed the tab. Then a second landed, then two more, and by the time I looked up it was four contrib advisories in fourteen days, all the same bug underneath: a string a user controls getting evaluated as a Twig or token template. That's worth stopping for, not because my little VPS is on fire, but because the pattern is a lesson.
The four
Between 23 September and 7 October 2026, on drupal.org:
- Webform — SA-CONTRIB-2026-175, Critical (18/25), CVE-2026-96355. It "doesn't adequately exclude certain format templates from token replacement," so submitted data can be evaluated as template code when a submission is rendered. Impact runs from info disclosure to stored XSS to RCE depending on config. The precondition: a webform with a custom multiple-value item format that includes submission-value tokens. Affected below 6.2.12, and 6.3.0 up to 6.3.1; fixed in 6.2.12 and 6.3.1. Reported by Michael Maturi, fixed by Jacob Rockowitz and Liam Morland.
- AI CKEditor — SA-CONTRIB-2026-187, Moderately critical (10/25), CVE-2026-96392. Below 1.4.3, default config exploitable, needs a user-level account. (The title says "code execution" but the scored impact is only partial confidentiality — the advisory doesn't reconcile that, so I won't either.)
- Linked Field — SA-CONTRIB-2026-200 (14/25), CVE-2026-107259. Field content isn't separated from template code; depending on which Twig extensions are installed, an attacker can read config values like API keys. Needs a role that can create or edit content where the formatter is enabled. Fixed in 1.8.0.
- Inline Formatter Field — SA-CONTRIB-2026-203 (13/25), CVE-2026-107264. Users can render protected data or run unsafe Twig; default config exploitable, a config change disables it. Fixed in 4.2.0.
Same two batches also carried SA-CONTRIB-2026-192 (Block AJAX, Highly critical 20/25, unauthenticated PHP object injection — but only where Layout Builder or another plugin hands the data to something unsafe; fixed 3.0.2) and a Project Browser CSRF. And ECA Helper got two advisories marked "Unsupported (known unfixed issue)" — a reminder that an advisory sometimes means "stop using this," not "update."
Why these keep happening
The common thread is a feature, not a mistake: letting an editor supply a template. Format strings, field formatters that render Twig, token replacement over user data — they're all "let a trusted user write a tiny program." The moment that user is one notch less trusted than you assumed, template code is a confused deputy with your filesystem and config behind it. Drupal's own engine makes the sharp edge easy to hit: TwigEnvironment::renderInline() wraps its output in Markup::create(), so the result isn't auto-escaped. (The unescaped-output point is my read of the code, not a line in the docstring — the docstring only warns about keeping templates static for PHPStorage. Verify before you lean on it.)
What's a little dispiriting is watching the AI-assisted contrib land copy the old mistake. AI CKEditor is new-generation tooling reaching for the same "render this string as a template" move that burned us a decade ago. The lesson didn't transfer.
Every one of these is scored moderate-to-high because it needs an editor-level account. That's exactly why they're dangerous: they turn "a content editor" into "someone who can read your API keys," and most of us hand out editor accounts like business cards.
The core hook, while you're in here
Drupal pre-announced a critical core release for 14 Oct 2026, 16:00–21:00 UTC — PSA-2026-10-12, scored 19/25, affecting 11.4.x, 11.3.x, 10.6.x and 12.0.0-beta1. Exploit maturity is "theoretical," but the Security Team's own advice is the useful bit: update to the latest patch release before the window, so any upgrade breakage surfaces on your schedule instead of during an emergency.
What I actually did on my VPS
Fifteen minutes, mostly waiting on cache rebuilds:
- Ran
composer auditto see what my lockfile admits to. - Grepped for the risky surface:
grep -rIl "renderInline\|inline_template\|createTemplate\|twig_tweak" web/modules web/themes. It turned up about ten files, mostly benign staticinline_templateuses — but "mostly" is doing work there; I haven't audited each one, and I'm not telling you yours are safe either. The point of the grep is to know your surface, not to bless it. - Put the 14 Oct window in the calendar and patched contrib to current before then.
None of my four were installed, which is the honest anticlimax. But the grep is the habit worth keeping: the next template-injection advisory will be for a module you do run, and you want to already know where in your tree a string becomes a program.