[meta-python][wrynose][PATCH 2/6] python3-pyjwt: Fix CVE-2026-48523

"Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" <[email protected]>
Newsgroups org.openembedded.lists.openembedded-devel
Message-ID <[email protected]>
From: Hetvi Thakar <[email protected]>

This patch applies the upstream 2.13.0 backport for
CVE-2026-48523. The upstream fix commit is referenced in [1],
and the public CVE advisory is referenced in [2].

[1] https://github.com/jpadilla/pyjwt/commit/95791b1759b8aa4f2203575d344d5c78564cdc81
[2] https://github.com/advisories/GHSA-jq35-7prp-9v3f

Signed-off-by: Hetvi Thakar <[email protected]>
---
 .../python/files/CVE-2026-48523.patch         | 115 ++++++++++++++++++
 .../python/python3-pyjwt_2.12.1.bb            |   4 +-
 2 files changed, 118 insertions(+), 1 deletion(-)
 create mode 100644 meta-python/recipes-devtools/python/files/CVE-2026-48523.patch

diff --git a/meta-python/recipes-devtools/python/files/CVE-2026-48523.patch b/meta-python/recipes-devtools/python/files/CVE-2026-48523.patch
new file mode 100644
index 0000000000..f272338979
--- /dev/null
+++ b/meta-python/recipes-devtools/python/files/CVE-2026-48523.patch
@@ -0,0 +1,115 @@
+From 6590add3a8d18098b107fe446ff256ae92e7238f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jos=C3=A9=20Padilla?= <[email protected]>
+Date: Thu, 21 May 2026 14:11:10 -0400
+Subject: [PATCH] Bundle security fixes and hardening into 2.13.0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Security:
+- `HMACAlgorithm.prepare_key` rejects JWK JSON documents passed as raw
+  HMAC secrets to close an algorithm-confusion gap not covered by the
+  existing PEM/SSH guard. Reported by @aradona91 in GHSA-xgmm-8j9v-c9wx.
+- Bind the JWT header `alg` to `PyJWK.algorithm_name` during verification
+  so the caller's `algorithms` allow-list cannot be bypassed when decoding
+  with a `PyJWK` / `PyJWKClient` key. Reported by @sushi-gif in
+  GHSA-jq35-7prp-9v3f.
+- Skip the unconditional base64 decode of the compact-form payload
+  segment when `b64=false` is set, and require that segment to be empty
+  (RFC 7515 Appendix F detached form). Closes an unauthenticated DoS
+  amplifier. Reported by @thesmartshadow in GHSA-w7vc-732c-9m39.
+- `PyJWKClient` rejects any URI whose scheme is not `http` or `https` so
+  attacker-influenced URIs cannot read local files or reach unintended
+  schemes via urllib's default `file://` / `ftp://` / `data:` handlers.
+  Reported by @KEIJOT in GHSA-993g-76c3-p5m4.
+- Preserve the cached JWK Set on fetch errors in `PyJWKClient.fetch_data`.
+  The previous `finally`-block `put(None)` pattern cleared the cache on
+  any transient outage. Reported by @eddieran in GHSA-fhv5-28vv-h8m8.
+
+Fixes:
+- Reject empty HMAC keys outright in `HMACAlgorithm.prepare_key` with
+  `InvalidKeyError` instead of accepting them with only a warning.
+  Hardening prompted by reports from @SnailSploit and @spartan8806.
+- Forward per-call `options` (including `enforce_minimum_key_length`)
+  from `PyJWT.decode` through to `PyJWS._verify_signature`. Thanks to
+  @WLUB.
+- RFC 7797 §3 compliance for `b64=false`: encoder auto-adds `"b64"` to
+  `crit`; decoder rejects tokens that set `b64=false` without listing
+  it in `crit`. Thanks to @MachineLearning-Nerd.
+
+CVE: CVE-2026-48523
+Upstream-Status: Backport [https://github.com/jpadilla/pyjwt/commit/95791b1759b8aa4f2203575d344d5c78564cdc81]
+
+Backport Changes:
+- Split out the PyJWK algorithm-binding validation because the upstream
+  commit bundles multiple CVEs.
+- Omitted CHANGELOG.rst because it conflicted and is release documentation.
+- Omitted the 2.13.0 version bump and other bundled fixes; applicable CVE
+  fixes are carried in separate patches.
+
+(cherry picked from commit 95791b1759b8aa4f2203575d344d5c78564cdc81)
+Signed-off-by: Hetvi Thakar <[email protected]>
+---
+ jwt/api_jws.py        | 10 ++++++++++
+ tests/test_api_jws.py | 27 +++++++++++++++++++++++++++
+ 2 files changed, 37 insertions(+)
+
+diff --git a/jwt/api_jws.py b/jwt/api_jws.py
+index 0ab7e4b..91d2ae3 100644
+--- a/jwt/api_jws.py
++++ b/jwt/api_jws.py
+@@ -348,6 +348,16 @@ class PyJWS:
+             raise InvalidAlgorithmError("The specified alg value is not allowed")
+ 
+         if isinstance(key, PyJWK):
++            # The PyJWK has a fixed algorithm bound at construction time.
++            # Verification must use that algorithm, not whatever the token
++            # header advertises, otherwise the caller's allow-list check
++            # above degenerates into a string compare with no behavioural
++            # effect on which algorithm actually verifies the signature.
++            if alg != key.algorithm_name:
++                raise InvalidAlgorithmError(
++                    f"Token algorithm {alg!r} does not match the key's "
++                    f"algorithm {key.algorithm_name!r}"
++                )
+             alg_obj = key.Algorithm
+             prepared_key = key.key
+         else:
+diff --git a/tests/test_api_jws.py b/tests/test_api_jws.py
+index 9f7edc0..0715b9e 100644
+--- a/tests/test_api_jws.py
++++ b/tests/test_api_jws.py
+@@ -397,6 +397,33 @@ class TestJWS:
+         with pytest.raises(InvalidAlgorithmError):
+             jws.decode(example_jws, jwk)
+ 
++    def test_decodes_with_jwk_rejects_header_alg_outside_jwk_alg(
++        self, jws: PyJWS
++    ) -> None:
++        # Token header says HS256 and the caller's allow-list also accepts
++        # HS256, but the PyJWK is bound to HS512. Even though the allow-list
++        # would pass, verification must be locked to the PyJWK's algorithm
++        # rather than the header's — otherwise an attacker who controls a
++        # registered key can advertise a disallowed algorithm in the header
++        # and have it accepted.
++        jwk = PyJWK(
++            {
++                "kty": "oct",
++                "alg": "HS512",
++                "k": "c2VjcmV0",  # "secret"
++            }
++        )
++        example_jws = (
++            b"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9."
++            b"aGVsbG8gd29ybGQ."
++            b"gEW0pdU4kxPthjtehYdhxB9mMOGajt1xCKlGGXDJ8PM"
++        )
++
++        with pytest.raises(
++            InvalidAlgorithmError, match="does not match the key's algorithm"
++        ):
++            jws.decode(example_jws, jwk, algorithms=["HS256", "HS512"])
++
+     # 'Control' Elliptic Curve jws created by another library.
+     # Used to test for regressions that could affect both
+     # encoding / decoding operations equally (causing tests
diff --git a/meta-python/recipes-devtools/python/python3-pyjwt_2.12.1.bb b/meta-python/recipes-devtools/python/python3-pyjwt_2.12.1.bb
index ed7a280ee5..e67c7bae2f 100644
--- a/meta-python/recipes-devtools/python/python3-pyjwt_2.12.1.bb
+++ b/meta-python/recipes-devtools/python/python3-pyjwt_2.12.1.bb
@@ -5,7 +5,9 @@ HOMEPAGE = "https://github.com/jpadilla/pyjwt"
 LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=e4b56d2c9973d8cf54655555be06e551"
 
-SRC_URI += "file://CVE-2026-48522.patch"
+SRC_URI += "file://CVE-2026-48522.patch \
+           file://CVE-2026-48523.patch \
+           "
 
 SRC_URI[sha256sum] = "c74a7a2adf861c04d002db713dd85f84beb242228e671280bf709d765b03672b"
 
-- 
2.35.6
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.