Skip to main content

Threats Tagged 'cve-2026-48523'

View all threats tagged with 'cve-2026-48523'. Filter and sort to focus on specific types of threats.

Pro Console Lifetime

Stop chasing alerts. Route them.

Start free, then upgrade once to turn Radar into an automated delivery engine for your security stack.

Custom feeds / Automations: email, Slack, webhooks, SIEM/MISP / API access (baseline limits)

View Plans & Pricing

API access activates after upgrading in Console -> Billing.

Breach by OffSeqOFFSEQFRIENDS — 25% OFF

Check if your credentials are on the dark web

Instant breach scanning across billions of leaked records. Free tier available.

Scan now

Filter Threats

Narrow down the results by type, severity, or affected countries

Search threats by title, CVE ID, or description. Maximum 100 characters.
Active filters (1):Tag: cve-2026-48523

Threats Tagged 'cve-2026-48523'

Click on any threat for detailed analysis and mitigation recommendations

> [!NOTE] > Scored assuming a deployment where algorithm policy functions as an authentication/authorization boundary. In deployments where the algorithm policy enforces crypto agility only, the practical confidentiality impact is lower and the issue is closer to an integrity-of-policy-enforcement bug. PyJWT `2.9.0` through `2.12.1` allows a verifier-side algorithm allow-list bypass when `jwt.decode()` or `jwt.decode_complete()` are called with a `PyJWK` key. The token header `alg` is checked against the caller-supplied `algorithms` allow-list, but signature verification is performed with the algorithm bound to the `PyJWK` object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented `PyJWKClient.get_signing_key_from_jwt(...)` flow. ### Summary PyJWT's `PyJWK` verification path allows a verifier-side algorithm allow-list bypass. In affected versions, when a JWT is decoded with a `PyJWK` object, PyJWT verifies that the header `alg` string is present in the caller's `algorithms=[...]` list, but it does not actually use the header algorithm to verify the signature. Instead, it verifies with the algorithm already bound to the `PyJWK` object. This lets an attacker who controls a registered JWK/JWKS private key sign with a disallowed algorithm and have the token accepted as long as the JWT header advertises an allowed algorithm. This affects the documented `PyJWKClient` usage flow and does not require any non-default flags or unsafe configuration. ### Details In `jwt/api_jws.py` in `2.12.1`, `_verify_signature()` treats `PyJWK` keys differently from normal PEM/public-key inputs: ```python if algorithms is None and isinstance(key, PyJWK): algorithms = [key.algorithm_name] ... if not alg or (algorithms is not None and alg not in algorithms): raise InvalidAlgorithmError("The specified alg value is not allowed") if isinstance(key, PyJWK): alg_obj = key.Algorithm prepared_key = key.key else: alg_obj = self.get_algorithm_by_name(alg) prepared_key = alg_obj.prepare_key(key) ``` This logic means: 1. The JWT header `alg` is checked only as a string against the caller-supplied allow-list. 2. If the key is a `PyJWK`, the actual verifier is not selected from the header algorithm. 3. Instead, PyJWT always verifies with `key.Algorithm`, which is fixed when the `PyJWK` object is created. `PyJWK` binds its algorithm in `jwt/api_jwk.py` from the JWK's `alg` field or from key-type defaults: ```python if not algorithm and isinstance(self._jwk_data, dict): algorithm = self._jwk_data.get("alg", None) ... self.algorithm_name = algorithm self.Algorithm = get_default_algorithms()[algorithm] self.key = self.Algorithm.from_jwk(self._jwk_data) ``` So once a `PyJWK` is constructed, the verifier uses the `PyJWK`'s bound algorithm, not the JWT header algorithm. The issue is reachable through the documented JWKS flow. In `docs/usage.rst`, the project documents: ```python signing_key = jwks_client.get_signing_key_from_jwt(token) jwt.decode( token, signing_key, audience="https://expenses-api", options={"verify_exp": False}, algorithms=["RS256"], ) ``` `PyJWKClient.get_signing_key_from_jwt()` returns a `PyJWK`, so this documented path is affected. This is not a "no-key forgery" issue. The attacker still needs control of an accepted JWK/JWKS private key. However, that is realistic in deployments such as: - self-service OAuth client assertions - multi-tenant key registration - federation / BYO-JWKS trust models - any system where external parties sign JWTs with their own registered keys In those cases, the attacker can bypass verifier-side algorithm policy. For example, if the server intends to only accept `PS256`, an attacker controlling an accepted RSA JWK can sign with `RS256`, set `alg=PS256` in the JWT header, and still be accepted through the `PyJWK` path. The same forged token is rejected through the normal PEM/public-key verification path, which shows the bug is specific to `PyJWK` verification rather than expected JWT behavior. This behavior was introduced by commit `ab8176abe21e550dbc1c9a6bb7e78ad80853bfb1` (`Decode with PyJWK (#886)`), which is present in tagged releases `2.9.0`, `2.10.0`, `2.10.1`, `2.11.0`, `2.12.0`, and `2.12.1`. ### PoC Tested locally against PyJWT `2.12.1` on Python `3.12.10` with `cryptography 45.0.6`. Install dependencies: ```bash python -m pip install pyjwt==2.12.1 cryptography ``` Run the following script: ```python import json import jwt from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat from jwt.api_jwk import PyJWK from jwt.algorithms import RSAAlgorithm from jwt.utils import base64url_encode # Generate an RSA keypair controlled by the attacker. priv = rsa.generate_p

