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-QVC2-MG72-JJHX

GHSA-qvc2-mg72-jjhx: Mutation XSS (mXSS) in justhtml HTML Serializer

Amit Schendel
Amit Schendel
Senior Security Researcher

Mar 19, 2026·7 min read·21 visits

Executive Summary (TL;DR)

justhtml versions prior to 1.12.0 are vulnerable to Mutation XSS when configured with custom sanitization policies allowing <script> or <style> tags, enabling arbitrary JavaScript execution via unescaped closing tags.

The justhtml Python library prior to version 1.12.0 contains a Cross-Site Scripting (XSS) vulnerability due to flawed HTML serialization logic. The serializer preserves the literal text content of raw-text elements like script and style to maintain round-trip fidelity. If an application uses a custom sanitization policy that permits these elements, an attacker can supply closing tag sequences to break out of the context and execute arbitrary JavaScript in the victim's browser.

Vulnerability Overview

The justhtml Python package is a library utilized for building, sanitizing, and serializing HTML documents. Prior to version 1.12.0, the library contains a Mutation Cross-Site Scripting (mXSS) vulnerability within its HTML serialization component. The flaw is tracked under GitHub Advisory GHSA-qvc2-mg72-jjhx and carries a moderate severity rating with a CVSS 4.0 score of 5.3.

The vulnerability is not exposed under the library's default configuration. The default SanitizationPolicy automatically drops the contents of script and style elements, thereby mitigating the attack vector entirely. The issue strictly manifests when developers implement a custom sanitization policy that explicitly permits these raw-text elements.

When a custom policy allows script or style tags, the serializer fails to properly neutralize closing-tag sequences embedded within text nodes. An attacker can leverage this oversight to supply input that the server-side parser treats as a single text node, but the client-side browser interprets as a context breakout. This mismatch enables the execution of arbitrary JavaScript in the victim's browser context.

Root Cause Analysis

The root cause of this vulnerability lies in a feature introduced in justhtml version 1.9.1, designed to improve round-trip parsing fidelity. The maintainers updated the HTML serialization logic to preserve the literal text content of raw-text elements, specifically script and style. This change prevented the serializer from converting necessary syntax characters, such as >, into HTML entities like &gt;, which would otherwise break the intended script or stylesheet logic.

The implementation of this feature relied on a hardcoded set of elements (_LITERAL_TEXT_SERIALIZATION_ELEMENTS) and a function named _serialize_text_for_parent. When the serializer processes a text node, it checks the identity of the parent element. If the parent is a script or style tag, the function returns the text unmodified, bypassing the standard _escape_text routine applied to all other elements.

This exact preservation of text creates a critical desynchronization between the server-side DOM representation and the client-side browser parsing behavior. In the HTML specification, a browser's HTML parser terminates a script context immediately upon encountering the first </script> sequence, regardless of the document structure established by the server. The justhtml serializer failed to account for this client-side mutation behavior.

Because the serializer outputs the text node literally, an attacker can embed a premature closing tag followed by a new, executable HTML element. The server correctly models this as a single string within a script tag, but the browser parses it as the end of the script block followed by a new, active DOM element.

Code Analysis

The vulnerability is isolated to the text serialization routines within serialize.py. Prior to version 1.12.0, the code utilized a static set to identify elements that required literal text preservation. The standard text escaping mechanism was deliberately bypassed for these specific tags.

_LITERAL_TEXT_SERIALIZATION_ELEMENTS = frozenset({"script", "style"})
 
def _serialize_text_for_parent(text: str | None, parent_name: str | None) -> str:
    if not text:
        return ""
    # If the parent is a script or style tag, the text is emitted literally
    if parent_name in _LITERAL_TEXT_SERIALIZATION_ELEMENTS:
        return text
    # Other elements have their text escaped (e.g., <div>, <span>)
    return _escape_text(text)

The fix implemented in version 1.12.0 introduces two primary hardening measures to address the breakout vector. First, the serialization logic was updated to actively identify and neutralize closing-tag sequences (such as </script> or </style>) whenever they appear within the text nodes of raw-text elements. This neutralization ensures that the browser parser cannot prematurely terminate the context.

