VAITP Dataset

← Back to the dataset

CVE-2026-46338

PyMdown `snippets` path traversal allows reading files from sibling paths.

  • CVSS 4.3
  • CWE-22
  • Input Validation and Sanitization
  • Remote

PyMdown Extensions is a set of extensions for the Python-Markdown markdown project. From 10.0.1 until 10.21.3, pymdownx.snippets uses a string-prefix containment check in SnippetPreprocessor.get_snippet_path() in pymdownx/snippets.py when `restrict_base_path: True`, allowing markdown snippet directives to read files from sibling paths that share the same base_path prefix, such as docs and docs_internal. This is a regression of CVE-2023-32309. This issue is fixed in version 10.21.3.

CVSS base score
4.3
Published
2026-07-16
OWASP
A01 Broken Access Control
Orthogonal defect classification
Checking
Code defect classification
Incorrect Check
Category
Input Validation and Sanitization
Subcategory
Path Traversal
Accessibility scope
Remote
Impact
Information Disclosure
Affected component
PyMdown Exte
Fixed by upgrading
Yes

Solution

Upgrade PyMdown Extensions to version 10.21.3 or later.

Vulnerable code sample

import os

def get_snippet_path(base_path, file_path, current_file_dir):
    """
    A representation of the vulnerable function logic before the fix.
    `restrict_base_path` is assumed to be True.
    """

    # Resolve the user-provided path to an absolute path.
    # In the real library, this is resolved relative to the current markdown file.
    resolved_path = os.path.abspath(os.path.join(current_file_dir, file_path))

    # THE VULNERABLE CHECK:
    # A simple string prefix check is used for path containment.
    # This check is insufficient. For example, if `base_path` is '/app/docs',
    # a `resolved_path` of '/app/docs_internal/secret.txt' will pass
    # because the string starts with the `base_path` string.
    if not resolved_path.startswith(base_path):
        raise ValueError("Path is outside the restricted base path.")

    # If the check passes (even incorrectly), the path is returned.
    return resolved_path

Patched code sample

import os

def get_snippet_path_fixed(path: str, base_path: str) -> str:
    """
    Safely resolves a snippet path, ensuring it is contained within the base_path.
    This demonstrates the fix for the path traversal vulnerability.
    """

    # Normalize the base path to an absolute path for reliable comparison.
    abs_base_path = os.path.abspath(os.path.normpath(base_path))

    # Resolve the requested snippet path relative to the base path.
    requested_path = os.path.abspath(os.path.normpath(os.path.join(abs_base_path, path)))

    # The vulnerable approach used a simple string prefix check, e.g.,
    # `requested_path.startswith(abs_base_path)`, which allowed traversal
    # to sibling directories like 'docs' and 'docs_internal'.

    # The fix uses `os.path.commonpath` to ensure the requested path is
    # truly inside the base directory. If the common path of the two is not
    # the base path itself, the request is considered invalid.
    if os.path.commonpath([abs_base_path, requested_path]) != abs_base_path:
        # If the path is outside the restricted base, fall back to the base path.
        return abs_base_path

    return requested_path

Payload

--(8<-- "docs_internal/secrets.txt"

Cite this entry

@misc{vaitp:cve202646338,
  title        = {{PyMdown `snippets` path traversal allows reading files from sibling paths.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-46338},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-46338/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::