Common Weakness Enumeration

CWE-674

Allowed-with-Review

Uncontrolled 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.

751 vulnerabilities reference this CWE, most recent first.

GHSA-8MPJ-M6QM-5QR8

Vulnerability from github – Published: 2026-07-20 21:24 – Updated: 2026-07-20 21:24
VLAI
Summary
Mistune directives/include: mutual `.. include::` recursion crashes the renderer with `RecursionError`, denial of service via two attacker-controlled markdown files
Details

Summary

Type: Uncontrolled recursion via mutual include. The Include directive checks for direct self-reference (a.md cannot include a.md), but does not detect indirect cycles. Two markdown files that include each other (a.md → includes b.md → includes a.md) cause unbounded recursion until Python's stack limit fires RecursionError. The exception propagates out of the renderer and crashes the calling code. File: src/mistune/directives/include.py, lines 33-37 (the self-include check is the only cycle-detection logic). Root cause: the include logic only compares os.path.abspath(dest) == os.path.abspath(source_file). There is no per-render set of "files already included" that would catch transitive cycles. When a.md includes b.md, the recursive block.parse(new_state) call uses dest (b.md) as the new __file__, which then includes a.md (passing the self-check, because the immediate parent file is b.md, not a.md), which then includes b.md, and so on. Each recursion level adds Python frames; the default stack limit of 1000 frames trips after ~7-10 cycle iterations and Python raises RecursionError. Since the directive does not catch the exception, it propagates out of Markdown.parse() and surfaces in the calling code, crashing the request.

Affected Code

File: src/mistune/directives/include.py, lines 28-54.

relpath = self.parse_title(m)
dest = os.path.join(os.path.dirname(source_file), relpath)
dest = os.path.normpath(dest)

if os.path.abspath(dest) == os.path.abspath(source_file):       # <-- only catches direct self-include
    return {"type": "block_error", "raw": "Could not include self: " + relpath}

if not os.path.isfile(dest):
    return {"type": "block_error", "raw": "Could not find file: " + relpath}

with open(dest, "rb") as f:
    content = f.read().decode(encoding)

ext = os.path.splitext(relpath)[1]
if ext in {".md", ".markdown", ".mkd"}:
    new_state = block.state_cls()
    new_state.env["__file__"] = dest
    new_state.process(content)
    block.parse(new_state)                                       # <-- recursive parse, no cycle tracking
    return new_state.tokens

Why it's wrong: the cycle-detection check is one level deep. Multi-file cycles slip through trivially. Python's default recursion limit is 1000 frames, so a cycle of length 2 trips after a few hundred mutual includes; the exception is uncaught by the directive, propagating out of Markdown.__call__() and crashing whatever called it.

Exploit Chain

  1. Application uses mistune with the Include directive enabled. Application accepts user-supplied markdown files (CMS, wiki, multi-user documentation platform, note-taking app, CI/CD doc renderer).
  2. Attacker uploads two markdown files:
  3. a.md: .. include:: b.md
  4. b.md: .. include:: a.md
  5. Renderer is invoked on a.md (or any markdown that references this pair). Include directive includes b.md, which includes a.md, which includes b.md, ... Each recursion adds Python frames.
  6. After ~340 cycle iterations (depending on default sys.setrecursionlimit(1000) and the per-include frame depth), Python raises RecursionError: maximum recursion depth exceeded.
  7. The exception is not caught by the directive. It propagates through block.parse, through Markdown.__call__, and into the application's request handler. If the application doesn't catch it explicitly, the request errors out (HTTP 500 in web contexts, crash in CLI tools).

Security Impact

Attacker capability: crash the rendering engine on demand by submitting any markdown that triggers the cycle. Repeated requests deny service. If the renderer is used in a hot path (per-page-view docs rendering, search-index regeneration, scheduled doc-export jobs), the cycle persists across the whole pipeline. Preconditions: application uses mistune with the Include directive enabled and renders user-supplied markdown that can reference other user-uploaded files. Attacker needs write access to two .md files in the include search path (or a single file including a known-recurring pair). Differential: PoC-verified against mistune@3.2.1:

import os, mistune
from mistune.directives import RSTDirective, Include

os.makedirs('/tmp/mistune-recur', exist_ok=True)
with open('/tmp/mistune-recur/a.md', 'w') as f:
    f.write('A\n\n.. include:: b.md')
with open('/tmp/mistune-recur/b.md', 'w') as f:
    f.write('B\n\n.. include:: a.md')

md = mistune.create_markdown(plugins=[RSTDirective([Include()])])
state = md.block.state_cls()
state.env['__file__'] = '/tmp/mistune-recur/a.md'
md.parse('.. include:: b.md', state=state)
# RecursionError: maximum recursion depth exceeded

The patched build (with the suggested fix below) returns a block_error token like the existing self-include check, instead of recursing forever.

Suggested Fix

Track included paths in state.env and reject any include that would re-enter a path already on the include stack:

--- a/src/mistune/directives/include.py
+++ b/src/mistune/directives/include.py
@@ -28,8 +28,18 @@ class Include(DirectivePlugin):
         relpath = self.parse_title(m)
-        dest = os.path.join(os.path.dirname(source_file), relpath)
-        dest = os.path.normpath(dest)
+        base = os.path.realpath(os.path.dirname(source_file))
+        dest = os.path.realpath(os.path.join(base, relpath))
+
+        # Track include stack across recursive parses to detect cycles.
+        include_stack = state.env.setdefault("__include_stack__", [])
+        if dest in include_stack or dest == os.path.realpath(source_file):
+            return {
+                "type": "block_error",
+                "raw": "Could not include (cycle): " + relpath,
+            }

-        if os.path.abspath(dest) == os.path.abspath(source_file):
-            return {
-                "type": "block_error",
-                "raw": "Could not include self: " + relpath,
-            }
@@ ... in the markdown-include branch ...
+        include_stack.append(dest)
+        try:
+            new_state = block.state_cls()
+            new_state.env["__file__"] = dest
+            new_state.env["__include_stack__"] = include_stack
+            new_state.process(content)
+            block.parse(new_state)
+            return new_state.tokens
+        finally:
+            include_stack.pop()

