CVE-2026-52889 Overview
CVE-2026-52889 is a server-side template injection (SSTI) vulnerability in Formie, a Craft CMS plugin for creating forms. Versions prior to 3.1.27 pass request-derived Hidden field defaults such as HTTP User-Agent, Referer URL, Current URL, Query Parameters, and Cookie Values directly to Craft's Twig rendering layer during front-end form rendering. An unauthenticated attacker can inject Twig syntax into any of these request-controlled inputs when a public form contains an affected Hidden field. The Hidden::getFrontEndInputOptions() method assigns the attacker-controlled value to defaultValue and calls renderString, triggering server-side template evaluation. The issue is fixed in version 3.1.27 and tracked under [CWE-1336].
Critical Impact
Unauthenticated remote attackers can achieve information disclosure, application state modification, or remote code execution via Twig template injection through common HTTP request headers.
Affected Products
- Formie plugin for Craft CMS (all versions prior to 3.1.27)
- Craft CMS sites publishing front-end forms with Hidden fields configured to request-derived defaults
- Publicly accessible Craft CMS deployments using Formie for form rendering
Discovery Timeline
- 2026-08-19 - CVE-2026-52889 published to NVD
- 2026-08-19 - Last updated in NVD database
- Fixed version released - Formie 3.1.27 published on GitHub
Technical Details for CVE-2026-52889
Vulnerability Analysis
The vulnerability resides in the Hidden field implementation of the Formie plugin. When a form containing a Hidden field is rendered on the front end, Formie retrieves the field's configured default value and passes it through Craft's Twig renderString function. This behavior is intended to support dynamic default values authored by trusted site administrators. However, Formie also supports request-derived defaults, including HTTP User-Agent, Referer URL, Current URL, Current URL without Query String, Query Parameter, and Cookie Value. These attacker-controlled inputs flow into the same Twig rendering path without sanitization or output-mode restriction.
An unauthenticated attacker submits a request containing Twig syntax such as {{ 7*7 }} or more advanced payloads inside a targeted header or cookie. Formie captures the value, assigns it to defaultValue, and hands it to the Twig engine. The engine evaluates the payload in the site template mode, granting access to Twig filters, functions, and object graph traversal available to the Craft installation.
Root Cause
The root cause is unsafe evaluation of untrusted input as a template expression. The getFrontEndInputOptions() method unconditionally called renderString on the raw default value, regardless of whether the value originated from an administrator-defined static string or from a request header. This corresponds to CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine.
Attack Vector
Exploitation requires only a public form on the target Craft CMS site containing a Hidden field configured to use one of the request-derived default sources. The attacker sends an HTTP GET or POST request to the form page with a crafted header, cookie, or query parameter containing Twig syntax. The payload is evaluated server-side during page render, and its output may be reflected in the rendered form or executed silently depending on the payload.
public function getFrontEndInputOptions(Form $form, mixed $value, array $renderOptions = []): array
{
$inputOptions = parent::getFrontEndInputOptions($form, $value, $renderOptions);
+ $defaultValue = (string)$this->defaultValue;
- try {
- $defaultValue = Craft::$app->getView()->renderString(
- (string)$this->defaultValue,
- [
- 'field' => $this,
- 'form' => $form,
- ],
- View::TEMPLATE_MODE_SITE
- );
- } catch (Throwable $e) {
- $defaultValue = $this->defaultValue;
- Formie::error('Failed to render hidden field template: ' . $e->getMessage());
+ if ($this->defaultOption === 'custom') {
+ try {
+ $defaultValue = Craft::$app->getView()->renderString(
+ $defaultValue,
+ [
+ 'field' => $this,
+ 'form' => $form,
+ ],
+ View::TEMPLATE_MODE_SITE
+ );
+ } catch (Throwable $e) {
+ $defaultValue = (string)$this->defaultValue;
+ Formie::error('Failed to render hidden field template: ' . $e->getMessage());
Source: GitHub Commit d3b9d15. The patch restricts Twig rendering to Hidden fields where defaultOption equals custom, preventing request-derived values from reaching the template engine.
Detection Methods for CVE-2026-52889
Indicators of Compromise
- HTTP requests to Craft CMS pages containing Twig delimiters such as {{, }}, {%, or %} inside User-Agent, Referer, Cookie, or query string values.
- Unusual PHP process activity or child process spawns originating from the Craft CMS web application immediately after form page requests.
- Web server logs showing repeated requests to pages hosting Formie forms with anomalous header content.
- Errors in Formie logs referencing Failed to render hidden field template on unpatched installations.
Detection Strategies
- Inspect web access logs for Twig syntax patterns in request headers, cookies, and query parameters targeting URLs that render Formie forms.
- Correlate outbound network activity from the web server against inbound requests containing template metacharacters.
- Deploy web application firewall rules to flag {{, }}, and {% ... %} sequences in HTTP headers where they should never appear.
Monitoring Recommendations
- Monitor Craft CMS and Formie log files for template rendering errors following external requests.
- Track process-tree telemetry on web servers hosting Craft CMS for unexpected sh, bash, php, or file-write activity.
- Alert on new outbound connections from the Craft CMS host to unknown external endpoints during form page requests.
How to Mitigate CVE-2026-52889
Immediate Actions Required
- Upgrade the Formie plugin to version 3.1.27 or later immediately using Composer: composer require verbb/formie:^3.1.27.
- Audit all Craft CMS forms for Hidden fields configured with request-derived default sources (User-Agent, Referer, Current URL, Query Parameter, Cookie Value).
- Review web server and application logs for prior exploitation attempts containing Twig syntax in request headers or cookies.
Patch Information
The issue is fixed in Formie 3.1.27. The patch in commit d3b9d15290405e484e3b5c91c5d8fab93047f9b2 gates Twig rendering behind an explicit defaultOption === 'custom' check, so request-derived default sources bypass the template engine entirely. Details are published in GitHub Security Advisory GHSA-565m-g33j-jq96 and Formie Release 3.1.27.
Workarounds
- If upgrading is not immediately possible, remove or disable Hidden fields on public forms that use request-derived default value sources.
- Reconfigure affected Hidden fields to use static values or custom Twig defaults authored by trusted administrators only.
- Deploy WAF rules that block requests containing Twig delimiters in User-Agent, Referer, and Cookie headers targeting form pages.
# Upgrade Formie to the patched version
composer require verbb/formie:^3.1.27
php craft migrate/all
php craft clear-caches/all
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

