Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessInject blank line into code/pre element text
-
DeliverySubmit crafted HTML to application
-
Exploitto_markdown() emits unescaped content after broken span
-
ExecutionMarkdown renderer parses payload as live HTML
-
ImpactXSS executes in victim browser session
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Output encoding, context-aware escaping
MITRE ATT&CK
2 techniques across 2 tactics: Initial Access, Execution The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires three co-occurring conditions. First, the target application must invoke justhtml's to_markdown() on HTML that includes attacker-controlled text inside code or pre elements - this function must sit on a security-relevant code path (i.e., it is being used to sanitize or safe-render user content). Second, the resulting Markdown output must be rendered by a CommonMark-compliant or similarly spec-adherent Markdown renderer in a browser context where JavaScript can execute; plain-text display of the Markdown source is not exploitable. Third, the attacker must be able to inject a blank line (\n\n) into the code or pre element's text content before it reaches to_markdown(). Exploitation is limited by UI:P (victim must view the rendered page) and by the requirement that to_markdown() output reaches a live renderer - applications that store Markdown for later non-browser consumption are not affected. PR:N in the CVSS 4.0 vector indicates no privileges are needed on the target system for the injection step. |
| Impact | The CVSS 4.0 score of 5.3 (Medium) is reasonably calibrated for this vulnerability. The UI:P metric correctly captures that exploitation requires a victim to view rendered Markdown output - there is no server-side code execution path. The VC:L/VI:L impact ratings reflect XSS-class outcomes (session token theft, DOM manipulation) rather than full system compromise. Real-world risk is gated by several co-occurring conditions: the application must use to_markdown() as a sanitization step, the output must be rendered by a compliant Markdown renderer in a browser context, and the attacker must be able to inject blank lines into code or pre element text that passes through the pipeline. No CISA KEV listing and no confirmed public exploit code limit the urgency for most operators; however, the scope-change nature of XSS (affecting the victim's browser session independently of the server) means that even smaller deployments relying on justhtml for content sanitization should treat upgrading to 1.22.0 as a priority rather than deferring it. EPSS data was not provided in the intelligence sources. |
| Exploit ScenarioDerived | An attacker submits user-controlled content containing a code element whose text includes a blank line - for example, <code>safe content\n\njavascript:alert(document.cookie)</code> - to an application that pipes HTML through justhtml's to_markdown() before storing or displaying it. When a victim views the resulting Markdown rendered by a compliant renderer (e.g., CommonMark), the blank line breaks the inline code span, and the attacker's trailing payload is interpreted as live Markdown or raw HTML, executing JavaScript in the victim's browser. No public proof-of-concept code has been confirmed in the available intelligence sources. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Aug 23, 2026
Cross-site scripting in justhtml 0.9.0-1.21.0 allows an attacker who can control the text content of HTML code or pre elements to escape the Markdown inline code span produced by to_markdown(), causing sanitized content to be emitted unescaped and re-parsed as live HTML by a downstream Markdown renderer. The to_markdown() function is explicitly documented as a security boundary, making this a trust-model violation. No public exploit code has been identified and CISA KEV status is not confirmed, but the root cause is a fundamental gap in the inline code-span helper that bypasses the library's own stated sanitization guarantees.
RemediationAI
Upgrade justhtml to version 1.22.0, which is confirmed as the fixed release per the GHSA-jf6w-2mvx-633j advisory and EUVD-2026-64657 data (fixed in: 1.22.0). The vendor advisory is at https://github.com/EmilStenstrom/justhtml/security/advisories/GHSA-jf6w-2mvx-633j. If an immediate upgrade is not possible, the most specific compensating control is to avoid passing the output of to_markdown() to a Markdown renderer in any context where untrusted user input could appear in code or pre elements - this effectively disables the vulnerable pipeline entirely, with the trade-off that HTML-to-Markdown conversion for those elements becomes unavailable. Alternatively, strip or replace \n\n sequences from code and pre element text before passing to to_markdown(), though this is fragile and not a substitute for patching. There is no indication of a vendor-provided configuration flag to disable the vulnerable code path without modifying the call site.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
justhtml (CPE: cpe:2.3:a:emilstenstrom:justhtml:*:*:*:*:*:*:*:*) is a Python pip package that converts HTML to Markdown via to_markdown(). The vulnerability is rooted in CWE-79 (XSS) arising from CWE-116 (Improper Encoding/Escaping of Output). The internal _markdown_code_span() helper at src/justhtml/node.py:32-41 sizes its backtick fence only to prevent backtick injection, but does not strip or escape embedded newlines. In CommonMark and other compliant Markdown renderers, a blank line (\n\n) unconditionally terminates an inline construct and begins a new block - so any attacker-controlled text containing \n\n causes the opening backticks to be left unmatched (rendered as literal characters), and all subsequent text - including arbitrary HTML - is emitted into the rendered output unescaped. The code path applies to both tagcode (inline) and tagpre inside a link (inline path at node.py:1061-1078). The block-level pre path uses a proper fenced code block and is not affected.
Know when Justhtml gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N
Network delivery, trivial blank-line injection (AC:L), no privileges needed, but scope changes to victim browser (S:C) with limited XSS impact; user must view rendered output (UI:R).
Primary rating from Vendor (VulnCheck).
CVSS VectorVendor: VulnCheck
DescriptionCVE.org
justhtml versions 0.9.0 through 1.21.0 contain a cross-site scripting vulnerability in to_markdown() where inline code spans fail to account for blank lines as block boundaries. Attackers can inject blank lines into code or pre element text to break the inline span, causing sanitized HTML to be emitted unescaped and re-parsed as live Markdown by compliant renderers.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Cross-Site Scripting occurs when an application accepts untrusted data and sends it to a web browser without proper validation or encoding.
Uncontrolled recursion in the justhtml Python HTML parsing library (all versions through 1.9.1) allows any remote unauth
Sanitizer bypass in the justhtml Python library (versions <= 1.11.0) allows attacker-controlled input to survive as raw
Cross-site scripting via HTML sanitization bypass affects justhtml (a Python HTML parsing/sanitization library by EmilSt
Sanitization bypass in justhtml (a Python HTML/Markdown sanitization library) before 1.15.0 lets attacker-controlled inp
Uncontrolled resource consumption in justhtml before 1.18.0 enables denial-of-service conditions through CPU and memory
Cross-site scripting in justhtml before 3.11.0 allows remote unauthenticated attackers to execute arbitrary JavaScript i
Mutation XSS in justhtml (versions ≤1.11.0) allows injection of arbitrary HTML into serialized output when applications
Mutation XSS (mXSS) in justhtml 1.13.0 and earlier enables markup injection bypass against applications using non-defaul
Cross-site scripting in justhtml versions before 1.13.0 allows attackers who control `<pre>` element content to break ou
Sanitization bypass in justhtml (Python HTML sanitization library) before version 1.17.0 enables cross-site scripting in
EUVD-2026-64657
GHSA-3r4x-v5v7-fm2r
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB