The vulnerability in PyJWT (GHSA-fhv5-28vv-h8m8) is a denial-of-service (DoS) issue within the PyJWKClient. It has two main components.
First, the PyJWKClient.get_signing_key function is the primary entry point for the DoS attack. It is responsible for retrieving a signing key based on the kid (key ID) from a JWT header. If the kid is not found in the local cache, the function triggers an immediate, uncached fetch of the entire JSON Web Key Set (JWKS) from the configured endpoint by calling get_signing_keys(refresh=True). An attacker can exploit this by sending a high volume of JWTs with randomly generated, non-existent kids. This forces the PyJWKClient to issue a continuous stream of HTTP requests to the JWKS endpoint, potentially overwhelming it and causing a DoS. This function would be the top-level application function in a stack trace during an exploit attempt.
Second, the PyJWKClient.fetch_data function, which handles the actual HTTP request to the JWKS endpoint, contained a flaw that exacerbated the DoS condition. In vulnerable versions, the function was structured with a try...except...finally block where the cache update (self.jwk_set_cache.put(...)) occurred in the finally block. If the HTTP request failed for any reason (e.g., the JWKS endpoint became rate-limited due to the attack), an exception would be thrown, and the finally block would execute with an uninitialized jwk_set variable (which defaults to None). This had the effect of wiping the entire JWKS cache. As a result, even legitimate tokens with valid kids could no longer be verified, extending the denial of service to all users of the application until the JWKS endpoint recovered and a successful fetch could occur.
The provided patch specifically addresses the second issue by moving the cache update logic out of the finally block, ensuring that the cache is only written to upon a successful fetch. While get_signing_key was not modified, it remains the function that initiates the vulnerable process. Therefore, both PyJWKClient.get_signing_key and PyJWKClient.fetch_data are critical indicators of this vulnerability.