CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-8RQH-VXPR-X77P

GHSA-8RQH-VXPR-X77P: Stored Cross-Site Scripting via MIME Type Spoofing in Plone REST API

Amit Schendel
Amit Schendel
Senior Security Researcher

Jul 18, 2026·7 min read·0 visits

Executive Summary (TL;DR)

A stored XSS vulnerability exists in Plone's REST API and textfield components where attackers can bypass HTML sanitization by spoofing input MIME types as 'text/x-html-safe'. Upgrading plone.restapi and plone.app.textfield is required to mitigate this flaw.

A stored Cross-Site Scripting (XSS) vulnerability exists within plone.restapi, the REST API package for Plone content management system. By supplying a spoofed input MIME type (text/x-html-safe), an attacker can mislead the rendering layer (plone.app.textfield) into assuming that the supplied content is already sanitized. This causes the system to skip the safe_html transform, allowing arbitrary JavaScript to execute in the victim's browser when they view the compromised page.

Vulnerability Overview

Plone is an open-source, Python-based content management system (CMS) widely used in enterprise and public sector environments. The plone.restapi package exposes REST endpoints for content CRUD operations, forming the core data-exchange layer for modern Plone frontends. Within this architecture, rich text fields are managed by the plone.app.textfield library, which handles raw storage, transformation, and output rendering.

A high-impact stored Cross-Site Scripting (XSS) vulnerability exists when deserializing and rendering user-supplied rich text. The core security flaw involves a trust boundary violation where the REST API deserializer blindly accepts client-supplied MIME types. By declaring input data as already sanitized, an attacker can trick the system into skipping the necessary HTML purification steps.

The vulnerability is classified under CWE-80: Improper Neutralization of Script-Related HTML Tags in a Web Page. If an authenticated user with permission to add or modify content submits a crafted JSON request, they can embed arbitrary JavaScript code that executes in the browsers of other users who view the affected page. This can lead to session hijacking, credential theft, and unauthorized actions within the CMS context.

Technical Root Cause Analysis

The root cause of this vulnerability lies in the optimization and serialization architecture of plone.app.textfield. Plone designates the custom MIME type text/x-html-safe to signal that HTML markup has successfully passed through the system's sanitation engine and is safe to render. The rendering pipeline uses the RichTextValue.output_relative_to method to convert the raw stored format into the target output format, relying on an ITransformer adapter.

In vulnerable versions of plone.app.textfield, an optimization check was introduced in value.py. This check compared the declared input mimeType of a field directly against the requested outputMimeType. If these two values matched, the rendering engine assumed that the markup was already in the desired final format and skipped the entire transformation process, returning the raw content unchanged.

This shortcut created a critical security flaw. If a RichTextValue object was initialized with both mimeType and outputMimeType set to text/x-html-safe, the code bypassed the safe_html transform registry completely. Because Plone templates render rich text fields using the Zope Page Templates structure modifier, HTML entity escaping is disabled, allowing raw browser-executable scripts to be rendered directly into the Document Object Model (DOM).

Code-Level Flow and Structural Analysis

The vulnerability requires two distinct components to cooperate: the input deserializer (plone.restapi) and the storage rendering layer (plone.app.textfield). First, when a user posts new content, the REST API deserializer parses the incoming JSON request. In vulnerable versions, the deserializer extracted the user-supplied content-type value directly from the JSON body without validation and used it to construct the internal RichTextValue object.

Once saved in the Zope Object Database (ZODB), the malicious payload is stored permanently. When a standard user requests the page, the rendering engine calls output_relative_to(). Because both the stored mimeType and the requested outputMimeType are evaluated as text/x-html-safe, the comparison evaluates to true, executing the shortcut path and delivering the unsanitized script block directly to the browser.

The following diagram illustrates the vulnerable execution flow where user-supplied content bypasses the safety transforms:

Patch Analysis and Fix Integrity

The vulnerability is resolved via a two-layer defense-in-depth approach. At the input layer, the plone.restapi deserializer was updated to prevent external API requests from declaring the text/x-html-safe MIME type. If an incoming REST API payload attempts to set "content-type": "text/x-html-safe", the deserializer raises a ValueError exception, completely blocking external input spoofing attempts.

However, API-level blocking does not protect against existing database entries or direct programmatic instantiation of RichTextValue objects in custom add-ons. To address this, the second layer of the patch modifies plone.app.textfield's rendering logic in value.py. The comparison shortcut is restricted so that it will never apply if the requested output is safe HTML. If both input and output types are text/x-html-safe, the input type is overwritten to text/html to force the sanitization transform.

