☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
[ VENDOR STATS ]
CVSS: 4.3 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N 🐛 CWE-80
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-54503

CVE-2026-54503 Vulnerability in Plone
📅 PUBLISHED: 2026-09-15 00:00 UTC 🔄 UPDATED: 2026-09-22 10:15 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix
[ DEFENSE PATCH ↓ ]
💣 PoC: Public
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.23%
👁️
0.23% probability
5.8× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1189
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS VECTOR BREAKDOWN 4.3
AV: N Attack Vector Network
AC: L Attack Complexity Low
PR: L Privileges Required Low
UI: N User Interaction None
S: U Scope Unchanged
C: L Confidentiality Low
I: N Integrity None
A: N Availability None
4.3
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-54503 is a stored cross-site scripting (XSS) vulnerability in plone.app.textfield, the library supplying the RichText field type used across Plone content types and the Plone REST API. Prior to versions 2.0.2, 3.0.2, and 4.0.1 (depending on the release line), RichTextValue.output returns an unsanitized stored value when the value's MIME type equals the configured outputMimeType, bypassing the safe_html transform. An authenticated user able to set a RichText field can store JavaScript that executes in the browser of any viewer, including administrators — yielding session theft, CSRF-token abuse, and privileged actions under the victim's session. CVSS: 4.3 (AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N); EPSS 0.00233 (14.4th percentile); no public PoC, no Nuclei template, not in CISA KEV.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

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.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Technical Analysis

plone.app.textfield provides RichTextValue, a zope.schema-style value object that couples a text body with a related MIME type. The vulnerability resides in the RichTextValue.output accessor. Under normal operation, when a stored value is requested for rendering, the library is expected to route non-safe content through the safe_html transform, which strips event-handler attributes (e.g., onclick, onerror) and unsafe URI schemes (e.g., javascript:). The transform itself is described as functioning correctly.

The flaw is a type-equality shortcut: when the stored value's MIME type equals the field's outputMimeType, output returns the raw stored value without invoking safe_html. Two paths produce this equality condition:

  1. Misconfigured or intentionally matched field — a RichText field whose mimeType and outputMimeType are both configured to the same value (including text/x-html-safe).
  2. REST API input — a request that explicitly supplies text/x-html-safe as the content type for the stored value, causing the stored MIME type to match the output type.

The resulting attacker-controlled value is then emitted through TAL as tal:content="structure", which interprets the string as markup rather than text and performs no escaping. Because the safe transform is skipped, script-bearing markup survives storage and is rendered into the victim's DOM — a classic stored XSS (CWE-80: Improper Neutralization of Script-Related HTML Tags in a Web Page / Basic XSS). Note that text/x-html-safe is the type used for already-sanitized output; the shortcut effectively trusts a caller-supplied claim of safety instead of re-deriving it. That trust inversion is the root cause.

Attack surface: any Plone object exposing a RichText field the attacker can write to, and the Plone REST API where content type is attacker-influenced. No code execution on the server side is required; the impact is client-side, in the context of a victim's authenticated session. Insufficient public technical detail is available to identify specific endpoint paths, parameter names, or internal function signatures beyond those stated above; the analysis is bounded accordingly.

Exploitation Scenarios

No public PoC is available; the chain below is inferred from the vulnerability class and the NVD description. It uses only identifiers verbatim from that description.

  1. Reconnaissance / target identification. The attacker identifies a Plone site whose content types expose a RichText field with matched mimeType/outputMimeType, or whose deployment permits the REST API to accept text/x-html-safe as the input content type. Fingerprinting a Plone instance is trivial via default assets and headings; no authentication is needed to survey the site.
  2. Triggering the flaw class (stored, type-equality bypass). The attacker obtains an authenticated account with permission to create or edit content containing a RichText field (CVSS PR:L). They submit a stored value whose MIME type equals the output type — either because the field is configured with identical mimeType and outputMimeType, or by supplying text/x-html-safe directly via REST API input. Because this equality triggers the shortcut, RichTextValue.output returns the value raw and the safe_html transform never runs.
  3. Payload / execution (vulnerability-class level). The attacker's stored value includes script-bearing markup (e.g., an event-handler attribute or a javascript: URI) that safe_html would have removed. When a viewer requests the affected content, it is emitted through tal:content="structure" unescaped and the browser executes the script in the Plone origin. No specific code pattern is asserted beyond standard XSS mechanisms.
  4. Post-exploitation impact. Executing in the victim's browser under the Plone origin enables session-token theft, reading of the victim's CSRF tokens, and state-changing requests as the victim. Targeting an administrative viewer upgrades impact toward full site compromise. The CVSS v3.1 subscores assign Confidentiality:Low, Integrity:None, Availability:None, Scope:Unchanged — the vector captures direct impact conservatively and does not model the escalation achievable via a privileged victim's session.

