Blog

Security review checklist for PRs touching authentication

Why authentication PRs require specialized security scrutiny, and how automated code review tools catch what manual reviews miss.

Alex Mercer

Why authentication PRs require specialized security scrutiny, and how automated code review tools catch what manual reviews miss

The authentication code is the gateway to your entire system. A single overlooked vulnerability in a login flow, session handler, or token validator can compromise every user account in your application. Yet teams routinely ship authentication changes with the same review process they use for UI tweaks or database migrations.

Authentication Failures ranks #7 in the OWASP Top 10 2025, spanning 36 Common Weakness Enumerations. OWASP calls credential stuffing, the use of lists of known username and password combinations, "now a very common attack" and recommends multi-factor authentication to prevent it. For the other nine categories, see our guide to the OWASP Top 10 2025.

PRs that touch authentication deserve a closer look. This checklist provides the security controls that secure code review must enforce when authentication code changes. Use it the same way when a coding agent wrote the change, and also check for the security risks in AI-written code, such as made-up dependencies and overly broad permissions. Bug Bench shows how AI models compare on security and privacy bugs in the code cubic reviews.

TLDR

  • Authentication vulnerabilities in PRs often go unnoticed because reviewers focus on functionality rather than security edge cases. 

  • Critical issues include JWT signature bypass, session fixation, hardcoded credentials, improper token validation, and weak password policies. 

  • Code review automation platforms with continuous codebase scanning catch these vulnerabilities by analyzing authentication flows across your entire repository, not just the changed lines. 

Session management: The foundation

A general code review checklist is helpful, but authentication changes require more focused security checks, starting with how you handle sessions. Session tokens are the keys to your system. Get them wrong, and attackers can hijack user accounts.

Token generation requirements:

OWASP Session Management guidelines specify that session tokens must use cryptographically secure random generators with at least 64 bits of entropy (128+ recommended in modern systems). Here's what vulnerable token generation looks like:

// VULNERABLE: Predictable session ID

function generateSessionId() {

  return `sess_${Date.now()}_${Math.random()}`;

}



// SECURE: Cryptographically random with sufficient entropy

const crypto = require('crypto');

function generateSessionId() {

  return crypto.randomBytes(32).toString('hex'); // 256 bits entropy

}


The vulnerable version uses Date.now() (predictable timestamps) and Math.random() (not cryptographically secure). Attackers can predict or brute-force these tokens. The secure version uses crypto.randomBytes(), providing 256 bits of entropy - far exceeding the 64-bit minimum.

Session fixation prevention:

CWE-384 Session Fixation occurs when applications don't regenerate session IDs after authentication. Check for this pattern in authentication PRs:

// VULNERABLE: Reuses pre-login session ID

app.post('/login', (req, res) => {

  const user = authenticateUser(req.body);

  if (user) {

    req.session.userId = user.id; // Session ID unchanged!

    res.json({ success: true });

  }

});



// SECURE: Regenerates session post-login

app.post('/login', (req, res) => {

  const user = authenticateUser(req.body);

  if (user) {

    req.session.regenerate((err) => {

      req.session.userId = user.id;

      res.json({ success: true });

    });

  }

});

Cookie security attributes:

Every authentication cookie must include Secure, HttpOnly, and SameSite flags. OWASP's Session Management Cheat Sheet calls Secure and HttpOnly mandatory and says session cookies must set SameSite=Strict (preferred) or SameSite=Lax:

// VULNERABLE: Missing security flags

res.cookie('session', sessionId);



// SECURE: All security attributes present

res.cookie('session', sessionId, {

  httpOnly: true,      // Prevents XSS from reading token

  secure: true,        // HTTPS only

  sameSite: 'strict',  // Defense in depth against CSRF, not a replacement for CSRF tokens

  maxAge: 7200000      // Cookie lifetime only; enforce the 2-hour absolute timeout on the server

});


JWT vulnerabilities: What to check

JSON Web Tokens power authentication in modern APIs, and JWT libraries have had serious flaws. In jsonwebtoken 8.5.1 and earlier, calling jwt.verify() without an algorithms list could fall back to the none algorithm and skip signature validation (CVE-2022-23540). A key lookup function that served both symmetric and asymmetric keys could also let forged tokens pass verification with HS256 (CVE-2022-23541). Version 9.0.0 fixes both.

Algorithm confusion and "none" bypass:

The most dangerous JWT vulnerability is accepting the "none" algorithm, which disables signature verification entirely. OWASP JWT Testing Guide documents this attack:

// VULNERABLE: Doesn't specify expected algorithms

const decoded = jwt.verify(token, secret);



// SECURE: Explicitly whitelists algorithms

const decoded = jwt.verify(token, secret, {

  algorithms: ['HS256'] // Pin the one algorithm your key uses; never accept HMAC and RSA for the same key

});


Signature validation bypass:

Developers sometimes use jwt.decode() instead of jwt.verify(), completely bypassing signature validation:

// CRITICAL VULNERABILITY: No signature verification

const payload = jwt.decode(token); // Just base64 decodes!

if (payload.userId) {

  // Attacker can forge any user ID

}



// SECURE: Verifies signature before trusting payload

try {

  const payload = jwt.verify(token, SECRET_KEY);

  if (payload.userId) {

    // Token cryptographically verified

  }

} catch (err) {

  // Invalid signature rejected

}

OWASP's testing guide calls this "one of the most serious vulnerabilities encountered with JWTs."

Token expiration and claims validation:

JWTs must validate iat (issued-at), nbf (not-before), and exp (expiration) claims:

