Aug 8, 2026·5 min read·2 visits
Inefficient regular expressions in multiple inline processors of pymdown-extensions allow unauthenticated attackers to cause complete CPU exhaustion and Denial of Service with short, crafted Markdown payloads of fewer than 50 bytes.
A high-severity Regular Expression Denial of Service (ReDoS) vulnerability in pymdown-extensions versions prior to 11.0.1 affects the Caret, Tilde, BetterEm, and MagicLink inline processors. When parsing user-supplied Markdown content containing malicious sequences of formatting delimiters, the regular expression engine is forced into catastrophic backtracking, resulting in CPU exhaustion and application denial of service.
The Python package pymdown-extensions provides a set of formatting and feature extensions for the standard Python Markdown implementation. These extensions are widely deployed in web applications, content management systems, wiki platforms, and static site generator pipelines to process user-supplied Markdown content into HTML.
The attack surface exists in the inline text parsers, which process formatted text runs such as superscripts, subscripts, emphasis, and auto-linked URLs. Specifically, the Caret, Tilde, BetterEm, and MagicLink inline processors fail to restrict backtracking pathways when evaluating complex or malformed sequences of formatting delimiters. This behavior exposes the system to unauthenticated, remote Regular Expression Denial of Service (ReDoS) attacks under CWE-1333.
Python's native re module uses a Non-deterministic Finite Automaton (NFA) regular expression engine. NFA engines evaluate inputs via backtracking, testing matching combinations sequentially until a match is found or all possibilities are exhausted. If a regular expression contains nested or overlapping quantifiers, the number of potential matching pathways grows exponentially with the length of the input string.
The vulnerability in the delimiter-based processors (Caret, Tilde, and BetterEm) stems from the nested non-capturing groups designed to match formatting runs. For example, the STAR_EM2 pattern contains the nested group ((?:[^\*]|\*{2,})+?). Within this group, the engine can match a contiguous run of asterisks by repeating the outer group, matching two asterisks via \*{2,}, or partitioning the run into multiple smaller matches. When presented with an unmatched input containing many contiguous delimiters, the engine must evaluate every possible integer partition of that delimiter run, leading to O(2^N) complexity.
In the MagicLink processor, the host-matching sub-pattern [^_\W][-\w]*(?:\.[-\w.]+)* contains overlapping paths. The character class [-\w.]+ inside the nested group includes the literal dot character, while the outer group is also repeated over dots. A long domain containing multiple dots that ultimately fails downstream validation causes the engine to evaluate every permutation of dot matches, exhausting CPU cycles.
The vulnerability was resolved by converting overlapping patterns into mutually exclusive paths and simulating possessive quantifiers to prevent backtracking. The key modification in the delimiter-based processors (such as Caret and BetterEm) involves adding a negative lookahead to the delimiter quantifier.
# Vulnerable configuration in BetterEm
STAR_EM2 = r'(?<!\*)(\*)(?![\*\s])((?:[^\*]|\*{2,})+?)(?<![\*\s])(\*)(?!\*)'
# Patched configuration in BetterEm (11.0.1)
STAR_EM2 = r'(?<!\*)(\*)(?![\*\s])((?:[^\*]|\*{2,}(?!\*))+?)(?<![\*\s])(\*)(?!\*)'By appending (?!\*) to \*{2,}, the engine is forced to consume all contiguous asterisks in a single step. The negative lookahead prevents the engine from splitting the delimiter run into smaller components for alternative evaluation loops, effectively blocking the backtracking pathway.
For magiclink.py, the nested quantifier structures were flattened entirely. The patch replaces the nested loops with a single non-overlapping choice.
# Vulnerable host pattern in MagicLink
RE_LINK_OLD = r'(?:ht|f)tps?://[^_\W][-\w]*(?:\.[-\w.]+)*'
# Patched host pattern in MagicLink (11.0.1)
RE_LINK_NEW = r'(?:ht|f)tps?://[^_\W](?:[-\w]|\.(?!=$))*'In the patched version, the sequence matches either a word character or a literal dot that is not at the end of the line. Because these choices are mutually exclusive, the processing time scales linearly, O(N), preventing ReDoS.
An attacker does not require authentication or specific system configuration to exploit this vulnerability. The only prerequisite is an exposed application endpoint that accepts and renders markdown content, such as a comment section, wiki editor, or API endpoint.
The payload is crafted to satisfy the initial assertion of a parser but fail the final boundary constraint, forcing a full backtrack. For example, sending a string starting with a single caret, followed by a alphanumeric character, and ending with a run of thirty carets (e.g., ^a^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^) will trigger the vulnerability in the Caret processor.
Because the input string lacks a valid closing boundary, the parser must backtrack through all possible groupings of the thirty trailing carets. A run of this length forces billions of operations, pinning a single CPU core at 100% utilization. If the web server runs a synchronous single-threaded process model, that worker process becomes entirely unresponsive to any subsequent requests.
The security impact of CVE-2026-67422 is high availability disruption. While it does not allow remote code execution or data leakage directly, the ease of triggering CPU exhaustion makes it highly effective for targeted denial of service.
In typical web environments, server workers (such as Gunicorn or uWSGI threads) are limited. An attacker can systematically disable all active workers by submitting a handful of concurrent requests containing the crafted payload, causing a complete application outage. The vulnerability receives a CVSS v3.1 base score of 7.5 due to its network-accessible, unauthenticated nature and low attack complexity.
The primary remediation step is upgrading the pymdown-extensions library to version 11.0.1 or higher. This update replaces the inefficient regular expressions with safe, non-backtracking alternatives.
For systems where an immediate upgrade is not feasible, temporary mitigation strategies can be applied at the application boundary. Developers should enforce a strict length limit on all user-submitted Markdown inputs to reduce the performance impact of backtracking. Additionally, Web Application Firewalls (WAFs) or input validation layers can be configured to reject strings containing excessive consecutive repetitions of formatting delimiters like asterisks, carets, or tildes.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
pymdown-extensions facelessuser | < 11.0.1 | 11.0.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-1333 |
| Attack Vector | Network |
| CVSS Score | 7.5 (High) |
| EPSS Score | 0.00582 (Percentile: 44.59%) |
| Impact | Denial of Service (CPU Exhaustion) |
| Exploit Status | Proof-of-Concept Available |
| KEV Status | Not Listed |
The application uses a regular expression that can take an exponential amount of time to compute relative to the size of the input string, leading to Denial of Service.
A critical unrestricted file upload vulnerability (CWE-434) in CodeIgniter4 allows unauthenticated remote attackers to execute arbitrary code. By bypassing weak validation filters in the `is_image` and `mime_in` rules, an attacker can upload a malicious PHP payload disguised as a valid image file.
A technical analysis of the use-after-free (UAF) vulnerability in the Ruby JSON gem (CVE-2026-71847) that impacts versions 2.20.0 through 2.21.1. This vulnerability occurs when parsing incomplete stream data containing duplicate keys.
An Algorithmic Complexity Denial of Service (DoS) vulnerability exists in the Hono web application framework within its languageDetector middleware. From version 4.12.0 to 4.12.33, the progressive language-tag truncation routine (normalizeLanguage) performs string operations with a quadratic time complexity O(N^2) relative to the number of hyphen-separated subtags in the user-supplied language tag. This allows an unauthenticated remote attacker to cause resource exhaustion and CPU spikes, resulting in a full denial of service of the single-threaded JavaScript runtime.
A vulnerability in the Hono framework's Proxy Helper allows the exposure of connection-scoped, internal, or session-specific metadata to unauthorized actors. The proxy helper fails to remove header fields dynamically listed in the response's Connection header, violating RFC 9110 Section 7.6.1.
A session data exposure vulnerability in the Hono web application framework (hono/jsx module) allows consecutive users to receive cached HTML outputs containing private data. When JSX components wrapped in `memo()` are rendered on the server, the caching mechanism utilizes a module-level closure that persists across independent HTTP requests. When subsequent requests occur with matching props, the components are not re-evaluated, and cached HTML is served. If these components read request-scoped or session-specific data via ambient APIs, the data of the first user is exposed to subsequent users.
A severe, twelve-year-old cryptographic weakness in crypto-js (versions < 4.0.0) generated pseudorandom numbers using a custom Multiply-With-Carry (MWC) algorithm seeded from the non-secure Math.random(). This reduces 128-bit and 256-bit key spaces to just 2^39 and 2^47 possibilities, allowing offline brute-force attacks.