mirror of
https://git.yoctoproject.org/poky
synced 2026-09-12 06:49:32 +02:00
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] e05ac61989
[2] https://github.com/advisories/GHSA-v92g-xgxw-vvmm
(From OE-Core rev: 0c13fdc7798a24dadb60b7dba60049558bf5c021)
Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
ce5d6b9653
commit
81c4f97c54
110
meta/recipes-devtools/python/python3-mako/CVE-2026-41205.patch
Normal file
110
meta/recipes-devtools/python/python3-mako/CVE-2026-41205.patch
Normal file
@@ -0,0 +1,110 @@
|
||||
From e05ac61989a7fb9dd7dcde6cfd72dc48328719a3 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Bayer <mike_mp@zzzcomputing.com>
|
||||
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 <hthakar@cisco.com>
|
||||
---
|
||||
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])
|
||||
@@ -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 \
|
||||
|
||||
Reference in New Issue
Block a user