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-JFM3-95JQ-Q3RF

GHSA-jfm3-95jq-q3rf: Algorithmic Complexity Denial of Service and Path-Delimiter Injection in league/commonmark Footnote Extension

Alon Barad
Alon Barad
Software Engineer

Aug 7, 2026·8 min read·2 visits

Executive Summary (TL;DR)

Unauthenticated remote attackers can exhaust server memory and CPU resources or crash the PHP worker process by submitting crafted footnote definitions containing duplicate labels or path-delimiting characters.

An architectural flaw in the Footnote extension of league/commonmark allows unauthenticated remote attackers to trigger severe denial of service conditions through algorithmic complexity exploitation (O(N^2) CPU and memory exhaustion) and path-delimiter injection leading to unexpected application-level crashes.

Vulnerability Overview

league/commonmark is a widely adopted Markdown processing library for PHP. The FootnoteExtension, introduced in version 1.5.0, enables native parsing and rendering of footnotes and their associated backreferences. This extension is typically used in applications accepting rich-text content from users, such as content management systems, blogs, or collaborative portals.

Because the footnote parser processes document structure prior to final HTML generation, it exposes an unauthenticated attack surface to anyone capable of submitting Markdown content. If the extension is enabled, an attacker can exploit structural processing weaknesses to trigger severe denial of service conditions. The issues stem from algorithmic inefficiencies and insecure key-value configuration storage mechanisms inside the parser's event-driven pipeline.

The vulnerability is tracked under GitHub Security Advisory ID GHSA-jfm3-95jq-q3rf. It has a CVSS v3.1 base score of 7.5, reflecting a high-severity impact on system availability. Remediation requires an update to the underlying library or disabling the affected extension altogether.

Root Cause Analysis

The vulnerability consists of two primary logical failures in the Footnote extension parser. The first failure is an algorithmic complexity issue ($O(N^2)$ complexity) located in the interaction between footnote definitions and their backreferences. The second failure is an injection vulnerability resulting from path delimiter parsing inside the library's internal configuration management system.

In the first issue, the parser processes footnote definitions using an event listener called GatherFootnotesListener. Under normal conditions, a single footnote definition maps to one or more references. However, the parser fails to enforce uniqueness constraints on footnote labels. When multiple duplicate footnote definitions exist for the same label, the system processes every duplicate definition block separately and associates each block with all existing backreferences. This creates an $O(M \times N)$ operational multiplier, where $M$ is the number of footnote references and $N$ is the number of duplicate footnote definitions.

In the second issue, the NumberFootnotesListener stores footnote references inside a metadata configuration dictionary managed by $document->data. This data container processes keys containing period (.) or slash (/) characters as nested path delimiters. Because the footnote destination labels are derived directly from user input, an attacker can inject path-delimiter characters. This causes the data manager to interpret literal strings as multidimensional array indices, leading to structural collisions, data mutation, or fatal PHP type mismatches.

Code Analysis

To understand the structural failure, we examine the logic of GatherFootnotesListener and NumberFootnotesListener prior to commit 66028124a17ba193da7b11cc3dfda92df21bfbf4.

In the vulnerable implementation of the footnote accumulator, the iterator iterates over all block nodes without checking if a given footnote label has already been declared. This allows redundant Footnote nodes to remain within the abstract syntax tree. For each node, it creates backreferences repeatedly based on keys stored in the document data:

// Vulnerable implementation of GatherFootnotesListener
foreach ($document->iterator(NodeIterator::FLAG_BLOCKS_ONLY) as $node) {
    if (! $node instanceof Footnote) {
        continue;
    }
    // User-controlled destination label is turned into a configuration lookup key
    $key = '#' . $this->config->get('footnote/footnote_id_prefix') . $node->getReference()->getDestination();
    if ($document->data->has($key)) {
        // Generates backref nodes for each duplicate footnote block
        $this->createBackrefs($node, $document->data->get($key));
    }
}

The corresponding patch addresses this by performing a tracking pass to deduplicate defined footnote labels. The duplicate nodes are cataloged and removed from the syntax tree prior to the generation of backreferences. This reduces the processing complexity from $O(N^2)$ down to a safe linear $O(N)$ execution path.

// Patched implementation of GatherFootnotesListener
$definitions = [];
$discarded   = [];
 
foreach ($document->iterator(NodeIterator::FLAG_BLOCKS_ONLY) as $node) {
    if (! $node instanceof Footnote) {
        continue;
    }
    $label = $node->getReference()->getLabel();
    if (isset($definitions[$label])) {
        // Identify redundant duplicate blocks for removal
        $discarded[] = $node;
        continue;
    }
    $definitions[$label] = $node;
}
 