This catches cycles of any length (a → b → a, a → b → c → a, etc.). Pair this with the path-containment fix from the LFI advisory and the HTML-extension fix from the include-XSS advisory; together those three patches make the Include directive safe to enable on user-supplied markdown.

Add a regression test asserting that a 2-cycle and a 3-cycle both produce block_error rather than RecursionError.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "mistune"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.3.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-59927"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-674",
      "CWE-755"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-20T21:24:42Z",
    "nvd_published_at": "2026-07-08T17:17:28Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\n**Type:** Uncontrolled recursion via mutual include. The `Include` directive checks for direct self-reference (`a.md` cannot include `a.md`), but does not detect indirect cycles. Two markdown files that include each other (`a.md` \u2192 includes `b.md` \u2192 includes `a.md`) cause unbounded recursion until Python\u0027s stack limit fires `RecursionError`. The exception propagates out of the renderer and crashes the calling code.\n**File:** `src/mistune/directives/include.py`, lines 33-37 (the self-include check is the only cycle-detection logic).\n**Root cause:** the include logic only compares `os.path.abspath(dest) == os.path.abspath(source_file)`. There is no per-render set of \"files already included\" that would catch transitive cycles. When `a.md` includes `b.md`, the recursive `block.parse(new_state)` call uses `dest` (b.md) as the new `__file__`, which then includes `a.md` (passing the self-check, because the immediate parent file is `b.md`, not `a.md`), which then includes `b.md`, and so on. Each recursion level adds Python frames; the default stack limit of 1000 frames trips after ~7-10 cycle iterations and Python raises `RecursionError`. Since the directive does not catch the exception, it propagates out of `Markdown.parse()` and surfaces in the calling code, crashing the request.\n\n## Affected Code\n\n**File:** `src/mistune/directives/include.py`, lines 28-54.\n\n```python\nrelpath = self.parse_title(m)\ndest = os.path.join(os.path.dirname(source_file), relpath)\ndest = os.path.normpath(dest)\n\nif os.path.abspath(dest) == os.path.abspath(source_file):       # \u003c-- only catches direct self-include\n    return {\"type\": \"block_error\", \"raw\": \"Could not include self: \" + relpath}\n\nif not os.path.isfile(dest):\n    return {\"type\": \"block_error\", \"raw\": \"Could not find file: \" + relpath}\n\nwith open(dest, \"rb\") as f:\n    content = f.read().decode(encoding)\n\next = os.path.splitext(relpath)[1]\nif ext in {\".md\", \".markdown\", \".mkd\"}:\n    new_state = block.state_cls()\n    new_state.env[\"__file__\"] = dest\n    new_state.process(content)\n    block.parse(new_state)                                       # \u003c-- recursive parse, no cycle tracking\n    return new_state.tokens\n```\n\n**Why it\u0027s wrong:** the cycle-detection check is one level deep. Multi-file cycles slip through trivially. Python\u0027s default recursion limit is 1000 frames, so a cycle of length 2 trips after a few hundred mutual includes; the exception is uncaught by the directive, propagating out of `Markdown.__call__()` and crashing whatever called it.\n\n## Exploit Chain\n\n1. Application uses mistune with the `Include` directive enabled. Application accepts user-supplied markdown files (CMS, wiki, multi-user documentation platform, note-taking app, CI/CD doc renderer).\n2. Attacker uploads two markdown files:\n   - `a.md`: `.. include:: b.md`\n   - `b.md`: `.. include:: a.md`\n3. Renderer is invoked on `a.md` (or any markdown that references this pair). `Include` directive includes `b.md`, which includes `a.md`, which includes `b.md`, ... Each recursion adds Python frames.\n4. After ~340 cycle iterations (depending on default `sys.setrecursionlimit(1000)` and the per-include frame depth), Python raises `RecursionError: maximum recursion depth exceeded`.\n5. The exception is not caught by the directive. It propagates through `block.parse`, through `Markdown.__call__`, and into the application\u0027s request handler. If the application doesn\u0027t catch it explicitly, the request errors out (HTTP 500 in web contexts, crash in CLI tools).\n\n## Security Impact\n\n**Attacker capability:** crash the rendering engine on demand by submitting any markdown that triggers the cycle. Repeated requests deny service. If the renderer is used in a hot path (per-page-view docs rendering, search-index regeneration, scheduled doc-export jobs), the cycle persists across the whole pipeline.\n**Preconditions:** application uses mistune with the `Include` directive enabled and renders user-supplied markdown that can reference other user-uploaded files. Attacker needs write access to two .md files in the include search path (or a single file including a known-recurring pair).\n**Differential:** PoC-verified against mistune@3.2.1:\n\n```python\nimport os, mistune\nfrom mistune.directives import RSTDirective, Include\n\nos.makedirs(\u0027/tmp/mistune-recur\u0027, exist_ok=True)\nwith open(\u0027/tmp/mistune-recur/a.md\u0027, \u0027w\u0027) as f:\n    f.write(\u0027A\\n\\n.. include:: b.md\u0027)\nwith open(\u0027/tmp/mistune-recur/b.md\u0027, \u0027w\u0027) as f:\n    f.write(\u0027B\\n\\n.. include:: a.md\u0027)\n\nmd = mistune.create_markdown(plugins=[RSTDirective([Include()])])\nstate = md.block.state_cls()\nstate.env[\u0027__file__\u0027] = \u0027/tmp/mistune-recur/a.md\u0027\nmd.parse(\u0027.. include:: b.md\u0027, state=state)\n# RecursionError: maximum recursion depth exceeded\n```\n\nThe patched build (with the suggested fix below) returns a `block_error` token like the existing self-include check, instead of recursing forever.\n\n## Suggested Fix\n\nTrack included paths in `state.env` and reject any include that would re-enter a path already on the include stack:\n\n```diff\n--- a/src/mistune/directives/include.py\n+++ b/src/mistune/directives/include.py\n@@ -28,8 +28,18 @@ class Include(DirectivePlugin):\n         relpath = self.parse_title(m)\n-        dest = os.path.join(os.path.dirname(source_file), relpath)\n-        dest = os.path.normpath(dest)\n+        base = os.path.realpath(os.path.dirname(source_file))\n+        dest = os.path.realpath(os.path.join(base, relpath))\n+\n+        # Track include stack across recursive parses to detect cycles.\n+        include_stack = state.env.setdefault(\"__include_stack__\", [])\n+        if dest in include_stack or dest == os.path.realpath(source_file):\n+            return {\n+                \"type\": \"block_error\",\n+                \"raw\": \"Could not include (cycle): \" + relpath,\n+            }\n\n-        if os.path.abspath(dest) == os.path.abspath(source_file):\n-            return {\n-                \"type\": \"block_error\",\n-                \"raw\": \"Could not include self: \" + relpath,\n-            }\n@@ ... in the markdown-include branch ...\n+        include_stack.append(dest)\n+        try:\n+            new_state = block.state_cls()\n+            new_state.env[\"__file__\"] = dest\n+            new_state.env[\"__include_stack__\"] = include_stack\n+            new_state.process(content)\n+            block.parse(new_state)\n+            return new_state.tokens\n+        finally:\n+            include_stack.pop()\n```\n\nThis catches cycles of any length (`a \u2192 b \u2192 a`, `a \u2192 b \u2192 c \u2192 a`, etc.). Pair this with the path-containment fix from the LFI advisory and the HTML-extension fix from the include-XSS advisory; together those three patches make the `Include` directive safe to enable on user-supplied markdown.\n\nAdd a regression test asserting that a 2-cycle and a 3-cycle both produce `block_error` rather than `RecursionError`.",
  "id": "GHSA-8mpj-m6qm-5qr8",
  "modified": "2026-07-20T21:24:42Z",
  "published": "2026-07-20T21:24:42Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/lepture/mistune/security/advisories/GHSA-8mpj-m6qm-5qr8"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-59927"
    },
    {
      "type": "WEB",
      "url": "https://github.com/lepture/mistune/commit/1bef343ade163fc3bb95572b15be720084cdb993"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/lepture/mistune"
    },
    {
      "type": "WEB",
      "url": "https://github.com/lepture/mistune/releases/tag/v3.3.0"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/mistune/PYSEC-2026-2215.yaml"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Mistune directives/include: mutual `.. include::` recursion crashes the renderer with `RecursionError`, denial of service via two attacker-controlled markdown files"
}