Impact Assessment

  • Primary impact: stored cross-site scripting executing in the Plone origin. Attacker-controlled JavaScript runs in the browser of every user who views the poisoned content, including administrators.
  • Direct (CVSS-modeled): Confidentiality:Low; Integrity:None; Availability:None; Scope:Unchanged; Attack Vector:Network; Attack Complexity:Low; Privileges Required:Low; User Interaction:None. Base score 4.3.
  • Practical blast radius: a single stored payload can affect all viewers of the content item, so one low-privileged authenticated account can reach a wide audience. Because scripts run in the site context, they can defeat CSRF protections and act as the victim user.
  • Affected systems: any deployment pulling a pre-2.0.2, pre-3.0.2, or pre-4.0.1 plone.app.textfield release (the version line depends on the Plone generation). OSV lists affected package records as unfixed in the supplied data, so consumers must confirm the resolved version in their own environment rather than relying on a single advisory.
  • Exposure context: Plone is commonly internet-facing (content management, intranets, extranets), and the bug is reachable through normal content authoring and the REST API — no exotic access required. EPSS is low (0.00233, 14.4th percentile) and there is no KEV listing or public exploit, so the immediate likelihood of mass exploitation is limited; targeted attacks remain plausible.

Detection Guidance

Because the payload is stored and served to viewers, detection must cover both the write path (content submission) and the read path (rendition of unsafe markup). The rules below are behavioral and class-level, since no exploit traffic is public.

Sigma Rule

title: Potential Plone RichText safe_html Bypass - Unsafe MIME Type Claim (CVE-2026-54503)
id: 7f3c9a21-5b14-4e8d-9c02-1a6e2d545031
status: experimental
description: Detects content submissions that claim text/x-html-safe as the RichText content type, or that carry script-bearing markup, consistent with the CVE-2026-54503 type-equality sanitization bypass.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-54503
author: valtersit.com
date: 2026/01/01
logsource:
  category: webserver
detection:
  selection_type:
    cs-method: ['POST', 'PUT', 'PATCH']
    cs-uri-query|contains: '/@@'   # plone REST/RPC style content endpoints
  selection_payload:
    - request_body|contains:
        - 'text/x-html-safe'
        - 'javascript:'
        - 'onerror='
        - 'onload='
        - '<script'
  condition: selection_type and selection_payload
falsepositives:
  - Legitimate rich text editors transmitting sanitized markup
  - Security tooling that scans for javascript: patterns
level: medium
tags:
  - attack.t1189
  - cve.2026.54503

YARA Rule

rule CVE_2026_54503_Plone_RichText_XSS
{
    meta:
        author      = "valtersit.com"
        description = "Detects stored RichText payloads abusing the text/x-html-safe type-equality shortcut (CVE-2026-54503)"
        cve         = "CVE-2026-54503"
        reference   = "https://nvd.nist.gov/vuln/detail/CVE-2026-54503"
        date        = "2026-01-01"

    strings:
        $mime  = "text/x-html-safe" ascii nocase
        $js1   = "javascript:" ascii nocase
        $evt1  = "onerror=" ascii nocase
        $evt2  = "onload=" ascii nocase
        $evt3  = "onclick=" ascii nocase
        $scr   = "<script" ascii nocase

    condition:
        uint32(0) != 0x04034b50 and
        (
            ($mime and any of ($js1, $evt*)) or
            ($mime and $scr)
        )
}

Suricata IDS Rule

