Skip to content

fix: hard-fail when GOOGLE_CLIENT_ID set but NEXTAUTH_SECRET is empty #2

@shrwnsan

Description

@shrwnsan

Problem

When a deployer configures Google OAuth by setting GOOGLE_CLIENT_ID but forgets NEXTAUTH_SECRET, NextAuth falls back to an empty string secret (process.env.NEXTAUTH_SECRET ?? ""). This means JWTs are effectively unsigned — anyone who knows the signing algorithm (HS256) can forge session tokens and impersonate any user.

Eval: eval-006 (HIGH)
Upstream status: Partially addressed by PR onecli#173 (removed auto-generated fallback), but the empty string fallback remains.

Current Behavior

// lib/env.ts
export const NEXTAUTH_SECRET = process.env.NEXTAUTH_SECRET ?? "";
// proxy.ts getSetupError()
// Only checks: secret set + no Google → "oauth-misconfigured"
// Does NOT check: Google set + no secret → silent misconfiguration

Proposed Fix

Add an inverse check in getSetupError():

// Google OAuth is configured but NEXTAUTH_SECRET is missing
if (GOOGLE_CLIENT_ID && !NEXTAUTH_SECRET) {
  return "missing-nextauth-secret";
}

Redirect to /setup-error?code=missing-nextauth-secret with instructions to generate a secret via openssl rand -hex 32.

Scope

  • apps/web/src/proxy.ts — add new setup error check
  • apps/web/src/app/setup-error/page.tsx — add error description

Tests

4 tests covering all env combinations:

  • Both set → no redirect (valid OAuth mode)
  • Neither set → no redirect (local mode)
  • Secret only → oauth-misconfigured
  • Google only → missing-nextauth-secret (NEW)

Branch

fix/nextauth-secret — based on integration branch

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions