This code review checklist covers the security checks that matter most when a PR touches session management, token issuance, or authentication flows. The item most reviewers miss is scope validation: confirming that a token is allowed to perform a specific action, not just that the token's signature is valid.
If you're reviewing a PR that adds a new login flow, moves to JWTs, changes a logout path, or touches any middleware that reads session data, this checklist applies directly to your situation. Work through each section before you approve.
Token Issuance and Storage
New tokens must be issued with the shortest lifetime the feature can tolerate, and stored only in memory or an HttpOnly cookie. Anything else introduces exposure.
- Check the token lifetime values. Access tokens should expire in minutes, not hours. Refresh tokens should expire in days, not months. Explicit expiry values must appear in the code; an absent or unlimited expiry is a defect worth blocking.
- Look for localStorage or sessionStorage writes. Both are readable by any script on the page. An XSS vulnerability combined with a token in localStorage gives an attacker a complete account takeover with no further steps required.
- Confirm the token type fits the use case. Short-lived JWTs suit stateless APIs. Opaque tokens suit sessions that need server-side revocation, because a JWT cannot be invalidated before its expiry without extra infrastructure.
- Check where the signing secret or private key comes from. It must be loaded from an environment variable. A secret hardcoded in the file is readable in version history even after it's removed.
Session Fixation and Regeneration
Every privilege change must regenerate the session ID. Login, role elevation, and password reset all count as privilege changes.
- Scan for authentication calls. If the session ID is the same before and after a login or re-authentication, the code is vulnerable to session fixation. An attacker can plant a known session ID and inherit the session once the user logs in.
- Confirm the old session is invalidated before the new one is created. Invalidating after creates a brief window where both session IDs are valid.
- Check the session ID generator. Session IDs must come from the framework's cryptographically secure pseudorandom number generator (CSPRNG). Application code that uses
Math.random()or a timestamp is not acceptable for this purpose.
Scope, Permissions, and Claims Validation
Every endpoint in the PR must verify that the token's scope permits the specific action being requested, not just that the token is structurally valid. Signature verification alone does not prevent privilege escalation.
- Look for middleware that checks "token is valid" but nothing else. Valid and authorised are two different things. A token signed correctly can still belong to a user with no permission to reach a given endpoint.
- Check the
algfield validation for JWTs. The server must validate the algorithm against an allowlist. Acceptingnoneas an algorithm disables signature verification entirely and is a well-documented critical misconfiguration. - Confirm that identity comes from the verified claim, not a request parameter. If user-supplied data is being used to look up a user ID, an attacker can substitute their own value. The identity must come from the token claim after the signature is verified.
- Check new roles or permission flags for rejection tests. If the PR adds a new flag, there must be a test that explicitly proves a user without that flag is rejected, not just that a user with it succeeds.
For a broader view of how security bugs fit into a structured review, a code review checklist built around bug classes organises defects by type rather than by file location.
Logout and Revocation
A logout that only clears the client-side cookie or in-memory token is incomplete. The server must also invalidate the session or token.
- Check for server-side invalidation on logout. Clearing a cookie removes the client's copy. It does nothing to a token an attacker already captured.
- For stateless JWTs, confirm a revocation mechanism exists. Options include a denylist keyed on the token's
jticlaim or a version counter stored against the user record that must match the token's claim. Without one, a stolen JWT remains valid until natural expiry. - Check that "sign out everywhere" clears all sessions, not only the current device. If the PR is implementing that feature, verify the data layer actually touches all session records for the user.
- Confirm a password reset or account lockdown hits the same invalidation path as logout. An attacker who already holds a valid token must lose access immediately when the account state changes.
Transport and Cookie Attributes
Tokens and session IDs must travel only over HTTPS, and every cookie that carries them needs the Secure, HttpOnly, and SameSite attributes set explicitly in code.
- Check
SameSitecarefully.Strictblocks the cookie on all cross-site requests, which breaks some OAuth redirect flows.Laxis the practical default for most applications.NonerequiresSecureand is appropriate only for explicitly cross-site use cases. - Look for tokens passed as URL query parameters. Query strings appear in server logs, browser history, and
Refererheaders. Any redirect in the PR that puts a token in the URL is a problem. - Verify the cookie's
DomainandPathare scoped narrowly. A token valid for/api/paymentsshould not be readable by/marketing. Broad scopes increase the blast radius of any other vulnerability on the same domain.
Testing the Changes
A PR that changes session or token handling without updating the security tests should not be merged. The test suite is part of the change.
- Check for rejection tests, not just acceptance tests. A test that logs in successfully proves the happy path works. A test that confirms an expired token gets a
401proves the expiry logic actually runs. - Look for a scope boundary test. The PR should include a test that sends a valid token to an endpoint the token's scope does not cover and asserts a
403, not a401. - Check that no existing security test is disabled or commented out. A passing build achieved by removing a test is a reason to block the merge, not approve it.
- Confirm the logout and revocation path has end-to-end coverage. Happy-path login tests are common. Tests that confirm a revoked token is rejected on the next request are far less common and far more valuable.
Building the habit of catching these issues before approval is a skill, not a checklist you apply mechanically. Code review skills that compound over a career explains which review habits keep improving and which ones plateau.
Frequently asked questions
What should be included in a code review?
A thorough code review covers correctness, security, performance implications, test coverage, and readability. For security-sensitive PRs like session and token changes, the security layer deserves its own pass before anything else, because those defects are the most expensive to fix after deployment.
What is a good prompt for a code review?
A useful review prompt names the specific risk category you're checking, not just the file. For session and token changes, a prompt like "does this endpoint verify scope, not just signature?" produces a more focused review than "check the auth code". What makes a code review comment actionable instead of just correct covers how to turn an observation into a comment the author can act on.