CVE-2026-22849 Overview
CVE-2026-22849 is a stored Cross-Site Scripting (XSS) vulnerability affecting Saleor, an open-source e-commerce platform. The vulnerability exists because Saleor allows users to modify rich text fields with HTML content without proper backend sanitization. This lack of input validation enables malicious actors to inject arbitrary scripts that persist in the application and execute when other users view the affected content.
The vulnerability is particularly concerning in e-commerce environments where both administrative dashboards and customer-facing storefronts can be targeted. Malicious staff members with access to content editing features can craft script injections to compromise other staff members' sessions, potentially stealing access tokens and refresh tokens used for authentication.
Critical Impact
Stored XSS attacks can lead to session hijacking, credential theft, and unauthorized access to administrative functions in Saleor e-commerce deployments.
Affected Products
- Saleor versions 3.0.0 through 3.20.107 (prior to 3.20.108)
- Saleor versions 3.21.0 through 3.21.42 (prior to 3.21.43)
- Saleor versions 3.22.0 through 3.22.26 (prior to 3.22.27)
Discovery Timeline
- January 21, 2026 - CVE-2026-22849 published to NVD
- January 21, 2026 - Last updated in NVD database
Technical Details for CVE-2026-22849
Vulnerability Analysis
This vulnerability falls under CWE-83 (Improper Neutralization of Script in Attributes in a Web Page), a specific type of stored XSS vulnerability. The root issue stems from Saleor's rich text editor implementation, which accepts HTML content from users but fails to sanitize it through backend HTML cleaners before storing or rendering the content.
In an e-commerce context, rich text fields are commonly used for product descriptions, category content, page content, and various marketing materials. When these fields accept unsanitized HTML, any user with content editing privileges can embed malicious JavaScript that will execute in the browsers of subsequent visitors.
The attack surface includes both the administrative dashboard (affecting staff members and administrators) and the public storefront (potentially affecting customers). The most critical exploitation scenario involves a malicious insider or compromised staff account targeting other privileged users to escalate access or exfiltrate sensitive authentication tokens.
Root Cause
The vulnerability originates from missing backend HTML sanitization in Saleor's rich text field processing. Prior to the patch, the application relied solely on client-side validation (if any) without implementing server-side HTML cleaning. This architectural flaw allowed raw HTML, including <script> tags and event handlers, to be stored in the database and served to other users without modification.
The fix introduces the nh3 library (a Python binding for the Ammonia HTML sanitizer written in Rust) to perform proper server-side HTML cleaning with configurable allowed schemes, attributes, and attribute values.
Attack Vector
The attack is network-based and requires the attacker to have authenticated access with privileges to modify rich text content (such as product descriptions or page content). Once malicious content is injected, any user who views the affected page will have the script execute in their browser context.
A typical attack flow involves:
- Attacker gains access to Saleor dashboard with content editing privileges
- Attacker injects malicious JavaScript into a rich text field
- Victim (another staff member or customer) views the page containing the injected content
- Malicious script executes, potentially stealing session tokens or performing actions on behalf of the victim
The following code shows the security patch that introduces the nh3 HTML sanitization library:
opentelemetry-api = "^1.32.1"
opentelemetry-sdk = "^1.32.1"
opentelemetry-semantic-conventions = "^0.53b1"
+ nh3 = "^0.3.2"
+ idna = "^3.11"
[tool.poetry.dependencies.kombu]
extras = [ "sqs" ]
Source: Saleor Commit 1085c78
The patch also introduces a comprehensive HTML cleaner module with configurable security settings:
+import json
+import os
+import warnings
+from copy import deepcopy
+from dataclasses import dataclass, field
+from typing import Self
+
+import nh3
+
+from ..deprecations import SaleorDeprecationWarning
+
+
+@dataclass
+class HtmlCleanerSettings:
+ allowed_schemes: set[str] = field(default_factory=set)
+ allowed_attributes: dict[str, set[str]] = field(
+ default_factory=lambda: deepcopy(nh3.ALLOWED_ATTRIBUTES)
+ )
+
+ # NOTE: nh3 doesn't expose the default values, however it's OK as
+ # the default value is empty https://github.com/rust-ammonia/ammonia/blob/6d803b5677006947da7d2f495dbae83090db4909/src/lib.rs#L447
+ allowed_attribute_values: dict[str, dict[str, set[str]]] = field(
+ default_factory=dict
+ )
+
+ # Configures the 'rel' attribute that will be added on links. `None` disables it.
+ #
+ # Recommended value: 'noopener noreferrer'
+ #
+ # - noopener: This prevents a particular type of XSS attack, and should usually be turned on for untrusted HTML.
Source: Saleor Commit 1085c78
Detection Methods for CVE-2026-22849
Indicators of Compromise
- Presence of <script> tags or JavaScript event handlers (e.g., onerror, onload, onclick) in database fields storing rich text content
- Unusual outbound network requests from user browsers when viewing product pages or dashboard content
- Unexpected authentication token activity or session anomalies following content viewing
- Modified rich text content containing encoded JavaScript or obfuscated payloads
Detection Strategies
- Implement Content Security Policy (CSP) headers to detect and block unauthorized inline script execution
- Deploy web application firewalls (WAF) with XSS detection rules to identify malicious payloads in HTTP requests
- Conduct regular database audits scanning rich text fields for suspicious HTML patterns and script content
- Monitor authentication logs for unusual token refresh patterns or session hijacking indicators
Monitoring Recommendations
- Enable detailed logging for all rich text field modifications with user attribution and timestamp tracking
- Configure browser-side XSS auditors where available and monitor CSP violation reports
- Implement real-time alerting for database modifications containing potentially malicious HTML patterns
- Review access logs for the Saleor dashboard to identify suspicious content editing activity
How to Mitigate CVE-2026-22849
Immediate Actions Required
- Upgrade Saleor to patched versions: 3.22.27, 3.21.43, or 3.20.108 depending on your current version branch
- Audit existing rich text content in the database for any malicious scripts or unauthorized HTML
- Review dashboard access logs to identify any suspicious content modifications
- Rotate authentication tokens for staff accounts if compromise is suspected
Patch Information
Saleor has released security patches across multiple supported version branches. Organizations should upgrade to one of the following patched versions:
| Version Branch | Patched Version |
|---|---|
| 3.22.x | 3.22.27 |
| 3.21.x | 3.21.43 |
| 3.20.x | 3.20.108 |
The patches introduce the nh3 library for robust server-side HTML sanitization. Multiple commits address different aspects of the fix, including URL cleaning and proper attribute validation. For detailed technical information, refer to the Saleor Security Advisory GHSA-8jcj-r5g2-qrpv.
Workarounds
- Implement a client-side HTML sanitizer (such as DOMPurify) as a temporary measure until backend patches can be applied
- Restrict rich text editing privileges to trusted staff members only
- Deploy Content Security Policy headers to mitigate the impact of any stored XSS payloads
- Consider placing a reverse proxy or WAF in front of Saleor to filter malicious HTML in requests
# Example: Implementing CSP headers in nginx for Saleor
# Add to nginx server configuration
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self'; frame-ancestors 'self';" always;
# For additional XSS protection
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