The patched implementation also introduces an in-memory cloning mechanism. If both input and output types are declared as safe, the code overrides the input type to text/html and forwards a clone of the value object to the transformer. Since RichTextValue is a ZODB persistent object, using __new__ to clone the object in memory allows the transform parameters to be updated dynamically without triggering unwanted database write operations.

Exploitation and Attack Methodology

An attacker must possess credentials for a low-privileged account that has permissions to create or modify content containing a rich text field, such as a contributor or editor. The attack is carried out over HTTP/HTTPS by interacting directly with the Plone REST API endpoints. Since the vulnerability is stored, it requires zero active user interaction from the target victim beyond navigating to the compromised resource.

To execute the exploit, the attacker first requests an authentication token by posting credentials to the @login endpoint. Once authenticated, they submit a POST or PATCH request targeting a specific content URL. The request payload contains a JSON structure representing the rich text field, where the data parameter holds the malicious payload, and the content-type is explicitly set to the spoofed type.

The payload can leverage various HTML tags and event handlers, such as <img src=x onerror=alert(document.cookie)> or standard inline <script> tags. Once the API accepts the payload, it writes it directly to the backend storage. When administrative users or general site visitors load the affected page, their browsers process the raw, unescaped scripts, allowing the attacker to steal cookies, extract CSRF tokens, or modify site configurations on behalf of the victim.

Remediation and Detection Strategies

Remediation requires upgrading both the plone.restapi and plone.app.textfield packages to their respective patched versions. For deployments running Plone 6.0 or 6.2, administrators must ensure that plone.restapi is updated to at least 9.15.6 or 10.0.1. Concurrently, plone.app.textfield must be upgraded to 2.0.2 (for Plone 6.0), 3.0.2 (for Plone 6.1), or 4.0.1 (for Plone 6.2).

Upgrading the libraries prevents future injection attempts but does not automatically remediate legacy payloads already stored in the Zope Object Database (ZODB). System administrators should run a diagnostic script in the Zope python shell to identify objects containing spoofed RichTextValue fields. The cleanup script locates any persistent field instance where mimeType is set to text/x-html-safe and changes it back to standard text/html to force sanitization on subsequent render requests.

In addition to applying application patches, network security teams can deploy Web Application Firewall (WAF) rules to detect and drop spoofed payloads at the perimeter. Rules should inspect incoming JSON payloads destined for Plone API endpoints and trigger blocks when detecting attempts to set content-type to text/x-html-safe. This provides immediate mitigation while administrators schedule downtime to perform full system updates and ZODB database cleanup.

Official Patches

Plone Foundationplone.app.textfield rendering-level comparison patch
Plone Foundationplone.restapi version 9 deserializer comparison patch
Plone Foundationplone.restapi version 10 deserializer comparison patch

Technical Appendix

CVSS Score
4.3/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N

Affected Systems

Plone CMSplone.restapiplone.app.textfield

Affected Versions Detail

Product
Affected Versions
Fixed Version
plone.restapi
Plone Foundation
< 9.15.69.15.6
plone.restapi
Plone Foundation
== 10.0.010.0.1
plone.app.textfield
Plone Foundation
< 2.0.22.0.2
plone.app.textfield
Plone Foundation
>= 3.0.0, < 3.0.23.0.2
plone.app.textfield
Plone Foundation
== 4.0.04.0.1
AttributeDetail
CWE IDCWE-80 (Improper Neutralization of Script-Related HTML Tags)
Attack VectorNetwork (AV:N)
CVSS v3.1 Score4.3 (Medium)
Attack ComplexityLow (AC:L)
Privileges RequiredLow (PR:L)
User InteractionNone (UI:N)
Exploit StatusPoC (Proof of Concept Available)

MITRE ATT&CK Mapping

T1189Drive-by Compromise
Initial Access
T1204.002User Execution: Malicious Link/Content
Execution
CWE-80
Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)

The software does not neutralize or incorrectly neutralizes user-controlled input before rendering it as HTML.

Known Exploits & Detection

GitHub Security Advisory (REST API Layer)Advisory documenting the REST API deserialization bypass mechanism and PoC inputs.
GitHub Security Advisory (Textfield Layer)Advisory covering the underlying rendering bypass in the textfield library.

Vulnerability Timeline