// Process only unique footnote definitions
foreach ($definitions as $node) {
    $key = '#' . $this->config->get('footnote/footnote_id_prefix') . $node->getReference()->getDestination();
    if (isset($backrefs[$key])) {
        $this->createBackrefs($node, $backrefs[$key]);
    }
}
 
// Detach the duplicate blocks to prevent downstream structural issues
foreach ($discarded as $duplicate) {
    $duplicate->detach();
}

Additionally, the dot-notation path traversal issue in NumberFootnotesListener is resolved. Instead of writing references dynamically using $document->data->append($destination, $reference), the library now aggregates backreferences in a native PHP associative array ($backrefs), which treats delimiters like dot and slash as standard characters. The aggregate array is subsequently stored under a single, secure nested dictionary path.

// Patched reference storage mechanism in NumberFootnotesListener
$backrefs = [];
foreach ($document->iterator() as $node) {
    // ... processes nodes ...
    // Safe insertion into a native PHP associative array instead of dot-notation storage
    $backrefs[$existingReference->getDestination()][] = $newReference;
}
// Write safe structured container to configuration
$document->data->set('footnote/backrefs', $backrefs);

Exploitation & Attack Methodology

Exploitation of the algorithmic complexity vulnerability requires only an unauthenticated HTTP request containing a crafted Markdown body. The attacker does not need special privileges or a specific session state. The target endpoint must parse user-supplied input using the league/commonmark parser with the FootnoteExtension enabled.

To construct an algorithmic complexity exploit payload, an attacker defines a highly repetitive list of footnote references matched with a corresponding block of duplicate footnote definitions. Because the parser attempts to map each reference to every duplicate definition, the payload size scales linearly while execution complexity scales quadratically.

This is a reference[^a] and another[^a] and another[^a] (repeated M times)
 
[^a]: Definition 1
[^a]: Definition 2
[^a]: Definition 3 (repeated N times)

For example, setting $M = 1000$ and $N = 1000$ results in a payload size of approximately 10 kilobytes. Processing this payload forces the parser to allocate more than 440 megabytes of memory and consume over 3 seconds of CPU execution. This exceeds typical default web server limitations, such as the PHP memory_limit of 128MB, triggering an immediate out-of-memory crash of the worker process.

Alternatively, path delimiter injection is triggered by utilizing footnote labels with nested periods. When parsing the document, the internal data manager interprets the dot notation as an array traversal instruction. If the target structure has a different format than expected (such as a string instead of an array), PHP throws a fatal runtime error and halts execution.

[^a] and [^a.b]
 
[^a]: base note
[^a.b]: nested path note

Impact Assessment

The impact of this vulnerability is a high-severity Denial of Service (DoS) affecting the availability of the application server. When a web server processes the malicious Markdown payload, the target PHP process consumes 100% CPU capacity and runs out of allocatable memory. This leads to the termination of the active PHP-FPM worker or Apache child process.

If multiple requests are submitted concurrently, an attacker can easily exhaust the entire pool of available web worker processes. This leaves the server unable to respond to legitimate HTTP traffic, resulting in a persistent offline state for the web application. Because the exploit payload is exceptionally small (approximately 10 KB), standard network-level mitigations such as maximum request size limits are ineffective.

Additionally, the path-delimiter injection flaw allows attackers to reliably crash any PHP script that parses footnote references. Because this error results in a fatal runtime exception, it bypasses standard application-level try-catch handling blocks, preventing graceful degradation or error reporting.

There is no known risk of remote code execution or data exposure associated with this vulnerability. The weakness is categorized strictly under CWE-407 (Inefficient Algorithmic Complexity) and CWE-400 (Uncontrolled Resource Consumption).

Remediation & Mitigation Guidance

The absolute remediation for this vulnerability is to upgrade the league/commonmark library to version 2.9.0 or higher. This release contains the formal patch that deduplicates footnote definitions and replaces the insecure dot-notation storage mechanism.

For environments where an immediate package upgrade is not feasible, the following workarounds can be implemented:

First, disable the FootnoteExtension from the Markdown configuration environment. If the extension is not registered, the parser treats footnote syntax as standard plaintext, completely neutralizing the attack vector.

// Insecure Configuration
$environment->addExtension(new FootnoteExtension());
 
// Mitigated Configuration (Remove the above line entirely)

Second, implement application-level pre-parsing filters. You can use regular expressions to detect duplicate footnote labels or labels containing period or slash characters prior to invoking the league/commonmark compiler. If any invalid or duplicate footnote pattern is detected, the application should reject the input before execution reaches the vulnerable parsing engine.

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Affected Systems

league/commonmark (Composer package, PHP)

Affected Versions Detail

