CWE-755
DiscouragedImproper Handling of Exceptional Conditions
Abstraction: Class · Status: Incomplete
The product does not handle or incorrectly handles an exceptional condition.
703 vulnerabilities reference this CWE, most recent first.
GHSA-8C4M-PXFW-44PH
Vulnerability from github – Published: 2022-01-26 00:00 – Updated: 2022-02-02 00:02On BIG-IP AFM version 16.1.x before 16.1.2, 15.1.x before 15.1.4.1, 14.1.x before 14.1.4.5, and 13.1.x beginning in 13.1.3.4, when a virtual server is configured with both HTTP protocol security and HTTP Proxy Connect profiles, undisclosed requests can cause the Traffic Management Microkernel (TMM) to terminate. Note: Software versions which have reached End of Technical Support (EoTS) are not evaluated.
{
"affected": [],
"aliases": [
"CVE-2022-23018"
],
"database_specific": {
"cwe_ids": [
"CWE-755"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-01-25T20:15:00Z",
"severity": "HIGH"
},
"details": "On BIG-IP AFM version 16.1.x before 16.1.2, 15.1.x before 15.1.4.1, 14.1.x before 14.1.4.5, and 13.1.x beginning in 13.1.3.4, when a virtual server is configured with both HTTP protocol security and HTTP Proxy Connect profiles, undisclosed requests can cause the Traffic Management Microkernel (TMM) to terminate. Note: Software versions which have reached End of Technical Support (EoTS) are not evaluated.",
"id": "GHSA-8c4m-pxfw-44ph",
"modified": "2022-02-02T00:02:00Z",
"published": "2022-01-26T00:00:38Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-23018"
},
{
"type": "WEB",
"url": "https://support.f5.com/csp/article/K24358905"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-8CM2-F4G9-WJFM
Vulnerability from github – Published: 2023-03-28 21:30 – Updated: 2025-11-04 21:30This vulnerability allows remote attackers to execute arbitrary code on affected installations of Netatalk. Authentication is not required to exploit this vulnerability. The specific flaw exists within the parse_entries function. The issue results from the lack of proper error handling when parsing AppleDouble entries. An attacker can leverage this vulnerability to execute code in the context of root. Was ZDI-CAN-15819.
{
"affected": [],
"aliases": [
"CVE-2022-23121"
],
"database_specific": {
"cwe_ids": [
"CWE-755"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-03-28T19:15:00Z",
"severity": "CRITICAL"
},
"details": "This vulnerability allows remote attackers to execute arbitrary code on affected installations of Netatalk. Authentication is not required to exploit this vulnerability. The specific flaw exists within the parse_entries function. The issue results from the lack of proper error handling when parsing AppleDouble entries. An attacker can leverage this vulnerability to execute code in the context of root. Was ZDI-CAN-15819.",
"id": "GHSA-8cm2-f4g9-wjfm",
"modified": "2025-11-04T21:30:33Z",
"published": "2023-03-28T21:30:20Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-23121"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/05/msg00018.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/06/msg00000.html"
},
{
"type": "WEB",
"url": "https://netatalk.sourceforge.io/3.1/ReleaseNotes3.1.13.html"
},
{
"type": "WEB",
"url": "https://security.gentoo.org/glsa/202311-02"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2023/dsa-5503"
},
{
"type": "WEB",
"url": "https://www.kb.cert.org/vuls/id/709991"
},
{
"type": "WEB",
"url": "https://www.zerodayinitiative.com/advisories/ZDI-22-527"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8F29-JV59-33JP
Vulnerability from github – Published: 2024-03-11 18:31 – Updated: 2024-03-11 18:31An improper error handling vulnerability in LabVIEW may result in remote code execution. Successful exploitation requires an attacker to provide a user with a specially crafted VI. This vulnerability affects LabVIEW 2024 Q1 and prior versions.
{
"affected": [],
"aliases": [
"CVE-2024-23609"
],
"database_specific": {
"cwe_ids": [
"CWE-1285",
"CWE-755"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-03-11T16:15:08Z",
"severity": "HIGH"
},
"details": "An improper error handling vulnerability in LabVIEW may result in remote code execution. Successful exploitation requires an attacker to provide a user with a specially crafted VI. This vulnerability affects LabVIEW 2024 Q1 and prior versions.\n\n",
"id": "GHSA-8f29-jv59-33jp",
"modified": "2024-03-11T18:31:07Z",
"published": "2024-03-11T18:31:07Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-23609"
},
{
"type": "WEB",
"url": "https://www.ni.com/en/support/security/available-critical-and-security-updates-for-ni-software/improper-error-handling-issues-in-labview.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8G53-W3HM-63C4
Vulnerability from github – Published: 2022-05-24 19:10 – Updated: 2022-05-24 19:10Uncaught exception in firmware for Intel(R) Ethernet Adapters 800 Series Controllers and associated adapters before version 1.5.3.0 may allow a privileged user to potentially enable denial of service via local access.
{
"affected": [],
"aliases": [
"CVE-2021-0005"
],
"database_specific": {
"cwe_ids": [
"CWE-755"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-08-11T13:15:00Z",
"severity": "MODERATE"
},
"details": "Uncaught exception in firmware for Intel(R) Ethernet Adapters 800 Series Controllers and associated adapters before version 1.5.3.0 may allow a privileged user to potentially enable denial of service via local access.",
"id": "GHSA-8g53-w3hm-63c4",
"modified": "2022-05-24T19:10:43Z",
"published": "2022-05-24T19:10:43Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-0005"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20210827-0009"
},
{
"type": "WEB",
"url": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00479.html"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-8GMR-PR73-9HWF
Vulnerability from github – Published: 2022-04-12 00:00 – Updated: 2022-04-19 00:01In ged, there is a possible memory corruption due to an incorrect error handling. This could lead to local information disclosure with System execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS05838808; Issue ID: ALPS05839556.
{
"affected": [],
"aliases": [
"CVE-2022-20076"
],
"database_specific": {
"cwe_ids": [
"CWE-755"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-04-11T20:15:00Z",
"severity": "MODERATE"
},
"details": "In ged, there is a possible memory corruption due to an incorrect error handling. This could lead to local information disclosure with System execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS05838808; Issue ID: ALPS05839556.",
"id": "GHSA-8gmr-pr73-9hwf",
"modified": "2022-04-19T00:01:21Z",
"published": "2022-04-12T00:00:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-20076"
},
{
"type": "WEB",
"url": "https://corp.mediatek.com/product-security-bulletin/April-2022"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-8H88-6GX7-V9HF
Vulnerability from github – Published: 2022-04-16 00:00 – Updated: 2022-04-23 00:03Multiple vulnerabilities in the Cisco IOx application hosting environment on multiple Cisco platforms could allow an attacker to inject arbitrary commands into the underlying host operating system, execute arbitrary code on the underlying host operating system, install applications without being authenticated, or conduct a cross-site scripting (XSS) attack against a user of the affected software. For more information about these vulnerabilities, see the Details section of this advisory.
{
"affected": [],
"aliases": [
"CVE-2022-20726"
],
"database_specific": {
"cwe_ids": [
"CWE-22",
"CWE-755"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-04-15T15:15:00Z",
"severity": "HIGH"
},
"details": "Multiple vulnerabilities in the Cisco IOx application hosting environment on multiple Cisco platforms could allow an attacker to inject arbitrary commands into the underlying host operating system, execute arbitrary code on the underlying host operating system, install applications without being authenticated, or conduct a cross-site scripting (XSS) attack against a user of the affected software. For more information about these vulnerabilities, see the Details section of this advisory.",
"id": "GHSA-8h88-6gx7-v9hf",
"modified": "2022-04-23T00:03:19Z",
"published": "2022-04-16T00:00:48Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-20726"
},
{
"type": "WEB",
"url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iox-yuXQ6hFj"
}
],
"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-8J3X-W35R-RW4R
Vulnerability from github – Published: 2024-01-25 21:32 – Updated: 2024-11-25 14:33A flaw was found in the json payload. If annotation based security is used to secure a REST resource, the JSON body that the resource may consume is being processed (deserialized) prior to the security constraints being evaluated and applied. This does not happen with configuration based security.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "io.quarkus.resteasy.reactive:resteasy-reactive"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.13.9.Final"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "io.quarkus.resteasy.reactive:resteasy-reactive"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0.Final"
},
{
"fixed": "3.2.9.Final"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-6267"
],
"database_specific": {
"cwe_ids": [
"CWE-280",
"CWE-502",
"CWE-755"
],
"github_reviewed": true,
"github_reviewed_at": "2024-01-31T22:38:58Z",
"nvd_published_at": "2024-01-25T19:15:08Z",
"severity": "HIGH"
},
"details": "A flaw was found in the json payload. If annotation based security is used to secure a REST resource, the JSON body that the resource may consume is being processed (deserialized) prior to the security constraints being evaluated and applied. This does not happen with configuration based security.",
"id": "GHSA-8j3x-w35r-rw4r",
"modified": "2024-11-25T14:33:44Z",
"published": "2024-01-25T21:32:14Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-6267"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2024:0494"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2024:0495"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2023-6267"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2251155"
},
{
"type": "PACKAGE",
"url": "https://github.com/quarkusio/quarkus"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Quarkus Improper Handling of Insufficient Permissions or Privileges and Improper Handling of Exceptional Conditions vulnerability"
}
GHSA-8JP5-89M5-6XP3
Vulnerability from github – Published: 2023-11-06 06:30 – Updated: 2025-11-04 18:30bgpd/bgp_flowspec.c in FRRouting (FRR) before 8.4.3 mishandles an nlri length of zero, aka a "flowspec overflow."
{
"affected": [],
"aliases": [
"CVE-2023-38406"
],
"database_specific": {
"cwe_ids": [
"CWE-755"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-11-06T06:15:40Z",
"severity": "CRITICAL"
},
"details": "bgpd/bgp_flowspec.c in FRRouting (FRR) before 8.4.3 mishandles an nlri length of zero, aka a \"flowspec overflow.\"",
"id": "GHSA-8jp5-89m5-6xp3",
"modified": "2025-11-04T18:30:44Z",
"published": "2023-11-06T06:30:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-38406"
},
{
"type": "WEB",
"url": "https://github.com/FRRouting/frr/pull/12884"
},
{
"type": "WEB",
"url": "https://github.com/FRRouting/frr/compare/frr-8.4.2...frr-8.4.3"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2024/04/msg00019.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2024/09/msg00007.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8M5M-VGWC-V2RV
Vulnerability from github – Published: 2025-01-14 15:30 – Updated: 2025-01-14 18:31Specifically crafted SCMI messages sent to an SCP running SCP-Firmware release versions up to and including 2.15.0 may lead to a Usage Fault and crash the SCP
{
"affected": [],
"aliases": [
"CVE-2024-11863"
],
"database_specific": {
"cwe_ids": [
"CWE-755"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-01-14T14:15:27Z",
"severity": "MODERATE"
},
"details": "Specifically crafted SCMI messages sent to an SCP running SCP-Firmware release versions up to and including 2.15.0 may lead to a Usage Fault and crash the SCP",
"id": "GHSA-8m5m-vgwc-v2rv",
"modified": "2025-01-14T18:31:56Z",
"published": "2025-01-14T15:30:52Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-11863"
},
{
"type": "WEB",
"url": "https://developer.arm.com/Arm%20Security%20Center/SCP-Firmware%20Vulnerability%20CVE-2024-11863-11864"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-8MPJ-M6QM-5QR8
Vulnerability from github – Published: 2026-07-20 21:24 – Updated: 2026-07-20 21:24Summary
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
- Application uses mistune with the
Includedirective enabled. Application accepts user-supplied markdown files (CMS, wiki, multi-user documentation platform, note-taking app, CI/CD doc renderer). - Attacker uploads two markdown files:
a.md:.. include:: b.mdb.md:.. include:: a.md- Renderer is invoked on
a.md(or any markdown that references this pair).Includedirective includesb.md, which includesa.md, which includesb.md, ... Each recursion adds Python frames. - After ~340 cycle iterations (depending on default
sys.setrecursionlimit(1000)and the per-include frame depth), Python raisesRecursionError: maximum recursion depth exceeded. - The exception is not caught by the directive. It propagates through
block.parse, throughMarkdown.__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.
{
"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"
}
No mitigation information available for this CWE.
No CAPEC attack patterns related to this CWE.