Second, the sanitization process was strictly hardened to drop any non-text children assigned to script and style tags. By enforcing that these elements can only contain valid text nodes, the maintainers eliminated the possibility of complex, nested DOM structures being mis-serialized into executable contexts. These dual measures effectively close the mXSS vector while maintaining the required round-trip fidelity.

Exploitation

Exploitation of this vulnerability requires a specific prerequisite: the target application must instantiate justhtml using a custom SanitizationPolicy that permits script or style tags. The attacker must then identify an input field or parameter processed by this configuration.

The attack payload is designed to initiate a valid script context, immediately break out of it using a literal closing tag, and append a subsequent payload. For example, an attacker supplies the string alert('injected'); </script><svg onload=alert('broken-out')>. The application processes this input and, due to the vulnerability, emits it exactly as provided without HTML entity encoding.

from justhtml import JustHTML, SanitizationPolicy
 
# 1. Define a custom policy that allows script or style tags
policy = SanitizationPolicy(
    allowed_tags=["script", "body"],
    allowed_attributes={}
)
 
# 2. Payload designed to break out of the script tag
xss_payload = "alert('injected'); </script><svg onload=alert('broken-out')>"
html_input = f"<body><script>{xss_payload}</script></body>"
 
# 3. Sanitize and serialize
sanitized_output = JustHTML(html_input, policy=policy).to_html()
 
# 4. Observe the result (Vulnerable output shown below)
print(sanitized_output)
# <body><script>alert('injected'); </script><svg onload=alert('broken-out')></script></body>

When the resulting HTML is rendered by a user's browser, the parser encounters the </script> tag and terminates the script context. It then processes the newly exposed <svg onload=alert('broken-out')> element, executing the embedded JavaScript. The final dangling </script> tag is typically ignored or discarded by the browser's error-handling routines.

Impact Assessment

The vulnerability carries a CVSS 4.0 vector string of CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N. This scoring reflects a network-based attack vector with low complexity, requiring no specialized access privileges but mandating user interaction. The vulnerable system itself suffers no direct confidentiality, integrity, or availability impact.

The concrete security impact is measured on the subsequent system, which is the web browser of the user viewing the serialized output. Successful exploitation grants the attacker the ability to execute arbitrary JavaScript within the context of the user's active session. This represents a classic Stored or Reflected Cross-Site Scripting (XSS) scenario, depending on how the application handles the input.

With JavaScript execution capabilities, an attacker can access sensitive session tokens, manipulate the Document Object Model (DOM), or perform actions on behalf of the authenticated user. Applications heavily reliant on custom HTML sanitization for user-generated content are at the highest risk if they explicitly allow raw-text elements.

The scope of the vulnerability is strictly confined to the client side. The server infrastructure executing the justhtml library remains entirely unaffected, as the flaw pertains exclusively to the generation of output that is misinterpreted by a downstream consumer.

Remediation

The primary remediation strategy is to upgrade the justhtml dependency to version 1.12.0 or later. This release introduces the necessary neutralization routines for closing-tag sequences and strictly enforces text-only children for raw-text elements. The update resolves the serialization flaw without requiring structural changes to the consuming application.

For environments where immediate patching is unfeasible, administrators must audit and modify their application code. Developers should inspect all instances of SanitizationPolicy and explicitly remove script and style from the allowed_tags parameter. Reverting to the default sanitization behavior entirely eliminates the attack surface.

Developers should review the official JustHTML Sanitization Documentation for comprehensive guidance on secure, context-aware serialization. Maintaining an aggressive deny-by-default posture for raw-text elements is a standard defense-in-depth practice for HTML sanitizers.

Technical Appendix

CVSS Score
5.3/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

Affected Systems

justhtml HTML serialization libraryPython applications utilizing custom justhtml SanitizationPolicy configurations

Affected Versions Detail

Product
Affected Versions
Fixed Version
justhtml
EmilStenstrom
< 1.12.01.12.0
AttributeDetail
CWE IDCWE-79
Attack VectorNetwork
CVSS Base Score5.3
Exploit StatusPoC Available
ImpactCross-Site Scripting (XSS)
Patch StatusFixed in 1.12.0

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The software does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.

Vulnerability Timeline

