Blog
Security review checklist for PRs touching authentication
Alex Mercer
Mar 5, 2026
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.
The data tells an astonishing story. Authentication Failures rank #7 in OWASP Top 10 2025, spanning 36 Common Weakness Enumerations. In 2024 alone, over 500,000 Roku accounts were compromised through credential stuffing, Australian Super members lost AUD $500,000 to auth attacks, and even Norton's password manager was breached through credential-based vulnerabilities.
PRs that touch authentication deserve a closer look. This checklist provides the security controls that secure code review must enforce when authentication code changes.
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.
Teams using AI-powered code review tools report finding 3-5x more authentication bugs before production compared to manual review alone.
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=Strict flags. Secure code review checklists emphasize these as non-negotiable:
// 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', // Prevents CSRF maxAge: 7200000 // 2 hour absolute timeout }); |
JWT vulnerabilities: What to check
JSON Web Tokens power authentication in modern APIs, but JWT vulnerabilities are pervasive. Six critical CVEs targeting JWT libraries were disclosed in 2025 alone, affecting cloud platforms and enterprise systems.
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', 'RS256'] // Rejects "none" }); |
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 } |
This exact bug enabled a B2B SaaS breach where attackers modified JWT payloads to access other users' data for four months before discovery.
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); // Old tokens work forever // 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 2025 Cryptographic Failures (A04) explicitly disallows MD5, SHA-1, DES, 3DES, and RC4:
// 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.
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 their OpenClaw security audit, cubic's continuous scanning found four critical authentication vulnerabilities, including an allowlist bypass and credential fallback logic that was too permissive, 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:
Session tokens: 64+ bits entropy, regenerated post-login, secure cookie flags
JWT validation: Explicit algorithm whitelist, signature verification, expiration enforcement
Credentials: No hardcoded secrets, approved hashing algorithms (bcrypt ≥12, Argon2)
Authorization: Ownership checks on all data access, role verification on privileged operations
Cross-file consistency: New code follows established patterns across the repository
Manual review catches points 1-4 if reviewers remember to check. AI for code review catches point 5 automatically by analyzing your entire codebase for pattern violations.
The authentication security gap
Authentication vulnerabilities rank #7 in OWASP's top threats because they're simultaneously common and catastrophic. 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 3-5x more authentication bugs before production 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.
