mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-08-25 05:21:31 +00:00
python3-pyjwt: Fix CVE-2026-48522
Restrict PyJWKClient JWKS retrieval to HTTP and HTTPS. urllib otherwise accepts schemes such as file, FTP and data, allowing attacker-influenced URLs to reach unintended resources. This patch applies the relevant subset of the upstream 2.13.0 fix. The upstream commit is referenced in [1], and the public advisory is referenced in [2]. [1] https://github.com/jpadilla/pyjwt/commit/95791b1759b8aa4f2203575d344d5c78564cdc81 [2] https://github.com/advisories/GHSA-993g-76c3-p5m4 Signed-off-by: Hetvi Thakar <hthakar@cisco.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
committed by
Anuj Mittal
parent
49bb7f1369
commit
773e345eca
@@ -0,0 +1,94 @@
|
||||
From ff542029d6865add176b3d4b650d8f1dc514ac85 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jos=C3=A9=20Padilla?= <jpadilla@users.noreply.github.com>
|
||||
Date: Mon, 3 Aug 2026 03:20:44 -0700
|
||||
Subject: [PATCH] PyJWKClient: reject non-HTTP(S) JWKS URIs
|
||||
|
||||
Restrict JWKS retrieval to HTTP and HTTPS. urllib otherwise accepts
|
||||
additional schemes such as file, FTP and data, allowing
|
||||
attacker-influenced URLs to reach unintended resources.
|
||||
|
||||
CVE: CVE-2026-48522
|
||||
Upstream-Status: Backport [https://github.com/jpadilla/pyjwt/commit/95791b1759b8aa4f2203575d344d5c78564cdc81]
|
||||
|
||||
Backport Changes:
|
||||
- Extracted only the CVE-2026-48522 URI-scheme validation and regression
|
||||
tests from the bundled upstream 2.13.0 commit. The other requested CVE
|
||||
fixes are carried as separate patches.
|
||||
- Adapted the hunk context to the PyJWT 2.8.0 constructor and typing imports.
|
||||
- Omitted upstream test comments while retaining the same URI cases and
|
||||
assertions.
|
||||
- Omitted the 2.13.0 version and changelog updates, CVE-2026-48523 (which
|
||||
does not affect 2.8.0), and unrelated hardening from the bundled commit.
|
||||
|
||||
(cherry picked from commit 95791b1759b8aa4f2203575d344d5c78564cdc81)
|
||||
Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
|
||||
---
|
||||
jwt/jwks_client.py | 11 +++++++++++
|
||||
tests/test_jwks_client.py | 25 +++++++++++++++++++++++++
|
||||
2 files changed, 36 insertions(+)
|
||||
|
||||
diff --git a/jwt/jwks_client.py b/jwt/jwks_client.py
|
||||
index f19b10a..18de342 100644
|
||||
--- a/jwt/jwks_client.py
|
||||
+++ b/jwt/jwks_client.py
|
||||
@@ -4,6 +4,7 @@ from functools import lru_cache
|
||||
from ssl import SSLContext
|
||||
from typing import Any, Dict, List, Optional
|
||||
from urllib.error import URLError
|
||||
+from urllib.parse import urlparse
|
||||
|
||||
from .api_jwk import PyJWK, PyJWKSet
|
||||
from .api_jwt import decode_complete as decode_token
|
||||
@@ -25,6 +26,16 @@ class PyJWKClient:
|
||||
):
|
||||
if headers is None:
|
||||
headers = {}
|
||||
+ # urllib's default OpenerDirector also handles file://, ftp://, and
|
||||
+ # data: URIs. Reject anything that isn't http(s) eagerly so a caller
|
||||
+ # passing an attacker-influenced URL (e.g. taken from a `jku` token
|
||||
+ # header) can't read local files or reach other unintended schemes.
|
||||
+ scheme = urlparse(uri).scheme.lower()
|
||||
+ if scheme not in ("http", "https"):
|
||||
+ raise PyJWKClientError(
|
||||
+ f"Invalid JWKS URI scheme {scheme!r}: only 'http' and 'https' "
|
||||
+ f"are supported."
|
||||
+ )
|
||||
self.uri = uri
|
||||
self.jwk_set_cache: Optional[JWKSetCache] = None
|
||||
self.headers = headers
|
||||
diff --git a/tests/test_jwks_client.py b/tests/test_jwks_client.py
|
||||
index c3951ea..d4bdd35 100644
|
||||
--- a/tests/test_jwks_client.py
|
||||
+++ b/tests/test_jwks_client.py
|
||||
@@ -327,6 +327,31 @@ class TestPyJWKClient:
|
||||
jwks_client = PyJWKClient(url, lifespan=-1)
|
||||
assert jwks_client is None
|
||||
|
||||
+ @pytest.mark.parametrize(
|
||||
+ "uri",
|
||||
+ [
|
||||
+ "file:///etc/passwd",
|
||||
+ "ftp://example.org/keys.json",
|
||||
+ 'data:application/json,{"keys":[]}',
|
||||
+ "/etc/passwd",
|
||||
+ "ldap://internal.test/jwks",
|
||||
+ ],
|
||||
+ )
|
||||
+ def test_pyjwkclient_rejects_non_http_schemes(self, uri: str) -> None:
|
||||
+ with pytest.raises(PyJWKClientError, match="Invalid JWKS URI scheme"):
|
||||
+ PyJWKClient(uri)
|
||||
+
|
||||
+ @pytest.mark.parametrize(
|
||||
+ "uri",
|
||||
+ [
|
||||
+ "http://localhost/jwks.json",
|
||||
+ "https://example.test/jwks.json",
|
||||
+ "HTTPS://Example.Test/jwks.json",
|
||||
+ ],
|
||||
+ )
|
||||
+ def test_pyjwkclient_accepts_http_https_schemes(self, uri: str) -> None:
|
||||
+ PyJWKClient(uri)
|
||||
+
|
||||
def test_get_jwt_set_timeout(self):
|
||||
url = "https://dev-87evx9ru.auth0.com/.well-known/jwks.json"
|
||||
jwks_client = PyJWKClient(url, timeout=5)
|
||||
@@ -5,7 +5,10 @@ HOMEPAGE = "http://github.com/jpadilla/pyjwt"
|
||||
LICENSE = "MIT"
|
||||
LIC_FILES_CHKSUM = "file://LICENSE;md5=e4b56d2c9973d8cf54655555be06e551"
|
||||
|
||||
SRC_URI += "file://CVE-2026-32597.patch"
|
||||
SRC_URI += " \
|
||||
file://CVE-2026-32597.patch \
|
||||
file://CVE-2026-48522.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"
|
||||
|
||||
PYPI_PACKAGE = "PyJWT"
|
||||
|
||||
Reference in New Issue
Block a user