Why send algorithm in jwt header
HS256
is a signature algorithm so the client (as you have described it) can read the contents of the token anyway, without verifying the signature (unless the content is encrypted separately).
It is a good point that if the receiver of the token needs it then there is no good reason to send a copy of it in the token. In fact it was a criticism of JWT that the algorithm is included in the header and this led to various vulnerabilities in libraries implementing the standard, particularly since it includes a none
option for the signature algorithm which allowed the sender of a token to bypass verification completely if the receiver only used the information in the JWT header (see this article for more information). This also details another vulnerability due to weakly typed signing keys.
It's now often recommended that the verifier of a token specify what algorithm it expects it to be using (since in many cases this will be known), rather than rely on the information in the JWT header.
So the problem is not so much about exposing information about the algorithm used (the algorithms should be robust enough for it to make no difference), but about receiving invalid algorithm information which can be used to deceived the receiver of the token into believing it is valid when it is actually forged.
Why do we send it to the client
The obvious, pedantic reason is simply that the standard requires it:
RFC 7515 4.1.1
This Header Parameter MUST be present and MUST be understood and processed by implementations.
While I don't know this for sure as I can't find any IETF meeting notes discussing it, I believe the algorithm is required because of historical precedent. These standards did not just appear over-night, on their own, in the form we know them today. Rather they evolved from the XML dsig technology, where algorithm is specifically sent as part of embedded public keys.
Isn't not sending the algorithm more secure ?
Requiring implementations to change behavior based on client input is questionable. The alg
header is client-provided, which means even if it's valid, it can be used to trick the implementation into open failure modes. Two critical vulnerabilities were exploited almost immediately after JWT was standardized, based on allowing the client to direct the server as to the algorithm choice.
Whether this is a design bug or an implementation bug has been debated.
Bottom line, the JOSE family (JWT, JWS, JWE, JWK, and JWA) allows implementors and users to mix and match cryptographic algorithms, which offers a huge array of use-case capability. Unfortunately, it also means users should be extremely picky about their JWT library's handling of client-provided algorithm.
If you're looking into other bearer-token type options, options that don't have this unusual (bizarre?) requirement, check-out:
- PASETO
- Macaroons