CVE-2026-48591 Overview
CVE-2026-48591 is a stored cross-site scripting (XSS) vulnerability in the pragdave/earmark Elixir Markdown library. The flaw allows attackers to inject arbitrary JavaScript through markdown link URLs or titles that contain bare double-quote characters. The Elixir.Earmark.Transform module emits attribute values verbatim, bypassing the existing text-node escape routine. The earmark project has been retired on Hex and will not receive a patch. All releases from 1.4.1 onward are affected [CWE-83].
Critical Impact
Attackers can execute arbitrary JavaScript in a victim's browser by submitting crafted markdown content rendered by any application using earmark 1.4.1 or later.
Affected Products
- pragdave earmark 1.4.1 and later
- Elixir applications rendering untrusted Markdown with earmark
- Downstream Hex packages depending on earmark for Markdown processing
Discovery Timeline
- 2026-06-17 - CVE-2026-48591 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2026-48591
Vulnerability Analysis
The vulnerability resides in _make_att1/2 within lib/earmark/transform.ex. The function constructs HTML attributes by splicing values directly between literal double-quote bytes using the pattern [" ", name, "=\"", value, "\""]. Text nodes pass through an escape function that converts " to ", but attribute values never reach that escape path. A markdown link whose URL or title contains a bare " closes the attribute early, letting the browser parse the remaining bytes as additional HTML attributes. This converts a benign link into an arbitrary event-handler injection vector.
Root Cause
The root cause is missing output encoding for HTML attribute contexts. The library applies attribute-context escaping only to text nodes and assumes attribute values are safe. Because Markdown link targets and titles are user-controlled, unescaped double quotes break out of the href attribute and inject sibling attributes such as onerror or onload.
Attack Vector
An attacker supplies markdown content containing a link with a quote-bearing URL or title. For example, the input [click](http://example.com/?a=x" onerror="alert(1)) renders as <a href="http://example.com/?a=x" onerror="alert(1)">click</a>. When a victim views the rendered page, the injected onerror handler executes in the victim's browser session, enabling session theft, defacement, or further client-side attacks. Exploitation requires user interaction with the rendered output.
No verified public proof-of-concept code is published beyond the example in the CNA Security Advisory.
Detection Methods for CVE-2026-48591
Indicators of Compromise
- Stored markdown content containing link targets with embedded " followed by handler attributes such as onerror=, onload=, or onclick=.
- Rendered HTML output where an <a> tag contains attributes other than href, title, or rel.
- Outbound requests from end-user browsers to attacker-controlled domains after viewing user-generated content.
Detection Strategies
- Inventory Elixir dependencies and flag any application using earmark version 1.4.1 or later via mix.lock inspection.
- Scan stored Markdown corpora and database fields for link syntax matching \]\([^)]*"[^)]*\) to identify injection attempts.
- Apply Content Security Policy (CSP) violation reporting to surface inline-script execution on pages that should contain only sanitized Markdown.
Monitoring Recommendations
- Monitor web application logs for POST requests containing markdown payloads with embedded double quotes inside parentheses.
- Track browser CSP report endpoints for script-src violations originating from user-content rendering paths.
- Alert on anomalous DOM event-handler attributes in cached or CDN-served HTML produced by earmark.
How to Mitigate CVE-2026-48591
Immediate Actions Required
- Migrate Markdown rendering away from earmark to a maintained library such as MDEx.
- Sanitize all rendered HTML output through a downstream HTML sanitizer that strips disallowed attributes and event handlers.
- Apply a strict Content Security Policy that disallows inline event handlers and inline scripts on pages rendering user-supplied Markdown.
Patch Information
No patched version of earmark will be released. The project has been retired on Hex, and all releases from 1.4.1 onward remain vulnerable. The CNA recommends migrating to MDEx. See the CNA Security Advisory and the OSV Vulnerability Report for guidance.
Workarounds
- Post-process earmark output with an allowlist-based HTML sanitizer (for example, html_sanitize_ex) before sending content to browsers.
- Pre-filter Markdown input to reject or escape link URLs and titles containing raw " characters.
- Enforce CSP directives script-src 'self' and object-src 'none' to block injected handler execution.
# Replace earmark with MDEx in mix.exs
# {:earmark, "~> 1.4"},
{:mdex, "~> 0.1"}
mix deps.unlock earmark
mix deps.clean earmark
mix deps.get
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

