CWE-407
Allowed-with-ReviewInefficient Algorithmic Complexity
Abstraction: Class · Status: Incomplete
An algorithm in a product has an inefficient worst-case computational complexity that may be detrimental to system performance and can be triggered by an attacker, typically using crafted manipulations that ensure that the worst case is being reached.
262 vulnerabilities reference this CWE, most recent first.
GHSA-5MF9-H53Q-7MHQ
Vulnerability from github – Published: 2026-04-07 15:30 – Updated: 2026-06-05 17:51An issue was discovered in 6.0 before 6.0.4, 5.2 before 5.2.13, and 4.2 before 4.2.30. MultiPartParser allows remote attackers to degrade performance by submitting multipart uploads with Content-Transfer-Encoding: base64 including excessive whitespace.
Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Seokchan Yoon for reporting this issue.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "Django"
},
"ranges": [
{
"events": [
{
"introduced": "6.0"
},
{
"fixed": "6.0.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "Django"
},
"ranges": [
{
"events": [
{
"introduced": "5.2"
},
{
"fixed": "5.2.13"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "Django"
},
"ranges": [
{
"events": [
{
"introduced": "4.2"
},
{
"fixed": "4.2.30"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-33033"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-08T15:29:16Z",
"nvd_published_at": "2026-04-07T15:17:39Z",
"severity": "MODERATE"
},
"details": "An issue was discovered in 6.0 before 6.0.4, 5.2 before 5.2.13, and 4.2 before 4.2.30. `MultiPartParser` allows remote attackers to degrade performance by submitting multipart uploads with `Content-Transfer-Encoding: base64` including excessive whitespace.\n\nEarlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected.\nDjango would like to thank Seokchan Yoon for reporting this issue.",
"id": "GHSA-5mf9-h53q-7mhq",
"modified": "2026-06-05T17:51:58Z",
"published": "2026-04-07T15:30:51Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33033"
},
{
"type": "WEB",
"url": "https://docs.djangoproject.com/en/dev/releases/security"
},
{
"type": "PACKAGE",
"url": "https://github.com/django/django"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2026-48.yaml"
},
{
"type": "WEB",
"url": "https://groups.google.com/g/django-announce"
},
{
"type": "WEB",
"url": "https://www.djangoproject.com/weblog/2026/apr/07/security-releases"
}
],
"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:H",
"type": "CVSS_V3"
}
],
"summary": "Django has potential DoS via MultiPartParser through crafted multipart uploads"
}
GHSA-5MJQ-6XVH-RMV2
Vulnerability from github – Published: 2026-08-13 21:36 – Updated: 2026-08-13 21:36A flaw in Elasticsearch allows a low-privileged authenticated user who can index documents to submit a single small document containing a crafted user-supplied input. Processing one such document occupies a worker thread from a bounded pool for a disproportionate amount of time, degrading the availability of indexing operations on the affected node.
{
"affected": [],
"aliases": [
"CVE-2026-72685"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-13T20:17:29Z",
"severity": "MODERATE"
},
"details": "A flaw in Elasticsearch allows a low-privileged authenticated user who can index documents to submit a single small document containing a crafted user-supplied input. Processing one such document occupies a worker thread from a bounded pool for a disproportionate amount of time, degrading the availability of indexing operations on the affected node.",
"id": "GHSA-5mjq-6xvh-rmv2",
"modified": "2026-08-13T21:36:11Z",
"published": "2026-08-13T21:36:11Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-72685"
},
{
"type": "WEB",
"url": "https://discuss.elastic.co/t/elasticsearch-8-19-20-9-4-5-security-update-esa-2026-77/389500"
}
],
"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"
}
]
}
GHSA-5P4M-2WFM-XMQJ
Vulnerability from github – Published: 2026-08-06 20:27 – Updated: 2026-08-06 20:27Quadratic CPU consumption in !!omap resolution (js-yaml 3.x and 4.x)
Summary
resolveYamlOmap() enforces key uniqueness for !!omap sequences with a linear
scan (objectKeys.indexOf(...)) inside the per-element loop, making resolution
O(n²) in the number of entries. A modestly sized YAML document therefore
consumes disproportionate CPU inside yaml.load(), giving a denial of service
against any consumer that parses untrusted YAML.
!!omap is registered in the default schema
(lib/schema/default.js → require('../type/omap')), so a plain
yaml.load(untrustedInput) with no options is affected — no custom schema or
non-default configuration is required.
This is the same weakness as CVE-2026-59870 / GHSA-724g-mxrg-4qvm, which was fixed in the 5.x line in 5.2.1. That fix was never backported: both currently maintained legacy lines still carry the original implementation.
Affected versions
| Line | Latest tested | Status |
|---|---|---|
| 3.x | 3.15.0 | Affected — objectKeys.indexOf(pairKey) at lib/type/omap.js:29 |
| 4.x | 4.3.0 | Affected — objectKeys.indexOf(pairKey) at lib/type/omap.js:30 |
| 5.x | 5.2.2 | Not affected — fixed in 5.2.1 (uses a Set) |
Both figures are the newest release of each line at the time of writing, so this is not a "you are on an old version" issue.
Details
lib/type/omap.js (js-yaml 4.3.0):
if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey)
else return false
objectKeys grows by one element per entry, and Array.prototype.indexOf is a
linear scan, so resolving an n-entry !!omap performs roughly
1 + 2 + … + n comparisons — quadratic in n. The work happens synchronously
inside yaml.load(), blocking the event loop for its whole duration.
The 5.x line already solves exactly this by tracking seen keys in a Set
(src/tag/sequence/omap.ts):
if (carrier.seen.has(key)) return 'duplicate key in ordered map'
carrier.seen.add(key)
Proof of concept
// poc.js — node poc.js
const yaml = require('js-yaml');
const doc = n => '!!omap\n' + Array.from({length: n}, (_, i) => `- k${i}: ${i}`).join('\n') + '\n';
for (const n of [10000, 20000, 40000, 80000]) {
const d = doc(n), t = Date.now();
yaml.load(d); // default schema, no options
console.log(`n=${n} bytes=${d.length} load=${Date.now() - t}ms`);
}
Measured (node v20.20.2, default heap, no flags)
js-yaml 4.3.0
n=10000 bytes=137787 load=54ms
n=20000 bytes=297787 load=169ms
n=40000 bytes=617787 load=646ms
n=80000 bytes=1257787 load=2607ms
js-yaml 3.15.0
n=10000 bytes=137787 load=53ms
n=20000 bytes=297787 load=166ms
n=40000 bytes=617787 load=641ms
n=80000 bytes=1257787 load=2567ms
Runtime grows by a factor of ~4 for each doubling of n, which is the
signature of O(n²) (linear growth would be ~2×).
Scaling further: a 2.48 MB document with 150,000 entries blocked
yaml.load() for 10.8 seconds.
Impact
Any service that parses attacker-influenced YAML with js-yaml 3.x or 4.x can be stalled with a small input. Because the loop is synchronous, a single request blocks the Node.js event loop and stalls every other request in the process — so the amplification is per-process, not just per-request.
Suggested severity: consistent with CVE-2026-59870 (the same weakness in 5.x), i.e. Availability-only impact, network attack vector, no privileges or user interaction required.
Suggested fix
Mirror the 5.x fix — replace the linear scan with a Set:
// lib/type/omap.js
const seen = new Set()
// ...
if (seen.has(pairKey)) return false
seen.add(pairKey)
This preserves the existing duplicate-key rejection semantics exactly while
making resolution O(n). A maxOmapLength-style cap would also work, but the
Set matches what 5.x already ships and requires no new option.
References
- CVE-2026-59870 / GHSA-724g-mxrg-4qvm — same weakness in 5.0.0–5.2.0, fixed in 5.2.1
lib/type/omap.js(3.x, 4.x) — the affected resolverlib/schema/default.js— registers!!omapin the default schema
Discovery
Found by an automated static-analysis and executed-proof-of-concept scanner run against js-yaml 4.2.0, then manually verified against 3.15.0 and 4.3.0 by executing the proof of concept above. All timings in this report were measured on the current releases of each line, not on the version originally scanned.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "js-yaml"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0"
},
{
"fixed": "4.3.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "js-yaml"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "3.15.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-06T20:27:32Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "# Quadratic CPU consumption in `!!omap` resolution (js-yaml 3.x and 4.x)\n\n## Summary\n\n`resolveYamlOmap()` enforces key uniqueness for `!!omap` sequences with a linear\nscan (`objectKeys.indexOf(...)`) inside the per-element loop, making resolution\n**O(n\u00b2)** in the number of entries. A modestly sized YAML document therefore\nconsumes disproportionate CPU inside `yaml.load()`, giving a denial of service\nagainst any consumer that parses untrusted YAML.\n\n`!!omap` is registered in the **default schema**\n(`lib/schema/default.js` \u2192 `require(\u0027../type/omap\u0027)`), so a plain\n`yaml.load(untrustedInput)` with no options is affected \u2014 no custom schema or\nnon-default configuration is required.\n\n**This is the same weakness as CVE-2026-59870 / GHSA-724g-mxrg-4qvm**, which was\nfixed in the 5.x line in 5.2.1. That fix was never backported: both currently\nmaintained legacy lines still carry the original implementation.\n\n## Affected versions\n\n| Line | Latest tested | Status |\n|---|---|---|\n| 3.x | **3.15.0** | Affected \u2014 `objectKeys.indexOf(pairKey)` at `lib/type/omap.js:29` |\n| 4.x | **4.3.0** | Affected \u2014 `objectKeys.indexOf(pairKey)` at `lib/type/omap.js:30` |\n| 5.x | 5.2.2 | **Not affected** \u2014 fixed in 5.2.1 (uses a `Set`) |\n\nBoth figures are the newest release of each line at the time of writing, so\nthis is not a \"you are on an old version\" issue.\n\n## Details\n\n`lib/type/omap.js` (js-yaml 4.3.0):\n\n```js\nif (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey)\nelse return false\n```\n\n`objectKeys` grows by one element per entry, and `Array.prototype.indexOf` is a\nlinear scan, so resolving an `n`-entry `!!omap` performs roughly\n`1 + 2 + \u2026 + n` comparisons \u2014 quadratic in `n`. The work happens synchronously\ninside `yaml.load()`, blocking the event loop for its whole duration.\n\nThe 5.x line already solves exactly this by tracking seen keys in a `Set`\n(`src/tag/sequence/omap.ts`):\n\n```ts\nif (carrier.seen.has(key)) return \u0027duplicate key in ordered map\u0027\ncarrier.seen.add(key)\n```\n\n## Proof of concept\n\n```js\n// poc.js \u2014 node poc.js\nconst yaml = require(\u0027js-yaml\u0027);\nconst doc = n =\u003e \u0027!!omap\\n\u0027 + Array.from({length: n}, (_, i) =\u003e `- k${i}: ${i}`).join(\u0027\\n\u0027) + \u0027\\n\u0027;\n\nfor (const n of [10000, 20000, 40000, 80000]) {\n const d = doc(n), t = Date.now();\n yaml.load(d); // default schema, no options\n console.log(`n=${n} bytes=${d.length} load=${Date.now() - t}ms`);\n}\n```\n\n### Measured (node v20.20.2, default heap, no flags)\n\n**js-yaml 4.3.0**\n\n```\nn=10000 bytes=137787 load=54ms\nn=20000 bytes=297787 load=169ms\nn=40000 bytes=617787 load=646ms\nn=80000 bytes=1257787 load=2607ms\n```\n\n**js-yaml 3.15.0**\n\n```\nn=10000 bytes=137787 load=53ms\nn=20000 bytes=297787 load=166ms\nn=40000 bytes=617787 load=641ms\nn=80000 bytes=1257787 load=2567ms\n```\n\nRuntime grows by a factor of ~4 for each doubling of `n`, which is the\nsignature of O(n\u00b2) (linear growth would be ~2\u00d7).\n\nScaling further: a **2.48 MB** document with 150,000 entries blocked\n`yaml.load()` for **10.8 seconds**.\n\n## Impact\n\nAny service that parses attacker-influenced YAML with js-yaml 3.x or 4.x can be\nstalled with a small input. Because the loop is synchronous, a single request\nblocks the Node.js event loop and stalls every other request in the process \u2014\nso the amplification is per-process, not just per-request.\n\nSuggested severity: consistent with **CVE-2026-59870** (the same weakness in\n5.x), i.e. Availability-only impact, network attack vector, no privileges or\nuser interaction required.\n\n## Suggested fix\n\nMirror the 5.x fix \u2014 replace the linear scan with a `Set`:\n\n```js\n// lib/type/omap.js\nconst seen = new Set()\n// ...\nif (seen.has(pairKey)) return false\nseen.add(pairKey)\n```\n\nThis preserves the existing duplicate-key rejection semantics exactly while\nmaking resolution O(n). A `maxOmapLength`-style cap would also work, but the\n`Set` matches what 5.x already ships and requires no new option.\n\n## References\n\n- CVE-2026-59870 / GHSA-724g-mxrg-4qvm \u2014 same weakness in 5.0.0\u20135.2.0, fixed in 5.2.1\n- `lib/type/omap.js` (3.x, 4.x) \u2014 the affected resolver\n- `lib/schema/default.js` \u2014 registers `!!omap` in the default schema\n\n## Discovery\n\nFound by an automated static-analysis and executed-proof-of-concept scanner run\nagainst js-yaml 4.2.0, then manually verified against 3.15.0 and 4.3.0 by\nexecuting the proof of concept above. All timings in this report were measured\non the **current** releases of each line, not on the version originally scanned.",
"id": "GHSA-5p4m-2wfm-xmqj",
"modified": "2026-08-06T20:27:32Z",
"published": "2026-08-06T20:27:32Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nodeca/js-yaml/security/advisories/GHSA-5p4m-2wfm-xmqj"
},
{
"type": "PACKAGE",
"url": "https://github.com/nodeca/js-yaml"
}
],
"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": "JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) \u2014 CVE-2026-59870 fix not backported"
}
GHSA-5RVQ-CXJ2-64VF
Vulnerability from github – Published: 2026-06-15 20:24 – Updated: 2026-06-15 20:24Summary
When parsing application/x-www-form-urlencoded bodies, QuerystringParser located the field separator with a two step lookup: it first scanned the entire remaining buffer for &, and only when no & existed anywhere ahead did it fall back to scanning for ;. For a body that uses ; as the separator and contains no &, every field iteration performed a full failed & scan over the entire remaining buffer before locating the nearby ;. With N semicolon separated fields in a chunk of size B, this yields O(B^2) byte comparisons per chunk.
An attacker can submit a small crafted body of the form a;a;a;... and cause the parser to spend seconds of CPU per request. A handful of concurrent requests can exhaust worker processes.
Details
In python_multipart/multipart.py, both the FIELD_NAME and FIELD_DATA states located the next separator like this:
sep_pos = data.find(b"&", i)
if sep_pos == -1:
sep_pos = data.find(b";", i)
data.find(b"&", i) scans from i to the end of the buffer and returns -1 only when there is no & anywhere in the remainder. For a ; separated body with no &, this failed full buffer scan repeats once per field, making parsing quadratic in the body length.
For example, a 1 MiB url encoded body consisting of a; repeated ~500,000 times, submitted with Content-Type: application/x-www-form-urlencoded, causes the parser to perform on the order of 10^11 byte comparisons, consuming several seconds of CPU for a single request. Cost scales quadratically with chunk size.
The parser is reachable through the public QuerystringParser class and through the high level FormParser, create_form_parser, and parse_form APIs for url encoded bodies. It is also the parser Starlette and FastAPI use for application/x-www-form-urlencoded request bodies via request.form().
Impact
Uncontrolled CPU consumption (denial of service). Parsing is synchronous, so a single small crafted form body occupies the handling worker for seconds, blocking any other work on that worker until parsing finishes. Sustained concurrent requests keep workers continuously busy, degrading or denying service.
Mitigation
Upgrade to python-multipart 0.0.30 or later, which treats only & as a field separator (per the WHATWG URL standard) using a single bounded scan, making parsing linear in the body length.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "python-multipart"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.30"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53539"
],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:24:09Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nWhen parsing `application/x-www-form-urlencoded` bodies, `QuerystringParser` located the field separator with a two step lookup: it first scanned the entire remaining buffer for `\u0026`, and only when no `\u0026` existed anywhere ahead did it fall back to scanning for `;`. For a body that uses `;` as the separator and contains no `\u0026`, every field iteration performed a full failed `\u0026` scan over the entire remaining buffer before locating the nearby `;`. With N semicolon separated fields in a chunk of size B, this yields O(B^2) byte comparisons per chunk.\n\nAn attacker can submit a small crafted body of the form `a;a;a;...` and cause the parser to spend seconds of CPU per request. A handful of concurrent requests can exhaust worker processes.\n\n### Details\n\nIn `python_multipart/multipart.py`, both the `FIELD_NAME` and `FIELD_DATA` states located the next separator like this:\n\n```python\nsep_pos = data.find(b\"\u0026\", i)\nif sep_pos == -1:\n sep_pos = data.find(b\";\", i)\n```\n\n`data.find(b\"\u0026\", i)` scans from `i` to the end of the buffer and returns `-1` only when there is no `\u0026` anywhere in the remainder. For a `;` separated body with no `\u0026`, this failed full buffer scan repeats once per field, making parsing quadratic in the body length.\n\nFor example, a 1 MiB url encoded body consisting of `a;` repeated ~500,000 times, submitted with `Content-Type: application/x-www-form-urlencoded`, causes the parser to perform on the order of 10^11 byte comparisons, consuming several seconds of CPU for a single request. Cost scales quadratically with chunk size.\n\nThe parser is reachable through the public `QuerystringParser` class and through the high level `FormParser`, `create_form_parser`, and `parse_form` APIs for url encoded bodies. It is also the parser Starlette and FastAPI use for `application/x-www-form-urlencoded` request bodies via `request.form()`.\n\n### Impact\n\nUncontrolled CPU consumption (denial of service). Parsing is synchronous, so a single small crafted form body occupies the handling worker for seconds, blocking any other work on that worker until parsing finishes. Sustained concurrent requests keep workers continuously busy, degrading or denying service.\n\n### Mitigation\n\nUpgrade to `python-multipart` `0.0.30` or later, which treats only `\u0026` as a field separator (per the [WHATWG URL standard](https://url.spec.whatwg.org/#urlencoded-parsing)) using a single bounded scan, making parsing linear in the body length.",
"id": "GHSA-5rvq-cxj2-64vf",
"modified": "2026-06-15T20:24:09Z",
"published": "2026-06-15T20:24:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Kludex/python-multipart/security/advisories/GHSA-5rvq-cxj2-64vf"
},
{
"type": "PACKAGE",
"url": "https://github.com/Kludex/python-multipart"
}
],
"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": "python-multipart: Quadratic-time querystring parsing with semicolon separators causes CPU denial of service"
}
GHSA-6522-R5FQ-99GW
Vulnerability from github – Published: 2026-05-20 12:30 – Updated: 2026-07-29 15:30NLnet Labs Unbound up to and including version 1.25.0 has a vulnerability when handling replies with very large RRsets that Unbound needs to perform name compression for. Malicious upstream responses with very large RRsets with records that don't share a suffix above the root can cause Unbound to spend a considerable time applying name compression to downstream replies. This can lead to degraded performance and eventually denial of service in well orchestrated attacks. An adversary can exploit the vulnerability by querying Unbound for the specially crafted contents of a malicious zone with very large RRsets. Before Unbound replies to the query it will try to apply name compression which was an unbounded operation that could lock the CPU until the whole packet was complete. A compression limit was introduced in 1.21.1 for this but it didn't account for the case where records would not share any suffix above the root. That causes Unbound to go in a different code path because of the compression tree lookup failure and eventually not increment the compression counter for those operations. Unbound 1.25.1 contains a patch with a fix that increments the compression counter regardless of the compression tree lookup. This is a complement fix to CVE-2024-8508.
{
"affected": [],
"aliases": [
"CVE-2026-44390"
],
"database_specific": {
"cwe_ids": [
"CWE-1050",
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-05-20T10:16:28Z",
"severity": "MODERATE"
},
"details": "NLnet Labs Unbound up to and including version 1.25.0 has a vulnerability when handling replies with very large RRsets that Unbound needs to perform name compression for. Malicious upstream responses with very large RRsets with records that don\u0027t share a suffix above the root can cause Unbound to spend a considerable time applying name compression to downstream replies. This can lead to degraded performance and eventually denial of service in well orchestrated attacks. An adversary can exploit the vulnerability by querying Unbound for the specially crafted contents of a malicious zone with very large RRsets. Before Unbound replies to the query it will try to apply name compression which was an unbounded operation that could lock the CPU until the whole packet was complete. A compression limit was introduced in 1.21.1 for this but it didn\u0027t account for the case where records would not share any suffix above the root. That causes Unbound to go in a different code path because of the compression tree lookup failure and eventually not increment the compression counter for those operations. Unbound 1.25.1 contains a patch with a fix that increments the compression counter regardless of the compression tree lookup. This is a complement fix to CVE-2024-8508.",
"id": "GHSA-6522-r5fq-99gw",
"modified": "2026-07-29T15:30:48Z",
"published": "2026-05-20T12:30:37Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44390"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:24013"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:36320"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:36777"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:37282"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-44390"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2480130"
},
{
"type": "WEB",
"url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-44390.json"
},
{
"type": "WEB",
"url": "https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-44390.txt"
}
],
"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"
},
{
"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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Amber",
"type": "CVSS_V4"
}
]
}
GHSA-684P-MHW3-3CWQ
Vulnerability from github – Published: 2026-08-06 18:30 – Updated: 2026-08-19 12:32Inefficient Algorithmic Complexity vulnerability in the traversal engine in rrrene html_sanitize_ex allows an unauthenticated remote attacker to exhaust server CPU and memory via a flat run of sibling elements in sanitized HTML. The list clause of HtmlSanitizeEx.Traverser.traverse/2 recurses on the tail of a sibling list and then evaluates List.flatten([head] ++ tail) over the already flattened result, so every one of n siblings copies and re-walks the entire remaining tail. The flattening is only needed for the rare case where scrub returns several replacement nodes for one node, but the cost is paid across the whole tail at every step, making traversal quadratic in sibling count.
The traverser sits on every public entry point, so no particular scrubber or configuration is required and the payload needs only allowed tags. A 160 KB body of 20,000 sibling elements occupies a scheduler for roughly 1.7 seconds, and the cost grows faster than the body does.
This issue affects html_sanitize_ex: from 0.3.1 before 1.5.3.
{
"affected": [],
"aliases": [
"CVE-2026-68750"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-06T16:16:51Z",
"severity": "HIGH"
},
"details": "Inefficient Algorithmic Complexity vulnerability in the traversal engine in rrrene html_sanitize_ex allows an unauthenticated remote attacker to exhaust server CPU and memory via a flat run of sibling elements in sanitized HTML. The list clause of HtmlSanitizeEx.Traverser.traverse/2 recurses on the tail of a sibling list and then evaluates List.flatten([head] ++ tail) over the already flattened result, so every one of n siblings copies and re-walks the entire remaining tail. The flattening is only needed for the rare case where scrub returns several replacement nodes for one node, but the cost is paid across the whole tail at every step, making traversal quadratic in sibling count.\n\nThe traverser sits on every public entry point, so no particular scrubber or configuration is required and the payload needs only allowed tags. A 160 KB body of 20,000 sibling elements occupies a scheduler for roughly 1.7 seconds, and the cost grows faster than the body does.\n\nThis issue affects html_sanitize_ex: from 0.3.1 before 1.5.3.",
"id": "GHSA-684p-mhw3-3cwq",
"modified": "2026-08-19T12:32:22Z",
"published": "2026-08-06T18:30:50Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/rrrene/html_sanitize_ex/security/advisories/GHSA-463q-p2fr-mh9p"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-68750"
},
{
"type": "WEB",
"url": "https://github.com/rrrene/html_sanitize_ex/commit/507a6fb95dd4c466cac8a8355d8989043e9fbcc1"
},
{
"type": "WEB",
"url": "https://github.com/rrrene/html_sanitize_ex/commit/9f5ccedbed230930813f992a1e6906fcf485981e"
},
{
"type": "WEB",
"url": "https://cna.erlef.org/cves/CVE-2026-68750.html"
},
{
"type": "WEB",
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-68750"
}
],
"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"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-68JQ-C3RV-PCRR
Vulnerability from github – Published: 2026-04-14 01:05 – Updated: 2026-06-08 23:09The OverlappingFieldsCanBeMerged validation rule exhibits quadratic time complexity when processing queries with many repeated fields sharing the same response name. An attacker can send a crafted query like { hello hello hello ... } with thousands of repeated fields, causing excessive CPU usage during validation before execution begins.
This is not mitigated by existing QueryDepth or QueryComplexity rules.
Observed impact (tested on v15.31.4): - 1000 fields: ~0.6s - 2000 fields: ~2.4s - 3000 fields: ~5.3s - 5000 fields: request timeout (>20s)
Root cause: collectConflictsWithin() performs O(n²) pairwise comparisons of all fields with the same response name. For identical repeated fields, every comparison returns "no conflict" but the quadratic iteration count causes resource exhaustion.
Fix: Deduplicate structurally identical fields before pairwise comparison, reducing the complexity from O(n²) to O(u²) where u is the number of unique field signatures (typically 1 for this attack pattern).
Credit: Ashwak N (ashwakn04@gmail.com)
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 15.31.4"
},
"package": {
"ecosystem": "Packagist",
"name": "webonyx/graphql-php"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "15.31.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-40476"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-14T01:05:05Z",
"nvd_published_at": "2026-04-17T22:16:33Z",
"severity": "MODERATE"
},
"details": "The `OverlappingFieldsCanBeMerged` validation rule exhibits quadratic time complexity when processing queries with many repeated fields sharing the same response name. An attacker can send a crafted query like `{ hello hello hello ... }` with thousands of repeated fields, causing excessive CPU usage during validation before execution begins.\n\nThis is not mitigated by existing QueryDepth or QueryComplexity rules.\n\n**Observed impact (tested on v15.31.4):**\n- 1000 fields: ~0.6s\n- 2000 fields: ~2.4s\n- 3000 fields: ~5.3s\n- 5000 fields: request timeout (\u003e20s)\n\n**Root cause:** `collectConflictsWithin()` performs O(n\u00b2) pairwise comparisons of all fields with the same response name. For identical repeated fields, every comparison returns \"no conflict\" but the quadratic iteration count causes resource exhaustion.\n\n**Fix:** Deduplicate structurally identical fields before pairwise comparison, reducing the complexity from O(n\u00b2) to O(u\u00b2) where u is the number of unique field signatures (typically 1 for this attack pattern).\n\n**Credit:** Ashwak N (ashwakn04@gmail.com)",
"id": "GHSA-68jq-c3rv-pcrr",
"modified": "2026-06-08T23:09:48Z",
"published": "2026-04-14T01:05:05Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/webonyx/graphql-php/security/advisories/GHSA-68jq-c3rv-pcrr"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-40476"
},
{
"type": "PACKAGE",
"url": "https://github.com/webonyx/graphql-php"
},
{
"type": "WEB",
"url": "https://github.com/webonyx/graphql-php/releases/tag/v15.31.5"
}
],
"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"
},
{
"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": "graphql-php is affected by a Denial of Service via quadratic complexity in OverlappingFieldsCanBeMerged validation"
}
GHSA-6PX8-752J-C2VV
Vulnerability from github – Published: 2024-07-23 18:31 – Updated: 2024-11-26 18:38In lj_str_hash.c in OpenResty 1.19.3.1 through 1.25.3.1, the string hashing function (used during string interning) allows HashDoS (Hash Denial of Service) attacks. An attacker could cause excessive resource usage during proxy operations via crafted requests, potentially leading to a denial of service with relatively few incoming requests. This vulnerability only exists in the OpenResty fork in the openresty/luajit2 GitHub repository. The LuaJIT/LuaJIT epository. is unaffected/
{
"affected": [],
"aliases": [
"CVE-2024-39702"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-07-23T16:15:05Z",
"severity": "MODERATE"
},
"details": "In lj_str_hash.c in OpenResty 1.19.3.1 through 1.25.3.1, the string hashing function (used during string interning) allows HashDoS (Hash Denial of Service) attacks. An attacker could cause excessive resource usage during proxy operations via crafted requests, potentially leading to a denial of service with relatively few incoming requests. This vulnerability only exists in the OpenResty fork in the openresty/luajit2 GitHub repository. The LuaJIT/LuaJIT epository. is unaffected/",
"id": "GHSA-6px8-752j-c2vv",
"modified": "2024-11-26T18:38:46Z",
"published": "2024-07-23T18:31:07Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-39702"
},
{
"type": "WEB",
"url": "https://openresty.org/en/ann-1025003002.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-6R92-CGXC-R5FG
Vulnerability from github – Published: 2022-01-21 23:35 – Updated: 2024-01-03 22:29Impact
Due to this library's use of an inefficient algorithm, it is vulnerable to a denial of service attack when a maliciously crafted input is passed to DecodeFromBytes or other CBOR decoding mechanisms in this library.
Affected versions include versions 4.0.0 through 4.5.0.
This vulnerability was privately reported to me.
Patches
This issue has been fixed in version 4.5.1. Users should use the latest version of this library. (The latest version is not necessarily 4.5.1. Check the NuGet page to see the latest version's version number.)
Workarounds
Again, users should use the latest version of this library.
In the meantime, note that the inputs affected by this issue are all CBOR maps or contain CBOR maps. An input that decodes to a single CBOR object is not capable of containing a CBOR map if—
- it begins with a byte other than 0x80 through 0xDF, or
- it does not contain a byte in the range 0xa0 through 0xBF.
Such an input is not affected by this vulnerability and an application can choose to perform this check before passing it to a CBOR decoding mechanism.
For more information
If you have any questions or comments about this advisory: * Open an issue in the CBOR repository.
{
"affected": [
{
"package": {
"ecosystem": "NuGet",
"name": "PeterO.Cbor"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0"
},
{
"fixed": "4.5.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-21909"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2022-01-18T22:57:46Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Impact\nDue to this library\u0027s use of an inefficient algorithm, it is vulnerable to a denial of service attack when a maliciously crafted input is passed to `DecodeFromBytes` or other CBOR decoding mechanisms in this library.\n\nAffected versions _include_ versions 4.0.0 through 4.5.0.\n\nThis vulnerability was privately reported to me.\n\n### Patches\nThis issue has been fixed in version 4.5.1. Users should use the latest version of this library. (The latest version is not necessarily 4.5.1. Check the [NuGet page](https://www.nuget.org/packages/PeterO.Cbor) to see the latest version\u0027s version number.)\n\n### Workarounds\n\nAgain, users should use the latest version of this library.\n\nIn the meantime, note that the inputs affected by this issue are all CBOR maps or contain CBOR maps. An input that decodes to a single CBOR object is not capable of containing a CBOR map if\u0026mdash;\n\n- it begins with a byte other than 0x80 through 0xDF, or\n- it does not contain a byte in the range 0xa0 through 0xBF.\n\nSuch an input is not affected by this vulnerability and an application can choose to perform this check before passing it to a CBOR decoding mechanism.\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in [the CBOR repository](https://github.com/peteroupc/CBOR).\n",
"id": "GHSA-6r92-cgxc-r5fg",
"modified": "2024-01-03T22:29:30Z",
"published": "2022-01-21T23:35:35Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/peteroupc/CBOR/security/advisories/GHSA-6r92-cgxc-r5fg"
},
{
"type": "WEB",
"url": "https://github.com/peteroupc/CBOR/commit/b4117dbbb4cd5a4a963f9d0c9aa132f033e15b95"
},
{
"type": "PACKAGE",
"url": "https://github.com/peteroupc/CBOR"
},
{
"type": "WEB",
"url": "https://github.com/peteroupc/CBOR/compare/v4.5...v4.5.1"
}
],
"schema_version": "1.4.0",
"severity": [],
"summary": "Denial of service in CBOR library"
}
GHSA-6V5V-WF23-FMFQ
Vulnerability from github – Published: 2026-06-15 20:41 – Updated: 2026-06-15 20:41Summary
A quadratic time complexity vulnerability exists in markdown-it's smartquotes rule (enabled via the typographer: true option). An attacker can craft a markdown input consisting of consecutive quotation marks that causes the parser to consume excessive CPU time, leading to denial of service.
Details
The vulnerability is in the replaceAt() helper function used by the smartquotes rule in lib/rules_core/smartquotes.mjs:
function replaceAt (str, index, ch) {
return str.slice(0, index) + ch + str.slice(index + 1)
}
When markdown-it processes a text token containing many quotation marks (either " or ') with typographer: true, the smartquotes rule iterates through each quote character and calls replaceAt() to substitute it with a typographic (curly) quote. Each call to replaceAt() creates three new string slices and concatenates them, which is an O(n) operation where n is the length of the string.
Since this is called once per quote character in the token, and there are n quote characters, the total time complexity becomes O(n^2).
The root cause is that the smartquotes rule modifies token.content in place using string slicing rather than building the result incrementally. The process_inlines() function (line 14) processes each quote in the text token, and for matching quote pairs, calls replaceAt() on both the opening and closing token's content (lines 151-152). When the entire input is a single text token of quote characters, this results in quadratic behavior.
PoC
const md = require('markdown-it');
const instance = md({ typographer: true });
// 160,000 consecutive double-quote characters
const payload = '"'.repeat(160000);
console.time('render');
instance.render(payload);
console.timeEnd('render');
// Output: render: ~21000ms (21 seconds)
// Compare with typographer disabled:
const safe = md({ typographer: false });
console.time('render-safe');
safe.render(payload);
console.timeEnd('render-safe');
// Output: render-safe: ~8ms
Measured timing on a modern system: - 10,000 quotes: ~19ms - 20,000 quotes: ~51ms - 40,000 quotes: ~212ms - 80,000 quotes: ~5,430ms - 160,000 quotes: ~21,198ms
The scaling is clearly superlinear (quadratic), with the 80K->160K step showing a ~3.9x increase for a 2x input increase, consistent with O(n^2).
Impact
Applications that render user-supplied markdown with typographer: true are vulnerable to denial of service. An attacker can submit a relatively small payload (160KB of quote characters) that causes the server to spend over 21 seconds processing a single request. Repeated submissions can exhaust server CPU resources and prevent legitimate users from being served.
The impact is mitigated by the fact that the typographer option defaults to false and must be explicitly enabled. However, the typographer feature is commonly enabled in production applications that want smart typography, and the markdown-it documentation prominently suggests enabling it.
A suggested fix would be to replace the replaceAt() approach with an array-based or StringBuilder-style approach that collects all replacements and applies them in a single pass, reducing the time complexity to O(n).
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 14.1.1"
},
"package": {
"ecosystem": "npm",
"name": "markdown-it"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.2.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-48988"
],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:41:06Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "### Summary\n\nA quadratic time complexity vulnerability exists in markdown-it\u0027s smartquotes rule (enabled via the `typographer: true` option). An attacker can craft a markdown input consisting of consecutive quotation marks that causes the parser to consume excessive CPU time, leading to denial of service.\n\n### Details\n\nThe vulnerability is in the `replaceAt()` helper function used by the smartquotes rule in `lib/rules_core/smartquotes.mjs`:\n\n```javascript\nfunction replaceAt (str, index, ch) {\n return str.slice(0, index) + ch + str.slice(index + 1)\n}\n```\n\nWhen markdown-it processes a text token containing many quotation marks (either `\"` or `\u0027`) with `typographer: true`, the smartquotes rule iterates through each quote character and calls `replaceAt()` to substitute it with a typographic (curly) quote. Each call to `replaceAt()` creates three new string slices and concatenates them, which is an O(n) operation where n is the length of the string.\n\nSince this is called once per quote character in the token, and there are n quote characters, the total time complexity becomes O(n^2).\n\nThe root cause is that the smartquotes rule modifies `token.content` in place using string slicing rather than building the result incrementally. The `process_inlines()` function (line 14) processes each quote in the text token, and for matching quote pairs, calls `replaceAt()` on both the opening and closing token\u0027s content (lines 151-152). When the entire input is a single text token of quote characters, this results in quadratic behavior.\n\n### PoC\n\n```javascript\nconst md = require(\u0027markdown-it\u0027);\nconst instance = md({ typographer: true });\n\n// 160,000 consecutive double-quote characters\nconst payload = \u0027\"\u0027.repeat(160000);\n\nconsole.time(\u0027render\u0027);\ninstance.render(payload);\nconsole.timeEnd(\u0027render\u0027);\n// Output: render: ~21000ms (21 seconds)\n\n// Compare with typographer disabled:\nconst safe = md({ typographer: false });\nconsole.time(\u0027render-safe\u0027);\nsafe.render(payload);\nconsole.timeEnd(\u0027render-safe\u0027);\n// Output: render-safe: ~8ms\n```\n\nMeasured timing on a modern system:\n- 10,000 quotes: ~19ms\n- 20,000 quotes: ~51ms\n- 40,000 quotes: ~212ms\n- 80,000 quotes: ~5,430ms\n- 160,000 quotes: ~21,198ms\n\nThe scaling is clearly superlinear (quadratic), with the 80K-\u003e160K step showing a ~3.9x increase for a 2x input increase, consistent with O(n^2).\n\n### Impact\n\nApplications that render user-supplied markdown with `typographer: true` are vulnerable to denial of service. An attacker can submit a relatively small payload (160KB of quote characters) that causes the server to spend over 21 seconds processing a single request. Repeated submissions can exhaust server CPU resources and prevent legitimate users from being served.\n\nThe impact is mitigated by the fact that the `typographer` option defaults to `false` and must be explicitly enabled. However, the typographer feature is commonly enabled in production applications that want smart typography, and the markdown-it documentation prominently suggests enabling it.\n\nA suggested fix would be to replace the `replaceAt()` approach with an array-based or StringBuilder-style approach that collects all replacements and applies them in a single pass, reducing the time complexity to O(n).",
"id": "GHSA-6v5v-wf23-fmfq",
"modified": "2026-06-15T20:41:06Z",
"published": "2026-06-15T20:41:06Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/markdown-it/markdown-it/security/advisories/GHSA-6v5v-wf23-fmfq"
},
{
"type": "PACKAGE",
"url": "https://github.com/markdown-it/markdown-it"
}
],
"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"
}
],
"summary": "markdown-it: Quadratic complexity DoS in smartquotes rule via replaceAt string operations"
}
No mitigation information available for this CWE.
No CAPEC attack patterns related to this CWE.