All Docs
FeaturesMaking Tax DigitalUpdated March 11, 2026

Security Advisory: Migration Endpoint Falls Back to NEXTAUTH_SECRET

Security Advisory: Migration Endpoint Falls Back to NEXTAUTH_SECRET

Version: 1.0.396
Severity: High
Framework: ISO 27001
Affected file: src/app/api/migrate/route.ts


Overview

A compliance audit identified a security misconfiguration in the /api/migrate endpoint. The endpoint authenticates incoming requests using the following logic:

MIGRATION_SECRET ?? NEXTAUTH_SECRET

When the MIGRATION_SECRET environment variable is not set, the endpoint silently accepts NEXTAUTH_SECRET as a valid authentication token. This behaviour was unintentional and widens the attack surface of a production system significantly.


What Is the Risk?

1. Expanded Blast Radius of a NEXTAUTH_SECRET Leak

NEXTAUTH_SECRET is the signing key for all user session tokens. Its exposure is already serious — an attacker with access to it can forge arbitrary session cookies. The fallback behaviour means the same secret also grants the ability to trigger database schema migrations over HTTP, compounding the impact of any leak substantially.

2. No Visibility Into the Insecure Configuration

Because the fallback is silent, operators have no way to know — from logs, startup output, or monitoring — whether a dedicated MIGRATION_SECRET is actually in use. A production system could be running in the insecure configuration indefinitely without any indication.

3. High Inherent Risk of HTTP-Triggered Migrations

Running arbitrary schema migrations via an HTTP endpoint is already a high-risk pattern in production environments. Coupling that endpoint to the session signing secret multiplies the risk further.


Recommended Remediation

Step 1 — Set a Dedicated MIGRATION_SECRET

Generate a strong, unique secret for migration endpoint authentication:

openssl rand -hex 32

Set this as the MIGRATION_SECRET environment variable in your production environment. Do not reuse NEXTAUTH_SECRET.

Step 2 — Remove the Fallback in Code

The fallback must be removed from src/app/api/migrate/route.ts. The endpoint should refuse to operate if MIGRATION_SECRET is not explicitly configured:

// Before (insecure)
const secret = process.env.MIGRATION_SECRET ?? process.env.NEXTAUTH_SECRET;

// After (required)
const secret = process.env.MIGRATION_SECRET;
if (!secret) {
  throw new Error(
    'MIGRATION_SECRET is not set. Refusing to expose migration endpoint without a dedicated secret.'
  );
}

Step 3 — Assert Secret Separation at Startup

Add a startup assertion to detect accidental reuse:

if (
  process.env.MIGRATION_SECRET &&
  process.env.MIGRATION_SECRET === process.env.NEXTAUTH_SECRET
) {
  throw new Error(
    'MIGRATION_SECRET must not equal NEXTAUTH_SECRET. Use a separate, unique secret for migration authentication.'
  );
}

Step 4 — Restrict Network Access (Recommended)

Apply IP allowlisting to the /api/migrate route so it is only reachable from your CI/CD infrastructure or a trusted internal network. This limits exposure even if the secret were leaked.

Step 5 — Consider Removing the HTTP Endpoint Entirely (Best Practice)

The most secure posture is to remove the /api/migrate HTTP endpoint altogether and run schema migrations exclusively as part of your CI/CD pipeline (e.g. a prisma migrate deploy step before the application starts). This eliminates the attack surface entirely.


Checklist for Production Operators

  • MIGRATION_SECRET is set to a unique value in all production environments
  • MIGRATION_SECRET does not equal NEXTAUTH_SECRET
  • The NEXTAUTH_SECRET fallback has been removed from src/app/api/migrate/route.ts
  • A startup assertion validates secret separation
  • Network access to /api/migrate is restricted to trusted sources, or the endpoint has been removed

References

  • ISO 27001 — A.9 Access Control
  • ISO 27001 — A.14 System Acquisition, Development and Maintenance
  • OWASP: Secrets Management