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.
313 vulnerabilities reference this CWE, most recent first.
GHSA-2883-XCG3-V3HH
Vulnerability from github – Published: 2026-09-08 21:24 – Updated: 2026-09-08 21:24Summary
maxTotalMergeKeys does not count empty mappings. An attacker can repeatedly merge a large sequence of them and consume significant CPU without reaching the configured limit.
Example
arr: &arr [{}, {}, {}, ...] # N empty mappings
targets:
- <<: *arr # repeated K times
For every target, the loader iterates all N elements of arr. This results in O(N * K) work while totalMergeKeys remains unchanged.
PoC
import { performance } from 'node:perf_hooks'
import { load, YAML11_SCHEMA } from 'js-yaml'
const n = 20000
const src =
'arr: &arr [' + '{},'.repeat(n).slice(0, -1) + ']\n' +
'targets:\n' +
' - <<: *arr\n'.repeat(n)
const started = performance.now()
load(src, { schema: YAML11_SCHEMA })
console.log(`${(performance.now() - started).toFixed(1)} ms`)
Observed results:
| N | YAML size | Time |
|---|---|---|
| 800 | ~13 KB | ~20 ms |
| 3200 | ~50 KB | ~180 ms |
| 20000 | ~500 KB | ~13 s |
Impact
An attacker can submit a relatively small YAML document that causes prolonged CPU consumption despite the default maxTotalMergeKeys limit.
Fix
Count each merge-source mapping as one budget unit, in addition to counting its keys.
Difference with v5
In v3 & v4, merge is enabled by default. So, the severity score is higher.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "js-yaml"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0"
},
{
"fixed": "4.3.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "js-yaml"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "3.15.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-84375"
],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-08T21:24:51Z",
"nvd_published_at": "2026-09-01T22:17:19Z",
"severity": "HIGH"
},
"details": "## Summary\n\n`maxTotalMergeKeys` does not count empty mappings. An attacker can repeatedly merge a large sequence of them and consume significant CPU without reaching the configured limit.\n\n## Example\n\n```yaml\narr: \u0026arr [{}, {}, {}, ...] # N empty mappings\ntargets:\n - \u003c\u003c: *arr # repeated K times\n```\n\nFor every target, the loader iterates all `N` elements of `arr`. This results in `O(N * K)` work while `totalMergeKeys` remains unchanged.\n\n## PoC\n\n```js\nimport { performance } from \u0027node:perf_hooks\u0027\nimport { load, YAML11_SCHEMA } from \u0027js-yaml\u0027\n\nconst n = 20000\n\nconst src =\n \u0027arr: \u0026arr [\u0027 + \u0027{},\u0027.repeat(n).slice(0, -1) + \u0027]\\n\u0027 +\n \u0027targets:\\n\u0027 +\n \u0027 - \u003c\u003c: *arr\\n\u0027.repeat(n)\n\nconst started = performance.now()\n\nload(src, { schema: YAML11_SCHEMA })\n\nconsole.log(`${(performance.now() - started).toFixed(1)} ms`)\n```\n\nObserved results:\n\n| N | YAML size | Time |\n|---:|---:|---:|\n| 800 | ~13 KB | ~20 ms |\n| 3200 | ~50 KB | ~180 ms |\n| 20000 | ~500 KB | ~13 s |\n\n## Impact\n\nAn attacker can submit a relatively small YAML document that causes prolonged CPU consumption despite the default `maxTotalMergeKeys` limit.\n\n## Fix\n\nCount each merge-source mapping as one budget unit, in addition to counting its keys.\n\n## Difference with v5\n\nIn v3 \u0026 v4, merge is enabled by default. So, the severity score is higher.",
"id": "GHSA-2883-xcg3-v3hh",
"modified": "2026-09-08T21:24:51Z",
"published": "2026-09-08T21:24:51Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nodeca/js-yaml/security/advisories/GHSA-2883-xcg3-v3hh"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-84375"
},
{
"type": "WEB",
"url": "https://github.com/nodeca/js-yaml/pull/797"
},
{
"type": "WEB",
"url": "https://github.com/nodeca/js-yaml/commit/3485bc06ff8a0251505f44a00414d90df2466639"
},
{
"type": "WEB",
"url": "https://github.com/nodeca/js-yaml/commit/6a8e05f9a485188ed730ac81e81ae221352ef480"
},
{
"type": "WEB",
"url": "https://github.com/nodeca/js-yaml/commit/d90b6612a5a84385bdcb556c44578eac76dc0f6b"
},
{
"type": "PACKAGE",
"url": "https://github.com/nodeca/js-yaml"
},
{
"type": "WEB",
"url": "https://github.com/nodeca/js-yaml/releases/tag/3.15.2"
},
{
"type": "WEB",
"url": "https://github.com/nodeca/js-yaml/releases/tag/4.3.2"
}
],
"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: maxTotalMergeKeys does not limit CPU use for empty merge sources"
}
GHSA-2CMP-7FM4-4V9W
Vulnerability from github – Published: 2026-09-07 15:33 – Updated: 2026-09-07 15:33commonmark versions from 1.5.0 before 2.8.4 contain a denial of service vulnerability in the Footnote extension that fails to deduplicate footnote definitions. Attackers can craft documents with duplicate footnote definitions and references to create quadratic output expansion, consuming excessive memory and CPU to exhaust server resources.
{
"affected": [],
"aliases": [
"CVE-2026-86435"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-09-07T13:20:43Z",
"severity": "HIGH"
},
"details": "commonmark versions from 1.5.0 before 2.8.4 contain a denial of service vulnerability in the Footnote extension that fails to deduplicate footnote definitions. Attackers can craft documents with duplicate footnote definitions and references to create quadratic output expansion, consuming excessive memory and CPU to exhaust server resources.",
"id": "GHSA-2cmp-7fm4-4v9w",
"modified": "2026-09-07T15:33:53Z",
"published": "2026-09-07T15:33:53Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/thephpleague/commonmark/security/advisories/GHSA-jfm3-95jq-q3rf"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-86435"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/commonmark-1.5.0-before-2.8.4-denial-of-service-via-footnote"
}
],
"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: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-2JHC-HF67-8VGX
Vulnerability from github – Published: 2026-03-25 18:31 – Updated: 2026-03-25 18:31GitLab has remediated an issue in GitLab CE/EE affecting all versions from 18.5 before 18.8.7, 18.9 before 18.9.3, and 18.10 before 18.10.1 that could have allowed an unauthenticated user to cause a denial of service by making the GitLab instance unresponsive due to improper input validation in GraphQL request processing.
{
"affected": [],
"aliases": [
"CVE-2026-3988"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-03-25T17:17:09Z",
"severity": "HIGH"
},
"details": "GitLab has remediated an issue in GitLab CE/EE affecting all versions from 18.5 before 18.8.7, 18.9 before 18.9.3, and 18.10 before 18.10.1 that could have allowed an unauthenticated user to cause a denial of service by making the GitLab instance unresponsive due to improper input validation in GraphQL request processing.",
"id": "GHSA-2jhc-hf67-8vgx",
"modified": "2026-03-25T18:31:55Z",
"published": "2026-03-25T18:31:55Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-3988"
},
{
"type": "WEB",
"url": "https://hackerone.com/reports/3597342"
},
{
"type": "WEB",
"url": "https://about.gitlab.com/releases/2026/03/25/patch-release-gitlab-18-10-1-released"
},
{
"type": "WEB",
"url": "https://gitlab.com/gitlab-org/gitlab/-/work_items/593140"
}
],
"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"
}
]
}
GHSA-2MP6-9MJC-P6JG
Vulnerability from github – Published: 2022-11-09 12:00 – Updated: 2025-11-04 00:30An issue was discovered in Python before 3.11.1. An unnecessary quadratic algorithm exists in one path when processing some inputs to the IDNA (RFC 3490) decoder, such that a crafted, unreasonably long name being presented to the decoder could lead to a CPU denial of service. Hostnames are often supplied by remote servers that could be controlled by a malicious actor; in such a scenario, they could trigger excessive CPU consumption on the client attempting to make use of an attacker-supplied supposed hostname. For example, the attack payload could be placed in the Location header of an HTTP response with status code 302. A fix is planned in 3.11.1, 3.10.9, 3.9.16, 3.8.16, and 3.7.16.
{
"affected": [],
"aliases": [
"CVE-2022-45061"
],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-11-09T07:15:00Z",
"severity": "HIGH"
},
"details": "An issue was discovered in Python before 3.11.1. An unnecessary quadratic algorithm exists in one path when processing some inputs to the IDNA (RFC 3490) decoder, such that a crafted, unreasonably long name being presented to the decoder could lead to a CPU denial of service. Hostnames are often supplied by remote servers that could be controlled by a malicious actor; in such a scenario, they could trigger excessive CPU consumption on the client attempting to make use of an attacker-supplied supposed hostname. For example, the attack payload could be placed in the Location header of an HTTP response with status code 302. A fix is planned in 3.11.1, 3.10.9, 3.9.16, 3.8.16, and 3.7.16.",
"id": "GHSA-2mp6-9mjc-p6jg",
"modified": "2025-11-04T00:30:34Z",
"published": "2022-11-09T12:00:19Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-45061"
},
{
"type": "WEB",
"url": "https://github.com/python/cpython/issues/98433"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/O67LRHDTJWH544KXB6KY4HMHQLYDXFPK"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/LKWAMPURWUV3DCCT4J7VHRF4NT2CFVBR"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/KNE4GMD45RGC2HWUAAIGTDHT5VJ2E4O4"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/JTYVESWVBPD57ZJC35G5722Q6TS37WSB"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/JCDJXNBHWXNYUTOEV4H2HCFSRKV3SYL3"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/IN26PWZTYG6IF3APLRXQJBVACQHZUPT2"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/GTPVDZDATRQFE6KAT6B4BQIQ4GRHIIIJ"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/BWJREJHWVRBYDP43YB5WRL3QC7UBA7BR"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/B4MYQ3IV6NWA4CKSXEHW45CH2YNDHEPH"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/B3YI6JYARWU6GULWOHNUROSACT54XFFS"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/7WQPHKGNXUJC3TC3BDW5RKGROWRJVSFR"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/63FS6VHY4DCS74HBTEINUDOECQ2X6ZCH"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/4WBZJNSALFGMPYTINIF57HAAK46U72WQ"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/35YDIWCUMWTMDBWFRAVENFH6BLB65D6S"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/2AOUKI72ACV6CHY2QUFO6VK2DNMVJ2MB"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/ZB5YCMIRVX35RUB6XPOWKENCVCJEVDRK"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ORVCQGJCCAVLN4DJDTWGREFCUWXKQRML"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/PLQ2BNZVBBAQPV3SPRU24ZD37UYJJS7W"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QCKD4AFBHXIMHS64ZER2U7QRT33HNE7L"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QLUGZSEAO3MBWGKCUSMKQIRYJZKJCIOB"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/RDK3ZZBRYFO47ET3N4BNTKVXN47U6ICY"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/RH57BNT4VQERGEJ5SXNXSVMDYP66YD4H"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/RTN2OOLKYTG34DODUEJGT5MLC2PFGPBA"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/T3D5TX4TDJPXHXD2QICKTY3OCQC3JARP"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/UHVW73QZJMHA4MK7JBT7CXX7XSNYQEGF"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/VCMDX6IFKLOA3NXUQEV524L5LHTPI2JI"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/X3EJ6J7PXVQOULBQZQGBXCXY6LFF6LZD"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/XXZJL3CNAFS5PAIR7K4RL62S3Y7THR7O"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/YPNWZKXPKTNHS5FVMN7UQZ2UPCSEFJUK"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZB5YCMIRVX35RUB6XPOWKENCVCJEVDRK"
},
{
"type": "WEB",
"url": "https://security.gentoo.org/glsa/202305-02"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20221209-0007"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/JTYVESWVBPD57ZJC35G5722Q6TS37WSB"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/JCDJXNBHWXNYUTOEV4H2HCFSRKV3SYL3"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/IN26PWZTYG6IF3APLRXQJBVACQHZUPT2"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/GTPVDZDATRQFE6KAT6B4BQIQ4GRHIIIJ"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/BWJREJHWVRBYDP43YB5WRL3QC7UBA7BR"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/B4MYQ3IV6NWA4CKSXEHW45CH2YNDHEPH"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/B3YI6JYARWU6GULWOHNUROSACT54XFFS"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/7WQPHKGNXUJC3TC3BDW5RKGROWRJVSFR"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/63FS6VHY4DCS74HBTEINUDOECQ2X6ZCH"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/4WBZJNSALFGMPYTINIF57HAAK46U72WQ"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/35YDIWCUMWTMDBWFRAVENFH6BLB65D6S"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/2AOUKI72ACV6CHY2QUFO6VK2DNMVJ2MB"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2024/12/msg00000.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2024/11/msg00024.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/06/msg00039.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/05/msg00024.html"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/YPNWZKXPKTNHS5FVMN7UQZ2UPCSEFJUK"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/XXZJL3CNAFS5PAIR7K4RL62S3Y7THR7O"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/X3EJ6J7PXVQOULBQZQGBXCXY6LFF6LZD"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/VCMDX6IFKLOA3NXUQEV524L5LHTPI2JI"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/UHVW73QZJMHA4MK7JBT7CXX7XSNYQEGF"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/T3D5TX4TDJPXHXD2QICKTY3OCQC3JARP"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/RTN2OOLKYTG34DODUEJGT5MLC2PFGPBA"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/RH57BNT4VQERGEJ5SXNXSVMDYP66YD4H"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/RDK3ZZBRYFO47ET3N4BNTKVXN47U6ICY"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/QLUGZSEAO3MBWGKCUSMKQIRYJZKJCIOB"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/QCKD4AFBHXIMHS64ZER2U7QRT33HNE7L"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/PLQ2BNZVBBAQPV3SPRU24ZD37UYJJS7W"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/ORVCQGJCCAVLN4DJDTWGREFCUWXKQRML"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/O67LRHDTJWH544KXB6KY4HMHQLYDXFPK"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/LKWAMPURWUV3DCCT4J7VHRF4NT2CFVBR"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/KNE4GMD45RGC2HWUAAIGTDHT5VJ2E4O4"
}
],
"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"
}
]
}
GHSA-2MR2-J2WM-V93X
Vulnerability from github – Published: 2026-09-01 18:30 – Updated: 2026-09-01 18:30A flaw was found in openshift/oauth-server. The OAuth login and error page endpoints pass the unauthenticated Accept-Language header to golang.org/x/text/language.ParseAcceptLanguage() without input validation. A bypass of the CVE-2022-32149 mitigation exists: the upstream guard counts only '-' characters but the internal BCP 47 scanner aliases '' to '-' after the guard check. An unauthenticated attacker can send a crafted Accept-Language header using '' separators to trigger quadratic-time parsing, consuming excessive CPU and denying authentication to all cluster users.
{
"affected": [],
"aliases": [
"CVE-2026-49329"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-09-01T16:16:57Z",
"severity": "HIGH"
},
"details": "A flaw was found in openshift/oauth-server. The OAuth login and error page endpoints pass the unauthenticated Accept-Language header to golang.org/x/text/language.ParseAcceptLanguage() without input validation. A bypass of the CVE-2022-32149 mitigation exists: the upstream guard counts only \u0027-\u0027 characters but the internal BCP 47 scanner aliases \u0027_\u0027 to \u0027-\u0027 after the guard check. An unauthenticated attacker can send a crafted Accept-Language header using \u0027_\u0027 separators to trigger quadratic-time parsing, consuming excessive CPU and denying authentication to all cluster users.",
"id": "GHSA-2mr2-j2wm-v93x",
"modified": "2026-09-01T18:30:40Z",
"published": "2026-09-01T18:30:40Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-49329"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-49329"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2483248"
}
],
"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"
}
]
}
GHSA-2Q4P-G7HV-5RGV
Vulnerability from github – Published: 2026-08-06 20:37 – Updated: 2026-08-06 20:37Impact
Affected versions of league/commonmark can have quadratic time complexity when parsing specially crafted Markdown lines. In practical terms, doubling the length of an affected line can make the parser perform roughly four times as much work. The parser identifies locations using character positions, but regular-expression matches report byte positions. These positions differ when a UTF-8 character uses more than one byte. Several parsing paths repeatedly rescan growing portions of the line to translate between the two positions. The Autolink extension can also copy and validate the remaining line at every URL-like prefix.
In current 2.x releases, a single non-ASCII character anywhere on a line can place that whole line on the slower multibyte path. An attacker can combine it with a long run of leading whitespace or repeated Markdown punctuation, causing increasingly large rescans. When the Autolink extension is enabled, repeated URL-like prefixes provide another trigger, even on ASCII-only lines. Each trigger fits within one long line, so complex Markdown structure is unnecessary.
An attacker who can submit Markdown for conversion can use a comparatively small request to consume disproportionate CPU time and allocation activity. Repeated or concurrent requests can occupy all available PHP workers and prevent legitimate requests from completing. The core paths affect CommonMarkConverter, GithubFlavoredMarkdownConverter, and custom environments. The autolink-specific path affects applications using AutolinkExtension or GithubFlavoredMarkdownExtension. Applications that process only trusted Markdown are not remotely exploitable. The impact is limited to availability: it does not disclose data, change rendered output, or bypass rendering restrictions. Settings such as html_input and allow_unsafe_links do not mitigate the issue because the expensive work occurs before rendering.
Patches
The issue is patched in 2.9.0 and later. Starting in that release, the parser records UTF-8 character-to-byte positions incrementally, converts ordered regular-expression match positions without restarting from the beginning of the line, and matches autolinks against the original line instead of copying every remaining suffix. The affected work then grows in direct proportion to the input size while preserving existing Markdown output and configuration behavior. Versions from 0.6.0 through 2.8.3 are affected. The 0.x and 1.x release lines are no longer supported, so their users must upgrade to 2.9.0 or later.
Workarounds
If you cannot upgrade immediately, reject or truncate inputs with excessively long individual lines before passing them to the converter. A total request-size limit is also useful, but a per-line limit is important because every demonstrated trigger fits on one line. Choose limits appropriate for the application and enforce them before Markdown parsing begins. Restricting conversion to trusted users, applying strict execution-time limits, rate-limiting requests, and limiting concurrent conversions can further reduce exposure, but these measures are not complete substitutes for upgrading.
Disabling AutolinkExtension and avoiding GithubFlavoredMarkdownExtension removes the autolink-specific trigger, but the core multibyte parsing paths remain reachable in the standard parser. Existing nesting, delimiter, raw-HTML, and unsafe-link configuration options do not eliminate all affected paths. Applications that must continue processing untrusted Markdown should therefore enforce input limits even when autolinking is disabled.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "league/commonmark"
},
"ranges": [
{
"events": [
{
"introduced": "0.6.0"
},
{
"fixed": "2.9.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-71488"
],
"database_specific": {
"cwe_ids": [
"CWE-1050",
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-06T20:37:20Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Impact\n\nAffected versions of `league/commonmark` can have quadratic time complexity when parsing specially crafted Markdown lines. In practical terms, doubling the length of an affected line can make the parser perform roughly four times as much work. The parser identifies locations using character positions, but regular-expression matches report byte positions. These positions differ when a UTF-8 character uses more than one byte. Several parsing paths repeatedly rescan growing portions of the line to translate between the two positions. The Autolink extension can also copy and validate the remaining line at every URL-like prefix.\n\nIn current 2.x releases, a single non-ASCII character anywhere on a line can place that whole line on the slower multibyte path. An attacker can combine it with a long run of leading whitespace or repeated Markdown punctuation, causing increasingly large rescans. When the Autolink extension is enabled, repeated URL-like prefixes provide another trigger, even on ASCII-only lines. Each trigger fits within one long line, so complex Markdown structure is unnecessary.\n\nAn attacker who can submit Markdown for conversion can use a comparatively small request to consume disproportionate CPU time and allocation activity. Repeated or concurrent requests can occupy all available PHP workers and prevent legitimate requests from completing. The core paths affect `CommonMarkConverter`, `GithubFlavoredMarkdownConverter`, and custom environments. The autolink-specific path affects applications using `AutolinkExtension` or `GithubFlavoredMarkdownExtension`. Applications that process only trusted Markdown are not remotely exploitable. The impact is limited to availability: it does not disclose data, change rendered output, or bypass rendering restrictions. Settings such as `html_input` and `allow_unsafe_links` do not mitigate the issue because the expensive work occurs before rendering.\n\n### Patches\n\nThe issue is patched in `2.9.0` and later. Starting in that release, the parser records UTF-8 character-to-byte positions incrementally, converts ordered regular-expression match positions without restarting from the beginning of the line, and matches autolinks against the original line instead of copying every remaining suffix. The affected work then grows in direct proportion to the input size while preserving existing Markdown output and configuration behavior. Versions from `0.6.0` through `2.8.3` are affected. The 0.x and 1.x release lines are no longer supported, so their users must upgrade to `2.9.0` or later.\n\n### Workarounds\n\nIf you cannot upgrade immediately, reject or truncate inputs with excessively long individual lines before passing them to the converter. A total request-size limit is also useful, but a per-line limit is important because every demonstrated trigger fits on one line. Choose limits appropriate for the application and enforce them before Markdown parsing begins. Restricting conversion to trusted users, applying strict execution-time limits, rate-limiting requests, and limiting concurrent conversions can further reduce exposure, but these measures are not complete substitutes for upgrading.\n\nDisabling `AutolinkExtension` and avoiding `GithubFlavoredMarkdownExtension` removes the autolink-specific trigger, but the core multibyte parsing paths remain reachable in the standard parser. Existing nesting, delimiter, raw-HTML, and unsafe-link configuration options do not eliminate all affected paths. Applications that must continue processing untrusted Markdown should therefore enforce input limits even when autolinking is disabled.",
"id": "GHSA-2q4p-g7hv-5rgv",
"modified": "2026-08-06T20:37:20Z",
"published": "2026-08-06T20:37:20Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/thephpleague/commonmark/security/advisories/GHSA-2q4p-g7hv-5rgv"
},
{
"type": "WEB",
"url": "https://github.com/thephpleague/commonmark/commit/a6ef6cdc308dfa39a34239c35818e75892a0e6a8"
},
{
"type": "WEB",
"url": "https://github.com/thephpleague/commonmark/commit/a70979ea0d7d3377bd7127536748454a922bf5eb"
},
{
"type": "WEB",
"url": "https://github.com/thephpleague/commonmark/commit/c97b02e5e652b992033b93ba5d6182f706343fc6"
},
{
"type": "PACKAGE",
"url": "https://github.com/thephpleague/commonmark"
},
{
"type": "WEB",
"url": "https://github.com/thephpleague/commonmark/releases/tag/2.9.0"
}
],
"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": "league/commonmark: Quadratic-time denial of service when parsing crafted Markdown"
}
GHSA-2WVJ-GVC7-GFHX
Vulnerability from github – Published: 2026-05-20 12:30 – Updated: 2026-08-19 12:32NLnet Labs Unbound up to and including version 1.25.0 is vulnerable to a degradation of service attack related to parsing long lists of incoming EDNS options. An adversary sending queries with too many EDNS options can hold Unbound threads hostage while they are parsing and creating internal data structures for the options. Coordinated attacks can result in degradation and/or denial of service. Unbound 1.25.1 contains a patch with a fix to limit acceptable incoming EDNS options (100).
{
"affected": [],
"aliases": [
"CVE-2026-41292"
],
"database_specific": {
"cwe_ids": [
"CWE-1050",
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-05-20T10:16:27Z",
"severity": "MODERATE"
},
"details": "NLnet Labs Unbound up to and including version 1.25.0 is vulnerable to a degradation of service attack related to parsing long lists of incoming EDNS options. An adversary sending queries with too many EDNS options can hold Unbound threads hostage while they are parsing and creating internal data structures for the options. Coordinated attacks can result in degradation and/or denial of service. Unbound 1.25.1 contains a patch with a fix to limit acceptable incoming EDNS options (100).",
"id": "GHSA-2wvj-gvc7-gfhx",
"modified": "2026-08-19T12:32:10Z",
"published": "2026-05-20T12:30:36Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41292"
},
{
"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/errata/RHSA-2026:54769"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-41292"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2480125"
},
{
"type": "WEB",
"url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-41292.json"
},
{
"type": "WEB",
"url": "https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-41292.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:H",
"type": "CVSS_V3"
},
{
"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/E:U/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:Red",
"type": "CVSS_V4"
}
]
}
GHSA-2X7J-588G-CCC2
Vulnerability from github – Published: 2026-09-08 21:33 – Updated: 2026-09-08 21:33Summary
Nodemailer's address parser (lib/addressparser/index.js) parses a list of comma‑separated addresses in quadratic time — O(n²) in the number of addresses. A single crafted address string (e.g. a To, Cc, Bcc, From, or Reply‑To value, or any value passed to the exported addressparser) therefore consumes CPU proportional to the square of its length and blocks Node's single‑threaded event loop for the entire duration, denying service to every other request in the process.
This requires no special application configuration and no cooperating receiver — it is entirely inside the parser and triggers on the library's default code path. A ~1.5 MB address value freezes the process for ~25–30 seconds of 100% CPU; the cost grows with the square of the input, so a few‑MB value stalls the server for minutes. It is a distinct issue from the recursion DoS fixed as CVE‑2025‑14874 (that path is guarded by a nesting‑depth cap; this one is a flat, comma‑separated list with no such limit).
Details
addressparser tokenizes the input, splits it into per‑address token groups, and then accumulates the parsed results in a loop (lib/addressparser/index.js, ~lines 500–505):
addresses.forEach(addr => {
const handled = _handleAddress(addr, depth);
if (handled.length) {
parsedAddresses = parsedAddresses.concat(handled); // <-- line ~503
}
});
Array.prototype.concat builds and returns a new array containing a copy of every element accumulated so far. Reassigning parsedAddresses = parsedAddresses.concat(handled) on each of the n iterations copies 1 + 2 + 3 + … + n elements in total, i.e. O(n²) work (and O(n²) transient allocations) for an input containing n addresses. Tokenization and _handleAddress themselves are linear; the quadratic blowup is entirely this accumulator.
Root‑cause proof. Replacing only that line with an in‑place append and re‑running the exact same input:
parsedAddresses = parsedAddresses.concat(handled); -> 100000 addresses: ~6068 ms
parsedAddresses.push.apply(parsedAddresses, handled); -> 100000 addresses: ~51 ms (≈119x faster, now linear)
Measured scaling (nodemailer 9.0.6, 'a@b.com,'.repeat(n)):
| addresses n | input size | parse time | ratio for 2× input |
|---|---|---|---|
| 25,000 | 0.19 MB | ~0.35 s | – |
| 50,000 | 0.38 MB | ~1.4 s | ×4.0 |
| 100,000 | 0.76 MB | ~6–8 s | ×3.9 |
| 200,000 | 1.53 MB | ~25–30 s | ×4.1 |
Doubling the input quadruples the time — the signature of O(n²).
Reachability. The parser is invoked on any structured‑address header value on the normal send path (MimeNode.setHeader('To'/'Cc'/'Bcc'/'From'/'Reply-To', value) → _parseAddresses → addressparser, and getEnvelope()), so a single transport.sendMail({ to: <crafted string> }) triggers it. It is also reached directly through the exported require('nodemailer/lib/addressparser'), which many applications call to validate or display user‑supplied recipient lists. Confirmed via the public API: setHeader('To', 'a@b.com,'.repeat(80000)) + getEnvelope() blocks for ~3.9 s.
Suggested fix: accumulate in place instead of rebuilding the array each iteration, e.g. parsedAddresses.push.apply(parsedAddresses, handled); (or for (const h of handled) parsedAddresses.push(h);). Optionally cap the number of addresses / input length before parsing.
PoC
Environment: Node.js ≥ 18 and the published nodemailer@9.0.6. No transport, network, or configuration required — the cost is in parsing.
poc-dos.js:
'use strict';
const addressparser = require('nodemailer/lib/addressparser');
console.log('addresses | input size | parse time');
for (const n of [25000, 50000, 100000, 200000]) {
const payload = 'a@b.com,'.repeat(n); // n valid, comma-separated recipients
const t0 = process.hrtime.bigint();
addressparser(payload); // blocks synchronously
const ms = Number(process.hrtime.bigint() - t0) / 1e6;
console.log(String(n).padStart(9) + ' | ' + (payload.length / 1048576).toFixed(2) + ' MB | ' + ms.toFixed(0).padStart(7) + ' ms');
}
Run:
npm init -y && npm install nodemailer@9.0.6
node poc-dos.js
Actual output (nodemailer 9.0.6):
addresses | input size | parse time
25000 | 0.19 MB | 381 ms
50000 | 0.38 MB | 1435 ms
100000 | 0.76 MB | 7949 ms
200000 | 1.53 MB | 25154 ms
Equivalent trigger through the normal send API (freezes the event loop):
const nodemailer = require('nodemailer');
nodemailer.createTransport({ jsonTransport: true })
.sendMail({ from: 'a@b.com', to: 'a@b.com,'.repeat(150000), subject: 'x', text: 'y' });
// ~15+ seconds of 100% CPU inside addressparser before anything is sent
Impact
- Who is impacted: any service that runs Nodemailer (or the standalone
nodemailer/lib/addressparser) on an address value that can be influenced by an untrusted party — a recipient field in a "send email / invite / share" feature, aReply‑To/Fromderived from user input, a contact‑import or mailing‑list parser, or any endpoint that validates addresses withaddressparser. No authentication, special option, or particular receiver is needed.
Patched in 9.1.0
Three separate quadratic paths were fixed, not one:
addressparserrebuilt its accumulator withconcat()on every address (9116da9).- The display-name merge loop directly below spliced each fragment out of the array, the same shape reached through
'a, b <c@d.com>,'.repeat(n)(same commit). MimeNode#_convertAddresseschecked recipient uniqueness with a linear scan per address (7cc38af, refined in 34da642). This was the most severe of the three and the reported proof of concept did not reach it:'a@b.com,'.repeat(n)is one address repeated, which dedupes to a single envelope entry. A list of distinct recipients cost O(n^2) here, taking ~35s for 100k even afteraddressparserwas fixed.
Fixed alongside: [].concat.apply in _parseAddresses threw RangeError: Maximum call stack size exceeded past roughly 124k recipients, with no crafted input needed (83b8c48).
Parsing 200k addresses now takes ~80ms instead of ~25s, and every path scales linearly. A new maxRecipients option (default 100000) throws rather than truncating, as a backstop.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "nodemailer"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "9.1.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-08T21:33:17Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nNodemailer\u0027s address parser (`lib/addressparser/index.js`) parses a list of comma\u2011separated addresses in **quadratic time \u2014 O(n\u00b2)** in the number of addresses. A single crafted address string (e.g. a `To`, `Cc`, `Bcc`, `From`, or `Reply\u2011To` value, or any value passed to the exported `addressparser`) therefore consumes CPU proportional to the **square** of its length and blocks Node\u0027s single\u2011threaded event loop for the entire duration, denying service to every other request in the process.\n\nThis requires **no special application configuration and no cooperating receiver** \u2014 it is entirely inside the parser and triggers on the library\u0027s default code path. A ~1.5 MB address value freezes the process for ~25\u201330 seconds of 100% CPU; the cost grows with the square of the input, so a few\u2011MB value stalls the server for minutes. It is a distinct issue from the recursion DoS fixed as CVE\u20112025\u201114874 (that path is guarded by a nesting\u2011depth cap; this one is a flat, comma\u2011separated list with no such limit).\n\n### Details\n\n`addressparser` tokenizes the input, splits it into per\u2011address token groups, and then accumulates the parsed results in a loop (`lib/addressparser/index.js`, ~lines 500\u2013505):\n\n```js\naddresses.forEach(addr =\u003e {\n const handled = _handleAddress(addr, depth);\n if (handled.length) {\n parsedAddresses = parsedAddresses.concat(handled); // \u003c-- line ~503\n }\n});\n```\n\n`Array.prototype.concat` builds and returns a **new** array containing a copy of every element accumulated so far. Reassigning `parsedAddresses = parsedAddresses.concat(handled)` on each of the *n* iterations copies 1 + 2 + 3 + \u2026 + n elements in total, i.e. **O(n\u00b2)** work (and O(n\u00b2) transient allocations) for an input containing *n* addresses. Tokenization and `_handleAddress` themselves are linear; the quadratic blowup is entirely this accumulator.\n\n**Root\u2011cause proof.** Replacing only that line with an in\u2011place append and re\u2011running the exact same input:\n\n```\nparsedAddresses = parsedAddresses.concat(handled); -\u003e 100000 addresses: ~6068 ms\nparsedAddresses.push.apply(parsedAddresses, handled); -\u003e 100000 addresses: ~51 ms (\u2248119x faster, now linear)\n```\n\n**Measured scaling** (nodemailer 9.0.6, `\u0027a@b.com,\u0027.repeat(n)`):\n\n| addresses n | input size | parse time | ratio for 2\u00d7 input |\n|---|---|---|---|\n| 25,000 | 0.19 MB | ~0.35 s | \u2013 |\n| 50,000 | 0.38 MB | ~1.4 s | \u00d74.0 |\n| 100,000 | 0.76 MB | ~6\u20138 s | \u00d73.9 |\n| 200,000 | 1.53 MB | ~25\u201330 s| \u00d74.1 |\n\nDoubling the input quadruples the time \u2014 the signature of O(n\u00b2).\n\n**Reachability.** The parser is invoked on any structured\u2011address header value on the normal send path (`MimeNode.setHeader(\u0027To\u0027/\u0027Cc\u0027/\u0027Bcc\u0027/\u0027From\u0027/\u0027Reply-To\u0027, value)` \u2192 `_parseAddresses` \u2192 `addressparser`, and `getEnvelope()`), so a single `transport.sendMail({ to: \u003ccrafted string\u003e })` triggers it. It is also reached directly through the **exported** `require(\u0027nodemailer/lib/addressparser\u0027)`, which many applications call to validate or display user\u2011supplied recipient lists. Confirmed via the public API: `setHeader(\u0027To\u0027, \u0027a@b.com,\u0027.repeat(80000))` + `getEnvelope()` blocks for ~3.9 s.\n\n**Suggested fix:** accumulate in place instead of rebuilding the array each iteration, e.g. `parsedAddresses.push.apply(parsedAddresses, handled);` (or `for (const h of handled) parsedAddresses.push(h);`). Optionally cap the number of addresses / input length before parsing.\n\n### PoC\n\nEnvironment: Node.js \u2265 18 and the published `nodemailer@9.0.6`. No transport, network, or configuration required \u2014 the cost is in parsing.\n\n`poc-dos.js`:\n```js\n\u0027use strict\u0027;\nconst addressparser = require(\u0027nodemailer/lib/addressparser\u0027);\n\nconsole.log(\u0027addresses | input size | parse time\u0027);\nfor (const n of [25000, 50000, 100000, 200000]) {\n const payload = \u0027a@b.com,\u0027.repeat(n); // n valid, comma-separated recipients\n const t0 = process.hrtime.bigint();\n addressparser(payload); // blocks synchronously\n const ms = Number(process.hrtime.bigint() - t0) / 1e6;\n console.log(String(n).padStart(9) + \u0027 | \u0027 + (payload.length / 1048576).toFixed(2) + \u0027 MB | \u0027 + ms.toFixed(0).padStart(7) + \u0027 ms\u0027);\n}\n```\n\nRun:\n```\nnpm init -y \u0026\u0026 npm install nodemailer@9.0.6\nnode poc-dos.js\n```\n\nActual output (nodemailer 9.0.6):\n```\naddresses | input size | parse time\n 25000 | 0.19 MB | 381 ms\n 50000 | 0.38 MB | 1435 ms\n 100000 | 0.76 MB | 7949 ms\n 200000 | 1.53 MB | 25154 ms\n```\n\nEquivalent trigger through the normal send API (freezes the event loop):\n```js\nconst nodemailer = require(\u0027nodemailer\u0027);\nnodemailer.createTransport({ jsonTransport: true })\n .sendMail({ from: \u0027a@b.com\u0027, to: \u0027a@b.com,\u0027.repeat(150000), subject: \u0027x\u0027, text: \u0027y\u0027 });\n// ~15+ seconds of 100% CPU inside addressparser before anything is sent\n```\n\n### Impact\n\n* **Who is impacted:** any service that runs Nodemailer (or the standalone `nodemailer/lib/addressparser`) on an address value that can be influenced by an untrusted party \u2014 a recipient field in a \"send email / invite / share\" feature, a `Reply\u2011To`/`From` derived from user input, a contact\u2011import or mailing\u2011list parser, or any endpoint that validates addresses with `addressparser`. No authentication, special option, or particular receiver is needed.\n\n## Patched in 9.1.0\n\nThree separate quadratic paths were fixed, not one:\n\n* `addressparser` rebuilt its accumulator with `concat()` on every address ([9116da9](https://github.com/nodemailer/nodemailer/commit/9116da9)).\n* The display-name merge loop directly below spliced each fragment out of the array, the same shape reached through `\u0027a, b \u003cc@d.com\u003e,\u0027.repeat(n)` (same commit).\n* `MimeNode#_convertAddresses` checked recipient uniqueness with a linear scan per address ([7cc38af](https://github.com/nodemailer/nodemailer/commit/7cc38af), refined in [34da642](https://github.com/nodemailer/nodemailer/commit/34da642)). This was the most severe of the three and the reported proof of concept did not reach it: `\u0027a@b.com,\u0027.repeat(n)` is one address repeated, which dedupes to a single envelope entry. A list of *distinct* recipients cost O(n^2) here, taking ~35s for 100k even after `addressparser` was fixed.\n\nFixed alongside: `[].concat.apply` in `_parseAddresses` threw `RangeError: Maximum call stack size exceeded` past roughly 124k recipients, with no crafted input needed ([83b8c48](https://github.com/nodemailer/nodemailer/commit/83b8c48)).\n\nParsing 200k addresses now takes ~80ms instead of ~25s, and every path scales linearly. A new `maxRecipients` option (default 100000) throws rather than truncating, as a backstop.",
"id": "GHSA-2x7j-588g-ccc2",
"modified": "2026-09-08T21:33:17Z",
"published": "2026-09-08T21:33:17Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nodemailer/nodemailer/security/advisories/GHSA-2x7j-588g-ccc2"
},
{
"type": "WEB",
"url": "https://github.com/nodemailer/nodemailer/pull/1848"
},
{
"type": "WEB",
"url": "https://github.com/nodemailer/nodemailer/commit/34da64282dcdc9b0581c721a27ab2fa226673150"
},
{
"type": "WEB",
"url": "https://github.com/nodemailer/nodemailer/commit/7cc38af418ffa6fc7e86085195ca5ca681694b3e"
},
{
"type": "WEB",
"url": "https://github.com/nodemailer/nodemailer/commit/9116da9528c6524cefaed75185602a7e85d20434"
},
{
"type": "PACKAGE",
"url": "https://github.com/nodemailer/nodemailer"
},
{
"type": "WEB",
"url": "https://github.com/nodemailer/nodemailer/releases/tag/v9.1.0"
}
],
"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": "Nodemailer: Quadratic (O(n\u00b2)) time complexity in addressparser allows remote denial of service via a crafted address list"
}
GHSA-2X83-8G95-XH59
Vulnerability from github – Published: 2026-06-25 19:36 – Updated: 2026-06-25 19:36Summary
ExpandoObjectFormatter.Deserialize populates System.Dynamic.ExpandoObject by calling IDictionary<string, object>.Add for each map entry. ExpandoObject internally maintains member names in array-like structures, so inserting many distinct keys can require repeated linear scans and array copies.
For large attacker-controlled maps, this produces quadratic CPU and allocation behavior. The issue is especially surprising because ExpandoObjectResolver.Options is configured with MessagePackSecurity.UntrustedData, but collision-resistant dictionary comparers cannot protect ExpandoObject insertion internals.
Impact
Applications are affected when they deserialize untrusted MessagePack maps into ExpandoObject using ExpandoObjectResolver or related resolver options.
A hostile payload containing many distinct keys can cause CPU exhaustion and allocation churn disproportionate to the input size. This can make a server unresponsive or exhaust memory under concurrent request load.
This is not a hash-collision attack against a configurable dictionary comparer. The super-linear behavior comes from ExpandoObject's insertion model, so MessagePackSecurity.UntrustedData does not eliminate the cost.
Affected components
- Package:
MessagePack - APIs:
ExpandoObjectFormatter.Deserialize,ExpandoObjectResolver - Data type:
System.Dynamic.ExpandoObject - Finding ID:
MESSAGEPACKCSHARP-102
Patches
Fixes are prepared and will be released in coordinated patch versions.
Upgrade guidance:
- Upgrade
MessagePackto the patched version for your release line. - Upgrade companion MessagePack packages in the same dependency graph to the coordinated patched versions.
Potential fixes include applying a map-entry count limit for ExpandoObject under untrusted-data settings, buffering into a security-aware dictionary before materializing a bounded ExpandoObject, or otherwise rejecting maps large enough to trigger quadratic behavior.
Workarounds
Patching is recommended.
Until a patched version is available, avoid deserializing untrusted payloads into ExpandoObject. Prefer strongly typed DTOs or dictionaries with security-aware comparers and explicit count limits. Enforce request-size and map-entry limits at the transport or application layer.
Resources
MESSAGEPACKCSHARP-102:ExpandoObjectFormatterquadratic insertion behavior- CWE-407: Inefficient Algorithmic Complexity
{
"affected": [
{
"package": {
"ecosystem": "NuGet",
"name": "MessagePack"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.5.301"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "MessagePack"
},
"ranges": [
{
"events": [
{
"introduced": "3.0"
},
{
"fixed": "3.1.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-48511"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-25T19:36:23Z",
"nvd_published_at": "2026-06-22T22:16:47Z",
"severity": "MODERATE"
},
"details": "## Summary\n\n`ExpandoObjectFormatter.Deserialize` populates `System.Dynamic.ExpandoObject` by calling `IDictionary\u003cstring, object\u003e.Add` for each map entry. `ExpandoObject` internally maintains member names in array-like structures, so inserting many distinct keys can require repeated linear scans and array copies.\n\nFor large attacker-controlled maps, this produces quadratic CPU and allocation behavior. The issue is especially surprising because `ExpandoObjectResolver.Options` is configured with `MessagePackSecurity.UntrustedData`, but collision-resistant dictionary comparers cannot protect `ExpandoObject` insertion internals.\n\n## Impact\n\nApplications are affected when they deserialize untrusted MessagePack maps into `ExpandoObject` using `ExpandoObjectResolver` or related resolver options.\n\nA hostile payload containing many distinct keys can cause CPU exhaustion and allocation churn disproportionate to the input size. This can make a server unresponsive or exhaust memory under concurrent request load.\n\nThis is not a hash-collision attack against a configurable dictionary comparer. The super-linear behavior comes from `ExpandoObject`\u0027s insertion model, so `MessagePackSecurity.UntrustedData` does not eliminate the cost.\n\n## Affected components\n\n- Package: `MessagePack`\n- APIs: `ExpandoObjectFormatter.Deserialize`, `ExpandoObjectResolver`\n- Data type: `System.Dynamic.ExpandoObject`\n- Finding ID: `MESSAGEPACKCSHARP-102`\n\n## Patches\n\nFixes are prepared and will be released in coordinated patch versions.\n\nUpgrade guidance:\n\n1. Upgrade `MessagePack` to the patched version for your release line.\n2. Upgrade companion MessagePack packages in the same dependency graph to the coordinated patched versions.\n\nPotential fixes include applying a map-entry count limit for `ExpandoObject` under untrusted-data settings, buffering into a security-aware dictionary before materializing a bounded `ExpandoObject`, or otherwise rejecting maps large enough to trigger quadratic behavior.\n\n## Workarounds\n\nPatching is recommended.\n\nUntil a patched version is available, avoid deserializing untrusted payloads into `ExpandoObject`. Prefer strongly typed DTOs or dictionaries with security-aware comparers and explicit count limits. Enforce request-size and map-entry limits at the transport or application layer.\n\n## Resources\n\n- `MESSAGEPACKCSHARP-102`: `ExpandoObjectFormatter` quadratic insertion behavior\n- CWE-407: Inefficient Algorithmic Complexity",
"id": "GHSA-2x83-8g95-xh59",
"modified": "2026-06-25T19:36:23Z",
"published": "2026-06-25T19:36:23Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/MessagePack-CSharp/MessagePack-CSharp/security/advisories/GHSA-2x83-8g95-xh59"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-48511"
},
{
"type": "PACKAGE",
"url": "https://github.com/MessagePack-CSharp/MessagePack-CSharp"
}
],
"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:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "MessagePack-CSharp: ExpandoObject formatter can perform quadratic insertion work on untrusted maps"
}
GHSA-32F6-MGWR-PVC4
Vulnerability from github – Published: 2026-09-09 15:35 – Updated: 2026-09-09 15:35t-digest versions 3.1 through 3.3 fail to validate centroid means during deserialization in MergingDigest.fromBytes, allowing attackers to inject NaN values that bypass validation checks. Attackers can craft malicious serialized digests containing NaN centroids that degrade sorting performance from O(n log n) to O(n squared), causing severe processing delays during merge operations.
{
"affected": [],
"aliases": [
"CVE-2026-87822"
],
"database_specific": {
"cwe_ids": [
"CWE-407"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-09-09T15:17:27Z",
"severity": "HIGH"
},
"details": "t-digest versions 3.1 through 3.3 fail to validate centroid means during deserialization in MergingDigest.fromBytes, allowing attackers to inject NaN values that bypass validation checks. Attackers can craft malicious serialized digests containing NaN centroids that degrade sorting performance from O(n log n) to O(n squared), causing severe processing delays during merge operations.",
"id": "GHSA-32f6-mgwr-pvc4",
"modified": "2026-09-09T15:35:16Z",
"published": "2026-09-09T15:35:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-87822"
},
{
"type": "WEB",
"url": "https://github.com/tdunning/t-digest/issues/229"
},
{
"type": "WEB",
"url": "https://github.com/tdunning/t-digest"
},
{
"type": "WEB",
"url": "https://github.com/tdunning/t-digest/blob/8d5c1523c3d46925e9b3979a8d63c0b9d004ed1c/core/src/main/java/com/tdunning/math/stats/MergingDigest.java"
},
{
"type": "WEB",
"url": "https://github.com/tdunning/t-digest/blob/8d5c1523c3d46925e9b3979a8d63c0b9d004ed1c/core/src/main/java/com/tdunning/math/stats/Sort.java"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/t-digest-3.1-through-3.3-denial-of-service-via-nan-centroid-means-in-mergingdigest-frombytes"
}
],
"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: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"
}
]
}
No mitigation information available for this CWE.
No CAPEC attack patterns related to this CWE.