mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-19 21:09:03 +02:00
python3-urllib3: fix CVE-2025-50182
urllib3 is a user-friendly HTTP client library for Python. Prior
to 2.5.0, urllib3 does not control redirects in browsers and
Node.js. urllib3 supports being used in a Pyodide runtime utilizing
the JavaScript Fetch API or falling back on XMLHttpRequest. This
means Python libraries can be used to make HTTP requests from a
browser or Node.js. Additionally, urllib3 provides a mechanism to
control redirects, but the retries and redirect parameters are
ignored with Pyodide; the runtime itself determines redirect
behavior. This issue has been patched in version 2.5.0.
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2025-50182
Upstream patch:
7eb4a2aafe
(From OE-Core rev: 082b865d9814e7e7aca4466551a035199aa8b563)
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
parent
7994e19018
commit
0372024fe7
|
@ -0,0 +1,125 @@
|
||||||
|
From 7eb4a2aafe49a279c29b6d1f0ed0f42e9736194f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Illia Volochii <illia.volochii@gmail.com>
|
||||||
|
Date: Wed, 18 Jun 2025 16:30:35 +0300
|
||||||
|
Subject: [PATCH] Merge commit from fork
|
||||||
|
|
||||||
|
CVE: CVE-2025-50182
|
||||||
|
Upstream-Status: Backport [https://github.com/urllib3/urllib3/commit/7eb4a2aafe49a279c29b6d1f0ed0f42e9736194f]
|
||||||
|
|
||||||
|
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||||
|
---
|
||||||
|
docs/reference/contrib/emscripten.rst | 2 +-
|
||||||
|
src/urllib3/contrib/emscripten/fetch.py | 20 ++++++++++
|
||||||
|
test/contrib/emscripten/test_emscripten.py | 46 ++++++++++++++++++++++
|
||||||
|
3 files changed, 67 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/docs/reference/contrib/emscripten.rst b/docs/reference/contrib/emscripten.rst
|
||||||
|
index a8f1cda..4670757 100644
|
||||||
|
--- a/docs/reference/contrib/emscripten.rst
|
||||||
|
+++ b/docs/reference/contrib/emscripten.rst
|
||||||
|
@@ -65,7 +65,7 @@ Features which are usable with Emscripten support are:
|
||||||
|
* Timeouts
|
||||||
|
* Retries
|
||||||
|
* Streaming (with Web Workers and Cross-Origin Isolation)
|
||||||
|
-* Redirects (determined by browser/runtime, not restrictable with urllib3)
|
||||||
|
+* Redirects (urllib3 controls redirects in Node.js but not in browsers where behavior is determined by runtime)
|
||||||
|
* Decompressing response bodies
|
||||||
|
|
||||||
|
Features which don't work with Emscripten:
|
||||||
|
diff --git a/src/urllib3/contrib/emscripten/fetch.py b/src/urllib3/contrib/emscripten/fetch.py
|
||||||
|
index a514306..6695821 100644
|
||||||
|
--- a/src/urllib3/contrib/emscripten/fetch.py
|
||||||
|
+++ b/src/urllib3/contrib/emscripten/fetch.py
|
||||||
|
@@ -573,6 +573,11 @@ def send_jspi_request(
|
||||||
|
"method": request.method,
|
||||||
|
"signal": js_abort_controller.signal,
|
||||||
|
}
|
||||||
|
+ # Node.js returns the whole response (unlike opaqueredirect in browsers),
|
||||||
|
+ # so urllib3 can set `redirect: manual` to control redirects itself.
|
||||||
|
+ # https://stackoverflow.com/a/78524615
|
||||||
|
+ if _is_node_js():
|
||||||
|
+ fetch_data["redirect"] = "manual"
|
||||||
|
# Call JavaScript fetch (async api, returns a promise)
|
||||||
|
fetcher_promise_js = js.fetch(request.url, _obj_from_dict(fetch_data))
|
||||||
|
# Now suspend WebAssembly until we resolve that promise
|
||||||
|
@@ -693,6 +698,21 @@ def has_jspi() -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
+def _is_node_js() -> bool:
|
||||||
|
+ """
|
||||||
|
+ Check if we are in Node.js.
|
||||||
|
+
|
||||||
|
+ :return: True if we are in Node.js.
|
||||||
|
+ :rtype: bool
|
||||||
|
+ """
|
||||||
|
+ return (
|
||||||
|
+ hasattr(js, "process")
|
||||||
|
+ and hasattr(js.process, "release")
|
||||||
|
+ # According to the Node.js documentation, the release name is always "node".
|
||||||
|
+ and js.process.release.name == "node"
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def streaming_ready() -> bool | None:
|
||||||
|
if _fetcher:
|
||||||
|
return _fetcher.streaming_ready
|
||||||
|
diff --git a/test/contrib/emscripten/test_emscripten.py b/test/contrib/emscripten/test_emscripten.py
|
||||||
|
index 5eaa674..fbf89fc 100644
|
||||||
|
--- a/test/contrib/emscripten/test_emscripten.py
|
||||||
|
+++ b/test/contrib/emscripten/test_emscripten.py
|
||||||
|
@@ -960,6 +960,52 @@ def test_redirects(
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
+@pytest.mark.with_jspi
|
||||||
|
+def test_disabled_redirects(
|
||||||
|
+ selenium_coverage: typing.Any, testserver_http: PyodideServerInfo
|
||||||
|
+) -> None:
|
||||||
|
+ """
|
||||||
|
+ Test that urllib3 can control redirects in Node.js.
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ @run_in_pyodide # type: ignore[misc]
|
||||||
|
+ def pyodide_test(selenium_coverage: typing.Any, host: str, port: int) -> None:
|
||||||
|
+ import pytest
|
||||||
|
+
|
||||||
|
+ from urllib3 import PoolManager, request
|
||||||
|
+ from urllib3.contrib.emscripten.fetch import _is_node_js
|
||||||
|
+ from urllib3.exceptions import MaxRetryError
|
||||||
|
+
|
||||||
|
+ if not _is_node_js():
|
||||||
|
+ pytest.skip("urllib3 does not control redirects in browsers.")
|
||||||
|
+
|
||||||
|
+ redirect_url = f"http://{host}:{port}/redirect"
|
||||||
|
+
|
||||||
|
+ with PoolManager(retries=0) as http:
|
||||||
|
+ with pytest.raises(MaxRetryError):
|
||||||
|
+ http.request("GET", redirect_url)
|
||||||
|
+
|
||||||
|
+ response = http.request("GET", redirect_url, redirect=False)
|
||||||
|
+ assert response.status == 303
|
||||||
|
+
|
||||||
|
+ with PoolManager(retries=False) as http:
|
||||||
|
+ response = http.request("GET", redirect_url)
|
||||||
|
+ assert response.status == 303
|
||||||
|
+
|
||||||
|
+ with pytest.raises(MaxRetryError):
|
||||||
|
+ request("GET", redirect_url, retries=0)
|
||||||
|
+
|
||||||
|
+ response = request("GET", redirect_url, redirect=False)
|
||||||
|
+ assert response.status == 303
|
||||||
|
+
|
||||||
|
+ response = request("GET", redirect_url, retries=0, redirect=False)
|
||||||
|
+ assert response.status == 303
|
||||||
|
+
|
||||||
|
+ pyodide_test(
|
||||||
|
+ selenium_coverage, testserver_http.http_host, testserver_http.http_port
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def test_insecure_requests_warning(
|
||||||
|
selenium_coverage: typing.Any, testserver_http: PyodideServerInfo
|
||||||
|
) -> None:
|
||||||
|
--
|
||||||
|
2.40.0
|
|
@ -9,6 +9,7 @@ inherit pypi python_hatchling
|
||||||
|
|
||||||
SRC_URI += " \
|
SRC_URI += " \
|
||||||
file://CVE-2025-50181.patch \
|
file://CVE-2025-50181.patch \
|
||||||
|
file://CVE-2025-50182.patch \
|
||||||
"
|
"
|
||||||
|
|
||||||
DEPENDS += " \
|
DEPENDS += " \
|
||||||
|
|
Loading…
Reference in New Issue
Block a user