Reject JWS tokens declaring unsupported crit header extensions#410
Open
arpitjain099 wants to merge 1 commit into
Open
Reject JWS tokens declaring unsupported crit header extensions#410arpitjain099 wants to merge 1 commit into
arpitjain099 wants to merge 1 commit into
Conversation
RFC 7515 section 4.1.11 requires a verifier to reject any JWS whose protected header lists, via crit, an extension that the verifier does not understand. python-jose implements none of the optional crit extensions, so any well-formed non-empty crit list is unsupported and must cause verification to fail closed. Previously jws.verify ignored crit entirely and returned verified claims, which is a fail-open gap relative to RFC 7515 and to PyJWT (which rejects the same tokens). Add _validate_crit to the verification path: reject malformed crit values (non-list, empty, or non-string entries) and any listed extension that is not understood. Enforcement is gated on verify=True so it mirrors signature checking. Fixes mpdavis#406 Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #406
Summary
jws.verify(and thereforejwt.decode) accepts a token whose protectedheader declares a critical extension that the library does not understand,
instead of rejecting it. This is a fail-open gap: a relying party that issues
or expects a
critpolicy marker gets no enforcement, and an attacker canstrip or ignore the semantics the issuer intended to make mandatory.
RFC 7515 4.1.11
The
crit(Critical) Header Parameter "indicates that extensions to thisspecification and/or [JWA] are being used that MUST be understood and
processed." The spec is explicit that:
python-jose implements none of the optional
crit-flagged extensions (forexample
b64from RFC 7797), so any well-formed, non-emptycritlist namesan extension this library cannot honor and the token must be rejected. RFC 7515
also constrains the value itself:
critmust be a non-empty array of non-emptycase-sensitive strings, so malformed values are rejected as well.
PyJWT parity
PyJWT already fails closed on the same input, raising
InvalidTokenError: Unsupported critical extension: .... After this changepython-jose matches that behavior and raises
JWSError.Change
_validate_crit(header)tojose/jws.pyand call it fromverifybefore signature checking.
crit(not a list, empty, or containing a non-stringor empty entry) and any listed extension that is not in the understood set.
The understood set is intentionally empty because the library supports none
of the optional extensions.
verify=True, so it mirrors how signature checkingis skipped when verification is disabled.
Tests
Added
TestCritintests/test_jws.pycovering:critextension is rejectedcritstill verifiescrit(non-list, empty list, non-string entry) is rejectedcritis not enforced whenverify=FalseThe unsupported-
critand malformed-crittests fail on the currentmasterand pass with this change. The full
tests/test_jws.pyandtests/test_jwt.pysuites pass.
flake8,isort, andblackare clean on the changed files.