// VULNERABLE: No expiration enforcement

const payload = jwt.verify(token, secret);

// Tokens signed without an exp claim never expire



// SECURE: Enforces expiration + reasonable lifetime

const payload = jwt.verify(token, secret, {

  maxAge: '2h', // Tokens expire after 2 hours

  clockTolerance: 30 // 30 second clock skew tolerance

});



// Verify claims explicitly

if (!payload.exp || payload.exp < Date.now() / 1000) {

  throw new Error('Token expired');

}


Password and credential security

CWE-798 Use of Hard-coded Credentials and CWE-259 Use of Hard-coded Password are among the 36 CWEs mapped to Authentication Failures.

Hardcoded secrets detection:

# CRITICAL: Hardcoded API key

API_KEY = "sk_live_4eC39HqLyjWDarjtT1zdp7dc"



# CRITICAL: Hardcoded database password

db = psycopg2.connect(

    host="db.prod.com",

    password="SuperSecret123!"

)



# SECURE: Environment variables

import os

API_KEY = os.getenv('API_KEY')

db = psycopg2.connect(

    host=os.getenv('DB_HOST'),

    password=os.getenv('DB_PASSWORD')

)


Code review platforms with secrets detection capabilities scan for these patterns automatically.

cubic's codebase scans go further; they trace how credentials flow through your entire codebase, catching cases where secrets are passed through multiple files before being used insecurely.

Password hashing standards:

Never use deprecated algorithms. OWASP's 2025 Cryptographic Failures category (A04) says to avoid deprecated cryptographic functions such as MD5 and SHA1, and to store passwords with a strong adaptive, salted hash that has a work factor, such as Argon2, yescrypt, scrypt or PBKDF2-HMAC-SHA-512. For bcrypt, which OWASP's Password Storage Cheat Sheet limits to legacy systems, use a work factor of 10 or more:

// VULNERABLE: Weak hashing

const hash = crypto.createHash('md5')

  .update(password).digest('hex');



// SECURE: bcrypt with appropriate cost

const bcrypt = require('bcrypt');

const hash = await bcrypt.hash(password, 12); // Cost factor 12

Authorization bypass patterns

Authentication handles who you are. Authorization handles what you can do. PRs touching auth often conflate these.

Missing ownership checks:

// VULNERABLE: No ownership verification

app.delete('/api/documents/:id', authenticateUser, async (req, res) => {

  await db.documents.delete(req.params.id);

  // Any authenticated user can delete ANY document!

});



// SECURE: Verifies ownership before action

app.delete('/api/documents/:id', authenticateUser, async (req, res) => {

  const doc = await db. documents.findOne({

    id: req.params.id,

    ownerId: req.user.id // Ownership check

  });

  if (!doc) return res.status(404).send('Not found');

  await db.documents.delete(req.params.id);

});


This is where AI-based coding analysis excels. Automated code review tools trace data flows across your entire repository, identifying where user input (like req.params.id) reaches sensitive operations without authorization checks. cubic's API auth and tenant scoping agent, for example, flags endpoints that skip auth or trust a client-supplied account or tenant ID instead of the session.

What continuous codebase scanning catches

Manual PR review examines changed lines. But authentication vulnerabilities often exist in unchanged code that interacts with new changes. This is where continuous scanning becomes critical.

cubic's codebase scans run thousands of AI agents continuously across your full repository, finding:

  • Cross-file auth bypasses: Where a new API endpoint lacks authentication middleware that other endpoints use

  • Inconsistent token validation: Where some routes verify JWTs correctly, while others use vulnerable patterns

  • Session management drift: Where new code introduces different session handling than established patterns

In cubic's OpenClaw security audit, a single codebase scan found four exploitable vulnerabilities, including a voice allowlist bypass and a credential fallback that was too permissive. Both were business logic errors that looked reasonable in isolation but broke under security scrutiny.

The difference between PR review and continuous scanning:

PR review: "Does this new login endpoint hash passwords correctly?"

Continuous scanning: "This new endpoint uses bcrypt cost 10, but your 47 other endpoints use cost 12. Also, three endpoints in /admin routes lack the requireAdmin middleware that all other admin routes use."

Implementing an authentication security checklist

For every PR touching authentication:

  1. Session tokens: 64+ bits entropy, regenerated post-login, secure cookie flags

  2. JWT validation: Explicit algorithm whitelist, signature verification, expiration enforcement

  3. Credentials: No hardcoded secrets, approved hashing algorithms (bcrypt ≥12, Argon2)

  4. Authorization: Ownership checks on all data access, role verification on privileged operations

  5. Cross-file consistency: New code follows established patterns across the repository

Manual review catches points 1-4 if reviewers remember to check. AI code review catches point 5 automatically by analyzing your entire codebase for pattern violations.

The authentication security gap

Authentication Failures has held #7 in the OWASP Top 10 since 2021. A single unvalidated JWT or a missing ownership check can compromise your entire user base.

Manual code review struggles with authentication security because reviewers must remember dozens of security rules while also evaluating functionality, performance, and maintainability. Critical checks get missed under deadline pressure.

Code review automation solves this by encoding security knowledge into specialized agents that never forget to check. These systems analyze authentication flows across your entire repository, catching vulnerabilities that only emerge from how multiple files interact.

Teams serious about authentication security use both manual review (for business logic and design decisions) and automated code review tools (for systematic security verification). The combination catches more than either approach alone.

Ready to scan your authentication code for vulnerabilities?

Book a demo to see how continuous codebase scanning finds authentication bugs that PR reviews miss.

Table of contents