Skip to content

Commit c8ab900

Browse files
authored
Fix aud validation to support {'aud': null} case. (jpadilla#670)
* Fix aud validation to support {'aud': null} case. * Fix aud validation to support {'aud': null} case.
1 parent a629ecd commit c8ab900

File tree

3 files changed

+28
-8
lines changed

3 files changed

+28
-8
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Changed
1313
Fixed
1414
~~~~~
1515

16+
- Fix aud validation to support {'aud': null} case. `#670 <https://github.com/jpadilla/pyjwt/pull/670>`__
17+
1618
Added
1719
~~~~~
1820

jwt/api_jwt.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,19 +177,18 @@ def _validate_exp(self, payload, now, leeway):
177177
raise ExpiredSignatureError("Signature has expired")
178178

179179
def _validate_aud(self, payload, audience):
180-
if audience is None and "aud" not in payload:
181-
return
180+
if audience is None:
181+
if "aud" not in payload or not payload["aud"]:
182+
return
183+
# Application did not specify an audience, but
184+
# the token has the 'aud' claim
185+
raise InvalidAudienceError("Invalid audience")
182186

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

188-
if audience is None and "aud" in payload:
189-
# Application did not specify an audience, but
190-
# the token has the 'aud' claim
191-
raise InvalidAudienceError("Invalid audience")
192-
193192
audience_claims = payload["aud"]
194193

195194
if isinstance(audience_claims, str):

tests/test_api_jwt.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,16 @@ def test_decode_raises_exception_if_nbf_is_not_int(self, jwt):
202202
with pytest.raises(DecodeError):
203203
jwt.decode(example_jwt, "secret", algorithms=["HS256"])
204204

205+
def test_decode_raises_exception_if_aud_is_none(self, jwt):
206+
# >>> jwt.encode({'aud': None}, 'secret')
207+
example_jwt = (
208+
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9."
209+
"eyJhdWQiOm51bGx9."
210+
"-Peqc-pTugGvrc5C8Bnl0-X1V_5fv-aVb_7y7nGBVvQ"
211+
)
212+
decoded = jwt.decode(example_jwt, "secret", algorithms=["HS256"])
213+
assert decoded["aud"] is None
214+
205215
def test_encode_datetime(self, jwt):
206216
secret = "secret"
207217
current_datetime = datetime.utcnow()
@@ -413,6 +423,15 @@ def test_raise_exception_token_without_audience(self, jwt):
413423

414424
assert exc.value.claim == "aud"
415425

426+
def test_raise_exception_token_with_aud_none_and_without_audience(self, jwt):
427+
payload = {"some": "payload", "aud": None}
428+
token = jwt.encode(payload, "secret")
429+
430+
with pytest.raises(MissingRequiredClaimError) as exc:
431+
jwt.decode(token, "secret", audience="urn:me", algorithms=["HS256"])
432+
433+
assert exc.value.claim == "aud"
434+
416435
def test_check_issuer_when_valid(self, jwt):
417436
issuer = "urn:foo"
418437
payload = {"some": "payload", "iss": "urn:foo"}

0 commit comments

Comments
 (0)