Did you know a simple contact message could give an attacker full control of your back-office? A stored XSS vulnerability (CVE-2026-44212, CVSS 9.3) has been detected, affecting versions prior to 8.2.6 and 9.1.1. Don't do anything without reading this.
📄 Affected Files and Step-by-Step Manual Patch
At EasyPresta, we like to get straight to the point. If your store isn't updated to the secure versions yet, you can apply a manual patch today. It won't take you more than 5 minutes.
🎯 What vulnerability was discovered?
An attacker can send a message through your store's contact form with an "email" field containing malicious HTML/JS code. This message is stored in the database. When you (or your team) open the thread in the Customer Service section of the back-office, the code executes automatically. The attacker then takes control of your administration panel. They can install modules, modify prices, steal customer data... It's a disaster.
📁 Affected Files (according to the official PrestaShop patch)
The PrestaShop team has corrected the issue in two files:
{admin_folder}/themes/default/template/controllers/customer_threads/helpers/view/view.tpl– Here, the customer's email was displayed without escaping.classes/Validate.php– Email validation at the source has been reinforced to prevent malicious addresses from being stored.
You can see the exact changes in GitHub Pull Request #41342: https://github.com/PrestaShop/PrestaShop/pull/41342/changes
🛠️ How to manually patch your store
Step 1 – Edit view.tpl
Locate the lines where {$thread->email} appears. There are usually two:
- One inside an
<h3> - Another inside an
<input type="hidden">
Change both from:
{$thread->email}
to:
{$thread->email|escape:'html':'UTF-8'}
Step 2 – Edit classes/Validate.php
The necessary modification in this file depends on the version of PrestaShop you have installed. Patching a PrestaShop 1.6, 1.7, 8.0.x, or 8.1.x is not the same. Below, we show you the solutions by version. Find yours and apply the corresponding change:
PrestaShop 1.7.0 – 1.7.6.4 (Validate-1_7.php / Validate-1_7_6_5.php)
These two branches receive an identical patch. The root cause of the vulnerability is the use of a regex with the $ anchor without the D modifier. In PHP, $ without /D accepts an optional line break at the end of the string, so an email like passed validation. This allows email header injection: an attacker can inject additional SMTP headers (Bcc:, Subject:…) into any transactional email the store sends using that field. The patch replaces the regex with three chained checks:
BEFORE (vulnerable code):
public static function isEmail($email)
{
return preg_match('/^[a-z0-9!#$%&\'*+\/=?^`{}|~.-]+@[a-z0-9.-]+$/i', $email);
// ↑ accepts \n at the end
}
AFTER (Validate-1_7.php patched):
public static function isEmail($email)
{
if (empty($email)) {
return false;
}
// RFC 5321: maximum 254 characters per address
if (strlen($email) > 254) {
return false;
}
// Explicitly block CR, LF, and TAB which allow header injection
if (preg_match('/[\r\n\t]/', $email)) {
return false;
}
// Double validation: PHP built-in + SwiftMailer RFC grammar
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false && Swift_Validate::email($email);
}
The two final validators are applied in series: filter_var rejects clearly invalid formats at minimal cost, and Swift_Validate::email() applies the complete RFC 5321 grammatical analysis before SwiftMailer uses the address to build the To: header.
Required dependency: swiftmailer/swiftmailer, which is already part of the PrestaShop 1.7 core.
PrestaShop 1.7.6.5 – 1.7.8.x (Validate-1_7_8.php)
In the 1.7.8 branch, PrestaShop already incorporates Symfony and the egulias/email-validator library. The patch takes advantage of these components to replace the previous double validation with a more expressive triple layer, although without yet activating Symfony's strict mode.
AFTER (Validate-1_7_8.php patched):
public static function isEmail($email)
{
if (empty($email)) {
return false;
}
// Layer 1: Symfony Email constraint (lax mode)
$validator = Validation::createValidator();
$errors = $validator->validate($email, new Email());
if (count($errors) > 0) {
return false;
}
// Layers 2 and 3: RFC 5322 + SwiftMailer compatibility
return !empty($email) && (new EmailValidator())->isValid($email, new MultipleValidationWithAnd([
new RFCValidation(),
new SwiftMailerValidation(),
]));
}
The three layers have distinct responsibilities:
- Symfony - RFCValidation: Compliance with RFC 5321/5322 via the
egulias/email-validatorparser; detects syntactically valid but problematic formats in production. - SwiftMailerValidation: Guarantees the address can be used without injection risk within the sending engine.
Required dependencies: egulias/email-validator ^2.0 and symfony/validator, both already in the composer.json of 1.7.8.
PrestaShop 8.0 – 8.1.x (Validate-8_1.php)
Same structure as 1.7.8, but with an important change: Symfony's validator strict mode is activated, which applies the complete RFC 5322 grammar instead of the usual subset. This rejects variants such as addresses with comments (user(comment)@example.com) or with IP literals (user@[192.0.2.1]) that are syntactically valid according to the RFC but inappropriate in an e-commerce context. The redundant !empty($email) check in the return is also eliminated, as the guard at the beginning of the method makes it unnecessary.
AFTER (Validate-8_1.php patched):
public static function isEmail($email)
{
if (empty($email)) {
return false;
}
$validator = Validation::createValidator();
$errors = $validator->validate($email, new Email([
'mode' => 'strict', // ← new compared to 1.7.8
]));
if (count($errors) > 0) {
return false;
}
// Check if the value is correct according to both validators (RFC & SwiftMailer)
return (new EmailValidator())->isValid($email, new MultipleValidationWithAnd([
new RFCValidation(),
new SwiftMailerValidation(),
]));
}
Required dependencies: egulias/email-validator ^3.0 (the 8.x branch upgraded the major version compared to 1.7.8) and symfony/validator ^5.4.
PrestaShop 8.2.5 and PrestaShop 9.1.0
If your store runs 8.2.5 or PrestaShop 9.1.0, simply update to the latest available version of your branch (8.2.6 and 9.1.1 respectively) to keep your store secure.
Step 3 – Clear cache and verify
- Clear the PrestaShop cache (from the back-office or manually in
/var/cache). - Test that the email still displays correctly in the Customer Service section (without strange characters).
How to patch your PrestaShop 1.6.x store (old versions)
Important: This version no longer receives official support. If you are still using PrestaShop 1.6, we strongly recommend migrating to a modern version. In the meantime, apply these manual patches.
Step 1 – Edit message.tpl
Locate the file: {admin_folder}/themes/default/template/controllers/customer_threads/message.tpl
Find the ocurrences of {$message.email} (usually about 5 ocurrences) and replace them with:
{$message.email|escape:'html':'UTF-8'}
Step 2 – Edit classes/Validate.php
Modify the isEmail() method
to strengthen validation and prevent header injection.
Original code (vulnerable):
public static function isEmail($email)
{
return !empty($email) && preg_match(Tools::cleanNonUnicodeSupport('/^[a-z\p{L}0-9!#$%&\'*+\/=?^`{}|~_-]+[.a-z\p{L}0-9!#$%&\'*+\/=?^`{}|~_-]*@[a-z\p{L}0-9]+(?:[.]?[_a-z\p{L}0-9-])*\.[a-z\p{L}0-9]+$/ui'), $email);
}
Patched code (secure):
public static function isEmail($email)
{
if (empty($email) || strlen($email) > 254) {
return false;
}
if (preg_match('/[\r\n\t]/', $email)) {
return false;
}
return (bool)preg_match(Tools::cleanNonUnicodeSupport('/^[a-z\p{L}0-9!#$%&\'*+\/=?^`{}|~_-]+[.a-z\p{L}0-9!#$%&\'*+\/=?^`{}|~_-]*@[a-z\p{L}0-9]+(?:[.]?[_a-z\p{L}0-9-])*\.[a-z\p{L}0-9]+$/ui'), $email);
}
Step 3 – Clear cache and verify
- Clear the PrestaShop cache.
- Test that the email still displays correctly in the Customer Service section (without strange characters).
🔁 What if you don't want to touch code?
You can install the official hotfix module published by PrestaShop (search for "PrestaShop security patch" on their addons). Or directly update to version 8.2.6 (branch 8.2.x) or 9.1.1 (branch 9.1.x). We recommend a full update whenever possible, but if you need a quick patch, the previous steps are completely valid.
✅ In summary
Protect your store NOW. If you're in a hurry, apply the two manual changes we've indicated. If you prefer to delegate, contact us at EasyPresta and we'll do it for you.
Questions? Leave a comment or write to us directly.
Official references: INCIBE Advisory | GitHub Advisory