Automated Threat Modeling

PrestaShop CVE-2026-44212: Stored XSS to Back Office Takeover via Contact Form — Technical Breakdown with PoC and Detection Guidance

CVE-2026-44212 is a critical stored XSS in PrestaShop's back office Customer Service view that lets unauthenticated attackers hijack admin sessions. Covers the proof of concept, patch analysis, and detection methods.

CVE Analysis

10 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-05-14

PrestaShop CVE-2026-44212: Stored XSS to Back Office Takeover via Contact Form — Technical Breakdown with PoC and Detection Guidance
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A single malicious email address, submitted through a public contact form by an unauthenticated visitor, can give an attacker full administrative control over a PrestaShop store. CVE-2026-44212 is a stored Cross-Site Scripting vulnerability (CVSS 9.3) in PrestaShop's back office Customer Service view. It chains a permissive email validator with missing output escaping to hijack a session the moment a support employee opens the ticket.

PrestaShop is an open source e-commerce platform running on roughly 174,766 live websites, which is 0.7 percent of all websites with a known CMS and 3.0 percent of all e-commerce systems according to W3Techs and BuiltWith. With that much adoption across small and mid-sized merchants, the exposure is ecosystem-scale.

Technical Information

Root Cause

Two factors combine to create a clean exploitation path:

1. Permissive email validation. PrestaShop's Validate::isEmail() method in classes/Validate.php used Symfony's Email validation constraint configured in 'loose' mode. This mode accepts RFC 5321 quoted-string local parts, so an email address like "payload"@domain.com passes validation. Loose mode does minimal format checking, which let structurally unusual strings containing embedded event handlers pass and get stored in the database.

2. Missing output escaping in the Smarty template. The back office template at admin-dev/themes/default/template/controllers/customer_threads/helpers/view/view.tpl renders {$thread->email} without the |escape:'html':'UTF-8' modifier in two locations (around lines 96 and 117). Adjacent variables like $customer->firstname and $customer->lastname already had the escape modifier applied. The email field was the only variable left unprotected, a classic template oversight.

The email value is rendered directly into HTML attribute contexts (value="..."). A double-quote character in the email breaks out of the attribute boundary, which enables HTML attribute injection.

Why strip_tags() Does Not Help

The email address passes through strip_tags() before storage, which removes angle brackets. But the exploit payload uses only double-quote characters and plain ASCII text, with no angle brackets at all. The strip_tags() call has no effect on it.

Attack Flow

  1. The attacker visits the target store's public /contact-us page.
  2. They submit the contact form with a crafted email address containing an XSS payload built entirely from double quotes and event handler attributes (no angle brackets needed).
  3. PrestaShop's isEmail() validator, running in 'loose' mode, accepts the RFC 5321 quoted-string email address.
  4. The strip_tags() function processes the email but leaves it unchanged because it contains no angle brackets.
  5. The payload is stored in the ps_customer_thread table in the database.
  6. When any back office employee navigates to the Customer Service section and opens the affected thread, the Smarty template renders the raw email value inside value="..." attribute contexts.
  7. The double-quote in the email breaks out of the attribute, and the injected event handler (e.g., onfocus) executes JavaScript in the employee's browser session.
  8. The attacker's JavaScript can exfiltrate the admin's session cookie, enabling full back office takeover.

The CVSS 3.1 vector is CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N. The only friction is user interaction: an employee must open the customer thread. Since reviewing support tickets is a routine daily task, that requirement offers little real world protection.

Proof of Concept

Hadrian.io published a public proof of concept on May 12, 2026.

Exploit Payload

The following email address payload survives all three gates (validation, strip_tags(), database storage):

" autofocus onfocus=alert(document.cookie) x="@xss.com

This payload uses only " and plain ASCII text. There are no angle brackets, so strip_tags() passes it through unchanged. When an admin opens the affected customer thread, the onfocus event handler fires alert(document.cookie), which demonstrates session cookie theft.

Full Chain Scenario

An unauthenticated attacker submits the Contact Us form with the crafted email. The XSS payload is stored in the database and fires when any back office employee opens the Customer Service thread, which enables session hijacking and full administrative takeover via the stolen session cookie.

Nuclei Template for Detection

Hadrian also published a Nuclei template to detect vulnerable instances. The detection submits an RFC 5321 quoted-string email (a benign probe value) to the contact form endpoint. Vulnerable instances, using Symfony's loose email validation mode, accept it and return a success message. Patched versions, using strict mode, reject it with "Invalid email address."

The form submission uses the following body parameters:

id_contact=1&from="cve-2026-44212-probe"@xss-probe.invalid&message=security+probe&token={{token}}&submitMessage=Send&url=

Invocation:

nuclei -t cve-2026-44212.yaml -u http://TARGET -H "Host: TARGET_HOSTNAME"

Sample output:

[cve-2026-44212] [http] [critical] http://172.18.0.3/contact-us

