summaryrefslogtreecommitdiffstats
path: root/meta-python/recipes-devtools/python/python3-werkzeug/CVE-2024-34069-0002.patch
blob: 37d5ba47c7b19263ea337d916337e4d4bd66207b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
From 890b6b62634fa61224222aee31081c61b054ff01 Mon Sep 17 00:00:00 2001
From: David Lord <davidism@gmail.com>
Date: Fri, 3 May 2024 14:49:43 -0700
Subject: [PATCH] only require trusted host for evalex

CVE: CVE-2024-34069

Upstream-Status: Backport [https://github.com/pallets/werkzeug/commit/890b6b62634fa61224222aee31081c61b054ff01]

Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
---
 src/werkzeug/debug/__init__.py | 25 ++++++++++++++++++++-----
 src/werkzeug/sansio/utils.py   |  2 +-
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/src/werkzeug/debug/__init__.py b/src/werkzeug/debug/__init__.py
index 87e68c4..0302b24 100644
--- a/src/werkzeug/debug/__init__.py
+++ b/src/werkzeug/debug/__init__.py
@@ -16,7 +16,9 @@ from zlib import adler32

 from .._internal import _log
 from ..exceptions import NotFound
+from ..exceptions import SecurityError
 from ..http import parse_cookie
+from ..sansio.utils import host_is_trusted
 from ..security import gen_salt
 from ..utils import send_file
 from ..wrappers.request import Request
@@ -331,7 +333,7 @@ class DebuggedApplication:

             is_trusted = bool(self.check_pin_trust(environ))
             html = tb.render_debugger_html(
-                evalex=self.evalex,
+                evalex=self.evalex and self.check_host_trust(environ),
                 secret=self.secret,
                 evalex_trusted=is_trusted,
             )
@@ -359,10 +361,16 @@ class DebuggedApplication:
         frame: t.Union[DebugFrameSummary, _ConsoleFrame],
     ) -> Response:
         """Execute a command in a console."""
+        if not self.check_host_trust(request.environ):
+            return SecurityError()  # type: ignore[return-value]
+
         return Response(frame.eval(command), mimetype="text/html")

     def display_console(self, request: Request) -> Response:
         """Display a standalone shell."""
+        if not self.check_host_trust(request.environ):
+            return SecurityError()  # type: ignore[return-value]
+
         if 0 not in self.frames:
             if self.console_init_func is None:
                 ns = {}
@@ -411,12 +419,18 @@ class DebuggedApplication:
             return None
         return (time.time() - PIN_TIME) < int(ts)

+    def check_host_trust(self, environ: WSGIEnvironment) -> bool:
+        return host_is_trusted(environ.get("HTTP_HOST"), self.trusted_hosts)
+
     def _fail_pin_auth(self) -> None:
         time.sleep(5.0 if self._failed_pin_auth > 5 else 0.5)
         self._failed_pin_auth += 1

     def pin_auth(self, request: Request) -> Response:
         """Authenticates with the pin."""
+        if not self.check_host_trust(request.environ):
+            return SecurityError()  # type: ignore[return-value]
+
         exhausted = False
         auth = False
         trust = self.check_pin_trust(request.environ)
@@ -466,8 +480,11 @@ class DebuggedApplication:
             rv.delete_cookie(self.pin_cookie_name)
         return rv

-    def log_pin_request(self) -> Response:
+    def log_pin_request(self, request: Request) -> Response:
         """Log the pin if needed."""
+        if not self.check_host_trust(request.environ):
+            return SecurityError()  # type: ignore[return-value]
+
         if self.pin_logging and self.pin is not None:
             _log(
                 "info", " * To enable the debugger you need to enter the security pin:"
@@ -483,8 +500,6 @@ class DebuggedApplication:
         # form data!  Otherwise the application won't have access to that data
         # any more!
         request = Request(environ)
-        request.trusted_hosts = self.trusted_hosts
-        assert request.host  # will raise 400 error if not trusted
         response = self.debug_application
         if request.args.get("__debugger__") == "yes":
             cmd = request.args.get("cmd")
@@ -496,7 +511,7 @@ class DebuggedApplication:
             elif cmd == "pinauth" and secret == self.secret:
                 response = self.pin_auth(request)  # type: ignore
             elif cmd == "printpin" and secret == self.secret:
-                response = self.log_pin_request()  # type: ignore
+                response = self.log_pin_request(request)  # type: ignore
             elif (
                 self.evalex
                 and cmd is not None
diff --git a/src/werkzeug/sansio/utils.py b/src/werkzeug/sansio/utils.py
index 1b4d892..7e7b4d2 100644
--- a/src/werkzeug/sansio/utils.py
+++ b/src/werkzeug/sansio/utils.py
@@ -6,7 +6,7 @@ from ..urls import uri_to_iri
 from ..urls import url_quote


-def host_is_trusted(hostname: str, trusted_list: t.Iterable[str]) -> bool:
+def host_is_trusted(hostname: str | None, trusted_list: t.Iterable[str]) -> bool:
     """Check if a host matches a list of trusted names.

     :param hostname: The name to check.
--
2.40.0