CWE-674
Allowed-with-ReviewUncontrolled Recursion
Abstraction: Class · Status: Draft
The product does not properly control the amount of recursion that takes place, consuming excessive resources, such as allocated memory or the program stack.
755 vulnerabilities reference this CWE, most recent first.
GHSA-CW6X-M8JW-QMRH
Vulnerability from github – Published: 2026-09-02 14:33 – Updated: 2026-09-02 14:33Summary
nltk.featstruct.FeatStructReader (used by FeatStruct(str) and by FeatureGrammar.fromstring()) parses feature-structure strings such as [a=1] with a recursive-descent parser that has no nesting-depth limit. A small, trivially-crafted input (~700 bytes) with deeply nested brackets drives the parser past Python's recursion limit and raises an unhandled RecursionError instead of the library's normal, catchable ValueError/LogicalExpressionException. Any application that parses user-supplied feature-structure or feature-grammar text (e.g. NLP teaching tools, grammar "playgrounds", unification-grammar-based NLU pipelines) can be crashed by an unauthenticated input with no special privileges. This is a Denial of Service issue (CWE-674, Uncontrolled Recursion), not a memory-safety or code-execution issue.
This appears to be the same bug class as two issues already fixed elsewhere in the codebase — nltk/jsontags.py (JSONTaggedDecoder.decode_obj, guarded by MAX_DECODE_DEPTH = 200) and nltk/sem/logic.py (LogicParser, guarded by MAX_PARSE_DEPTH = 200) — but nltk/featstruct.py does not have an equivalent guard.
Details
The recursive call chain (current develop branch, nltk/featstruct.py):
FeatStructReader.fromstring()(featstruct.py:2184) callsread_partial()→_read_partial()(featstruct.py:2250)._read_partial()dispatches to_read_partial_featdict(), which calls_read_value()(featstruct.py:2436) for each feature's value._read_value()callsread_value()(featstruct.py:2442), which matches the value againstVALUE_HANDLERS(featstruct.py:2478).- If the value itself starts with
[(a nested feature structure), the matched handler isread_fstruct_value(featstruct.py:2479, defined atfeatstruct.py:2495):python def read_fstruct_value(self, s, position, reentrances, match): return self.read_partial(s, position, reentrances)This callsread_partial()again, which re-enters_read_partial()— the same function from step 1.
This closes a recursive cycle (_read_partial → _read_value → read_value → read_fstruct_value → read_partial → _read_partial → ...) with no depth counter, no MAX_*_DEPTH constant, and no try/except RecursionError anywhere in the class. Each additional [ in the input adds one more full cycle of Python stack frames. Once the input nests deeply enough, Python's own recursion-limit protection fires and raises RecursionError, which is not a subclass of ValueError (the exception type this parser's own _error() helper raises for normal, well-formed parse errors) and therefore propagates uncaught through this API.
For comparison, nltk/sem/logic.py's LogicParser was hardened against exactly this class of issue:
#: Maximum expression-nesting depth the recursive-descent parser will
#: descend to. Deeply nested input would otherwise recurse until Python
#: raises an uncaught RecursionError and crashes the caller
#: (uncontrolled recursion, CWE-674); past this depth a normal
#: LogicalExpressionException is raised instead. Configurable.
MAX_PARSE_DEPTH = 200
(nltk/sem/logic.py:102-107), and nltk/jsontags.py's JSONTaggedDecoder similarly has MAX_DECODE_DEPTH = 200 with an explicit depth check. nltk/featstruct.py has no analogous protection.
FeatureGrammar.fromstring() (nltk/grammar.py) parses feature structures embedded in FCFG grammar rules via the same FeatStructReader, so the same crash is reachable through grammar-string parsing as well as through FeatStruct() directly.
PoC
Verified against the current develop branch in a clean virtualenv (Python 3.12, NLTK installed from this checkout via pip install -e .):
from nltk.featstruct import FeatStruct
depth = 167
payload = "[a=" * depth + "1" + "]" * depth # 669 bytes
FeatStruct(payload)
Result:
Traceback (most recent call last):
...
File ".../nltk/featstruct.py", line 2310, in _read_partial_featdict
value, position = self._read_value(name, s, position, reentrances)
File ".../nltk/featstruct.py", line 2440, in _read_value
return self.read_value(s, position, reentrances)
File ".../nltk/featstruct.py", line 2446, in read_value
return handler_func(s, position, reentrances, match)
[... repeats ~167 times ...]
RecursionError: maximum recursion depth exceeded
- Crash threshold: nesting depth 167 (binary-searched between 50 and 200).
- Payload size: 669 bytes — fits trivially in a single HTTP request body/query parameter.
- Time to crash: <2ms — no resource exhaustion is needed, only recursion depth.
Minimal reproduction (no server required):
python3 -c "
from nltk.featstruct import FeatStruct
FeatStruct('[a=' * 200 + '1' + ']' * 200)
"
Illustrative server-side context (not part of NLTK itself, but representative of how the bug becomes reachable):
from flask import Flask, request
from nltk.featstruct import FeatStruct
app = Flask(__name__)
@app.route("/parse", methods=["POST"])
def parse_grammar():
return {"result": str(FeatStruct(request.json["grammar"]))}
A POST of {"grammar": "[a=" * 200 + "1" + "]" * 200} to this endpoint raises the uncaught RecursionError inside the request handler.
Impact
Vulnerability type: Denial of Service via uncontrolled recursion (CWE-674). This is not a memory-corruption bug and does not lead to code execution or data disclosure — Python's own recursion-limit safety net converts what would be a C-level stack overflow into a catchable (but here, uncaught) RecursionError.
Who is affected: Any application that passes externally-supplied text into nltk.featstruct.FeatStruct() or nltk.grammar.FeatureGrammar.fromstring() — for example, NLP/computational-linguistics teaching tools, unification-grammar demo services, or NLU pipelines that accept user-authored feature grammars. This is a narrower slice of NLTK's user base than, e.g., tokenization or POS tagging, since feature-structure/unification-grammar parsing is a more specialized part of the library.
Practical severity depends on deployment:
- In typical WSGI-style web frameworks (Flask/Django/FastAPI behind gunicorn/uwsgi), an uncaught exception inside a request handler is caught at the framework/server boundary: the single request fails (HTTP 500), the worker process itself survives, and unaffected requests are unimpacted.
- In single-threaded or per-task-unprotected contexts (e.g. a queue-consuming worker without per-task exception isolation), the uncaught RecursionError can terminate the entire process; without a process supervisor that auto-restarts it, this is a persistent outage until manually restarted. An attacker who repeats the payload can keep such a worker in a crash loop for as long as the attack continues.
Suggested fix: Add a depth counter and a MAX_PARSE_DEPTH-style constant to FeatStructReader, mirroring the existing fix in nltk/sem/logic.py, and raise the library's normal ValueError-based parse error once the limit is exceeded instead of letting RecursionError propagate.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.10.2"
},
"package": {
"ecosystem": "PyPI",
"name": "nltk"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.10.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-81724"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-02T14:33:22Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "### Summary\n\n`nltk.featstruct.FeatStructReader` (used by `FeatStruct(str)` and by `FeatureGrammar.fromstring()`) parses feature-structure strings such as `[a=1]` with a recursive-descent parser that has no nesting-depth limit. A small, trivially-crafted input (~700 bytes) with deeply nested brackets drives the parser past Python\u0027s recursion limit and raises an **unhandled `RecursionError`** instead of the library\u0027s normal, catchable `ValueError`/`LogicalExpressionException`. Any application that parses user-supplied feature-structure or feature-grammar text (e.g. NLP teaching tools, grammar \"playgrounds\", unification-grammar-based NLU pipelines) can be crashed by an unauthenticated input with no special privileges. This is a Denial of Service issue (CWE-674, Uncontrolled Recursion), not a memory-safety or code-execution issue.\n\nThis appears to be the same bug class as two issues already fixed elsewhere in the codebase \u2014 `nltk/jsontags.py` (`JSONTaggedDecoder.decode_obj`, guarded by `MAX_DECODE_DEPTH = 200`) and `nltk/sem/logic.py` (`LogicParser`, guarded by `MAX_PARSE_DEPTH = 200`) \u2014 but `nltk/featstruct.py` does not have an equivalent guard.\n\n### Details\n\nThe recursive call chain (current `develop` branch, `nltk/featstruct.py`):\n\n1. `FeatStructReader.fromstring()` ([`featstruct.py:2184`](nltk/featstruct.py#L2184)) calls `read_partial()` \u2192 `_read_partial()` ([`featstruct.py:2250`](nltk/featstruct.py#L2250)).\n2. `_read_partial()` dispatches to `_read_partial_featdict()`, which calls `_read_value()` ([`featstruct.py:2436`](nltk/featstruct.py#L2436)) for each feature\u0027s value.\n3. `_read_value()` calls `read_value()` ([`featstruct.py:2442`](nltk/featstruct.py#L2442)), which matches the value against `VALUE_HANDLERS` ([`featstruct.py:2478`](nltk/featstruct.py#L2478)).\n4. If the value itself starts with `[` (a nested feature structure), the matched handler is `read_fstruct_value` ([`featstruct.py:2479`](nltk/featstruct.py#L2479), defined at [`featstruct.py:2495`](nltk/featstruct.py#L2495)):\n ```python\n def read_fstruct_value(self, s, position, reentrances, match):\n return self.read_partial(s, position, reentrances)\n ```\n This calls `read_partial()` again, which re-enters `_read_partial()` \u2014 the same function from step 1.\n\nThis closes a recursive cycle (`_read_partial \u2192 _read_value \u2192 read_value \u2192 read_fstruct_value \u2192 read_partial \u2192 _read_partial \u2192 ...`) with **no depth counter, no `MAX_*_DEPTH` constant, and no `try/except RecursionError`** anywhere in the class. Each additional `[` in the input adds one more full cycle of Python stack frames. Once the input nests deeply enough, Python\u0027s own recursion-limit protection fires and raises `RecursionError`, which is not a subclass of `ValueError` (the exception type this parser\u0027s own `_error()` helper raises for normal, well-formed parse errors) and therefore propagates uncaught through this API.\n\nFor comparison, `nltk/sem/logic.py`\u0027s `LogicParser` was hardened against exactly this class of issue:\n```python\n#: Maximum expression-nesting depth the recursive-descent parser will\n#: descend to. Deeply nested input would otherwise recurse until Python\n#: raises an uncaught RecursionError and crashes the caller\n#: (uncontrolled recursion, CWE-674); past this depth a normal\n#: LogicalExpressionException is raised instead. Configurable.\nMAX_PARSE_DEPTH = 200\n```\n(`nltk/sem/logic.py:102-107`), and `nltk/jsontags.py`\u0027s `JSONTaggedDecoder` similarly has `MAX_DECODE_DEPTH = 200` with an explicit depth check. `nltk/featstruct.py` has no analogous protection.\n\n`FeatureGrammar.fromstring()` (`nltk/grammar.py`) parses feature structures embedded in FCFG grammar rules via the same `FeatStructReader`, so the same crash is reachable through grammar-string parsing as well as through `FeatStruct()` directly.\n\n### PoC\n\nVerified against the current `develop` branch in a clean virtualenv (Python 3.12, NLTK installed from this checkout via `pip install -e .`):\n\n```python\nfrom nltk.featstruct import FeatStruct\n\ndepth = 167\npayload = \"[a=\" * depth + \"1\" + \"]\" * depth # 669 bytes\nFeatStruct(payload)\n```\n\nResult:\n```\nTraceback (most recent call last):\n ...\n File \".../nltk/featstruct.py\", line 2310, in _read_partial_featdict\n value, position = self._read_value(name, s, position, reentrances)\n File \".../nltk/featstruct.py\", line 2440, in _read_value\n return self.read_value(s, position, reentrances)\n File \".../nltk/featstruct.py\", line 2446, in read_value\n return handler_func(s, position, reentrances, match)\n [... repeats ~167 times ...]\nRecursionError: maximum recursion depth exceeded\n```\n\n- Crash threshold: nesting depth 167 (binary-searched between 50 and 200).\n- Payload size: 669 bytes \u2014 fits trivially in a single HTTP request body/query parameter.\n- Time to crash: \u003c2ms \u2014 no resource exhaustion is needed, only recursion depth.\n\nMinimal reproduction (no server required):\n```bash\npython3 -c \"\nfrom nltk.featstruct import FeatStruct\nFeatStruct(\u0027[a=\u0027 * 200 + \u00271\u0027 + \u0027]\u0027 * 200)\n\"\n```\n\nIllustrative server-side context (not part of NLTK itself, but representative of how the bug becomes reachable):\n```python\nfrom flask import Flask, request\nfrom nltk.featstruct import FeatStruct\n\napp = Flask(__name__)\n\n@app.route(\"/parse\", methods=[\"POST\"])\ndef parse_grammar():\n return {\"result\": str(FeatStruct(request.json[\"grammar\"]))}\n```\nA POST of `{\"grammar\": \"[a=\" * 200 + \"1\" + \"]\" * 200}` to this endpoint raises the uncaught `RecursionError` inside the request handler.\n\n### Impact\n\n**Vulnerability type:** Denial of Service via uncontrolled recursion (CWE-674). This is not a memory-corruption bug and does not lead to code execution or data disclosure \u2014 Python\u0027s own recursion-limit safety net converts what would be a C-level stack overflow into a catchable (but here, uncaught) `RecursionError`.\n\n**Who is affected:** Any application that passes externally-supplied text into `nltk.featstruct.FeatStruct()` or `nltk.grammar.FeatureGrammar.fromstring()` \u2014 for example, NLP/computational-linguistics teaching tools, unification-grammar demo services, or NLU pipelines that accept user-authored feature grammars. This is a narrower slice of NLTK\u0027s user base than, e.g., tokenization or POS tagging, since feature-structure/unification-grammar parsing is a more specialized part of the library.\n\n**Practical severity depends on deployment:**\n- In typical WSGI-style web frameworks (Flask/Django/FastAPI behind gunicorn/uwsgi), an uncaught exception inside a request handler is caught at the framework/server boundary: the single request fails (HTTP 500), the worker process itself survives, and unaffected requests are unimpacted.\n- In single-threaded or per-task-unprotected contexts (e.g. a queue-consuming worker without per-task exception isolation), the uncaught `RecursionError` can terminate the entire process; without a process supervisor that auto-restarts it, this is a persistent outage until manually restarted. An attacker who repeats the payload can keep such a worker in a crash loop for as long as the attack continues.\n\n**Suggested fix:** Add a depth counter and a `MAX_PARSE_DEPTH`-style constant to `FeatStructReader`, mirroring the existing fix in `nltk/sem/logic.py`, and raise the library\u0027s normal `ValueError`-based parse error once the limit is exceeded instead of letting `RecursionError` propagate.",
"id": "GHSA-cw6x-m8jw-qmrh",
"modified": "2026-09-02T14:33:22Z",
"published": "2026-09-02T14:33:22Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/security/advisories/GHSA-cw6x-m8jw-qmrh"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-81724"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/commit/43c7b78cc8ea37e5cd3a129e27e32c415ea21cf1"
},
{
"type": "PACKAGE",
"url": "https://github.com/nltk/nltk"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/releases/tag/v3.10.3"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3739.yaml"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/nltk-before-3.10.3-denial-of-service-via-uncontrolled-recursion"
}
],
"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",
"type": "CVSS_V4"
}
],
"summary": "NLTK: Uncontrolled recursion in nltk.featstruct.FeatStructReader causes unhandled RecursionError (DoS) via deeply nested feature-structure input"
}
GHSA-CWFF-W289-23WM
Vulnerability from github – Published: 2022-05-13 01:27 – Updated: 2022-05-13 01:27An issue was discovered in cplus-dem.c in GNU libiberty, as distributed in GNU Binutils 2.29 and 2.30. Stack Exhaustion occurs in the C++ demangling functions provided by libiberty, and there are recursive stack frames: demangle_nested_args, demangle_args, do_arg, and do_type.
{
"affected": [],
"aliases": [
"CVE-2018-9138"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-03-30T08:29:00Z",
"severity": "MODERATE"
},
"details": "An issue was discovered in cplus-dem.c in GNU libiberty, as distributed in GNU Binutils 2.29 and 2.30. Stack Exhaustion occurs in the C++ demangling functions provided by libiberty, and there are recursive stack frames: demangle_nested_args, demangle_args, do_arg, and do_type.",
"id": "GHSA-cwff-w289-23wm",
"modified": "2022-05-13T01:27:12Z",
"published": "2022-05-13T01:27:12Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-9138"
},
{
"type": "WEB",
"url": "https://sourceware.org/bugzilla/show_bug.cgi?id=23008"
},
{
"type": "WEB",
"url": "https://usn.ubuntu.com/4326-1"
},
{
"type": "WEB",
"url": "https://usn.ubuntu.com/4336-1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-CWFG-VHJR-JVV6
Vulnerability from github – Published: 2023-08-22 21:30 – Updated: 2023-12-08 21:30Uncontrolled Recursion in pdfinfo, and pdftops in poppler 0.89.0 allows remote attackers to cause a denial of service via crafted input.
{
"affected": [],
"aliases": [
"CVE-2020-23804"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-08-22T19:16:19Z",
"severity": "HIGH"
},
"details": "Uncontrolled Recursion in pdfinfo, and pdftops in poppler 0.89.0 allows remote attackers to cause a denial of service via crafted input.",
"id": "GHSA-cwfg-vhjr-jvv6",
"modified": "2023-12-08T21:30:29Z",
"published": "2023-08-22T21:30:25Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-23804"
},
{
"type": "WEB",
"url": "https://gitlab.freedesktop.org/poppler/poppler/-/issues/936"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/10/msg00022.html"
}
],
"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-CWV3-863G-39VX
Vulnerability from github – Published: 2021-05-21 14:26 – Updated: 2024-10-31 21:22Impact
TFlite graphs must not have loops between nodes. However, this condition was not checked and an attacker could craft models that would result in infinite loop during evaluation. In certain cases, the infinite loop would be replaced by stack overflow due to too many recursive calls.
For example, the While implementation could be tricked into a scneario where both the body and the loop subgraphs are the same. Evaluating one of the subgraphs means calling the Eval function for the other and this quickly exhaust all stack space.
Patches
We have patched the issue in GitHub commit 9c1dc920d8ffb4893d6c9d27d1f039607b326743 (for the While operator) and in GitHub commit c6173f5fe66cdbab74f4f869311fe6aae2ba35f4 (in general).
The fix will be included in TensorFlow 2.5.0. We will also cherrypick this commit on TensorFlow 2.4.2, TensorFlow 2.3.3, TensorFlow 2.2.3 and TensorFlow 2.1.4, as these are also affected and still in supported range.
For more information
Please consult our security guide for more information regarding the security model and how to contact us with issues and questions.
Attribution
This vulnerability has been reported by members of the Aivul Team from Qihoo 360.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow"
},
"ranges": [
{
"events": [
{
"introduced": "2.2.0"
},
{
"fixed": "2.2.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow"
},
"ranges": [
{
"events": [
{
"introduced": "2.3.0"
},
{
"fixed": "2.3.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow"
},
"ranges": [
{
"events": [
{
"introduced": "2.4.0"
},
{
"fixed": "2.4.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow-cpu"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow-cpu"
},
"ranges": [
{
"events": [
{
"introduced": "2.2.0"
},
{
"fixed": "2.2.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow-cpu"
},
"ranges": [
{
"events": [
{
"introduced": "2.3.0"
},
{
"fixed": "2.3.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow-cpu"
},
"ranges": [
{
"events": [
{
"introduced": "2.4.0"
},
{
"fixed": "2.4.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow-gpu"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow-gpu"
},
"ranges": [
{
"events": [
{
"introduced": "2.2.0"
},
{
"fixed": "2.2.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow-gpu"
},
"ranges": [
{
"events": [
{
"introduced": "2.3.0"
},
{
"fixed": "2.3.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "tensorflow-gpu"
},
"ranges": [
{
"events": [
{
"introduced": "2.4.0"
},
{
"fixed": "2.4.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-29591"
],
"database_specific": {
"cwe_ids": [
"CWE-674",
"CWE-835"
],
"github_reviewed": true,
"github_reviewed_at": "2021-05-18T16:46:07Z",
"nvd_published_at": "2021-05-14T20:15:00Z",
"severity": "HIGH"
},
"details": "### Impact\nTFlite graphs must not have loops between nodes. However, this condition was not checked and an attacker could craft models that would result in infinite loop during evaluation. In certain cases, the infinite loop would be replaced by stack overflow due to too many recursive calls.\n\nFor example, the [`While` implementation](https://github.com/tensorflow/tensorflow/blob/106d8f4fb89335a2c52d7c895b7a7485465ca8d9/tensorflow/lite/kernels/while.cc) could be tricked into a scneario where both the body and the loop subgraphs are the same. Evaluating one of the subgraphs means calling the `Eval` function for the other and this quickly exhaust all stack space.\n \n### Patches \nWe have patched the issue in GitHub commit [9c1dc920d8ffb4893d6c9d27d1f039607b326743](https://github.com/tensorflow/tensorflow/commit/9c1dc920d8ffb4893d6c9d27d1f039607b326743) (for the `While` operator) and in GitHub commit [c6173f5fe66cdbab74f4f869311fe6aae2ba35f4](https://github.com/tensorflow/tensorflow/commit/c6173f5fe66cdbab74f4f869311fe6aae2ba35f4) (in general).\n \nThe fix will be included in TensorFlow 2.5.0. We will also cherrypick this commit on TensorFlow 2.4.2, TensorFlow 2.3.3, TensorFlow 2.2.3 and TensorFlow 2.1.4, as these are also affected and still in supported range.\n\n### For more information\nPlease consult [our security guide](https://github.com/tensorflow/tensorflow/blob/master/SECURITY.md) for more information regarding the security model and how to contact us with issues and questions.\n\n### Attribution \nThis vulnerability has been reported by members of the Aivul Team from Qihoo 360.",
"id": "GHSA-cwv3-863g-39vx",
"modified": "2024-10-31T21:22:52Z",
"published": "2021-05-21T14:26:56Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/tensorflow/tensorflow/security/advisories/GHSA-cwv3-863g-39vx"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-29591"
},
{
"type": "WEB",
"url": "https://github.com/tensorflow/tensorflow/commit/9c1dc920d8ffb4893d6c9d27d1f039607b326743"
},
{
"type": "WEB",
"url": "https://github.com/tensorflow/tensorflow/commit/c6173f5fe66cdbab74f4f869311fe6aae2ba35f4"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/tensorflow-cpu/PYSEC-2021-519.yaml"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/tensorflow-gpu/PYSEC-2021-717.yaml"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/tensorflow/PYSEC-2021-228.yaml"
},
{
"type": "PACKAGE",
"url": "https://github.com/tensorflow/tensorflow"
},
{
"type": "WEB",
"url": "https://github.com/tensorflow/tensorflow/blob/106d8f4fb89335a2c52d7c895b7a7485465ca8d9/tensorflow/lite/kernels/while.cc"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:L/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Stack overflow due to looping TFLite subgraph"
}
GHSA-F2FG-5M3G-HQWV
Vulnerability from github – Published: 2026-02-18 18:30 – Updated: 2026-02-18 18:30mayswind ezbookkeeping versions 1.2.0 and earlier contain a critical vulnerability in JSON and XML file import processing. The application fails to validate nesting depth during parsing operations, allowing authenticated attackers to trigger denial of service conditions by uploading deeply nested malicious files. This results in CPU exhaustion, service degradation, or complete service unavailability.
{
"affected": [],
"aliases": [
"CVE-2025-65519"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-02-18T16:22:28Z",
"severity": "MODERATE"
},
"details": "mayswind ezbookkeeping versions 1.2.0 and earlier contain a critical vulnerability in JSON and XML file import processing. The application fails to validate nesting depth during parsing operations, allowing authenticated attackers to trigger denial of service conditions by uploading deeply nested malicious files. This results in CPU exhaustion, service degradation, or complete service unavailability.",
"id": "GHSA-f2fg-5m3g-hqwv",
"modified": "2026-02-18T18:30:39Z",
"published": "2026-02-18T18:30:39Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-65519"
},
{
"type": "WEB",
"url": "https://github.com/ictrun/EBK-SA-2025-001"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-F38Q-MGVJ-VPH7
Vulnerability from github – Published: 2026-06-15 17:27 – Updated: 2026-07-15 22:06Summary
protobufjs accepted certain schema-derived names that could collide with properties used by protobufjs runtime helpers. The known affected names are fields named hasOwnProperty, field or oneof names such as $type when loaded through protobufjs JSON/reflection descriptors, and service methods whose generated helper name is rpcCall.
When affected message or service types were used, protobufjs could read schema-controlled data where it expected an own-property helper, reflected type metadata, or the base RPC helper. This could cause deterministic exceptions or recursive calls in affected decode post-checks, verification, object conversion, reflected JSON serialization, or protobufjs RPC helper invocation.
Impact
An attacker who can provide or influence protobuf schemas or protobufjs JSON descriptors may be able to make affected message or service types unusable, resulting in denial of service for the affected processing path.
Applications using only trusted schemas are affected only if those schemas contain one of the problematic names and the application reaches the affected API path.
The issue is not known to allow code execution by itself.
Preconditions
- The application must use an affected protobufjs version.
- The application must load or use a schema or protobufjs JSON descriptor containing one of the problematic names:
- a field named
hasOwnProperty, - a field or oneof named
$typethrough protobufjs JSON/reflection descriptor input, - or a service method whose generated helper name is
rpcCall. - The application must reach the affected API path for that name: required-field decode post-checks,
verify, ortoObjectforhasOwnProperty; reflected message JSON serialization for$type; or protobufjs RPC service invocation forrpcCall.
Workarounds
Do not load protobuf schemas or protobufjs JSON descriptors from untrusted sources with affected versions. If untrusted schemas or descriptors must be accepted, validate schema-derived field, oneof, and service method names before loading and reject the problematic names described above.
Applications using trusted schemas can avoid the issue by renaming affected fields or service methods, or by avoiding the affected API path.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 7.6.2"
},
"package": {
"ecosystem": "npm",
"name": "protobufjs"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "7.6.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.5.0"
},
"package": {
"ecosystem": "npm",
"name": "protobufjs-cli"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.5.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.3.2"
},
"package": {
"ecosystem": "npm",
"name": "protobufjs-cli"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.3.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.5.0"
},
"package": {
"ecosystem": "npm",
"name": "protobufjs"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.6.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54269"
],
"database_specific": {
"cwe_ids": [
"CWE-674",
"CWE-754"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T17:27:18Z",
"nvd_published_at": "2026-06-22T18:16:45Z",
"severity": "MODERATE"
},
"details": "## Summary\n\nprotobufjs accepted certain schema-derived names that could collide with properties used by protobufjs runtime helpers. The known affected names are fields named `hasOwnProperty`, field or oneof names such as `$type` when loaded through protobufjs JSON/reflection descriptors, and service methods whose generated helper name is `rpcCall`.\n\nWhen affected message or service types were used, protobufjs could read schema-controlled data where it expected an own-property helper, reflected type metadata, or the base RPC helper. This could cause deterministic exceptions or recursive calls in affected decode post-checks, verification, object conversion, reflected JSON serialization, or protobufjs RPC helper invocation.\n\n## Impact\n\nAn attacker who can provide or influence protobuf schemas or protobufjs JSON descriptors may be able to make affected message or service types unusable, resulting in denial of service for the affected processing path.\n\nApplications using only trusted schemas are affected only if those schemas contain one of the problematic names and the application reaches the affected API path.\n\nThe issue is not known to allow code execution by itself.\n\n## Preconditions\n\n* The application must use an affected protobufjs version.\n* The application must load or use a schema or protobufjs JSON descriptor containing one of the problematic names:\n * a field named `hasOwnProperty`,\n * a field or oneof named `$type` through protobufjs JSON/reflection descriptor input,\n * or a service method whose generated helper name is `rpcCall`.\n* The application must reach the affected API path for that name: required-field decode post-checks, `verify`, or `toObject` for `hasOwnProperty`; reflected message JSON serialization for `$type`; or protobufjs RPC service invocation for `rpcCall`.\n\n## Workarounds\n\nDo not load protobuf schemas or protobufjs JSON descriptors from untrusted sources with affected versions. If untrusted schemas or descriptors must be accepted, validate schema-derived field, oneof, and service method names before loading and reject the problematic names described above.\n\nApplications using trusted schemas can avoid the issue by renaming affected fields or service methods, or by avoiding the affected API path.",
"id": "GHSA-f38q-mgvj-vph7",
"modified": "2026-07-15T22:06:05Z",
"published": "2026-06-15T17:27:18Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/protobufjs/protobuf.js/security/advisories/GHSA-f38q-mgvj-vph7"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-54269"
},
{
"type": "PACKAGE",
"url": "https://github.com/protobufjs/protobuf.js"
}
],
"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": "protobufjs : Schema-derived names can shadow runtime-significant properties"
}
GHSA-F3PG-HPPR-JF6F
Vulnerability from github – Published: 2024-11-21 21:33 – Updated: 2024-12-24 15:30In the Linux kernel, the following vulnerability has been resolved:
afs: Fix lock recursion
afs_wake_up_async_call() can incur lock recursion. The problem is that it is called from AF_RXRPC whilst holding the ->notify_lock, but it tries to take a ref on the afs_call struct in order to pass it to a work queue - but if the afs_call is already queued, we then have an extraneous ref that must be put... calling afs_put_call() may call back down into AF_RXRPC through rxrpc_kernel_shutdown_call(), however, which might try taking the ->notify_lock again.
This case isn't very common, however, so defer it to a workqueue. The oops looks something like:
BUG: spinlock recursion on CPU#0, krxrpcio/7001/1646 lock: 0xffff888141399b30, .magic: dead4ead, .owner: krxrpcio/7001/1646, .owner_cpu: 0 CPU: 0 UID: 0 PID: 1646 Comm: krxrpcio/7001 Not tainted 6.12.0-rc2-build3+ #4351 Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014 Call Trace: dump_stack_lvl+0x47/0x70 do_raw_spin_lock+0x3c/0x90 rxrpc_kernel_shutdown_call+0x83/0xb0 afs_put_call+0xd7/0x180 rxrpc_notify_socket+0xa0/0x190 rxrpc_input_split_jumbo+0x198/0x1d0 rxrpc_input_data+0x14b/0x1e0 ? rxrpc_input_call_packet+0xc2/0x1f0 rxrpc_input_call_event+0xad/0x6b0 rxrpc_input_packet_on_conn+0x1e1/0x210 rxrpc_input_packet+0x3f2/0x4d0 rxrpc_io_thread+0x243/0x410 ? __pfx_rxrpc_io_thread+0x10/0x10 kthread+0xcf/0xe0 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x24/0x40 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30
{
"affected": [],
"aliases": [
"CVE-2024-53090"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-11-21T19:15:12Z",
"severity": "MODERATE"
},
"details": "In the Linux kernel, the following vulnerability has been resolved:\n\nafs: Fix lock recursion\n\nafs_wake_up_async_call() can incur lock recursion. The problem is that it\nis called from AF_RXRPC whilst holding the -\u003enotify_lock, but it tries to\ntake a ref on the afs_call struct in order to pass it to a work queue - but\nif the afs_call is already queued, we then have an extraneous ref that must\nbe put... calling afs_put_call() may call back down into AF_RXRPC through\nrxrpc_kernel_shutdown_call(), however, which might try taking the\n-\u003enotify_lock again.\n\nThis case isn\u0027t very common, however, so defer it to a workqueue. The oops\nlooks something like:\n\n BUG: spinlock recursion on CPU#0, krxrpcio/7001/1646\n lock: 0xffff888141399b30, .magic: dead4ead, .owner: krxrpcio/7001/1646, .owner_cpu: 0\n CPU: 0 UID: 0 PID: 1646 Comm: krxrpcio/7001 Not tainted 6.12.0-rc2-build3+ #4351\n Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014\n Call Trace:\n \u003cTASK\u003e\n dump_stack_lvl+0x47/0x70\n do_raw_spin_lock+0x3c/0x90\n rxrpc_kernel_shutdown_call+0x83/0xb0\n afs_put_call+0xd7/0x180\n rxrpc_notify_socket+0xa0/0x190\n rxrpc_input_split_jumbo+0x198/0x1d0\n rxrpc_input_data+0x14b/0x1e0\n ? rxrpc_input_call_packet+0xc2/0x1f0\n rxrpc_input_call_event+0xad/0x6b0\n rxrpc_input_packet_on_conn+0x1e1/0x210\n rxrpc_input_packet+0x3f2/0x4d0\n rxrpc_io_thread+0x243/0x410\n ? __pfx_rxrpc_io_thread+0x10/0x10\n kthread+0xcf/0xe0\n ? __pfx_kthread+0x10/0x10\n ret_from_fork+0x24/0x40\n ? __pfx_kthread+0x10/0x10\n ret_from_fork_asm+0x1a/0x30\n \u003c/TASK\u003e",
"id": "GHSA-f3pg-hppr-jf6f",
"modified": "2024-12-24T15:30:31Z",
"published": "2024-11-21T21:33:32Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-53090"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/610a79ffea02102899a1373fe226d949944a7ed6"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/d7cbf81df996b1eae2dee8deb6df08e2eba78661"
}
],
"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-F4QM-VJ5J-9XPW
Vulnerability from github – Published: 2026-04-14 18:48 – Updated: 2026-04-14 18:48A stack overflow vulnerability in ImageMagick's FX expression parser allows an attacker to crash the process by providing a deeply nested expression.
{
"affected": [
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-AnyCPU"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-AnyCPU"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-OpenMP-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-x86"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-OpenMP-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-OpenMP-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-x86"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-AnyCPU"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-OpenMP-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-OpenMP-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-x86"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-33902"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-14T18:48:06Z",
"nvd_published_at": "2026-04-13T22:16:28Z",
"severity": "MODERATE"
},
"details": "A stack overflow vulnerability in ImageMagick\u0027s FX expression parser allows an attacker to crash the process by providing a deeply nested expression.",
"id": "GHSA-f4qm-vj5j-9xpw",
"modified": "2026-04-14T18:48:07Z",
"published": "2026-04-14T18:48:06Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-f4qm-vj5j-9xpw"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33902"
},
{
"type": "WEB",
"url": "https://github.com/ImageMagick/ImageMagick/commit/d3c0a37485314c5ccef72efb18f3847cd53868ba"
},
{
"type": "PACKAGE",
"url": "https://github.com/ImageMagick/ImageMagick"
},
{
"type": "WEB",
"url": "https://github.com/ImageMagick/ImageMagick/releases/tag/7.1.2-19"
},
{
"type": "WEB",
"url": "https://github.com/dlemstra/Magick.NET/releases/tag/14.12.0"
}
],
"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"
}
],
"summary": " ImageMagick has a Stack Overflow via Recursive FX Expression Parsing"
}
GHSA-F5V8-V6Q3-Q4H6
Vulnerability from github – Published: 2026-04-16 22:50 – Updated: 2026-04-16 22:50Summary
Meridian v2.1.0 (Meridian.Mapping and Meridian.Mediator) shipped with nine defense-in-depth gaps reachable through its public APIs. Two are HIGH severity — the advertised DefaultMaxCollectionItems and DefaultMaxDepth safety caps are silently bypassed on the IMapper.Map(source, destination) overload and anywhere .UseDestinationValue() is configured on a collection-typed property. Four are MEDIUM (constructor invariant bypass, OpenTelemetry stack-trace info disclosure, retry amplification, notification fan-out amplification). Three are LOW (exception message disclosure, dictionary duplicate-key echo, static mediator cache growth under closed-generic types).
All nine are patched in v2.1.1. Upgrade is a drop-in NuGet bump; see the v2.1.1 CHANGELOG for the four behavioural changes (constructor selection, OTel default, publisher fan-out cap, retry caps).
Severity Matrix
| # | Severity | CWE | Finding | Fix |
|---|---|---|---|---|
| 1 | HIGH | CWE-770 | MappingEngine.TryMapCollectionOntoExisting enumerated the source without enforcing DefaultMaxCollectionItems. Reachable via Mapper.Map<TSrc,TDst>(src, dst) and any .ForMember(..., o => o.UseDestinationValue()) on a collection member through a plain Map(src) call. |
Shared cap enforcement helper between MapCollection and TryMapCollectionOntoExisting. |
| 2 | HIGH | CWE-674 | Collection-item recursion in the existing-destination path did not increment ResolutionContext.Depth, so self-referential collection graphs could reach stack overflow before DefaultMaxDepth fired. |
Depth increments at every collection-item boundary. |
| 3 | MEDIUM | CWE-665 | ObjectCreator.CreateWithConstructorMapping always invoked the widest public constructor, silently filling unresolved parameters with default(T) and bypassing narrower-ctor invariants. |
Widest-ctor selection now requires every parameter to be bound via explicit ctor mapping, source-name match, or a C# optional default. |
| 4 | MEDIUM | CWE-532 | Mediator.MarkActivityFailure emitted the full ex.ToString() (stack + inner chain) to the OpenTelemetry exception.stacktrace activity tag by default, leaking context to any shared trace sink. |
Gated on MediatorTelemetryOptions.RecordExceptionStackTrace — opt-in, default false. |
| 5 | MEDIUM | CWE-400 | RetryBehavior retried every exception type with unbounded MaxRetries; the exponential-backoff delay overflowed TimeSpan at ~30 attempts. No cancellation exclusion. |
Server-side MaxRetriesCap = 10, MaxBackoff = 5 min, OperationCanceledException short-circuit, recommended RetryPolicy.TransientOnly helper. |
| 6 | MEDIUM | CWE-400 | TaskWhenAllPublisher started every registered handler concurrently with no bound on fan-out. |
New constructor parameter maxDegreeOfParallelism (default 16; -1 restores legacy unbounded). |
| 7 | LOW | CWE-209 | Public mapping exceptions leaked FullName of source/destination types and concatenated inner exception messages into top-level property-mapping errors. |
Scrubbed to type Name; inner details only via InnerException chain. |
| 8 | LOW | CWE-209 | Dictionary materialization threw ArgumentException on duplicate keys, echoing the attacker-supplied key's .ToString(). |
Last-write-wins indexer semantics. |
| 9 | LOW | CWE-1325 | Static mediator handler caches grow monotonically under closed-generic request types. Doc-only mitigation; no code change — consumers must not allow attacker-controlled runtime type materialization to reach Send, Publish, or CreateStream. |
Documented in docs/security-model.md. |
Exploitation
Finding 1 / 2 (headline): A consumer that maps user-supplied collection payloads onto an existing destination list via mapper.Map(userCollection, existingList) — a documented and commonly used AutoMapper-style idiom — processes the full attacker-supplied collection with no size cap and no depth cap. An attacker sending a single request with a large (or self-referential) collection payload can block the worker thread for seconds and exhaust the managed heap or the call stack. Equivalent exposure through .UseDestinationValue() on a collection-typed destination member, reachable via a plain Map(src) call whose destination type default-initializes that member.
Finding 3: A destination type with multiple public constructors that differ only in their parameter-binding invariants (e.g., new UserAccount(string name, Email email) enforcing a non-default Email) could be instantiated with the narrower ctor's invariants silently bypassed if any source field was absent — the widest ctor was always picked, with unbound parameters replaced by default(T).
Findings 4 / 5 / 6: Amplification / information-disclosure vectors described in the matrix above. Each requires moderate integration context (telemetry sink trust, handler count, retry policy) to weaponize, but each is reachable through public APIs without authentication.
Patches
Meridian.Mapping2.1.1 (published 2026-04-16)Meridian.Mediator2.1.1 (published 2026-04-16)
Verified via:
- GitHub Release assets at https://github.com/UmutKorkmaz/meridian/releases/tag/v2.1.1
- Sigstore attestation (actions/attest-build-provenance@v2 → gh attestation verify green on both .nupkg from the GitHub Release)
- NuGet.org indexed both packages within the release workflow run
Workarounds
Users who cannot upgrade immediately may:
1. Avoid mapper.Map(src, dst) and .UseDestinationValue() on collection-typed destination members.
2. Wrap input collection deserialization with an explicit size limit before handing the payload to Meridian.
3. Register TaskWhenAllPublisher with maxDegreeOfParallelism ≤ 16 manually (v2.1.1+ only).
4. Disable OpenTelemetry exception.stacktrace tag emission at the trace exporter level if your trace sink is less trusted than your application.
These are defense-in-depth; the only complete mitigation is upgrading to 2.1.1.
Supported Versions
As of this advisory the supported security branch is 2.1.x. The 2.0.x line (published 2026-04-15) is not receiving the Phase 1 safety-defaults infrastructure needed to carry the HIGH-severity fixes, so 2.0.x is deprecated in favor of 2.1.x. See SECURITY.md for the updated supported-versions table.
Credits
- UmutKorkmaz (reporter and maintainer)
References
- v2.1.1 CHANGELOG section: https://github.com/UmutKorkmaz/meridian/blob/main/CHANGELOG.md#211---2026-04-16
docs/security-model.mdthreat model: https://github.com/UmutKorkmaz/meridian/blob/main/docs/security-model.mdSECURITY.mddisclosure policy: https://github.com/UmutKorkmaz/meridian/blob/main/SECURITY.md- AutoMapper CVE-2026-32933 (motivating precedent for Meridian's safety-defaults)
{
"affected": [
{
"package": {
"ecosystem": "NuGet",
"name": "Meridian.Mapping"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.1.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Meridian.Mediator"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.1.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-1325",
"CWE-209",
"CWE-400",
"CWE-532",
"CWE-665",
"CWE-674",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-16T22:50:37Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nMeridian v2.1.0 (`Meridian.Mapping` and `Meridian.Mediator`) shipped with nine defense-in-depth gaps reachable through its public APIs. Two are HIGH severity \u2014 the advertised `DefaultMaxCollectionItems` and `DefaultMaxDepth` safety caps are silently bypassed on the `IMapper.Map(source, destination)` overload and anywhere `.UseDestinationValue()` is configured on a collection-typed property. Four are MEDIUM (constructor invariant bypass, OpenTelemetry stack-trace info disclosure, retry amplification, notification fan-out amplification). Three are LOW (exception message disclosure, dictionary duplicate-key echo, static mediator cache growth under closed-generic types).\n\nAll nine are patched in **v2.1.1**. Upgrade is a drop-in NuGet bump; see the v2.1.1 CHANGELOG for the four behavioural changes (constructor selection, OTel default, publisher fan-out cap, retry caps).\n\n## Severity Matrix\n\n| # | Severity | CWE | Finding | Fix |\n|---|---|---|---|---|\n| 1 | **HIGH** | CWE-770 | `MappingEngine.TryMapCollectionOntoExisting` enumerated the source without enforcing `DefaultMaxCollectionItems`. Reachable via `Mapper.Map\u003cTSrc,TDst\u003e(src, dst)` and any `.ForMember(..., o =\u003e o.UseDestinationValue())` on a collection member through a plain `Map(src)` call. | Shared cap enforcement helper between `MapCollection` and `TryMapCollectionOntoExisting`. |\n| 2 | **HIGH** | CWE-674 | Collection-item recursion in the existing-destination path did not increment `ResolutionContext.Depth`, so self-referential collection graphs could reach stack overflow before `DefaultMaxDepth` fired. | Depth increments at every collection-item boundary. |\n| 3 | MEDIUM | CWE-665 | `ObjectCreator.CreateWithConstructorMapping` always invoked the widest public constructor, silently filling unresolved parameters with `default(T)` and bypassing narrower-ctor invariants. | Widest-ctor selection now requires every parameter to be bound via explicit ctor mapping, source-name match, or a C# optional default. |\n| 4 | MEDIUM | CWE-532 | `Mediator.MarkActivityFailure` emitted the full `ex.ToString()` (stack + inner chain) to the OpenTelemetry `exception.stacktrace` activity tag by default, leaking context to any shared trace sink. | Gated on `MediatorTelemetryOptions.RecordExceptionStackTrace` \u2014 opt-in, default `false`. |\n| 5 | MEDIUM | CWE-400 | `RetryBehavior` retried every exception type with unbounded `MaxRetries`; the exponential-backoff delay overflowed `TimeSpan` at ~30 attempts. No cancellation exclusion. | Server-side `MaxRetriesCap = 10`, `MaxBackoff = 5 min`, `OperationCanceledException` short-circuit, recommended `RetryPolicy.TransientOnly` helper. |\n| 6 | MEDIUM | CWE-400 | `TaskWhenAllPublisher` started every registered handler concurrently with no bound on fan-out. | New constructor parameter `maxDegreeOfParallelism` (default 16; `-1` restores legacy unbounded). |\n| 7 | LOW | CWE-209 | Public mapping exceptions leaked `FullName` of source/destination types and concatenated inner exception messages into top-level property-mapping errors. | Scrubbed to type `Name`; inner details only via `InnerException` chain. |\n| 8 | LOW | CWE-209 | Dictionary materialization threw `ArgumentException` on duplicate keys, echoing the attacker-supplied key\u0027s `.ToString()`. | Last-write-wins indexer semantics. |\n| 9 | LOW | CWE-1325 | Static mediator handler caches grow monotonically under closed-generic request types. **Doc-only mitigation**; no code change \u2014 consumers must not allow attacker-controlled runtime type materialization to reach `Send`, `Publish`, or `CreateStream`. | Documented in `docs/security-model.md`. |\n\n## Exploitation\n\n**Finding 1 / 2 (headline):** A consumer that maps user-supplied collection payloads onto an existing destination list via `mapper.Map(userCollection, existingList)` \u2014 a documented and commonly used AutoMapper-style idiom \u2014 processes the full attacker-supplied collection with no size cap and no depth cap. An attacker sending a single request with a large (or self-referential) collection payload can block the worker thread for seconds and exhaust the managed heap or the call stack. Equivalent exposure through `.UseDestinationValue()` on a collection-typed destination member, reachable via a plain `Map(src)` call whose destination type default-initializes that member.\n\n**Finding 3:** A destination type with multiple public constructors that differ only in their parameter-binding invariants (e.g., `new UserAccount(string name, Email email)` enforcing a non-default `Email`) could be instantiated with the narrower ctor\u0027s invariants silently bypassed if any source field was absent \u2014 the widest ctor was always picked, with unbound parameters replaced by `default(T)`.\n\n**Findings 4 / 5 / 6:** Amplification / information-disclosure vectors described in the matrix above. Each requires moderate integration context (telemetry sink trust, handler count, retry policy) to weaponize, but each is reachable through public APIs without authentication.\n\n## Patches\n\n- `Meridian.Mapping` **2.1.1** (published 2026-04-16)\n- `Meridian.Mediator` **2.1.1** (published 2026-04-16)\n\nVerified via:\n- GitHub Release assets at \u003chttps://github.com/UmutKorkmaz/meridian/releases/tag/v2.1.1\u003e\n- Sigstore attestation (`actions/attest-build-provenance@v2` \u2192 `gh attestation verify` green on both `.nupkg` from the GitHub Release)\n- NuGet.org indexed both packages within the release workflow run\n\n## Workarounds\n\nUsers who cannot upgrade immediately may:\n1. Avoid `mapper.Map(src, dst)` and `.UseDestinationValue()` on collection-typed destination members.\n2. Wrap input collection deserialization with an explicit size limit before handing the payload to Meridian.\n3. Register `TaskWhenAllPublisher` with `maxDegreeOfParallelism` \u2264 16 manually (v2.1.1+ only).\n4. Disable OpenTelemetry `exception.stacktrace` tag emission at the trace exporter level if your trace sink is less trusted than your application.\n\nThese are defense-in-depth; the only complete mitigation is upgrading to 2.1.1.\n\n## Supported Versions\n\nAs of this advisory the supported security branch is **2.1.x**. The 2.0.x line (published 2026-04-15) is not receiving the Phase 1 safety-defaults infrastructure needed to carry the HIGH-severity fixes, so 2.0.x is deprecated in favor of 2.1.x. See `SECURITY.md` for the updated supported-versions table.\n\n## Credits\n\n- UmutKorkmaz (reporter and maintainer)\n\n## References\n\n- v2.1.1 CHANGELOG section: \u003chttps://github.com/UmutKorkmaz/meridian/blob/main/CHANGELOG.md#211---2026-04-16\u003e\n- `docs/security-model.md` threat model: \u003chttps://github.com/UmutKorkmaz/meridian/blob/main/docs/security-model.md\u003e\n- `SECURITY.md` disclosure policy: \u003chttps://github.com/UmutKorkmaz/meridian/blob/main/SECURITY.md\u003e\n- AutoMapper CVE-2026-32933 (motivating precedent for Meridian\u0027s safety-defaults)",
"id": "GHSA-f5v8-v6q3-q4h6",
"modified": "2026-04-16T22:50:37Z",
"published": "2026-04-16T22:50:37Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/UmutKorkmaz/meridian/security/advisories/GHSA-f5v8-v6q3-q4h6"
},
{
"type": "PACKAGE",
"url": "https://github.com/UmutKorkmaz/meridian"
},
{
"type": "WEB",
"url": "https://github.com/UmutKorkmaz/meridian/blob/main/CHANGELOG.md#211---2026-04-16"
},
{
"type": "WEB",
"url": "https://github.com/UmutKorkmaz/meridian/releases/tag/v2.1.1"
}
],
"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": "Meridian: Multiple defense-in-depth gaps (collection/depth caps, telemetry, retry, fan-out)"
}
GHSA-FCGC-C6HR-PQM2
Vulnerability from github – Published: 2023-01-05 18:30 – Updated: 2023-01-11 21:30GPAC MP4Box 2.1-DEV-rev649-ga8f438d20 has a segment fault (/stack overflow) due to infinite recursion in Media_GetSample isomedia/media.c:662
{
"affected": [],
"aliases": [
"CVE-2022-47662"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-01-05T16:15:00Z",
"severity": "MODERATE"
},
"details": "GPAC MP4Box 2.1-DEV-rev649-ga8f438d20 has a segment fault (/stack overflow) due to infinite recursion in Media_GetSample isomedia/media.c:662",
"id": "GHSA-fcgc-c6hr-pqm2",
"modified": "2023-01-11T21:30:40Z",
"published": "2023-01-05T18:30:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-47662"
},
{
"type": "WEB",
"url": "https://github.com/gpac/gpac/issues/2359"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2023/dsa-5411"
}
],
"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"
}
]
}
Mitigation
Ensure that an end condition will be reached under all logic conditions. The end condition may include checking against the depth of recursion and exiting with an error if the recursion goes too deep. The complexity of the end condition contributes to the effectiveness of this action.
Mitigation
Increase the stack size.
CAPEC-230: Serialized Data with Nested Payloads
Applications often need to transform data in and out of a data format (e.g., XML and YAML) by using a parser. It may be possible for an adversary to inject data that may have an adverse effect on the parser when it is being processed. Many data format languages allow the definition of macro-like structures that can be used to simplify the creation of complex structures. By nesting these structures, causing the data to be repeatedly substituted, an adversary can cause the parser to consume more resources while processing, causing excessive memory consumption and CPU utilization.
CAPEC-231: Oversized Serialized Data Payloads
An adversary injects oversized serialized data payloads into a parser during data processing to produce adverse effects upon the parser such as exhausting system resources and arbitrary code execution.