Securing Next.js + Supabase, in depth
The specific mistakes that get apps on this stack hacked — and the exact fix for each. No generic checklists.
- ·7 min read
Next.js latest safe version: 16.4.1+ or 15.5.28+
The latest safe Next.js versions are 16.4.1+ on 16.x and 15.5.28 on 15.x, patched for critical RCEs on October 14, 2026. No 16.3.x or 14.x is fixed.
Next.jsCVEDependenciesSecurity Releases - ·7 min read
Next.js remotePatterns: there is no safe "allow all"
In next/image remotePatterns, hostname '*' and '**' both match every host, so /_next/image will fetch from any URL. Pin exact hosts and paths instead.
Next.jsImagesSSRFSupabaseSecurity - ·9 min read
Supabase Edge Function 401 Invalid JWT: the safe fix
A 401 Invalid JWT from a Supabase Edge Function comes from the platform's verify_jwt check. Turning it off is safe only if your code verifies the caller.
SupabaseEdge FunctionsAuthJWT - ·8 min read
"url" parameter is not allowed: Next.js 16 next/image
Next.js 16 returns "url" parameter is not allowed when an image host resolves to a private IP; gate dangerouslyAllowLocalIP to next dev, never commit true.
Next.jsImagesSSRFSupabaseSecurity - ·9 min read
Supabase webhook secret: DB webhooks aren't signed
There is no Supabase Database Webhook secret to find: the requests are unsigned, so send your own token header and check it with timingSafeEqual.
SupabaseWebhooksNext.jsSecretsSecurity - ·7 min read
Fix "Legacy API keys are disabled" in Supabase
Supabase's 'Legacy API keys are disabled' means a client sent an old anon or service_role JWT; give that client a new key instead of re-enabling the old pair.
SupabaseAPI KeysSecretsMigrations - ·7 min read
Supabase: Public Can Execute SECURITY DEFINER Function
The warning means anon can call a SECURITY DEFINER function over RPC, and revoking from anon alone won't clear it: revoke from public, anon and authenticated.
SupabasePostgresSECURITY DEFINERSecurity AdvisorGrants - ·7 min read
Next.js open redirect: why startsWith('/') fails
A Next.js redirect to a ?next= or returnTo param is an open redirect, and startsWith('/') won't stop /\evil.com. Check the parsed origin instead.
Next.jsOpen RedirectAuthSecurity - ·8 min read
Rate limiting a Next.js server action (Supabase)
Next.js has no built-in rate limiter, and Server Actions are public POST endpoints. Limit by IP in a shared store, and close the Supabase anon-key back door.
Next.jsServer ActionsSupabaseRate LimitingSecurity - ·7 min read
React2Shell in Next.js: affected versions and the fix
React2Shell (CVE-2025-55182) is a CVSS 10 RCE in Next.js 15.x and 16.x App Router apps. Check if your version was affected, patch it, and rotate secrets.
Next.jsCVEReact Server ComponentsDependenciesSupabase - ·7 min read
use server vs server-only: they're opposites
"use server" doesn't mean server-only. It makes functions callable from the browser. Use import "server-only" to keep a module off the client.
Next.jsServer ActionsSupabaseSecurity - ·7 min read
Next.js 16: middleware.ts is now proxy.ts
Next.js 16 deprecates middleware.ts in favour of proxy.ts. Here's the codemod, the Node-runtime trap, and the security checks that silently stop matching.
Next.jsMiddlewareMigrationAuthSecurity - ·7 min read
Next.js 16 auth: proxy.ts is the wrong place
Next.js 16's Proxy can be deployed to your CDN, separate from your app — an optimization layer, not an authorization boundary. Here's where checks belong.
Next.jsAuthProxyServer ActionsSecurity - ·7 min read
Supabase 22P02: invalid input syntax for uuid
Error 22P02 means a non-uuid string reached a uuid column — usually an empty string from a form. Validate at the edge; never cast the column to text.
SupabasePostgresValidationRLSNext.js - ·8 min read
Supabase UPDATE policy: the WITH CHECK (true) trap
An UPDATE policy needs no WITH CHECK — Postgres reuses USING. Adding WITH CHECK (true) is what lets a user hand their row to someone else.
SupabaseRLSPostgresPoliciesSecurity