From 81c4f97c543715dcde8ae9122b12b56e4668c0e5 Mon Sep 17 00:00:00 2001 From: Hetvi Thakar Date: Wed, 19 Aug 2026 04:15:09 -0700 Subject: [PATCH] python3-mako: Fix CVE-2026-41205 This patch applies the upstream fix as referenced in [2], using the commit shown in [1]. The backport makes Template URI normalization strip all leading slashes, preventing a double-slash URI from bypassing the path traversal check while keeping Mako at version 1.3.2. [1] https://github.com/sqlalchemy/mako/commit/e05ac61989a7fb9dd7dcde6cfd72dc48328719a3 [2] https://github.com/advisories/GHSA-v92g-xgxw-vvmm (From OE-Core rev: 0c13fdc7798a24dadb60b7dba60049558bf5c021) Signed-off-by: Hetvi Thakar Signed-off-by: Yoann Congal Signed-off-by: Richard Purdie --- .../python/python3-mako/CVE-2026-41205.patch | 110 ++++++++++++++++++ .../python/python3-mako_1.3.2.bb | 2 + 2 files changed, 112 insertions(+) create mode 100644 meta/recipes-devtools/python/python3-mako/CVE-2026-41205.patch diff --git a/meta/recipes-devtools/python/python3-mako/CVE-2026-41205.patch b/meta/recipes-devtools/python/python3-mako/CVE-2026-41205.patch new file mode 100644 index 0000000000..0699654b53 --- /dev/null +++ b/meta/recipes-devtools/python/python3-mako/CVE-2026-41205.patch @@ -0,0 +1,110 @@ +From e05ac61989a7fb9dd7dcde6cfd72dc48328719a3 Mon Sep 17 00:00:00 2001 +From: Mike Bayer +Date: Tue, 14 Apr 2026 15:45:19 -0400 +Subject: [PATCH] Fix path traversal via double-slash URI prefix in + TemplateLookup + +The URI normalization in Template.__init__ stripped only a single +leading slash, while TemplateLookup.get_template() stripped all +leading slashes. A URI such as "//../../secret.txt" could bypass +the directory traversal check. Changed to use lstrip("/") so +both code paths handle leading slashes consistently. + +Fixes: #434 +Change-Id: I400b9a40aed956cc2b5826a9c8736f104e84f1a4 + +CVE: CVE-2026-41205 +Upstream-Status: Backport [https://github.com/sqlalchemy/mako/commit/e05ac61989a7fb9dd7dcde6cfd72dc48328719a3] + +(cherry picked from commit e05ac61989a7fb9dd7dcde6cfd72dc48328719a3) +Signed-off-by: Hetvi Thakar +--- + doc/build/unreleased/434.rst | 10 +++++++++ + mako/template.py | 4 +--- + test/test_lookup.py | 41 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 52 insertions(+), 3 deletions(-) + create mode 100644 doc/build/unreleased/434.rst + +diff --git a/doc/build/unreleased/434.rst b/doc/build/unreleased/434.rst +new file mode 100644 +index 00000000..452265ad +--- /dev/null ++++ b/doc/build/unreleased/434.rst +@@ -0,0 +1,10 @@ ++.. change:: ++ :tags: bug, template ++ :tickets: 434 ++ ++ Fixed issue in :class:`.TemplateLookup` where a URI with a double-slash ++ prefix (e.g. ``//../../``) could bypass the directory traversal check in ++ :class:`.Template`, allowing reads of arbitrary files outside of the ++ template directory. The issue was caused by an inconsistency in how leading ++ slashes were stripped between :meth:`.TemplateLookup.get_template` and ++ :class:`.Template` initialization. +diff --git a/mako/template.py b/mako/template.py +index 82c7cba8..d8ebc949 100644 +--- a/mako/template.py ++++ b/mako/template.py +@@ -259,9 +259,7 @@ def __init__( + self.module_id = "memory:" + hex(id(self)) + self.uri = self.module_id + +- u_norm = self.uri +- if u_norm.startswith("/"): +- u_norm = u_norm[1:] ++ u_norm = self.uri.lstrip("/") + u_norm = os.path.normpath(u_norm) + if u_norm.startswith(".."): + raise exceptions.TemplateLookupException( +diff --git a/test/test_lookup.py b/test/test_lookup.py +index 6a797d7a..2f7cdf0b 100644 +--- a/test/test_lookup.py ++++ b/test/test_lookup.py +@@ -127,6 +127,47 @@ def test_dont_accept_relative_outside_of_root(self): + # this is OK since the .. cancels out + runtime._lookup_template(ctx, "foo/../index.html", index.uri) + ++ def test_dont_accept_relative_outside_of_root_via_double_slash(self): ++ """test that double-slash URI prefix 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) ++ ++ # single-slash prefix should also be blocked ++ assert_raises_message( ++ exceptions.TemplateLookupException, ++ "cannot be relative outside of the root path", ++ tl.get_template, ++ "/" + rel, ++ ) ++ ++ # double-slash prefix must not bypass the check ++ assert_raises_message( ++ exceptions.TemplateLookupException, ++ "cannot be relative outside of the root path", ++ tl.get_template, ++ "//" + rel, ++ ) ++ ++ # triple-slash prefix must not bypass the check ++ 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]) diff --git a/meta/recipes-devtools/python/python3-mako_1.3.2.bb b/meta/recipes-devtools/python/python3-mako_1.3.2.bb index 5b7df9192f..617bf33443 100644 --- a/meta/recipes-devtools/python/python3-mako_1.3.2.bb +++ b/meta/recipes-devtools/python/python3-mako_1.3.2.bb @@ -8,6 +8,8 @@ PYPI_PACKAGE = "Mako" inherit pypi python_setuptools_build_meta +SRC_URI += "file://CVE-2026-41205.patch \ + " SRC_URI[sha256sum] = "2a0c8ad7f6274271b3bb7467dd37cf9cc6dab4bc19cb69a4ef10669402de698e" RDEPENDS:${PN} = "python3-html \