Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix aud validation to support {'aud': null} case. #670

Merged
merged 2 commits into from Jul 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Expand Up @@ -13,6 +13,8 @@ Changed
Fixed
~~~~~

- Fix aud validation to support {'aud': null} case. `#670 <https://github.com/jpadilla/pyjwt/pull/670>`__

Added
~~~~~

Expand Down
15 changes: 7 additions & 8 deletions jwt/api_jwt.py
Expand Up @@ -177,19 +177,18 @@ def _validate_exp(self, payload, now, leeway):
raise ExpiredSignatureError("Signature has expired")

def _validate_aud(self, payload, audience):
if audience is None and "aud" not in payload:
return
if audience is None:
if "aud" not in payload or not payload["aud"]:
return
# Application did not specify an audience, but
# the token has the 'aud' claim
raise InvalidAudienceError("Invalid audience")

if audience is not None and "aud" not in payload:
if "aud" not in payload or not payload["aud"]:
# Application specified an audience, but it could not be
# verified since the token does not contain a claim.
raise MissingRequiredClaimError("aud")

if audience is None and "aud" in payload:
# Application did not specify an audience, but
# the token has the 'aud' claim
raise InvalidAudienceError("Invalid audience")

audience_claims = payload["aud"]

if isinstance(audience_claims, str):
Expand Down
19 changes: 19 additions & 0 deletions tests/test_api_jwt.py
Expand Up @@ -202,6 +202,16 @@ def test_decode_raises_exception_if_nbf_is_not_int(self, jwt):
with pytest.raises(DecodeError):
jwt.decode(example_jwt, "secret", algorithms=["HS256"])

def test_decode_raises_exception_if_aud_is_none(self, jwt):
# >>> jwt.encode({'aud': None}, 'secret')
example_jwt = (
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9."
"eyJhdWQiOm51bGx9."
"-Peqc-pTugGvrc5C8Bnl0-X1V_5fv-aVb_7y7nGBVvQ"
)
decoded = jwt.decode(example_jwt, "secret", algorithms=["HS256"])
assert decoded["aud"] is None

def test_encode_datetime(self, jwt):
secret = "secret"
current_datetime = datetime.utcnow()
Expand Down Expand Up @@ -413,6 +423,15 @@ def test_raise_exception_token_without_audience(self, jwt):

assert exc.value.claim == "aud"

def test_raise_exception_token_with_aud_none_and_without_audience(self, jwt):
payload = {"some": "payload", "aud": None}
token = jwt.encode(payload, "secret")

with pytest.raises(MissingRequiredClaimError) as exc:
jwt.decode(token, "secret", audience="urn:me", algorithms=["HS256"])

assert exc.value.claim == "aud"

def test_check_issuer_when_valid(self, jwt):
issuer = "urn:foo"
payload = {"some": "payload", "iss": "urn:foo"}
Expand Down