High severity8.7GHSA Advisory· Published May 12, 2026· Updated May 13, 2026
CVE-2026-44307
CVE-2026-44307
Description
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.
Affected products
1- Range: <= 1.3.11
Patches
172e10c573ca0Fix path traversal via backslash URI on Windows in TemplateLookup
4 files changed · +52 −2
doc/build/unreleased/435.rst+10 −0 added@@ -0,0 +1,10 @@ +.. change:: + :tags: bug, template + :tickets: 435 + + Fixed issue in :class:`.TemplateLookup` where a URI with backslash path + separators (e.g. ``\..\secret.txt``) could bypass the directory traversal + check on Windows, allowing reads of arbitrary files outside of the template + directory. This is an incomplete fix for :cve:`2026-41205`. Backslash + characters in URIs are now normalized to forward slashes before path + resolution.
mako/lookup.py+1 −1 modified@@ -241,7 +241,7 @@ def get_template(self, uri): else: return self._collection[uri] except KeyError as e: - u = re.sub(r"^\/+", "", uri) + u = re.sub(r"^\/+", "", uri.replace("\\", "/")) for dir_ in self.directories: # make sure the path seperators are posix - os.altsep is empty # on POSIX and cannot be used.
mako/template.py+1 −1 modified@@ -259,7 +259,7 @@ def __init__( self.module_id = "memory:" + hex(id(self)) self.uri = self.module_id - u_norm = self.uri.lstrip("/") + u_norm = self.uri.replace("\\", "/").lstrip("/") u_norm = os.path.normpath(u_norm) if u_norm.startswith(".."): raise exceptions.TemplateLookupException(
test/test_lookup.py+40 −0 modified@@ -168,6 +168,46 @@ def test_dont_accept_relative_outside_of_root_via_double_slash(self): "///" + rel, ) + def test_dont_accept_relative_outside_of_root_via_backslash(self): + """test that backslash traversal URI can't bypass the + path traversal check""" + with tempfile.TemporaryDirectory() as base: + tmpl_dir = os.path.join(base, "app", "templates") + os.makedirs(tmpl_dir) + with open(os.path.join(tmpl_dir, "index.html"), "w") as f: + f.write("Hello") + + secret = os.path.join(base, "secrets", "creds.txt") + os.makedirs(os.path.dirname(secret)) + with open(secret, "w") as f: + f.write("SECRET_KEY=supersecret123") + + tl = lookup.TemplateLookup(directories=[tmpl_dir]) + rel = os.path.relpath(secret, tmpl_dir).replace("/", "\\") + + assert_raises_message( + exceptions.TemplateLookupException, + "cannot be relative outside of the root path", + tl.get_template, + rel, + ) + + # with leading backslash + assert_raises_message( + exceptions.TemplateLookupException, + "cannot be relative outside of the root path", + tl.get_template, + "\\" + rel, + ) + + # with leading forward slash + assert_raises_message( + exceptions.TemplateLookupException, + "cannot be relative outside of the root path", + tl.get_template, + "/" + rel, + ) + def test_checking_against_bad_filetype(self): with tempfile.TemporaryDirectory() as tempdir: tl = lookup.TemplateLookup(directories=[tempdir])
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-2h4p-vjrc-8xpqghsaADVISORY
- github.com/sqlalchemy/mako/commit/72e10c573ca0fbcbddd4455abca8ce92a61780d7nvd
- github.com/sqlalchemy/mako/issues/435nvd
- github.com/sqlalchemy/mako/releases/tag/rel_1_3_12nvd
- github.com/sqlalchemy/mako/security/advisories/GHSA-2h4p-vjrc-8xpqnvd
- nvd.nist.gov/vuln/detail/CVE-2026-44307ghsa
News mentions
0No linked articles in our index yet.