GHSA-8MPR-6XR2-CHHC

Vulnerability from github – Published: 2026-03-12 14:02 – Updated: 2026-03-12 14:02
VLAI
Summary
ImageMagick: MSL - Stack overflow in ProcessMSLScript
Details

Summary

Magick fails to check for circular references between two MSLs, leading to a stack overflow.

Details

After reading a.msl using magick, the following is displayed:

MSLStartElement -> ReadImage -> ReadMSLImage -> ProcessMSLScript -> xmlParseChunk -> xmlParseTryOrFinish -> MSLStartElement

AddressSanitizer:DEADLYSIGNAL
=================================================================
==114345==ERROR: AddressSanitizer: UNKNOWN SIGNAL on unknown address 0x000000000000 (pc 0x72509fc7d804 bp 0x7ffd6598b390 sp 0x7ffd6598ab20 T0)
    #0 0x72509fc7d804 in strlen ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:388
[...]
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-AnyCPU"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-HDRI-AnyCPU"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-HDRI-OpenMP-arm64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-HDRI-arm64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-HDRI-x64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-HDRI-x86"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-OpenMP-arm64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-OpenMP-x64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-OpenMP-x86"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-arm64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-x64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-x86"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q16-HDRI-OpenMP-x64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q8-AnyCPU"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q8-OpenMP-arm64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q8-OpenMP-x64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q8-arm64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q8-x64"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Magick.NET-Q8-x86"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "14.10.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-25971"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-674",
      "CWE-787"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-12T14:02:04Z",
    "nvd_published_at": "2026-02-24T02:16:02Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\nMagick fails to check for circular references between two MSLs, leading to a stack overflow.\n\n### Details\nAfter reading a.msl using magick, the following is displayed:\n\n`MSLStartElement` -\u003e `ReadImage` -\u003e `ReadMSLImage` -\u003e `ProcessMSLScript` -\u003e `xmlParseChunk` -\u003e `xmlParseTryOrFinish` -\u003e `MSLStartElement`\n\n```bash\nAddressSanitizer:DEADLYSIGNAL\n=================================================================\n==114345==ERROR: AddressSanitizer: UNKNOWN SIGNAL on unknown address 0x000000000000 (pc 0x72509fc7d804 bp 0x7ffd6598b390 sp 0x7ffd6598ab20 T0)\n    #0 0x72509fc7d804 in strlen ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:388\n[...]\n```",
  "id": "GHSA-8mpr-6xr2-chhc",
  "modified": "2026-03-12T14:02:04Z",
  "published": "2026-03-12T14:02:04Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-8mpr-6xr2-chhc"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-25971"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/ImageMagick/ImageMagick"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dlemstra/Magick.NET/releases/tag/14.10.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "ImageMagick: MSL - Stack overflow in ProcessMSLScript"
}

GHSA-8PFC-JJGW-6G26

Vulnerability from github – Published: 2026-04-03 21:45 – Updated: 2026-04-06 23:18
VLAI
Summary
SandboxJS: Stack overflow DoS via deeply nested expressions in recursive descent parser
Details

Summary

The @nyariv/sandboxjs parser contains unbounded recursion in the restOfExp function and the lispify/lispifyExpr call chain. An attacker can crash any Node.js process that parses untrusted input by supplying deeply nested expressions (e.g., ~2000 nested parentheses), causing a RangeError: Maximum call stack size exceeded that terminates the process.

Details

The root cause is in src/parser.ts. The restOfExp function (line 443) iterates through expression characters, and when it encounters a closing bracket that doesn't match the expected firstOpening, it recursively calls itself at line 503:

// src/parser.ts:486-505
} else if (closings[char]) {
  // ...
  if (char === firstOpening) {
    done = true;
    break;
  } else {
    const skip = restOfExp(constants, part.substring(i + 1), [], char);  // line 503
    cache.set(skip.start - 1, skip.end);
    i += skip.length + 1;
  }
}

