The vulnerability lies in the jws library's streaming interface, specifically in the createVerify function, which constructs a VerifyStream. The core issue is an improper verification of the cryptographic signature when using HMAC-based algorithms (e.g., HS256). The VerifyStream constructor failed to validate that a secret key was actually provided. An attacker could craft a JWS token and manipulate the application's key lookup logic (e.g., by providing a specific kid in the header) to cause it to return null or undefined for the secret. The vulnerable code would then attempt to verify the signature using this null key, leading to a successful but insecure verification.
The patch addresses this by adding an explicit check in the constructors of both VerifyStream and SignStream. This check tests if an HMAC algorithm is being used (/^hs/i.test(...)) and if the secret is null or undefined. If both conditions are true, it throws a TypeError, preventing the use of a null key and mitigating the vulnerability. The function VerifyStream is the primary vulnerable function as it's directly responsible for the insecure signature verification that an attacker would exploit.
VerifyStreamlib/verify-stream.js
SignStreamlib/sign-stream.js
| Package Name | Ecosystem | Vulnerable Versions | First Patched Version |
|---|---|---|---|
| jws | npm | < 3.2.3 | 3.2.3 |
| jws | npm | = 4.0.0 | 4.0.1 |