Skip to content

Commit c2aa9b5

Browse files
[AutoPR- Security] Patch python-mako for CVE-2026-41205 [HIGH] (microsoft#16919)
Co-authored-by: BinduSri-6522866 <v-badabala@microsoft.com>
1 parent 81d252d commit c2aa9b5

2 files changed

Lines changed: 115 additions & 2 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
From 9d5d1628e7ee111ce0078bd8b8e8fbab878cd504 Mon Sep 17 00:00:00 2001
2+
From: Mike Bayer <mike_mp@zzzcomputing.com>
3+
Date: Tue, 14 Apr 2026 15:45:19 -0400
4+
Subject: [PATCH] Fix path traversal via double-slash URI prefix in
5+
TemplateLookup
6+
7+
The URI normalization in Template.__init__ stripped only a single
8+
leading slash, while TemplateLookup.get_template() stripped all
9+
leading slashes. A URI such as "//../../secret.txt" could bypass
10+
the directory traversal check. Changed to use lstrip("/") so
11+
both code paths handle leading slashes consistently.
12+
13+
Fixes: #434
14+
Change-Id: I400b9a40aed956cc2b5826a9c8736f104e84f1a4
15+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
16+
Upstream-reference: https://github.com/sqlalchemy/mako/commit/e05ac61989a7fb9dd7dcde6cfd72dc48328719a3.patch
17+
---
18+
doc/build/unreleased/434.rst | 10 +++++++++
19+
mako/template.py | 4 +---
20+
test/test_lookup.py | 41 ++++++++++++++++++++++++++++++++++++
21+
3 files changed, 52 insertions(+), 3 deletions(-)
22+
create mode 100644 doc/build/unreleased/434.rst
23+
24+
diff --git a/doc/build/unreleased/434.rst b/doc/build/unreleased/434.rst
25+
new file mode 100644
26+
index 0000000..452265a
27+
--- /dev/null
28+
+++ b/doc/build/unreleased/434.rst
29+
@@ -0,0 +1,10 @@
30+
+.. change::
31+
+ :tags: bug, template
32+
+ :tickets: 434
33+
+
34+
+ Fixed issue in :class:`.TemplateLookup` where a URI with a double-slash
35+
+ prefix (e.g. ``//../../``) could bypass the directory traversal check in
36+
+ :class:`.Template`, allowing reads of arbitrary files outside of the
37+
+ template directory. The issue was caused by an inconsistency in how leading
38+
+ slashes were stripped between :meth:`.TemplateLookup.get_template` and
39+
+ :class:`.Template` initialization.
40+
diff --git a/mako/template.py b/mako/template.py
41+
index 8c70731..9d313b2 100644
42+
--- a/mako/template.py
43+
+++ b/mako/template.py
44+
@@ -264,9 +264,7 @@ class Template:
45+
self.module_id = "memory:" + hex(id(self))
46+
self.uri = self.module_id
47+
48+
- u_norm = self.uri
49+
- if u_norm.startswith("/"):
50+
- u_norm = u_norm[1:]
51+
+ u_norm = self.uri.lstrip("/")
52+
u_norm = os.path.normpath(u_norm)
53+
if u_norm.startswith(".."):
54+
raise exceptions.TemplateLookupException(
55+
diff --git a/test/test_lookup.py b/test/test_lookup.py
56+
index 6a797d7..2f7cdf0 100644
57+
--- a/test/test_lookup.py
58+
+++ b/test/test_lookup.py
59+
@@ -127,6 +127,47 @@ class LookupTest:
60+
# this is OK since the .. cancels out
61+
runtime._lookup_template(ctx, "foo/../index.html", index.uri)
62+
63+
+ def test_dont_accept_relative_outside_of_root_via_double_slash(self):
64+
+ """test that double-slash URI prefix can't bypass the
65+
+ path traversal check"""
66+
+ with tempfile.TemporaryDirectory() as base:
67+
+ tmpl_dir = os.path.join(base, "app", "templates")
68+
+ os.makedirs(tmpl_dir)
69+
+ with open(os.path.join(tmpl_dir, "index.html"), "w") as f:
70+
+ f.write("Hello")
71+
+
72+
+ secret = os.path.join(base, "secrets", "creds.txt")
73+
+ os.makedirs(os.path.dirname(secret))
74+
+ with open(secret, "w") as f:
75+
+ f.write("SECRET_KEY=supersecret123")
76+
+
77+
+ tl = lookup.TemplateLookup(directories=[tmpl_dir])
78+
+ rel = os.path.relpath(secret, tmpl_dir)
79+
+
80+
+ # single-slash prefix should also be blocked
81+
+ assert_raises_message(
82+
+ exceptions.TemplateLookupException,
83+
+ "cannot be relative outside of the root path",
84+
+ tl.get_template,
85+
+ "/" + rel,
86+
+ )
87+
+
88+
+ # double-slash prefix must not bypass the check
89+
+ assert_raises_message(
90+
+ exceptions.TemplateLookupException,
91+
+ "cannot be relative outside of the root path",
92+
+ tl.get_template,
93+
+ "//" + rel,
94+
+ )
95+
+
96+
+ # triple-slash prefix must not bypass the check
97+
+ assert_raises_message(
98+
+ exceptions.TemplateLookupException,
99+
+ "cannot be relative outside of the root path",
100+
+ tl.get_template,
101+
+ "///" + rel,
102+
+ )
103+
+
104+
def test_checking_against_bad_filetype(self):
105+
with tempfile.TemporaryDirectory() as tempdir:
106+
tl = lookup.TemplateLookup(directories=[tempdir])
107+
--
108+
2.45.4
109+

SPECS/python-mako/python-mako.spec

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
Summary: Python templating language
33
Name: python-mako
44
Version: 1.2.4
5-
Release: 2%{?dist}
5+
Release: 3%{?dist}
66
License: MIT
77
Vendor: Microsoft Corporation
88
Distribution: Azure Linux
99
Group: Development/Languages/Python
1010
URL: https://www.makotemplates.org/
1111
Source0: https://github.com/sqlalchemy/mako/archive/refs/tags/rel_%{version_tag}.tar.gz#/%{name}-%{version}.tar.gz
12+
Patch0: CVE-2026-41205.patch
1213
BuildArch: noarch
1314

1415
%if 0%{?with_check}
@@ -39,7 +40,7 @@ into Python modules for maximum performance. Mako’s syntax and API borrows fro
3940
many others, including Django templates, Cheetah, Myghty, and Genshi.
4041

4142
%prep
42-
%autosetup -n mako-rel_%{version_tag}
43+
%autosetup -p1 -n mako-rel_%{version_tag}
4344

4445
%build
4546
%py3_build
@@ -59,6 +60,9 @@ ln -s mako-render %{buildroot}/%{_bindir}/mako-render3
5960
%{_bindir}/mako-render3
6061

6162
%changelog
63+
* Tue Apr 28 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 1.2.4-3
64+
- Patch for CVE-2026-41205
65+
6266
* Tue May 13 2025 Riken Maharjan <rmaharjan@microsoft.com> - 1.2.4-2
6367
- Fix Ptest by using pytest instead of tox.
6468

0 commit comments

Comments
 (0)