Product
Affected Versions
Fixed Version
league/commonmark
thephpleague
>= 1.5.0, < 2.9.02.9.0
AttributeDetail
CWE IDCWE-407 (Inefficient Algorithmic Complexity)
Attack VectorNetwork (Remote, Unauthenticated)
CVSS v3.1 Score7.5 (High)
Impact TypeDenial of Service (OOM and CPU Exhaustion)
Exploit StatusProof of Concept available
KEV StatusNot listed

MITRE ATT&CK Mapping

T1499.003Endpoint DoS: Application Exhaustion
Impact
CWE-407
Inefficient Algorithmic Complexity

The product or application uses an algorithm or data structure with an inefficient worst-case complexity (such as quadratic O(N^2)) that can be abused by an attacker to consume excessive resources.

Vulnerability Timeline

Vulnerability patched in source repository
2026-08-03
Official package version 2.9.0 released
2026-08-06
GHSA security advisory published
2026-08-06

References & Sources

  • [1]GitHub Advisory Database Entry
  • [2]Vendor Security Advisory
  • [3]Official Patch Commit
  • [4]Release v2.9.0 Changelog

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

•about 1 hour ago•GHSA-WVPP-8HX9-P66J
9.8

GHSA-WVPP-8HX9-P66J: Arbitrary Command Execution via Option Guard Bypass in GitPython

An unsafe option guard bypass vulnerability exists in GitPython before version 3.1.58. When keyword arguments are passed to Git commands with split_single_char_options=False, GitPython's argument validation helper fails to inspect the combined short-option value. This discrepancy allows short-option token smuggling or clustering manipulation, enabling remote attackers to bypass option blocklists and execute arbitrary system commands.

Alon Barad
Alon Barad
2 views•8 min read
•about 2 hours ago•GHSA-WG23-69C2-GJC8
9.1

GHSA-WG23-69C2-GJC8: Passkey Login Replay Vulnerability in Craft CMS

GHSA-WG23-69C2-GJC8 is a critical security vulnerability discovered in the native Passkey (WebAuthn) login implementation of Craft CMS. The vulnerability allows an attacker to bypass WebAuthn's core cryptographic challenge-response and signature-counter replay protections. By intercepting a single successful passkey login request body, an attacker can replay the identical request payload to generate additional authenticated active sessions, resulting in complete account takeover.

Alon Barad
Alon Barad
1 views•6 min read
•about 4 hours ago•GHSA-MH25-X5HQ-WRQP
7.5

GHSA-MH25-X5HQ-WRQP: Algorithmic Complexity Denial of Service in league/commonmark UniqueSlugNormalizer

An algorithmic complexity vulnerability in the UniqueSlugNormalizer component of the league/commonmark PHP library allows unauthenticated remote attackers to trigger severe CPU resource consumption and Denial of Service (DoS) by submitting a Markdown document containing a high volume of duplicate headings. The slug generation loop resets its sequential search index back to 1 for every collision, resulting in a quadratic execution path. This flaw affects versions from 2.0.0-beta1 up to and including 2.8.3, and is patched in version 2.9.0.

Alon Barad
Alon Barad
1 views•6 min read
•about 5 hours ago•GHSA-MJ63-M3RC-8PPR
5.3

GHSA-MJ63-M3RC-8PPR: Quadratic-Time Complexity in league/commonmark XML Pretty-Printing

A Denial of Service vulnerability exists in the league/commonmark package for PHP when using the XML rendering subsystem. Due to unconstrained indentation based on AST depth, rendering deeply nested elements leads to asymmetric resource consumption (quadratic output size complexity).

Amit Schendel
Amit Schendel
2 views•7 min read
•about 6 hours ago•GHSA-265M-7826-WJQM
8.7

GHSA-265m-7826-wjqm: Authenticated Remote Code Execution in Craft CMS via condition.config JSON Cleanse Bypass

Craft CMS contains an authenticated remote code execution vulnerability due to a sanitization bypass in its search condition configuration parser. An attacker with access to the control panel can inject unsafe Yii2 behavior configurations wrapped inside a JSON-encoded string. When decoded and merged by the application, these keys bypass the global config cleanse filter and are evaluated by the Yii2 component factory, leading to arbitrary code execution.

Alon Barad
Alon Barad
3 views•7 min read
•about 7 hours ago•GHSA-F5WM-88JV-G5HX
8.7

GHSA-F5WM-88JV-G5HX: Authenticated Remote Code Execution via Twig Sandbox Escape in Craft CMS

An authenticated remote code execution vulnerability exists in Craft CMS due to a flaw in how the Twig template sandbox policy handles class-level allowlists. Prior to the fix, the security policy allowed arbitrary public methods from parent classes of allowed interfaces, allowing authenticated attackers to invoke Yii component methods such as attachBehavior on element models to load arbitrary classes and execute system commands.

Alon Barad
Alon Barad
1 views•6 min read