Each nested bracket ((, [, {) adds a stack frame. There is no depth counter or limit check. The function signature has no depth parameter:

export function restOfExp(
  constants: IConstants,
  part: CodeString,
  tests?: RegExp[],
  quote?: string,
  firstOpening?: string,
  closingsTests?: RegExp[],
  details: restDetails = {},
): CodeString {

A second unbounded recursive path exists through lispifylispTypes.get(type)group handler → lispifyExpr (line 672) → lispify, which processes parenthesized groups recursively with no depth limit.

All public API methods (Sandbox.parse(), Sandbox.compile(), Sandbox.compileAsync(), Sandbox.compileExpression(), Sandbox.compileExpressionAsync()) pass user input directly to parse() with no input validation or depth limiting.

A RangeError: Maximum call stack size exceeded in Node.js is not a catchable exception in the normal sense — it crashes the current execution context and, in a server handling requests synchronously, can crash the entire process.

PoC

# Install the package
npm install @nyariv/sandboxjs

# Create test file
cat > poc.js << 'EOF'
const { default: Sandbox } = require('@nyariv/sandboxjs');
const s = new Sandbox();

// Trigger via nested parentheses
console.log("Testing nested parentheses...");
try {
  s.compile('('.repeat(2000) + '1' + ')'.repeat(2000));
  console.log("No crash");
} catch(e) {
  console.log(`Crash: ${e.constructor.name}: ${e.message}`);
}

// Trigger via nested array brackets
console.log("Testing nested array brackets...");
try {
  s.compile('a' + '[0]'.repeat(2000));
  console.log("No crash");
} catch(e) {
  console.log(`Crash: ${e.constructor.name}: ${e.message}`);
}
EOF

node poc.js

Expected output:

Testing nested parentheses...
Crash: RangeError: Maximum call stack size exceeded
Testing nested array brackets...
Crash: RangeError: Maximum call stack size exceeded

Verified on Node.js v22 with @nyariv/sandboxjs@0.8.35.

Impact

Any application using @nyariv/sandboxjs to parse untrusted user input is vulnerable to denial of service. Since SandboxJS is explicitly designed to safely execute untrusted JavaScript, its primary use case involves untrusted input — making this a high-impact vulnerability for its intended deployment scenario.

An attacker can crash the host Node.js process with a single crafted input string. In server-side applications, this causes complete service disruption. The attack payload is trivial to construct and requires no authentication.

Recommended Fix

Add a depth parameter to restOfExp and throw a ParseError when a maximum depth is exceeded:

// src/parser.ts - restOfExp function
const MAX_PARSE_DEPTH = 256;

export function restOfExp(
  constants: IConstants,
  part: CodeString,
  tests?: RegExp[],
  quote?: string,
  firstOpening?: string,
  closingsTests?: RegExp[],
  details: restDetails = {},
  depth: number = 0,          // ADD depth parameter
): CodeString {
  if (depth > MAX_PARSE_DEPTH) {
    throw new ParseError('Expression nesting depth exceeded', part.toString());
  }
  // ... existing code ...

  // At line 503, pass depth + 1:
  const skip = restOfExp(constants, part.substring(i + 1), [], char, undefined, undefined, {}, depth + 1);

  // At line 480 (template literal), also pass depth + 1:
  const skip = restOfExp(constants, part.substring(i + 2), [], '{', undefined, undefined, {}, depth + 1);
}

Similarly, add depth tracking to lispify and lispifyExpr:

function lispify(
  constants: IConstants,
  part: CodeString,
  expected?: readonly string[],
  lispTree?: Lisp,
  topLevel = false,
  depth: number = 0,         // ADD depth parameter
): Lisp {
  if (depth > MAX_PARSE_DEPTH) {
    throw new ParseError('Expression nesting depth exceeded', part.toString());
  }
  // ... pass depth + 1 to recursive lispify/lispifyExpr calls ...
}
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.8.35"
      },
      "package": {
        "ecosystem": "npm",
        "name": "@nyariv/sandboxjs"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.8.36"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-34211"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-674"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-03T21:45:14Z",
    "nvd_published_at": "2026-04-06T16:16:34Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nThe `@nyariv/sandboxjs` parser contains unbounded recursion in the `restOfExp` function and the `lispify`/`lispifyExpr` call chain. An attacker can crash any Node.js process that parses untrusted input by supplying deeply nested expressions (e.g., ~2000 nested parentheses), causing a `RangeError: Maximum call stack size exceeded` that terminates the process.\n\n## Details\n\nThe root cause is in `src/parser.ts`. The `restOfExp` function (line 443) iterates through expression characters, and when it encounters a closing bracket that doesn\u0027t match the expected `firstOpening`, it recursively calls itself at line 503:\n\n```typescript\n// src/parser.ts:486-505\n} else if (closings[char]) {\n  // ...\n  if (char === firstOpening) {\n    done = true;\n    break;\n  } else {\n    const skip = restOfExp(constants, part.substring(i + 1), [], char);  // line 503\n    cache.set(skip.start - 1, skip.end);\n    i += skip.length + 1;\n  }\n}\n```\n\nEach nested bracket (`(`, `[`, `{`) adds a stack frame. There is no depth counter or limit check. The function signature has no depth parameter:\n\n```typescript\nexport function restOfExp(\n  constants: IConstants,\n  part: CodeString,\n  tests?: RegExp[],\n  quote?: string,\n  firstOpening?: string,\n  closingsTests?: RegExp[],\n  details: restDetails = {},\n): CodeString {\n```\n\nA second unbounded recursive path exists through `lispify` \u2192 `lispTypes.get(type)` \u2192 `group` handler \u2192 `lispifyExpr` (line 672) \u2192 `lispify`, which processes parenthesized groups recursively with no depth limit.\n\nAll public API methods (`Sandbox.parse()`, `Sandbox.compile()`, `Sandbox.compileAsync()`, `Sandbox.compileExpression()`, `Sandbox.compileExpressionAsync()`) pass user input directly to `parse()` with no input validation or depth limiting.\n\nA `RangeError: Maximum call stack size exceeded` in Node.js is not a catchable exception in the normal sense \u2014 it crashes the current execution context and, in a server handling requests synchronously, can crash the entire process.\n\n## PoC\n\n```bash\n# Install the package\nnpm install @nyariv/sandboxjs\n\n# Create test file\ncat \u003e poc.js \u003c\u003c \u0027EOF\u0027\nconst { default: Sandbox } = require(\u0027@nyariv/sandboxjs\u0027);\nconst s = new Sandbox();\n\n// Trigger via nested parentheses\nconsole.log(\"Testing nested parentheses...\");\ntry {\n  s.compile(\u0027(\u0027.repeat(2000) + \u00271\u0027 + \u0027)\u0027.repeat(2000));\n  console.log(\"No crash\");\n} catch(e) {\n  console.log(`Crash: ${e.constructor.name}: ${e.message}`);\n}\n\n// Trigger via nested array brackets\nconsole.log(\"Testing nested array brackets...\");\ntry {\n  s.compile(\u0027a\u0027 + \u0027[0]\u0027.repeat(2000));\n  console.log(\"No crash\");\n} catch(e) {\n  console.log(`Crash: ${e.constructor.name}: ${e.message}`);\n}\nEOF\n\nnode poc.js\n```\n\n**Expected output:**\n```\nTesting nested parentheses...\nCrash: RangeError: Maximum call stack size exceeded\nTesting nested array brackets...\nCrash: RangeError: Maximum call stack size exceeded\n```\n\nVerified on Node.js v22 with `@nyariv/sandboxjs@0.8.35`.\n\n## Impact\n\nAny application using `@nyariv/sandboxjs` to parse untrusted user input is vulnerable to denial of service. Since SandboxJS is explicitly designed to safely execute untrusted JavaScript, its primary use case involves untrusted input \u2014 making this a high-impact vulnerability for its intended deployment scenario.\n\nAn attacker can crash the host Node.js process with a single crafted input string. In server-side applications, this causes complete service disruption. The attack payload is trivial to construct and requires no authentication.\n\n## Recommended Fix\n\nAdd a `depth` parameter to `restOfExp` and throw a `ParseError` when a maximum depth is exceeded:\n\n```typescript\n// src/parser.ts - restOfExp function\nconst MAX_PARSE_DEPTH = 256;\n\nexport function restOfExp(\n  constants: IConstants,\n  part: CodeString,\n  tests?: RegExp[],\n  quote?: string,\n  firstOpening?: string,\n  closingsTests?: RegExp[],\n  details: restDetails = {},\n  depth: number = 0,          // ADD depth parameter\n): CodeString {\n  if (depth \u003e MAX_PARSE_DEPTH) {\n    throw new ParseError(\u0027Expression nesting depth exceeded\u0027, part.toString());\n  }\n  // ... existing code ...\n\n  // At line 503, pass depth + 1:\n  const skip = restOfExp(constants, part.substring(i + 1), [], char, undefined, undefined, {}, depth + 1);\n\n  // At line 480 (template literal), also pass depth + 1:\n  const skip = restOfExp(constants, part.substring(i + 2), [], \u0027{\u0027, undefined, undefined, {}, depth + 1);\n}\n```\n\nSimilarly, add depth tracking to `lispify` and `lispifyExpr`:\n\n```typescript\nfunction lispify(\n  constants: IConstants,\n  part: CodeString,\n  expected?: readonly string[],\n  lispTree?: Lisp,\n  topLevel = false,\n  depth: number = 0,         // ADD depth parameter\n): Lisp {\n  if (depth \u003e MAX_PARSE_DEPTH) {\n    throw new ParseError(\u0027Expression nesting depth exceeded\u0027, part.toString());\n  }\n  // ... pass depth + 1 to recursive lispify/lispifyExpr calls ...\n}\n```",
  "id": "GHSA-8pfc-jjgw-6g26",
  "modified": "2026-04-06T23:18:26Z",
  "published": "2026-04-03T21:45:14Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nyariv/SandboxJS/security/advisories/GHSA-8pfc-jjgw-6g26"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34211"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nyariv/SandboxJS"
    }
  ],
  "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:L/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "SandboxJS: Stack overflow DoS via deeply nested expressions in recursive descent parser"
}

GHSA-8Q78-M7W9-J45M

Vulnerability from github – Published: 2026-09-01 18:30 – Updated: 2026-09-01 21:31
VLAI
Details

llama.cpp b5693 and before is vulnerable to Uncontrolled Recursion in common/json-schema-to-grammar.cpp, resulting in a denial of service.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-52130"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-674"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-01T18:17:43Z",
    "severity": "HIGH"
  },
  "details": "llama.cpp b5693 and before is vulnerable to Uncontrolled Recursion in common/json-schema-to-grammar.cpp, resulting in a denial of service.",
  "id": "GHSA-8q78-m7w9-j45m",
  "modified": "2026-09-01T21:31:45Z",
  "published": "2026-09-01T18:30:45Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-52130"
    },
    {
      "type": "WEB",
      "url": "https://blog.ph4nt0m.xyz/ko/cves/cve-2026-52130"
    },
    {
      "type": "WEB",
      "url": "https://github.com/ggml-org/llama.cpp"
    }
  ],
  "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-8QVM-5X2C-J2W7