Join the discussion

This update includes the following RPMs: rust: * cargo-1.97.0-1.1.hum1 (aarch64, x86_64) * clippy-1.97.0-1.1.hum1 (aarch64, x86_64) * rust-1.97.0-1.1.hum1 (aarch64, x86_64) * rust-analyzer-1.97.0-1.1.hum1 (aarch64, x86_64) * rust-debugger-common-1.97.0-1.1.hum1 (noarch) * rust-doc-1.97.0-1.1.hum1 (aarch64, x86_64) * rust-gdb-1.97.0-1.1.hum1 (noarch) * rust-lldb-1.97.0-1.1.hum1 (noarch) * rust-src-1.97.0-1.1.hum1 (noarch) * rust-std-static-1.97.0-1.1.hum1 (aarch64, x86_64) * rust-std-static-aarch64-unknown-none-softfloat-1.97.0-1.1.hum1 (noarch) * rust-std-static-aarch64-unknown-uefi-1.97.0-1.1.hum1 (noarch) * rust-std-static-i686-pc-windows-gnu-1.97.0-1.1.hum1 (noarch) * rust-std-static-wasm32-unknown-unknown-1.97.0-1.1.hum1 (noarch) * rust-std-static-wasm32-wasip1-1.97.0-1.1.hum1 (noarch) * rust-std-static-x86_64-pc-windows-gnu-1.97.0-1.1.hum1 (noarch) * rust-std-static-x86_64-unknown-none-1.97.0-1.1.hum1 (noarch) * rust-std-static-x86_64-unknown-uefi-1.97.0-1.1.hum1 (noarch) * rustfmt-1.97.0-1.1.hum1 (aarch64, x86_64) * rust-1.97.0-1.1.hum1.src (src)

Join the discussion
0

PyJWKClient in the kimi-cli library allows fetching JSON Web Key Sets (JWKS) from URLs with schemes beyond HTTP and HTTPS, including file://, ftp://, and data:. This can lead to server-side request forgery (SSRF) on local files and other protocols. An attacker who can influence the jku URL and write to a local file path can forge JWT tokens that the application accepts as valid. The vulnerability affects PyJWT versions 2.11.0 and 2.12.1 and likely earlier versions. A fix is available that restricts allowed URL schemes to HTTP and HTTPS.

Join the discussion

This update includes the following RPMs: llvm: * clang-21.1.8-1.1.hum1 (aarch64, x86_64) * clang-analyzer-21.1.8-1.1.hum1 (aarch64, x86_64) * clang-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * clang-libs-21.1.8-1.1.hum1 (aarch64, x86_64) * clang-resource-filesystem-21.1.8-1.1.hum1 (aarch64, x86_64) * clang-tools-extra-21.1.8-1.1.hum1 (aarch64, x86_64) * clang-tools-extra-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * compiler-rt-21.1.8-1.1.hum1 (aarch64, x86_64) * git-clang-format-21.1.8-1.1.hum1 (aarch64, x86_64) * libcxx-21.1.8-1.1.hum1 (aarch64, x86_64) * libcxx-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * libcxx-static-21.1.8-1.1.hum1 (aarch64, x86_64) * libcxxabi-21.1.8-1.1.hum1 (aarch64, x86_64) * libcxxabi-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * libcxxabi-static-21.1.8-1.1.hum1 (aarch64, x86_64) * libomp-21.1.8-1.1.hum1 (aarch64, x86_64) * libomp-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * lld-21.1.8-1.1.hum1 (aarch64, x86_64) * lld-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * lld-libs-21.1.8-1.1.hum1 (aarch64, x86_64) * lldb-21.1.8-1.1.hum1 (aarch64, x86_64) * lldb-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-bolt-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-cmake-utils-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-doc-21.1.8-1.1.hum1 (noarch) * llvm-filesystem-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-googletest-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-libs-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-libunwind-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-libunwind-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-libunwind-static-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-static-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-test-21.1.8-1.1.hum1 (aarch64, x86_64) * mlir-21.1.8-1.1.hum1 (aarch64, x86_64) * mlir-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * mlir-static-21.1.8-1.1.hum1 (aarch64, x86_64) * polly-21.1.8-1.1.hum1 (aarch64, x86_64) * polly-devel-21.1.8-1.1.hum1 (aarch64, x86_64) * python3-clang-21.1.8-1.1.hum1 (aarch64, x86_64) * python3-lit-21.1.8-1.1.hum1 (noarch) * python3-lldb-21.1.8-1.1.hum1 (aarch64, x86_64) * python3-mlir-21.1.8-1.1.hum1 (aarch64, x86_64) * llvm-21.1.8-1.1.hum1.src (src)

Join the discussion

Showing 1 to 4 of 4 results

Filters:Tag: cve-2026-48523
Page 1 of 1
OffSeq TrainingCredly Certified

Lead Pen Test Professional

Technical5-day eLearningPECB Accredited
View courses