Introduction
linkify-it is the autolinking engine behind popular markdown renderers like markdown-it — it scans plain text for things that look like URLs, emails, or mailto: addresses and turns them into clickable links. Because it runs on untrusted input (comments, markdown documents, chat messages, README files rendered on the fly), any inefficiency in its matching logic becomes a direct denial-of-service vector against whatever process is doing the rendering.
CVE-2026-59887 affects linkify-it 5.0.1: when the library's mailto: link matcher is handed a specially crafted address, it can burn a disproportionate amount of CPU time relative to the size of the input before it decides whether the text is or isn't a valid mailto link. An attacker doesn't need to control an entire document — a single crafted mailto: substring embedded in an otherwise ordinary paragraph is enough to trigger the slow path.
Affected Versions
| Affected | 5.0.1 |
| Fixed in | 5.0.2 |
| Ecosystem | npm |
| CVE / GHSA | CVE-2026-59887 / not assigned |
| CWE | unknown |
The Vulnerability Explained
linkify-it maintains a set of schema matchers — one for http:, one for mailto:, and so on — that are tried against every position in the text being scanned. The mailto: matcher has to validate the shape of an email address (local-part, @, domain) inline, without the benefit of a full email-parsing grammar, because it's operating character-by-character over arbitrary text rather than a pre-tokenized address field.
In 5.0.1, that inline validation logic could be pushed into a pathological processing path by a carefully constructed local-part/domain combination in a mailto: link. Instead of failing fast on invalid or edge-case input, the matcher spends far more time than the input length would justify — the hallmark of a resource-exhaustion bug rather than a memory-safety one.
Attack scenario: Consider a service that renders user-submitted markdown with markdown-it and has linkify: true enabled (the common configuration for "GitHub-flavored" rendering). An attacker submits a comment or issue body containing a normal-looking paragraph with one crafted mailto: link buried in it. When the server calls into markdown-it's renderer — which delegates to linkify.match() under the hood — the request thread stalls processing that single document. Repeat the submission a handful of times concurrently, and the render workers (or the whole Node.js event loop, if rendering happens synchronously on it) back up, degrading or halting the service for all users — a classic high-severity availability issue with a very low bar to exploit.
The trivy scan that flagged this in the dependency tree couldn't confirm reachability from source, but any code path that feeds attacker-influenced text into linkify-it's matching functions — directly or through markdown-it — is exposed.
The Fix
The remediation here is a dependency version bump, not a source-code patch in this repository: linkify-it is upgraded from 5.0.1 to 5.0.2 in the manifest and lockfile.
- "linkify-it": "5.0.1"
+ "linkify-it": "5.0.2"
Upstream, 5.0.2 corrects the mailto: matcher so that crafted local-part/domain input no longer forces the disproportionate scan behavior — the matcher now rejects malformed or adversarial mailto candidates without the excessive processing cost. Because the fix lives entirely inside linkify-it, no application code needs to change; consumers only need to pull in the patched dependency.
It's worth noting that the diff for this change is otherwise dominated by unrelated lockfile bookkeeping — moving a typedoc-material-theme entry from dependencies to devDependencies and marking a few Shiki-related packages as dev — none of which affects runtime behavior. The security-relevant change is exclusively the linkify-it version bump.
Key Takeaways
- If your app renders user-supplied markdown with
linkifyenabled, treatlinkify-itas directly reachable by attacker input, not as an incidental transitive dependency. - A DoS in a link-matching library doesn't need a huge payload — one crafted
mailto:substring inside a normal document is enough. - Pin and monitor
linkify-itversions the same way you would any parser that runs against untrusted text; 5.0.1 → 5.0.2 is a drop-in, no-API-change upgrade. - Rendering markdown synchronously on a shared event loop (e.g., Node.js) turns a single slow parse into a service-wide stall — consider isolating rendering for untrusted content regardless of this specific fix.
How Orbis AppSec Detected This
- Source: text passed into
linkify.match()/linkify.test()— typically user-submitted markdown, comments, or chat content routed throughmarkdown-it's linkify option. - Sink:
linkify-it's internalmailto:schema matcher, invoked automatically during autolink scanning. - Missing control: no bound on the processing cost of validating a crafted
mailto:local-part/domain combination before version 5.0.2. - CWE: unknown (not assigned in the advisory).
- Fix: Upgrade the
linkify-itdependency from 5.0.1 to 5.0.2, which patches themailto:matching logic.
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
CVE-2026-59887 is a reminder that autolinking libraries sit directly in the path of untrusted text, and a single inefficient matcher — here, the mailto: handler in linkify-it 5.0.1 — is enough to turn ordinary content rendering into a denial-of-service vector. The fix is a one-line dependency bump to 5.0.2, but the impact scales with how much of your rendering pipeline touches attacker-controlled text, so it's worth verifying the upgrade landed anywhere linkify-it or markdown-it's linkify option is in use.