Vulnerability from github – Published: 2025-06-16 16:02 – Updated: 2025-06-16 16:02
VLAI
Summary
protobuf-python has a potential Denial of Service issue
Details

Summary

Any project that uses Protobuf pure-Python backend to parse untrusted Protocol Buffers data containing an arbitrary number of recursive groups, recursive messages or a series of SGROUP tags can be corrupted by exceeding the Python recursion limit.

Reporter: Alexis Challande, Trail of Bits Ecosystem Security Team ecosystem@trailofbits.com

Affected versions: This issue only affects the pure-Python implementation of protobuf-python backend. This is the implementation when PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python environment variable is set or the default when protobuf is used from Bazel or pure-Python PyPi wheels. CPython PyPi wheels do not use pure-Python by default.

This is a Python variant of a previous issue affecting protobuf-java.

Severity

This is a potential Denial of Service. Parsing nested protobuf data creates unbounded recursions that can be abused by an attacker.

Proof of Concept

For reproduction details, please refer to the unit tests decoder_test.py and message_test

Remediation and Mitigation

A mitigation is available now. Please update to the latest available versions of the following packages: * protobuf-python(4.25.8, 5.29.5, 6.31.1)

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "protobuf"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.25.8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "protobuf"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.26.0rc1"
            },
            {
              "fixed": "5.29.5"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "protobuf"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "6.30.0rc1"
            },
            {
              "fixed": "6.31.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-4565"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-674"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-06-16T16:02:58Z",
    "nvd_published_at": "2025-06-16T15:15:24Z",
    "severity": "HIGH"
  },
  "details": "### Summary\nAny project that uses Protobuf pure-Python backend to parse untrusted Protocol Buffers data containing an arbitrary number of **recursive groups**, **recursive messages** or **a series of [`SGROUP`](https://protobuf.dev/programming-guides/encoding/#groups) tags** can be corrupted by exceeding the Python recursion limit.\n\nReporter: Alexis Challande, Trail of Bits Ecosystem Security Team\n[ecosystem@trailofbits.com](mailto:ecosystem@trailofbits.com)\n\nAffected versions: This issue only affects the [pure-Python implementation](https://github.com/protocolbuffers/protobuf/tree/main/python#implementation-backends) of protobuf-python backend. This is the implementation when `PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python` environment variable is set or the default when protobuf is used from Bazel or pure-Python PyPi wheels. CPython PyPi wheels do not use pure-Python by default.\n\nThis is a Python variant of a [previous issue affecting protobuf-java](https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-735f-pc8j-v9w8).\n\n### Severity\nThis is a potential Denial of Service. Parsing nested protobuf data creates unbounded recursions that can be abused by an attacker.\n\n### Proof of Concept\nFor reproduction details, please refer to the unit tests [decoder_test.py](https://github.com/protocolbuffers/protobuf/blob/main/python/google/protobuf/internal/decoder_test.py#L87-L98) and [message_test](https://github.com/protocolbuffers/protobuf/blob/main/python/google/protobuf/internal/message_test.py#L1436-L1478)\n\n### Remediation and Mitigation\nA mitigation is available now. Please update to the latest available versions of the following packages:\n* protobuf-python(4.25.8, 5.29.5, 6.31.1)",
  "id": "GHSA-8qvm-5x2c-j2w7",
  "modified": "2025-06-16T16:02:58Z",
  "published": "2025-06-16T16:02:58Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-735f-pc8j-v9w8"
    },
    {
      "type": "WEB",
      "url": "https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-8qvm-5x2c-j2w7"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-4565"
    },
    {
      "type": "WEB",
      "url": "https://github.com/protocolbuffers/protobuf/commit/17838beda2943d08b8a9d4df5b68f5f04f26d901"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/protocolbuffers/protobuf"
    },
    {
      "type": "WEB",
      "url": "https://github.com/protocolbuffers/protobuf/blob/main/python/google/protobuf/internal/decoder_test.py#L87-L98"
    },
    {
      "type": "WEB",
      "url": "https://github.com/protocolbuffers/protobuf/blob/main/python/google/protobuf/internal/message_test.py#L1436-L1478"
    },
    {
      "type": "WEB",
      "url": "https://github.com/protocolbuffers/protobuf/tree/main/python#implementation-backends"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "protobuf-python has a potential Denial of Service issue"
}