plone.app.textfield v4.0.0 is released.
2026-05-16
plone.restapi v9.15.5 is released.
2026-05-21
Bypass identified and patches drafted by developers Guido A.J. Stevens and Maurits van Rees.
2026-05-30
Patched versions released for plone.app.textfield (2.0.2, 3.0.2, 4.0.1) and plone.restapi (9.15.6, 10.0.1).
2026-06-05
Official security advisories GHSA-8rqh-vxpr-x77p and GHSA-4r4f-gg25-rmg5 are published.
2026-07-17

References & Sources

  • [1]GHSA-8rqh-vxpr-x77p (REST API Advisory)
  • [2]GHSA-4r4f-gg25-rmg5 (Underlying Library Advisory)
  • [3]Public GitHub Advisory Database Entry
Related Vulnerabilities
CVE-2026-54503

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 2 hours ago•CVE-2026-11400
8.0

CVE-2026-11400: Privilege Escalation via Untrusted Search Path in AWS Advanced JDBC Wrapper

An untrusted search path vulnerability in the GlobalDatabasePlugin component of the AWS Advanced JDBC Wrapper for Amazon Aurora PostgreSQL allows authenticated, low-privilege database users to hijack administrative session queries. By defining a custom function in a writable schema such as the public schema, an attacker can hijack queries executed automatically during driver-level topology detection. When a highly privileged database user connects to the database utilizing an affected version of the wrapper, the custom function executes under their security context, enabling remote privilege escalation to rds_superuser.

Alon Barad
Alon Barad
2 views•6 min read
•about 3 hours ago•CVE-2026-27771
8.2

CVE-2026-27771: Authentication Bypass and Information Disclosure in Gitea Container and Composer Registries

CVE-2026-27771 represents a critical security flaw in Gitea and Forgejo (up to and including version 1.26.1) involving missing authorization checks (CWE-862). Unauthenticated remote attackers can query, enumerate, and download private container images from the OCI-compliant container registry. Additionally, unauthorized users can retrieve private or internal source repository URLs via the Composer package registry metadata API. A public proof-of-concept exists, and threat metrics indicate highly active scanning and exploitation risks.

Alon Barad
Alon Barad
3 views•7 min read
•about 4 hours ago•GHSA-CVPC-HCCG-WMW4
8.8

GHSA-CVPC-HCCG-WMW4: Missing Authorization in Formie Administrative Settings Allows Privilege Escalation

A missing authorization vulnerability in the Formie plugin for Craft CMS prior to version 3.1.28 allows low-privileged Control Panel users to read and modify sensitive administrative settings, configuration options, and third-party integrations.

Amit Schendel
Amit Schendel
2 views•6 min read
•about 5 hours ago•CVE-2026-53598
7.5

CVE-2026-53598: Arbitrary File Read via File Reference Expansion in Microsoft Prompty

CVE-2026-53598 is a directory traversal and arbitrary file read vulnerability in Microsoft Prompty ecosystem loaders across multiple languages. Prior to version 2.0.0-beta.2, the loaders resolved `${file:...}` reference strings inside frontmatter configuration blocks without enforcing that the target file paths resided within authorized directories. This deficiency allows an attacker-controlled configuration file to read sensitive operating system and application files through absolute paths, directory traversal, or symbolic link escapes. The issue is addressed across the Python, C#, Node.js/TypeScript, and Rust ecosystems.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 6 hours ago•GHSA-MFR4-MQ8W-VMG6
7.3

GHSA-MFR4-MQ8W-VMG6: Path Traversal in proot-distro copy Command Allows Container Escape

A directory traversal vulnerability exists in the copy subcommand of the proot-distro utility. Due to incomplete path sanitization, local attackers or malicious scripts can read from or write to arbitrary files outside the container rootfs, bypassing isolation barriers and potentially gaining unauthorized access or persistent execution on the host system.

Alon Barad
Alon Barad
6 views•7 min read
•about 10 hours ago•GHSA-8QQM-FP2Q-V734
8.2

GHSA-8QQM-FP2Q-V734: Authorization Bypass in Skipper's Open Policy Agent Integration

An authorization bypass vulnerability in the Open Policy Agent (OPA) integration of the Skipper HTTP router allows unauthenticated remote attackers to bypass OPA policy inspection. When an incoming HTTP request declares a Content-Length exceeding Skipper's configured maxBodyBytes limit, Skipper bypasses body parsing and forwards an empty document to OPA, while transmitting the full, uninspected payload intact to the upstream backend.

Amit Schendel
Amit Schendel
8 views•6 min read