Two active auth libraries means two independent systems of record for who a user is. Password reset may work in NextAuth but silently fail for Clerk-authenticated users. Session revocation on logout may only fire in one library, leaving valid sessions alive in the other. OWASP A07 (Identification & Authentication Failures) and CWE-287 both flag fragmented identity systems as a direct path to authentication bypass — attackers can exploit the gap between which library enforces your authorization checks and which issued the session token they forged. Every route that trusts the wrong library is unprotected.
Critical because split auth systems produce routes that enforce access control against a session they didn't issue, creating authentication bypass vulnerabilities exploitable without credentials.
Pick one auth library and route every session lookup through it. Delete the runner-up's session-getting code, consolidate into a single src/lib/auth.ts helper, then npm uninstall the discarded package.
// src/lib/auth.ts — single canonical session helper
import { getServerSession } from 'next-auth'
import { authOptions } from './auth-options'
export function getSession() {
return getServerSession(authOptions)
}
Search for any remaining imports of the removed library with grep -r "@clerk/nextjs\|lucia" src/ and eliminate them before deploying.
ID: ai-slop-code-drift.data-auth-drift.dual-auth
Severity: critical
What to look for: Apply the three-condition rule against this exact auth allowlist: next-auth, @auth/core, @auth/nextjs, @clerk/nextjs, @clerk/clerk-react, @clerk/clerk-sdk-node, lucia, @lucia-auth/adapter-prisma, @supabase/auth-helpers-nextjs, @supabase/ssr, firebase (with auth import), firebase-admin, @auth0/nextjs-auth0, auth0, better-auth, @kinde-oss/kinde-auth-nextjs, @workos-inc/authkit-nextjs, iron-session, cookie-session, passport. Before evaluating, extract and quote the exact package names found in package.json dependencies matching the allowlist. Count all that meet all three conditions (at least 1 non-escape-hatch importing file). Report the package names and file counts for each library.
Detector snippet (shell-capable tools only): If the tool has shell access, list every source file that imports one of the allowlisted auth libraries. Group by library and count distinct files per library. If rg is not installed or exits >=2, fall back to prose reasoning above.
rg -l -e "from ['\"]next-auth" -e "from ['\"]@auth/" -e "from ['\"]@clerk/" -e "from ['\"]lucia" -e "from ['\"]@supabase/auth" -e "from ['\"]@auth0/" -e "from ['\"]better-auth" -e "from ['\"]passport" src/
Pass criteria: 0 or 1 auth libraries from the allowlist are actively used. When 1 is found, quote its name and report: "Canonical auth: [name] ([N] importing files)."
Fail criteria: 2 or more auth libraries actively used — sessions split across systems, password reset works for one but not the other, security model fragmented.
Do NOT pass when: A custom JWT helper file exists alongside an auth library AND both have non-trivial import counts — count the custom helper as a second auth approach.
Skip (N/A) when: 0 auth libraries from the allowlist appear in RUNTIME_DEPS.
Cross-reference: For deeper authentication flow analysis, the SaaS Authentication audit (saas-authentication) covers session management and auth security in depth.
Detail on fail: "2 active auth libraries detected: 'next-auth' (5 importing files) AND '@clerk/nextjs' (7 importing files). Sessions are split between systems — users may be logged in to one but not the other."
Remediation: Multiple auth libraries means two systems of record for "who is the user." Pick one and migrate:
// Bad: src/lib/auth.ts uses NextAuth, src/lib/clerk.ts uses Clerk
// Pick one approach and consolidate ALL session logic there.
// Good: a single src/lib/auth.ts that wraps your chosen provider
import { auth } from '@/lib/auth' // single import everywhere
Pull the loser's session-getting code into a single migration file, route all session lookups through one helper, then npm uninstall the loser.