alert http any any -> any any (msg:"CVE-2026-54503 Plone RichText safe_html Bypass - text/x-html-safe with script markup"; flow:established,to_server; http.method; content:"POST"; http.content_type; content:"text/x-html-safe"; http.request_body; content:"text/x-html-safe"; nocase; pcre:"/(?:javascript:|on(?:error|load|click|mouseover)\s*=)/i"; reference:cve,2026-54503; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-54503; classtype:web-application-attack; sid:5450301; rev:1;)

Elastic Detection

sequence by source.ip with maxspan=1m
  [ network where http.request.method in ("POST","PUT","PATCH")
      and http.request.body.text/  *"text/x-html-safe"* ]
  [ network where http.request.body.text :
      ("*javascript:*" or "*onerror=*" or "*onload=*" or "*<script*") ]

Splunk SPL Query

index=web sourcetype=access_combined OR sourcetype=plone_access
| eval body = coalesce(request_body, form_data, post_data, "")
| where (method="POST" OR method="PUT" OR method="PATCH")
| where match(body, "(?i)text/x-html-safe") AND (match(body, "(?i)javascript:") OR match(body, "(?i)on(error|load|click|mouseover)\s*=") OR match(body, "(?i)<script"))
| stats count min(_time) as first_seen max(_time) as last_seen by src, uri_path, method, user
| sort - count
| convert ctime(first_seen) ctime(last_seen)

Wazuh OSSEC Rule

<group name="web,plone,xss,cve-2026-54503,">
  <rule id="545030" level="10">
    <decoded_as>web-accesslog</decoded_as>
    <match>text/x-html-safe</match>
    <description>CVE-2026-54503: Plone RichText submission claiming text/x-html-safe content type</description>
    <group>attack.t1189,pci_dss_6.5.7,</group>
  </rule>
  <rule id="545031" level="12">
    <decoded_as>web-accesslog</decoded_as>
    <regex>on(error|load|click|mouseover)\s*=</regex>
    <description>CVE-2026-54503: Possible stored XSS payload in RichText submission</description>
    <group>attack.t1189,pci_dss_6.5.7,</group>
  </rule>
</group>

Tune level and decoded_as to match your deployment's web-accesslog decoder; adjust for the log source that captures request bodies (many access logs do not, in which case enable body logging or WAF telemetry for these rules).

Mitigation & Patch Guidance

Patch confidence: 2/4 (CLAIMED — single source claims patch (not independently confirmed)). Verify against upstream before treating as authoritative.

1) Immediate mitigations

  • Disable or restrict REST API access that allows callers to supply text/x-html-safe as the content type; where possible, validate/reject client-supplied MIME types server-side.
  • Restrict the ability to create or edit content with RichText fields to trusted roles only; the vulnerability requires write access (PR:L).
  • Deploy a WAF/reverse proxy rule blocking request bodies that claim text/x-html-safe while carrying event-handler attributes or javascript: URIs, and filter response bodies for unescaped script markup.
  • Audit existing stored content for script-bearing values in RichText fields; treat any found as potentially malicious.

2) Patch / upgrade steps

  • Upgrade plone.app.textfield to 2.0.2, 3.0.2, or 4.0.1, selecting the line matching your Plone generation; do not assume a single version applies to every deployment.
  • Confirm the resolved version in the running environment (the OSV data lists affected package records as unfixed, so verify locally).
  • After upgrade, re-run the safe_html path on previously stored content to strip any payloads that survived before the fix.

3) Long-term hardening

  • Never derive safety from a caller-supplied MIME type; always route RichTextValue.output through safe_html (or equivalent) regardless of type equality.
  • Configure RichText fields so mimeType and outputMimeType cannot be set identically in a way that disables sanitization.
  • Enforce a Content Security Policy and state-changing request CSRF protections so a residual XSS cannot escalate to account or site compromise.
  • Add CI checks for XSS regression across tal:content="structure" sinks.

References

Threat actor campaigns / exploit-in-the-wild: none identified. CISA KEV: not listed. Public PoC: none. Nuclei template: none. No evidence of active exploitation as of this report.

👁️ SHODAN DORKS (THREAT HUNTING)

What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.

product:"Plone"
title:"Plone"

💣 PoC CODE AVAILABLE

Exploit code for this CVE is tracked in our database. Access poc_code via API Pro.

[ API_PRO ] →
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-54503/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.