GHSA-8R93-F22G-X9VJ

Vulnerability from github – Published: 2026-05-19 09:31 – Updated: 2026-05-19 09:31
VLAI
Details

Uncontrolled Recursion vulnerability in Samsung Open Source Escargot allows Oversized Serialized Data Payloads.

This issue affects Escargot: 590345cc6258317c5da850d846ce6baaf2afc2d3.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-47309"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-674"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-19T07:16:29Z",
    "severity": "MODERATE"
  },
  "details": "Uncontrolled Recursion vulnerability in Samsung Open Source Escargot allows Oversized Serialized Data Payloads.\n\nThis issue affects Escargot: 590345cc6258317c5da850d846ce6baaf2afc2d3.",
  "id": "GHSA-8r93-f22g-x9vj",
  "modified": "2026-05-19T09:31:19Z",
  "published": "2026-05-19T09:31:19Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47309"
    },
    {
      "type": "WEB",
      "url": "https://github.com/Samsung/escargot/pull/1565"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-8WCC-M6J2-QXVM

Vulnerability from github – Published: 2024-12-16 19:33 – Updated: 2024-12-23 17:13
VLAI
Summary
ASA-2024-0012, ASA-2024-0013: CosmosSDK: Transaction decoding may result in a stack overflow or resource exhaustion
Details

Summary

ASA-2024-0012

Name: ASA-2024-0012, Transaction decoding may result in a stack overflow Component: Cosmos SDK Criticality: High (Considerable Impact, and Possible Likelihood per ACMv1.2) Affected versions: cosmos-sdk versions <= v0.50.10, <= v0.47.14 Affected users: Chain Builders + Maintainers, Validators, node operators

ASA-2024-0013

Name: ASA-2024-0013: CosmosSDK: Transaction decoding may result in resource exhaustion
Component: Cosmos SDK Criticality: High (Considerable Impact, and Possible Likelihood per ACMv1.2) Affected versions: cosmos-sdk versions <= v0.50.10, <= v0.47.14 Affected users: Chain Builders + Maintainers, Validators, node operators

Impact

ASA-2024-0012

When decoding a maliciously formed packet with a deeply-nested structure, it may be possible for a stack overflow to occur and result in a network halt. This was addressed by adding a recursion limit while decoding the packet.

ASA-2024-0013

Nested messages in a transaction can consume exponential cpu and memory on UnpackAny calls. Themax_tx_bytes sets a limit for external TX but is not applied for internal messages emitted by wasm contracts or a malicious validator block. This may result in a node crashing due to resource exhaustion. This was addressed by adding additional validation to prevent this condition.

Patches

The issues above are resolved in Cosmos SDK versions v0.47.15 or v0.50.11. Please upgrade ASAP.

Timeline for ASA-2024-0012

  • October 1, 2024, 12:29pm UTC: Issue reported to the Cosmos Bug Bounty program
  • October 1, 2024, 2:47pm UTC: Issue triaged by Amulet on-call, and distributed to Core team
  • December 9, 2024, 11:13am UTC: Core team completes patch for issue
  • Dec 14, 2024,16:00 UTC: Pre-notification delivered
  • Dec 16, 2024, 16:00 UTC: Patch made available

This issue was reported to the Cosmos Bug Bounty Program on HackerOne on October 1, 2024.

Timeline for ASA-2024-0013

  • October 19, 2024, 8:12pm UTC: Issue reported to the Cosmos Bug Bounty program
  • October 19, 2024, 8:28pm UTC: Issue triaged by Amulet on-call, and distributed to Core team
  • December 11, 2024, 3:31pm UTC: Core team completes patch for issue
  • Dec 14, 2024, 16:00 UTC: Pre-notification delivered
  • Dec 16, 2024, 16:00 UTC: Patch made available

This issue was reported by LonelySloth to the Cosmos Bug Bounty Program on HackerOne on October 19, 2024.

If you believe you have found a bug in the Interchain Stack or would like to contribute to the program by reporting a bug, please see https://hackerone.com/cosmos.

If you have questions about Interchain security efforts, please reach out to our official communication channel at security@interchain.io. For more information about the Interchain Foundation’s engagement with Amulet, and to sign up for security notification emails, please see https://github.com/interchainio/security.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/cosmos/cosmos-sdk"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.50.0-alpha.0"
            },
            {
              "fixed": "0.50.11"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/cosmos/cosmos-sdk"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.47.15"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "cosmossdk.io/x/tx"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.13.7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-400",
      "CWE-674"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-12-16T19:33:30Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary \n\n### ASA-2024-0012\nName: ASA-2024-0012,  Transaction decoding may result in a stack overflow\nComponent: Cosmos SDK\nCriticality: High (Considerable Impact, and Possible Likelihood per [ACMv1.2](https://github.com/interchainio/security/blob/main/resources/CLASSIFICATION_MATRIX.md))\nAffected versions: cosmos-sdk versions \u003c= v0.50.10, \u003c= v0.47.14\nAffected users: Chain Builders + Maintainers, Validators, node operators\n\n### ASA-2024-0013\nName: ASA-2024-0013: CosmosSDK: Transaction decoding may result in resource exhaustion  \nComponent: Cosmos SDK\nCriticality: High (Considerable Impact, and Possible Likelihood per [ACMv1.2](https://github.com/interchainio/security/blob/main/resources/CLASSIFICATION_MATRIX.md))\nAffected versions: cosmos-sdk versions \u003c= v0.50.10, \u003c= v0.47.14\nAffected users: Chain Builders + Maintainers, Validators, node operators\n\n\n\n### Impact\n\n### ASA-2024-0012\n\nWhen decoding a maliciously formed packet with a deeply-nested structure, it may be possible for a stack overflow to occur and result in a network halt. This was addressed by adding a recursion limit while decoding the packet.\n\n### ASA-2024-0013\n\nNested messages in a transaction can consume exponential cpu and memory on `UnpackAny` calls.  The`max_tx_bytes` sets a limit for external TX but is not applied for internal messages emitted by wasm contracts or a malicious validator block. This may result in a node crashing due to resource exhaustion.  This was addressed by adding additional validation to prevent this condition.\n\n\n### Patches\n\nThe issues above are resolved in Cosmos SDK versions v0.47.15 or v0.50.11.\nPlease upgrade ASAP.\n\n### Timeline for ASA-2024-0012\n\n* October 1, 2024, 12:29pm UTC: Issue reported to the Cosmos Bug Bounty program\n* October 1, 2024, 2:47pm UTC: Issue triaged by Amulet on-call, and distributed to Core team\n* December 9, 2024, 11:13am UTC: Core team completes patch for issue\n* Dec 14, 2024,16:00 UTC: Pre-notification delivered\n* Dec 16, 2024, 16:00 UTC: Patch made available\n\nThis issue was reported to the Cosmos Bug Bounty Program on HackerOne on October 1, 2024.\n\n### Timeline for ASA-2024-0013\n\n* October 19, 2024, 8:12pm UTC: Issue reported to the Cosmos Bug Bounty program\n* October 19, 2024, 8:28pm UTC: Issue triaged by Amulet on-call, and distributed to Core team\n* December 11, 2024, 3:31pm UTC: Core team completes patch for issue\n* Dec 14, 2024, 16:00 UTC: Pre-notification delivered\n* Dec 16, 2024, 16:00 UTC: Patch made available\n\nThis issue was reported by LonelySloth to the Cosmos Bug Bounty Program on HackerOne on October 19, 2024. \n\n\nIf you believe you have found a bug in the Interchain Stack or would like to contribute to the program by reporting a bug, please see https://hackerone.com/cosmos.\n\nIf you have questions about Interchain security efforts, please reach out to our official communication channel at [security@interchain.io](mailto:security@interchain.io).  For more information about the Interchain Foundation\u2019s engagement with Amulet, and to sign up for security notification emails, please see https://github.com/interchainio/security.  ",
  "id": "GHSA-8wcc-m6j2-qxvm",
  "modified": "2024-12-23T17:13:22Z",
  "published": "2024-12-16T19:33:30Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/cosmos/cosmos-sdk/security/advisories/GHSA-8wcc-m6j2-qxvm"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cosmos/cosmos-sdk/commit/c6b1bdcd5628e3e425a3f02881d3c7db1d7af653"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/cosmos/cosmos-sdk"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.15"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.11"
    }
  ],
  "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": "ASA-2024-0012, ASA-2024-0013: CosmosSDK: Transaction decoding may result in a stack overflow or resource exhaustion "
}

