security: remove INSECURE_DEFAULT JWT_SECRET fallback - #1
Conversation
Both auth.ts and auth-edge.ts previously fell back to a hardcoded constant string when JWT_SECRET env var was missing. auth.ts had a production-only check that threw, but auth-edge.ts (used by middleware, runs in Edge runtime) had NO check — meaning if JWT_SECRET was accidentally unset on Vercel, middleware would silently use a publicly-known string for JWT verification. Anyone reading the public repo could forge valid JWTs in that scenario. Fix: remove INSECURE_DEFAULT entirely. Both files now throw at module load if JWT_SECRET is missing or shorter than 32 chars. This applies in dev and prod — fail fast, never silently use a known string. Vercel will mark the deployment as failed if JWT_SECRET is unset, which is the correct behavior (better a failed deploy than a silently-insecure one).
📝 WalkthroughWalkthroughBoth auth modules now validate ChangesJWT secret validation
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed: one or more packages not found in the registry. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/auth-edge.ts`:
- Around line 4-6: The security check in auth-edge is only triggered at runtime,
so the build can still pass when JWT_SECRET is missing. Update the build/deploy
flow by wiring the existing security:check script into the main build path (for
example in the package.json build script used by next build/vercel build) so the
required env var is validated before deployment; keep the check associated with
the auth-edge middleware startup path so the failure happens during build, not
first request.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 5dfaabec-4af0-4bf3-8797-1fa1d21a4ec2
📒 Files selected for processing (2)
src/lib/auth-edge.tssrc/lib/auth.ts
| // Edge runtime (middleware) imports this module, so the throw happens at | ||
| // middleware load time — Vercel will mark the deployment as failed if | ||
| // JWT_SECRET is unset, rather than silently using a known string. |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Description: Check whether JWT_SECRET validation is wired into build/deploy scripts.
# Expectation: package/vercel config should run scripts/security-check.js or an equivalent JWT_SECRET check before deployment succeeds.
fd -t f '^(package\.json|vercel\.json)$' . -x sh -c '
echo "== $1 ==";
if [ "$(basename "$1")" = "package.json" ]; then
jq ".scripts // {}" "$1"
else
cat "$1"
fi
' sh {}
rg -n -C2 'security-check|JWT_SECRET|next build|vercel' package.json vercel.json scripts/security-check.js 2>/dev/null || trueRepository: isaJrKai/planned
Length of output: 296
🏁 Script executed:
cd isaJrKai/planned
# Check package.json scripts directly
cat package.json | grep -A 20 '"scripts"'
# Check vercel.json content
cat vercel.json 2>/dev/null || echo "vercel.json not found"
# Check if security-check.js exists and what it does
cat scripts/security-check.js 2>/dev/null | head -30 || echo "security-check.js not found"
# Check Next.js middleware config or vercel build config for pre-deploy hooks
if [ -f vercel.json ]; then
cat vercel.json
fi
# Look for build hooks in next.config.js
grep -n 'vercel\|build\|env' next.config.js 2>/dev/null || echo "next.config.js not found or no relevant lines"Repository: isaJrKai/planned
Length of output: 2602
🏁 Script executed:
grep -r "security:check" . --include="*.json" --include="*.yml" --include="*.yaml" --include="*.js" --include="*.ts" 2>/dev/null | head -20Repository: isaJrKai/planned
Length of output: 225
🏁 Script executed:
grep -A5 -B5 "security" package.json vercel.json 2>/dev/null || grep -n "security" package.json
grep -n "postbuild\|prebuild" package.json 2>/dev/null || echo "No prebuild/postbuild hooks"
ls -la scripts/ 2>/dev/null || echo "No scripts directory"Repository: isaJrKai/planned
Length of output: 1091
Verify build/deploy pipeline invokes the security check
The security:check script exists but is not wired into next build, vercel build, or any postinstall hook. Consequently, if JWT_SECRET is missing on Vercel, the build will not fail immediately; the error will occur only at runtime (when the middleware first executes).
Please explicitly fail the build if a required environment variable is missing by running the check as part of the build script.
{
"package.json": {
"scripts": {
"build": "security:check && prisma generate && next build"
}
}
}Alternatively, enforce the check in vercel.json using a build hook if available, though modifying package.json scripts is the standard approach for Next.js projects.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/lib/auth-edge.ts` around lines 4 - 6, The security check in auth-edge is
only triggered at runtime, so the build can still pass when JWT_SECRET is
missing. Update the build/deploy flow by wiring the existing security:check
script into the main build path (for example in the package.json build script
used by next build/vercel build) so the required env var is validated before
deployment; keep the check associated with the auth-edge middleware startup path
so the failure happens during build, not first request.
What this fixes
Removes the
INSECURE_DEFAULThardcoded JWT secret fallback from bothsrc/lib/auth.tsandsrc/lib/auth-edge.ts.The vulnerability
Previously, both files contained:
auth.tshad a production-only check that threw ifJWT_SECRETwas missing — so the fallback only fired in dev.auth-edge.ts(used by middleware, runs in Edge runtime) had no such check — ifJWT_SECRETwas accidentally unset on Vercel, middleware would silently use the hardcoded string for JWT verification.Since this repo is public, anyone could read the source, see the
INSECURE_DEFAULTconstant, and forge valid JWTs against any deployment whereJWT_SECRETwas misconfigured.The fix
INSECURE_DEFAULTconstant entirely from both files.JWT_SECRETis missing or shorter than 32 characters.JWT_SECRETis unset, which is the correct behavior (better a failed deploy than a silently-insecure one).Files changed
src/lib/auth.ts— removed fallback + production-only check, replaced with unconditional throwsrc/lib/auth-edge.ts— same treatment, plus explanatory comment about Edge runtime behavior+21 / -11 lines across 2 files.
Verification
npx tsc --noEmit— cleannpx eslint src/lib/auth.ts src/lib/auth-edge.ts— cleanJWT_SECRETis unsetPre-deploy checklist
Before merging, verify on Vercel:
JWT_SECRETis set for Production (should be a 64+ char random string)node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))"If
JWT_SECRETis already set correctly on Vercel (which it should be — the app is currently working), this PR is safe to merge with zero downtime.Summary by CodeRabbit