Skip to content

Commit 8d77b49

Browse files
test updates
1 parent 0a7dd8e commit 8d77b49

1 file changed

Lines changed: 25 additions & 9 deletions

File tree

tests/test_planet_auth/unit/auth/auth_clients/oidc/test_multi_validator.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import inspect
16+
import json
1617
import jwt.utils
1718
import secrets
1819
import time
@@ -337,16 +338,22 @@ def test_malformed_token_5_iss_liars(self):
337338
under_test.validate_access_token(token=test_jwt) # No throw
338339

339340
# TC 1
340-
# Use the real signing key, but make the iss an invalid type.
341-
# You can make the argument this is still valid, because the signature is still
342-
# from a trusted issuer. But, we reject it based on bad structure.
343-
token_body["iss"] = [primary_issuer.token_builder.issuer, untrusted_issuer.token_builder.issuer]
344-
test_jwt = primary_issuer.token_builder.encode(body=token_body, extra_headers=token_header)
341+
# Token with iss set to an invalid type (list instead of string).
342+
# Newer versions of PyJWT prevent encoding non-string iss claims,
343+
# so we use FakeTokenBuilder to craft the malformed token directly.
344+
# The issuer type check happens before signature verification.
345+
fake_jwt = FakeTokenBuilder.fake_token(
346+
body={
347+
**token_body,
348+
"iss": [primary_issuer.token_builder.issuer, untrusted_issuer.token_builder.issuer],
349+
},
350+
header=token_header,
351+
)
345352
with pytest.raises(
346353
InvalidTokenException,
347354
match=re.escape("Issuer claim ('iss') must be a of string type. 'list' type was detected."),
348355
):
349-
under_test.validate_access_token(token=test_jwt)
356+
under_test.validate_access_token(token=fake_jwt)
350357

351358
# TC 2
352359
# Liar token. Untrusted issuer signing key claiming to be valid issuer
@@ -359,13 +366,22 @@ def test_malformed_token_5_iss_liars(self):
359366

360367
# TC 3
361368
# Double-talk liar. Using the untrusted signing key, claiming to be ourselves and the trusted issuer.
362-
token_body["iss"] = [primary_issuer.token_builder.issuer, untrusted_issuer.token_builder.issuer]
363-
test_jwt = untrusted_issuer.token_builder.encode(body=token_body, extra_headers=token_header)
369+
# We encode a valid token with the untrusted key, then tamper the payload
370+
# post-signing to inject a list iss. This produces a token with a real
371+
# (but untrusted) signature that no longer matches the modified payload —
372+
# a more realistic attack than pure garbage signatures.
373+
legit_jwt = untrusted_issuer.token_builder.encode(body=token_body, extra_headers=token_header)
374+
header_b64, payload_b64, signature_b64 = legit_jwt.split(".")
375+
payload_bytes = jwt.utils.base64url_decode(payload_b64)
376+
payload = json.loads(payload_bytes)
377+
payload["iss"] = [primary_issuer.token_builder.issuer, untrusted_issuer.token_builder.issuer]
378+
tampered_payload_b64 = jwt.utils.base64url_encode(json.dumps(payload).encode("utf-8")).decode("utf-8")
379+
tampered_jwt = f"{header_b64}.{tampered_payload_b64}.{signature_b64}"
364380
with pytest.raises(
365381
InvalidTokenException,
366382
match=re.escape("Issuer claim ('iss') must be a of string type. 'list' type was detected."),
367383
):
368-
under_test.validate_access_token(token=test_jwt)
384+
under_test.validate_access_token(token=tampered_jwt)
369385

370386
def test_missing_signature(self):
371387
# QE TC11 - JWT without a signature

0 commit comments

Comments
 (0)