Security Research CVE-2026-59924
Path traversal in mistune's Include directive allows reading arbitrary files outside the intended markdown directory. Affects all versions up to 3.1.4, fixed in 3.3.0.
Summary
A path-traversal issue exists in mistune, a Python Markdown parser, in the optional Include directive used by its RST-style directive plugin. When a markdown file is processed with md.read(), a crafted include path can cause mistune to read files located outside the intended markdown directory. The issue affects all versions up to and including 3.1.4 and is fixed in 3.3.0.
Vulnerability Details
The Include directive lets one markdown file pull in the contents of another file by relative path. The flaw sits in Include.parse(), where the requested path is joined onto the current file’s directory and normalized, but the result is never checked to confirm it stays within that directory:
relpath = self.parse_title(m)
dest = os.path.join(os.path.dirname(source_file), relpath)
dest = os.path.normpath(dest)
Because dest is used to open a file without first verifying it is a descendant of a trusted base directory, a relative path containing enough ../ sequences can escape the markdown source tree entirely and reference arbitrary files elsewhere on the filesystem, limited only by the permissions of the running process.
- Weakness class: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)
- Attack vector: Network — reachable wherever untrusted markdown is rendered server-side
- Attack complexity: High — requires the target application to render attacker-supplied markdown through the
Includedirective - Privileges required: None
- User interaction: None
Impact
Applications that process untrusted or user-submitted markdown with the Include directive enabled may allow unintended file disclosure. The confidentiality impact is rated High: an attacker able to submit markdown that gets rendered by the vulnerable code path could read arbitrary files accessible to the process, such as configuration files, credentials, or source code outside the intended docs directory. There is no integrity or availability impact — the flaw only permits reading files, not modifying or deleting them.
Real-world exposure depends on whether an application:
- Enables
RSTDirectivewith theIncludeplugin, and - Renders markdown originating from a source it does not fully control (user uploads, wiki content, external contributions, etc.)
Proof of Concept — Steps to Reproduce
- Create a markdown file, e.g.
test.md, containing an include directive that traverses upward out of its directory:
.. include:: ../../../example.txt
- Process the file with mistune’s
RSTDirectiveandIncludeplugin enabled:
import mistune
from mistune.directives import RSTDirective, Include
md = mistune.create_markdown(
plugins=[RSTDirective([Include()])]
)
result, state = md.read("test.md")
print(result)
- Observe that the contents of
example.txt, located outside the markdown source directory, are read and included in the output — confirming the path traversal.
Affected Version and Fixed Version
| Affected versions | mistune ≤ 3.1.4 |
| Fixed version | mistune 3.3.0 |
CWE Classification
CWE-22 — Improper Limitation of a Pathname to a Restricted Directory (“Path Traversal”)
Reference Links
- GitHub Security Advisory:
GHSA-r4rv-85jg-w4mf(lepture/mistune) - CVE Record: https://www.cve.org/CVERecord?id=CVE-2026-59924
- NVD Detail: https://nvd.nist.gov/vuln/detail/CVE-2026-59924
- Duplicate/related advisory:
GHSA-h7ww-273w-6cm8 - Fix release: mistune
v3.3.0on GitHub
Remediation
- Upgrade mistune to 3.3.0 or later, which validates that a resolved include path stays within the expected base directory before opening it.
- If upgrading immediately isn’t possible, disable the
Includedirective for any pipeline that renders markdown from a source you do not fully trust — user uploads, external contributions, or content sourced from the internet. - After upgrading, audit any deployments that render user-supplied markdown to confirm no other custom directives introduce similar unrestricted file-path resolution.
Source: GitHub Security Advisory GHSA-r4rv-85jg-w4mf, lepture/mistune.