GHSA-mh25-x5hq-wrqp: High severity composer/league/commonmark vulnerability
Impact
UniqueSlugNormalizer::normalize() makes each slug document-unique by searching for an unused numeric suffix, but restarts that search from 1 on every collision. The k-th heading that collapses to the same base slug performs k−1 array lookups, so K colliding slugs cost Σ(k−1) = O(K²). An attacker can force every heading onto a single base slug trivially — many empty ATX headings, identical heading text, or punctuation-only headings that normalize to the empty string.
The path is reached whenever the shared slug normalizer runs over attacker-controlled text. That happens when HeadingPermalinkExtension is registered (its HeadingPermalinkProcessor normalizes every heading), independently through FootnoteExtension (its AnonymousFootnoteRefParser normalizes every ^[label] reference), and on any TableOfContentsExtension site (which requires HeadingPermalinkExtension to be co-registered). The default slugnormalizer/unique setting (UniqueSlugNormalizerInterface::PERDOCUMENT) accumulates collisions across the whole document. No authentication is required — a small document body turns into seconds of CPU and denies service. Availability impact only. UniqueSlugNormalizer was introduced in 2.0.0 (first shipped in 2.0.0-beta1, May 2021); the 1.x heading-permalink slug generator performed no de-duplication and is not affected. All 2.x releases (including 2.8.x) are affected.
Workarounds
Integrators who cannot upgrade immediately can:
- Set slugnormalizer/unique to false / UniqueSlugNormalizerInterface::DISABLED, which stops the de-duplication scan entirely — at the cost of losing id uniqueness (colliding headings then share an anchor). - Disable HeadingPermalinkExtension (and TableOfContentsExtension, which depends on it), and FootnoteExtension where anonymous footnotes reach the same normalizer, for untrusted Markdown. - Cap the accepted document size / heading count upstream so K cannot reach the quadratic danger zone.
Each of these trades off functionality or correctness; upgrading to the patched release (which removes the quadratic behavior while keeping unique ids and identical output) is the recommended remediation.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
composer/league/commonmarkto a version that resolves this vulnerability.Fixed in 2.9.0 - Configuration
Disable `HeadingPermalinkExtension` for untrusted Markdown (and also disable `TableOfContentsExtension`, which depends on it).
HeadingPermalinkExtension enabled/registration = disabled - Configuration
Disable `FootnoteExtension` for untrusted Markdown where anonymous footnotes reach the same slug normalizer.
FootnoteExtension enabled/registration = disabled - Configuration
Set `slug_normalizer/unique` to `false` / `UniqueSlugNormalizerInterface::DISABLED` to stop the de-duplication scan (accepting possible anchor id collisions).
slug_normalizer/unique (UniqueSlugNormalizerInterface) slug_normalizer/unique = false / UniqueSlugNormalizerInterface::DISABLED - Compensating control
Cap the accepted document size / heading count upstream so K cannot reach the quadratic danger zone.