GHSA-253c-mchw-3w2r: markdown-it linkify True Has Two Quadratic Paths, Vulnerability
MODERATEGHSA-253c-mchw-3w2r is a MODERATE true has two quadratic paths, vulnerability (CWE-400: Uncontrolled Resource Consumption) affecting markdown-it linkify libraries in the npm ecosystem. The issue involves true has two quadratic paths, so a few hundred kb of markdown blocks the event loop for tens of seconds. Remediation is available by upgrading affected packages to version 15.0.1, 14.3.1.
GHSA-253c-mchw-3w2r at a Glance
How to Fix GHSA-253c-mchw-3w2r
To remediate this vulnerability, upgrade all affected markdown-it linkify dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
npm install markdown-it@15.0.1
npm install markdown-it@14.3.1
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
npm ls markdown-it
How to Check if You Are Affected
To determine whether your Node.js application is affected by GHSA-253c-mchw-3w2r, inspect your project dependencies using npm:
npm ls markdown-it
Analyze the terminal output to locate any version of markdown-it linkify in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 15.0.1), your application is affected.
Note: The npm ls markdown-it command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-400: Uncontrolled Resource Consumption, where the product does not properly control the allocation and maintenance of a limited resource. In markdown-it linkify, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
GHSA-253c-mchw-3w2r Affected markdown-it linkify Versions
2 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
markdown-it
|
npm |
≥ 15.0.0
< 15.0.1
All 1 versions
15.0.0
|
15.0.1
|
|
markdown-it
|
npm |
< 14.3.1
|
14.3.1
|
References
Frequently Asked Questions
What is GHSA-253c-mchw-3w2r?
Which markdown-it linkify versions are affected?
What version fixes GHSA-253c-mchw-3w2r?
Is markdown-it affected?
What CWE is associated with GHSA-253c-mchw-3w2r?
How can I check npm dependencies for GHSA-253c-mchw-3w2r?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-253c-mchw-3w2r",
"modified" : "2026-09-29T17:57:56Z",
"published" : "2026-09-29T17:57:56Z",
"aliases" : [ ],
"summary" : "markdown-it linkify: true has two quadratic paths, so a few hundred KB of markdown blocks the event loop for tens of seconds",
"details" : "## Summary\n\nTwo independent quadratic paths in the `linkify: true` handling. Both are in markdown-it's own code rather than in linkify-it, which stays linear on both payloads.\n\n`src/rules_core/linkify.ts` calls `arrayReplaceAt` once per linkified text token, and that rebuilds the whole `children` array each time. A paragraph of N soft-broken lines is one inline token with about 2N children, so you get N rebuilds over a 2N array. Schema-less emails are what reach it. A `http://` link gets consumed by the inline rule first and never arrives as a text token, so those stay linear.\n\n`src/rules_inline/linkify.ts` runs `state.pending.match(SCHEME_RE)` at every `://` in the source. `state.pending` only gets truncated once a link is actually produced, so an unregistered scheme leaves it growing and every `://` rescans the lot.\n\n## Proof of concept\n\nClean install of 15.0.0 from npm, `new MarkdownIt({ linkify: true }).render(payload)`, Node 24.\n\n| N | 5,000 | 10,000 | 20,000 | 40,000 |\n|---|---|---|---|---|\n| `'a@b.co\\n'.repeat(N)`, 34KB to 273KB | 1.1s | 4.7s | 19.6s | 89s |\n| `'a://'.repeat(N)`, 20KB to 156KB | 0.25s | 0.76s | 3.1s | 15.0s |\n\nDoubling the input roughly quadruples the time in both. With `linkify: false` the same inputs run in 25 to 131ms and stay flat.\n\nControls for the first one, all at N=20000: putting every email in a single text token (`'a@b.co '`) takes 0.59s, one email per paragraph (`'a@b.co\\n\\n'`) takes 0.64s, and soft-broken lines with nothing linkifiable take 42ms. So it needs many children AND many of them linkifying. For the second, replaying just the `SCHEME_RE` calls against the same growing prefixes with no markdown-it involved accounts for 11.7s of the 15s.\n\nOrdinary prose does it too. `'ping a@b.co ok\\n'.repeat(20000)` is 293KB and takes 31s.\n\n## Caveat\n\n`linkify` is off by default, so this only reaches apps that turn it on.\n\n## Impact\n\nAvailability only. A few hundred KB of fairly ordinary markdown pins one core for tens of seconds, and because it's quadratic it degrades quickly with size. Nothing is read, written or executed.",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "npm",
"name" : "markdown-it"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "15.0.0"
}, {
"fixed" : "15.0.1"
} ]
} ],
"versions" : [ "15.0.0" ]
}, {
"package" : {
"ecosystem" : "npm",
"name" : "markdown-it"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "14.3.1"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/markdown-it/markdown-it/security/advisories/GHSA-253c-mchw-3w2r"
}, {
"type" : "WEB",
"url" : "https://github.com/markdown-it/markdown-it/commit/09fa07118dda4c953f058848f53dae88395618ca"
}, {
"type" : "WEB",
"url" : "https://github.com/markdown-it/markdown-it/commit/aaadcfa6d817b3c5f89afb49d97c7b797a6dd4fd"
}, {
"type" : "WEB",
"url" : "https://github.com/markdown-it/markdown-it/commit/ad70f6b7cff64bee10e42a774147112480ca0d49"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/markdown-it/markdown-it"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-400", "CWE-407" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-09-29T17:57:56Z",
"nvd_published_at" : null
}
}