GHSA-8WRW-HCVF-R5F8

Vulnerability from github – Published: 2023-07-06 21:14 – Updated: 2025-01-24 18:31
VLAI
Details

In Xpdf 4.04 (and earlier), a PDF object loop in the page label tree leads to infinite recursion and a stack overflow.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-2663"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-674"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-05-11T21:15:10Z",
    "severity": "MODERATE"
  },
  "details": "\u00a0In Xpdf 4.04 (and earlier), a PDF object loop in the page label tree leads to infinite recursion and a stack overflow.\n\n\n",
  "id": "GHSA-8wrw-hcvf-r5f8",
  "modified": "2025-01-24T18:31:05Z",
  "published": "2023-07-06T21:14:56Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-2663"
    },
    {
      "type": "WEB",
      "url": "https://forum.xpdfreader.com/viewtopic.php?t=42421"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-93J5-89VC-PPH4

Vulnerability from github – Published: 2026-08-18 16:32 – Updated: 2026-08-18 16:32
VLAI
Summary
RabbitMQ Java client ValueReader: Unbounded recursive table/array nesting causes StackOverflowError DoS
Details

Summary

ValueReader.readTable() and readArray() recursively call readFieldValue() with no depth limit. A malicious AMQP peer can crash the client JVM by sending a deeply nested table structure.

Vulnerable Code

src/main/java/com/rabbitmq/client/impl/ValueReader.java lines 139-155 and 237-249:

private static Map<String, Object> readTable(DataInputStream in) throws IOException {
    long tableLength = unsignedExtend(in.readInt());
    // ...
    while(tableIn.available() > 0) {
        String name = readShortstr(tableIn);
        Object value = readFieldValue(tableIn);  // recursive call
    }
}

static Object readFieldValue(DataInputStream in) throws IOException {
    switch(in.readUnsignedByte()) {
      case 'F': value = readTable(in);  // mutual recursion
      case 'A': value = readArray(in);  // mutual recursion
    }
}

Attack Scenario

A malicious AMQP server (or MitM) sends a connection.start frame with ~580 levels of nested tables. Each level costs ~7 bytes (4-byte length + 1-byte key length + 1-byte key + 1-byte type tag), totaling ~4060 bytes within the 131,072 byte max frame size. With the default JVM stack (~512KB, ~864 bytes/frame), this triggers StackOverflowError, killing the I/O thread.

Exploitable pre-authentication since connection.start is the very first server frame.

Impact

Denial of service. StackOverflowError kills the client I/O thread.

CWE

CWE-674: Uncontrolled Recursion

Remediation

Add a depth counter to readTable/readArray/readFieldValue and throw MalformedFrameException when exceeding a threshold (e.g., 32).

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 5.33.0"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "com.rabbitmq:amqp-client"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "5.33.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-69220"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-674"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-18T16:32:12Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\n\n`ValueReader.readTable()` and `readArray()` recursively call `readFieldValue()` with no depth limit. A malicious AMQP peer can crash the client JVM by sending a deeply nested table structure.\n\n## Vulnerable Code\n\n`src/main/java/com/rabbitmq/client/impl/ValueReader.java` lines 139-155 and 237-249:\n\n```java\nprivate static Map\u003cString, Object\u003e readTable(DataInputStream in) throws IOException {\n    long tableLength = unsignedExtend(in.readInt());\n    // ...\n    while(tableIn.available() \u003e 0) {\n        String name = readShortstr(tableIn);\n        Object value = readFieldValue(tableIn);  // recursive call\n    }\n}\n\nstatic Object readFieldValue(DataInputStream in) throws IOException {\n    switch(in.readUnsignedByte()) {\n      case \u0027F\u0027: value = readTable(in);  // mutual recursion\n      case \u0027A\u0027: value = readArray(in);  // mutual recursion\n    }\n}\n```\n\n## Attack Scenario\n\nA malicious AMQP server (or MitM) sends a `connection.start` frame with ~580 levels of nested tables. Each level costs ~7 bytes (4-byte length + 1-byte key length + 1-byte key + 1-byte type tag), totaling ~4060 bytes within the 131,072 byte max frame size. With the default JVM stack (~512KB, ~864 bytes/frame), this triggers `StackOverflowError`, killing the I/O thread.\n\nExploitable pre-authentication since `connection.start` is the very first server frame.\n\n## Impact\n\nDenial of service. `StackOverflowError` kills the client I/O thread.\n\n## CWE\n\nCWE-674: Uncontrolled Recursion\n\n## Remediation\n\nAdd a depth counter to `readTable`/`readArray`/`readFieldValue` and throw `MalformedFrameException` when exceeding a threshold (e.g., 32).",
  "id": "GHSA-93j5-89vc-pph4",
  "modified": "2026-08-18T16:32:12Z",
  "published": "2026-08-18T16:32:12Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/rabbitmq/rabbitmq-java-client/security/advisories/GHSA-93j5-89vc-pph4"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rabbitmq/rabbitmq-java-client/pull/2007"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rabbitmq/rabbitmq-java-client/pull/2008"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rabbitmq/rabbitmq-java-client/commit/09af76fce136f3136931654a0a1d43095c80e2f0"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rabbitmq/rabbitmq-java-client/commit/db89e34809fbc6ba4e946615f297f3684ccd0acc"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/rabbitmq/rabbitmq-java-client"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rabbitmq/rabbitmq-java-client/releases/tag/v5.33.1"
    }
  ],
  "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": "RabbitMQ Java client ValueReader: Unbounded recursive table/array nesting causes StackOverflowError DoS"
}

GHSA-94GC-V83R-7M7W

Vulnerability from github – Published: 2022-05-13 01:38 – Updated: 2022-05-13 01:38
VLAI
Details

It was found that Red Hat JBoss Core Services erratum RHSA-2016:2957 for CVE-2016-3705 did not actually include the fix for the issue found in libxml2, making it vulnerable to a Denial of Service attack due to a Stack Overflow. This is a regression CVE for the same issue as CVE-2016-3705.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2016-9597"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-119",
      "CWE-674"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-07-30T14:29:00Z",
    "severity": "HIGH"
  },
  "details": "It was found that Red Hat JBoss Core Services erratum RHSA-2016:2957 for CVE-2016-3705 did not actually include the fix for the issue found in libxml2, making it vulnerable to a Denial of Service attack due to a Stack Overflow. This is a regression CVE for the same issue as CVE-2016-3705.",
  "id": "GHSA-94gc-v83r-7m7w",
  "modified": "2022-05-13T01:38:28Z",
  "published": "2022-05-13T01:38:28Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2016-9597"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-9597"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/98567"
    }
  ],
  "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"
    }
  ]
}

Mitigation
Implementation

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
Implementation

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.