Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Fixed
~~~~~
- Validate key against allowed types for Algorithm family in `#964 <https://github.com/jpadilla/pyjwt/pull/964>`__
- Add iterator for JWKSet in `#1041 <https://github.com/jpadilla/pyjwt/pull/1041>`__

- Validate `iss` claim is a string during encoding and decoding by @pachewise in `#1040 <https://github.com/jpadilla/pyjwt/pull/1040>`__

Added
~~~~~
Expand Down
23 changes: 19 additions & 4 deletions jwt/api_jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ def encode(
if isinstance(payload.get(time_claim), datetime):
payload[time_claim] = timegm(payload[time_claim].utctimetuple())

# Issue #1039, iss being set to non-string
if "iss" in payload and not isinstance(payload["iss"], str):
raise TypeError("Issuer (iss) must be a string.")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering if this should also be an InvalidIssuerError.


json_payload = self._encode_payload(
payload,
headers=headers,
Expand Down Expand Up @@ -412,19 +416,30 @@ def _validate_aud(
if all(aud not in audience_claims for aud in audience):
raise InvalidAudienceError("Audience doesn't match")

def _validate_iss(self, payload: dict[str, Any], issuer: Any) -> None:
def _validate_iss(
self, payload: dict[str, Any], issuer: list[str] | str | None
Comment thread
pachewise marked this conversation as resolved.
Resolved
) -> None:
if issuer is None:
return

if "iss" not in payload:
raise MissingRequiredClaimError("iss")

iss = payload["iss"]
if not isinstance(iss, str):
raise InvalidIssuerError("Payload Issuer (iss) must be a string")

if isinstance(issuer, str):
if payload["iss"] != issuer:
if iss != issuer:
raise InvalidIssuerError("Invalid issuer")
else:
if payload["iss"] not in issuer:
raise InvalidIssuerError("Invalid issuer")
try:
if iss not in issuer:
raise InvalidIssuerError("Invalid issuer")
except TypeError:
raise InvalidIssuerError(
"Issuer param must be a str or list of str"
) from None


_jwt_global_obj = PyJWT()
Expand Down
26 changes: 26 additions & 0 deletions tests/test_api_jwt.py
Comment thread
pachewise marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,16 @@ def test_encode_bad_type(self, jwt):
lambda t=t: jwt.encode(t, "secret", algorithms=["HS256"]),
)

def test_encode_with_non_str_iss(self, jwt):
"""Regression test for Issue #1039."""
with pytest.raises(TypeError):
jwt.encode(
{
"iss": 123,
},
key="secret",
)

def test_encode_with_typ(self, jwt):
payload = {
"iss": "https://scim.example.com",
Expand Down Expand Up @@ -943,3 +953,19 @@ def test_jti_claim_with_invalid_int_value(self, jwt):

with pytest.raises(InvalidJTIError):
jwt.decode(token, secret, algorithms=["HS256"])

def test_validate_iss_with_non_str(self, jwt):
"""Regression test for #1039"""
payload = {
"iss": 123,
}
with pytest.raises(InvalidIssuerError):
jwt._validate_iss(payload, issuer="123")

def test_validate_iss_with_non_str_issuer(self, jwt):
"""Regression test for #1039"""
payload = {
"iss": "123",
}
with pytest.raises(InvalidIssuerError):
jwt._validate_iss(payload, issuer=123)