Feb 25, 2026·6 min read·51 visits
The Anthropic MCP TypeScript SDK failed to properly sanitize regex generation for 'exploded' URI templates. Attackers can send a string of commas to a vulnerable server, triggering an exponential regex calculation that hangs the Node.js event loop indefinitely. Fixed in version 1.25.2.
A high-severity Regular Expression Denial of Service (ReDoS) vulnerability exists in the Anthropic Model Context Protocol (MCP) TypeScript SDK. By crafting specific URI patterns containing 'exploded' array variables, an attacker can trigger catastrophic backtracking in the `UriTemplate` class. This vulnerability exploits the single-threaded nature of Node.js, allowing a single malicious request to peg the CPU at 100% and deny service to all other users.
The Model Context Protocol (MCP) is the new shiny standard for connecting AI models to data sources. It’s the plumbing that lets an LLM read your git repo or query your database. Naturally, because it's 2026, we’re writing the SDKs in TypeScript. And where there is TypeScript, there is Node.js. And where there is Node.js, there is the ever-looming threat of the single-threaded event loop being held hostage by a bad regular expression.
CVE-2026-0621 isn't a complex memory corruption bug or a buffer overflow. It’s a classic logic error in how the SDK parses URIs. Specifically, the UriTemplate class—responsible for routing requests to resources—has a fatal flaw in how it handles "exploded" variables (like {/id*}).
Why does this matter? Because MCP servers are often public-facing or internal-critical gateways. If you can kill the gateway, you blind the AI. It's effectively a "kill switch" for any agentic workflow relying on this SDK, accessible via a single, unauthenticated HTTP request.
The root cause lies in src/shared/uriTemplate.ts. The developers needed to support RFC 6570 "exploded" path expansion. This is where a template like {/ids*} turns a list ['a', 'b'] into /a,b. To match incoming URIs against these templates, the SDK dynamically generates a Regular Expression.
Here is the logic they used for an exploded path segment:
// The code asks: "Match anything that isn't a slash,
// followed by optional groups of (comma + anything that isn't a slash)"
pattern = part.exploded ? '([^/]+(?:,[^/]+)*)' : '([^/,]+)';Do you see the ambiguity? The definition of "anything that isn't a slash" ([^/]) includes the comma (,).
The regex structure is effectively (A+(BA+)*) where A overlaps with B. When the regex engine sees a string of commas like ,,,,,,, it panics. It doesn't know if a specific comma should be consumed by the initial [^/]+ or by the subsequent (?:,[^/]+)* group. Because regex engines are eager to please, they try every possible combination of assignments. This is catastrophic backtracking, leading to exponential execution time ($O(2^n)$).
It is rare that a high-severity denial of service is fixed by adding a single character to a character class, but here we are. The fix involves explicitly telling the regex engine that the "content" part of the group cannot contain the "separator" (the comma).
Here is the breakdown of the patch in src/shared/uriTemplate.ts:
switch (part.operator) {
case '':
// The character class [^/] implicitly allows commas
pattern = part.exploded ? '([^/]+(?:,[^/]+)*)' : '([^/,]+)';
break;switch (part.operator) {
case '':
// The character class [^/,] explicitly forbids commas
pattern = part.exploded ? '([^/,]+(?:,[^/,]+)*)' : '([^/,]+)';
break;By changing [^/]+ to [^/,]+, the two parts of the regex become mutually exclusive. A comma can only be matched by the literal comma separator in the second group, never by the character class in the first group. This forces the regex engine into a linear match ($O(n)$), saving the CPU from melting.
Exploiting this is trivially easy and requires no authentication if the MCP server exposes a resource using exploded templates. The attacker just needs to send a URI path that looks like a valid resource but contains a massive chain of commas, followed by a character that forces the regex to backtrack when it hits the end of the string.
Here is the attack flow:
const { UriTemplate } = require('@modelcontextprotocol/sdk');
// 1. Target a template with an exploded variable
const template = new UriTemplate('{/id*}');
// 2. Construct the payload
// 50 commas is usually enough to cause a noticeable lag.
// 3000 commas will hang the process for eternity.
const payload = '/' + ','.repeat(5000) + '!';
console.log("Starting match...");
const start = process.hrtime();
// 3. Trigger the hang
template.match(payload);
const end = process.hrtime(start);
console.log(`Matched in ${end[0]}s ${end[1] / 1000000}ms`);In a real-world scenario, you would send this payload to an endpoint like POST /mcp/rpc where the server attempts to route the request URI against its known schemas.
Node.js developers often fall into the trap of thinking, "My code is async, so blocking operations won't hurt me." Wrong. Regular expression matching in V8 (the JavaScript engine) is synchronous and runs on the main thread.
When this exploit triggers, the main thread enters a tight loop inside the C++ regex engine. While it is calculating the $2^{5000}$ ways to parse your commas:
setTimeout and setInterval are frozen.For an MCP server designed to be a high-availability bridge for AI agents, this is a total service collapse.
The fix is straightforward, but for those who cannot upgrade immediately, mitigation is tricky.
@modelcontextprotocol/sdk to version 1.25.2. This version contains the patch commit b392f02./{,}{10,}/). However, be careful not to block legitimate CSV-style data usage if your API supports it.CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
@modelcontextprotocol/sdk Anthropic | <= 1.25.1 | 1.25.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-1333 |
| Attack Vector | Network (AV:N) |
| CVSS v4.0 | 8.7 (High) |
| CVSS v3.1 | 7.5 (High) |
| Impact | High Availability (DoS) |
| Exploit Status | PoC Available |
| EPSS Score | 0.00022 |
The software uses a regular expression that can take a very large amount of time to evaluate specific input strings, leading to a Denial of Service.
An LDAP injection vulnerability exists in the centraldogma-server-auth-shiro module of LY Corporation Central Dogma before version 0.84.0. The search logic dynamically constructs LDAP search filters by interpolating user-provided usernames without escaping RFC 4515 metacharacters. Unauthenticated remote attackers can leverage this flaw to bypass authentication, enumerate directory hierarchies, and access unauthorized resources.
CVE-2026-11746 is a critical vulnerability in Central Dogma Server prior to version 0.84.0, where an embedded ZooKeeper replication secret silently falls back to a publicly known, hard-coded default string ('ch4n63m3'). Remote attackers with access to the replication network can authenticate as legitimate cluster peers, potentially leading to unauthorized data exposure, state manipulation, or complete cluster takeover.
A logical verification flaw in ZITADEL's external JWT Identity Provider validation allows attackers to bypass session expiration checks. If an incoming JWT lacks the 'exp' claim, the system skips validation entirely, creating an indefinitely valid session. This issue has been addressed in versions 3.4.12 and 4.15.2.
CVE-2026-59149 identifies a directory traversal vulnerability in `@mockoon/commons-server`, the backend mock-server library powering the Mockoon application. The flaw occurs in the path containment validation logic used during raw file response generation. An unauthenticated attacker can exploit this weakness to retrieve arbitrary files from sibling directories sharing a common prefix with the designated static base directory.
An in-depth analysis of CVE-2026-59148, a high-severity flaw in Mockoon where unauthenticated administrative endpoints and a wildcard Cross-Origin Resource Sharing (CORS) policy allow remote execution, state poisoning, and credential theft.
An improper authentication vulnerability (CWE-287) in ZITADEL's external identity provider handler before version 4.15.3 allows remote attackers to perform complete account takeover. When auto-linking by email is enabled, ZITADEL verifies that the local target account has a verified email address but fails to verify if the external provider confirmed ownership of that same email. Attackers can exploit this by registering an unverified account with a victim's email address on a permissive external provider, leading to unauthorized account binding and persistent access.