Skip to main content
Vulnerability Database/CVE-2026-111758

CVE-2026-111758: markdown-it Denial of Service Vulnerability

CVE-2026-111758 is a denial of service vulnerability in markdown-it, a Markdown parser, causing O(n²) performance degradation through unclosed link references. This post explains its impact, affected versions, and mitigation steps.

Published:

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

CVE-2026-111758 Overview

CVE-2026-111758 is a denial-of-service vulnerability in markdown-it, a widely used JavaScript Markdown parser. The flaw affects versions 14.1.0 up to 14.3.3 and 15.0.0 up to 15.0.3. An attacker can submit a Markdown document containing a link reference definition whose label or title is never closed, forcing the parser into quadratic O(n²) processing time. The issue stems from lazy continuation-line handling in src/rules_block/reference.ts, where repeated string concatenation and subsequent character inspection flatten V8 cons-strings on every iteration. No special parser options are required to trigger the condition, and the maintainers patched the issue in versions 14.3.3 and 15.0.3.

Critical Impact

Unauthenticated remote attackers can exhaust CPU resources on any service that parses untrusted Markdown with vulnerable markdown-it versions, leading to denial of service.

Affected Products

  • markdown-it versions 14.1.0 through 14.3.2
  • markdown-it versions 15.0.0 through 15.0.2
  • Downstream applications and services that render user-supplied Markdown using the affected versions

Discovery Timeline

  • 2026-10-20 - CVE-2026-111758 published to NVD
  • 2026-10-22 - Last updated in NVD database

Technical Details for CVE-2026-111758

Vulnerability Analysis

The vulnerability is an algorithmic complexity flaw categorized under [CWE-400: Uncontrolled Resource Consumption]. The parser's reference-definition rule accumulates continuation lines before validating whether the construct is well-formed. For every continuation line pulled into the buffer, the engine performs charCodeAt and slice operations on the growing string, forcing V8 to flatten its internal cons-string representation into a contiguous buffer. The parser repeats this flatten-and-copy cycle for each line, producing O(n²) runtime scaling with the number of continuation lines.

Because the invalidity check runs only after the loop completes, a malformed reference definition that never terminates still consumes work proportional to the square of its size. An attacker who submits a document with a large unclosed label or title can tie up the event loop and starve other requests sharing the same Node.js process.

Root Cause

The root cause is lazy string building inside src/rules_block/reference.ts. The pattern str += lineContent followed by index-based inspection of str repeatedly materializes the full accumulated buffer. Combined with the parser's deferred validation of label and title closure, this produces quadratic behavior for inputs that are never closed.

Attack Vector

Exploitation requires only the ability to submit Markdown input to a vulnerable parser instance. Common attack surfaces include issue trackers, chat platforms, documentation renderers, content management systems, and API endpoints that accept Markdown. Default parser options are sufficient to trigger the condition, and no authentication or user interaction is required when the service exposes Markdown rendering to anonymous users.

The patch commits for the 14.3.3 and 15.0.3 releases include related inline-HTML hardening. One change replaces the HTML_TAG_RE import with HTML_OPEN_CLOSE_TAG_RE in lib/rules_inline/html_inline.mjs, and another adds a skipHtmlSpecial flag in lib/rules_inline/state_inline.mjs to short-circuit repeated scans of unterminated HTML comments, processing instructions, declarations, and CDATA sections.

text
 // Process html tags
 
-import { HTML_TAG_RE } from '../common/html_re.mjs'
+import { HTML_OPEN_CLOSE_TAG_RE } from '../common/html_re.mjs'
 
 function isLinkOpen (str) {
   return /^<a[>\s]/i.test(str)

Source: GitHub Commit d99f488

text
   this.backticks = {}
   this.backticksScanned = false
 
+  // Set when html comment / PI / declaration / CDATA has no terminator,
+  // to skip further scans of these constructs
+  this.skipHtmlSpecial = false
+
   // Counter used to disable inline linkify-it execution
   // inside <a> and markdown links
   this.linkLevel = 0

Source: GitHub Commit d99f488

Detection Methods for CVE-2026-111758

Indicators of Compromise

  • Sustained high CPU utilization on Node.js worker processes handling Markdown rendering requests
  • Request payloads containing an unclosed [label]: reference definition with large repeated continuation content
  • Elevated event-loop lag or request timeouts correlated with Markdown parsing endpoints
  • Repeated POST requests from a single source submitting oversized Markdown bodies to comment, issue, or preview endpoints

Detection Strategies

  • Instrument Markdown rendering code paths with per-request timing and flag parses that exceed a defined CPU budget
  • Inspect inbound request bodies for Markdown containing reference-definition syntax with unclosed brackets or quotes beyond a reasonable length threshold
  • Correlate web application logs with container or host CPU metrics to identify slow-request amplification patterns

Monitoring Recommendations

  • Alert on Node.js event-loop lag spikes on services that parse user-supplied Markdown
  • Track markdown-it package versions across build pipelines using software composition analysis tooling
  • Monitor upstream and reverse-proxy timeout rates for endpoints that render Markdown content

How to Mitigate CVE-2026-111758

Immediate Actions Required

  • Upgrade markdown-it to version 14.3.3 or 15.0.3 across all applications and dependencies
  • Audit transitive dependencies with npm ls markdown-it or equivalent tooling to identify nested vulnerable copies
  • Enforce request size limits and per-request CPU timeouts on endpoints that accept Markdown from untrusted sources
  • Rate-limit anonymous Markdown rendering endpoints to reduce abuse potential

Patch Information

The maintainers released fixes in markdown-it 14.3.3 and markdown-it 15.0.3. The relevant changes are tracked in GitHub Commit 48fbc46 and GitHub Commit d99f488. Full details are documented in GHSA-gfr2-rv44-r23c.

Workarounds

  • Cap the maximum size of Markdown bodies accepted from untrusted users at the application or API gateway layer
  • Execute Markdown parsing inside worker threads or isolated processes with hard CPU and wall-clock limits
  • Pre-filter inbound Markdown and reject payloads containing unterminated reference-definition labels or titles exceeding a byte threshold
bash
# Upgrade markdown-it to a patched release
npm install markdown-it@^15.0.3
# Or, for applications pinned to the 14.x line
npm install markdown-it@^14.3.3
# Verify the resolved version across the dependency tree
npm ls markdown-it

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.