Version 1.3.0 released, hardening <noscript> handling against differential parsing mXSS.
2026-01-28
Version 1.9.1 released, introducing literal preservation in script/style elements, creating the mXSS vulnerability under custom policies.
2026-03-10
Version 1.12.0 released, fixing the mXSS breakout vulnerability.
2026-03-17
GitHub Advisory GHSA-qvc2-mg72-jjhx published.
2026-03-18

References & Sources

  • [1]GitHub Advisory GHSA-qvc2-mg72-jjhx
  • [2]justhtml Package Repository
  • [3]justhtml Changelog
  • [4]OSV Vulnerability Database Entry
  • [5]JustHTML Sanitization Documentation

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

•24 minutes ago•GHSA-C43V-4CR8-6MVP
6.5

GHSA-C43V-4CR8-6MVP: Authenticated Path Traversal in Craft CMS Asset Icon Helper

An authenticated path traversal and arbitrary local file read vulnerability exists in Craft CMS versions 4.x up to 4.17.6 within the assets/icon endpoint and Assets helper classes. By exploiting this vulnerability, an authenticated user can traverse directories and read arbitrary .svg files on the server's filesystem, or execute Stored Cross-Site Scripting (XSS) if they can upload a malicious SVG.

Alon Barad
Alon Barad
2 views•8 min read
•about 1 hour ago•GHSA-86VW-X4WW-X467
8.6

CVE-2026-56382: Remote Code Execution in Craft CMS via Yii2 Event Handler Injection

CVE-2026-56382 is a high-severity remote code execution vulnerability in Craft CMS versions 5.5.0 through 5.9.13. The vulnerability exists within the FieldsController::actionRenderCardPreview() method due to a lack of sanitization of the user-supplied fieldLayoutConfig configuration array, permitting authenticated administrators to register arbitrary PHP callbacks using Yii2 event handler injection mechanisms. This issue has been fully remediated in version 5.9.14.

Amit Schendel
Amit Schendel
2 views•6 min read
•about 2 hours ago•GHSA-382C-VX95-W3P5
6.5

GHSA-382C-VX95-W3P5: Missing Access Control on Profile Endpoint and MCP Tool in Gittensory

An insecure direct object reference (IDOR) and missing authorization validation check in the Gittensory REST API and Model Context Protocol (MCP) server allowed authenticated users to query arbitrary miner profiles, exposing sensitive cryptographic hotkeys and daily financial/economic yields.

Alon Barad
Alon Barad
3 views•6 min read
•about 18 hours ago•CVE-2026-53634
4.3

CVE-2026-53634: Missing Authorization in Code16 Sharp Quick Creation Command Controller

Code16 Sharp versions from 9.0.0 up to (but not including) 9.22.3 are vulnerable to a missing authorization flaw in the Quick Creation Command feature. The ApiEntityListQuickCreationCommandController fails to validate entity-level 'create' policies before returning administrative form designs or processing database modifications. Authenticated users with restricted access can bypass policy boundaries to access creation configurations and insert records.

Alon Barad
Alon Barad
6 views•5 min read
•about 18 hours ago•CVE-2026-49471
8.3

CVE-2026-49471: Unauthenticated Remote Code Execution in Serena MCP Toolkit via DNS Rebinding and Memory Poisoning

CVE-2026-49471 is a high-severity security vulnerability in Serena, an AI-assisted coding Model Context Protocol (MCP) toolkit. In versions prior to v1.5.2, Serena's built-in web dashboard exposes an unauthenticated Flask API on a predictable port. Lacking host validation and CSRF protections, this endpoint is vulnerable to DNS Rebinding. An attacker can lure a user to a malicious webpage, bypass the Same-Origin Policy (SOP), rewrite the AI agent's persistent memory, and execute arbitrary commands on the host operating system via the autonomous agent's shell execution engine.

Alon Barad
Alon Barad
11 views•5 min read
•about 19 hours ago•GHSA-MXWC-WH95-PW4G
5.3

GHSA-MXWC-WH95-PW4G: Denial of Service via Uncontrolled Recursion in Trapster DNS Parser

The trapster honeypot package is vulnerable to a remote denial of service (DoS) vulnerability due to uncontrolled recursion during the parsing of malformed DNS compression pointers in the decode_labels function.

Amit Schendel
Amit Schendel
7 views•6 min read