Note: this template was not yet included in the official projectdiscovery/nuclei-templates repository as of May 14, 2026, but the Hadrian blog provides a full template description for custom deployment.

Patch Information

The PrestaShop team addressed CVE-2026-44212 with a two-part fix, shipped in versions 8.2.6 (commit 1312be7) and 9.1.1 (commit 74791ff). Matthieu Rolland authored both commits.

1. Template Output Escaping (view.tpl)

The |escape:'html':'UTF-8' modifier was added to both occurrences of {$thread->email} in the Smarty template:

Display context (heading area):

- {l s="Your answer to" d='Admin.Orderscustomers.Feature'} {if isset($customer->firstname)}{$customer->firstname|escape:'html':'UTF-8'} {$customer->lastname|escape:'html':'UTF-8'} {else} {$thread->email}{/if} + {l s="Your answer to" d='Admin.Orderscustomers.Feature'} {if isset($customer->firstname)}{$customer->firstname|escape:'html':'UTF-8'} {$customer->lastname|escape:'html':'UTF-8'} {else} {$thread->email|escape:'html':'UTF-8'}{/if}

Hidden form input:

- <input type="hidden" name="msg_email" value="{$thread->email}" /> + <input type="hidden" name="msg_email" value="{$thread->email|escape:'html':'UTF-8'}" />

2. Stricter Email Validation (Validate.php)

The Symfony email validation mode was changed from permissive to strict:

$validator = Validation::createValidator(); $errors = $validator->validate($email, new Email([ - 'mode' => 'loose', + 'mode' => 'strict', ]));

Strict mode rejects RFC 5321 quoted-string addresses entirely, which stops the malicious email before it reaches the database. This acts as defense in depth: even if the output escaping were somehow bypassed, the payload is rejected at the point of entry.

Together, the patch applies the classic secure coding principle of validate input, escape output.

Hotfix Module

For organizations that cannot upgrade right away, PrestaShop published the official hotfix module pshotfix_ghsaw9f3qc75qgx9, which supports PrestaShop 1.7, 8.x, and 9.x. You can install the module from the command line or upload it through the Module Manager.

Detection Methods

Web Server Log Analysis

The attack needs a POST request to the /contact-us endpoint with a from= parameter containing URL-encoded double-quote characters (%22). Legitimate customer emails submitted through contact forms almost never contain double quotes. The Hadrian blog describes a Sigma-style rule sketch for webserver logs. It selects on cs-method: POST to a URI stem containing /contact-us where the query string includes both from= and URL-encoded " characters, then applies a regex for standard email address patterns as a negative condition, so only non-standard email submissions raise alerts. Security teams can adapt this logic to their SIEM of choice (Splunk, Elastic, Sentinel, etc.).

Database Integrity Check

Because this is a stored XSS, malicious payloads stay in the database even after the initial HTTP request has been logged and rotated. Defenders should query PrestaShop's ps_customer_thread table for email entries that begin with a double-quote character (") or contain spaces, ordered by date_add DESC. As Hadrian notes, "RFC 5321 quoted strings are vanishingly rare in legitimate e-commerce traffic." If your store has been running a vulnerable version, this retroactive database scan matters for finding payloads that may already be sitting dormant.

Version-Based Detection

All PrestaShop versions before 8.2.6 and versions 9.0.0 through 9.1.0 are affected. Dependency scanning tools like GitLab Dependency Scanning, Snyk, and Dependabot have already indexed this vulnerability and will flag affected prestashop/prestashop Composer packages. The simplest way to check your exposure is the PrestaShop version, via Composer (composer show prestashop/prestashop) or the back office admin panel.

Key Indicators of Compromise

Based on the Hadrian blog's analysis, defenders should watch for:

  • POST requests to /contact-us containing %22 (URL-encoded double quote) in the from parameter
  • Email values in ps_customer_thread database rows that start with " or contain spaces
  • HTML event handler keywords (onfocus, autofocus, onmouseover, etc.) embedded within email address fields in customer threads
  • Anomalous admin session activity right after a customer service thread is opened, which can indicate session hijacking after XSS execution

No official IDS/IPS signatures (e.g., Snort or Suricata rules) or YARA rules have been published for this CVE yet.

Affected Systems and Versions

BranchAffected RangeFixed VersionHotfix Module Support
1.7.xMultiple 1.7 releasesNo core fix notedYes
8.xAll versions prior to 8.2.68.2.6Yes
9.xVersions 9.0.0 through 9.1.09.1.1Yes

The vulnerability affects any PrestaShop deployment where the back office Customer Service view is accessible to employees and the public Contact Us form is enabled, which is the default configuration.

Vendor Security History

PrestaShop's response was well coordinated: simultaneous security releases for both the 8.x and 9.x branches, plus a dedicated hotfix module covering legacy 1.7.x installations. Covering three major version families with both core patches and a standalone module points to a mature incident response process. Savio from Doyensec responsibly disclosed the vulnerability in collaboration with Anthropic Research.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization