Fix a session token check written by hand

Review the AI's codeEasy15 min

Your task

Your API checks a signed session token on every request. A first draft called jwt.decodeVerify, a method the library does not have, so the check is now written out by hand.

An assistant wrote authorize_token(token, expected_signature, now_epoch). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • token: claims joined by |, each written key=value. For example alg=HS256|sub=alice|exp=1700000100|sig=abc123==.
  • expected_signature: the signature your server computes for this token with its own secret.
  • now_epoch: the current time in epoch seconds (seconds since 1 January 1970).
  • Return "ok:" followed by the sub value, or one of "reject:malformed", "reject:alg", "reject:signature" and "reject:expired".

Rules the tests check:

  • Split the token on |. Split each piece at its first = into a key and a value, so a value may contain =.
  • Keys and values are compared exactly: case matters and nothing is trimmed. Other keys, like iss, are allowed and ignored.
  • The token is malformed if any of these holds:
    • a piece has no = or has an empty key (an empty token counts)
    • any key appears twice
    • alg, sub, exp or sig is missing
    • sub is empty
    • exp is not one or more digits from 0 to 9
  • Check in this order and return the first result that applies:
    1. The token is malformed: "reject:malformed".
    2. alg is not exactly HS256: "reject:alg".
    3. sig is not exactly equal to expected_signature: "reject:signature".
    4. exp is less than or equal to now_epoch: "reject:expired".
  • If none applies, return "ok:" followed by sub.

Examples:

  • authorize_token("alg=HS256|sub=alice|exp=1700000100|sig=abc123==", "abc123==", 1700000000) returns "ok:alice".
  • authorize_token("alg=HS256|sub=alice|exp=1700000100|sig=forged", "abc123==", 1700000000) returns "reject:signature".
  • authorize_token("alg=none|sub=alice|exp=1700000100|sig=", "", 1700000000) returns "reject:alg". The empty signature matches, but the algorithm check comes first.

Then, in a sentence or two: how would you catch this kind of bug in review?

Examples

authorize_token(token: str, expected_signature: str, now_epoch: int) -> str
Example 1
Inputauthorize_token("alg=HS256|sub=alice|exp=1700000100|sig=abc123==", "abc123==", 1700000000)
Output"ok:alice"
Example 2
Inputauthorize_token("alg=HS256|sub=alice|exp=1700000100|sig=forged", "abc123==", 1700000000)
Output"reject:signature"
Example 3
Inputauthorize_token("alg=none|sub=alice|exp=1700000100|sig=", "", 1700000000)
Output"reject:alg"