Next.js security protects your users and backend data from Cross-Site Scripting (XSS), leaked credentials, and unauthorized Server Action calls. React escapes JSX text by default, so basic string interpolation is safe, while headers and server boundaries require careful setup.
Treating every browser boundary as untrusted keeps secrets safe and blocks injection attacks before they reach your database.
middleware.tsApply Content Security Policy (CSP) and frame protection headers in middleware.ts so browsers only execute approved scripts and cannot embed your app in hidden iframes.
// middleware.ts
import { NextResponse } from 'next/server';
export function middleware() {
const response = NextResponse.next();
const csp = [
"default-src 'self'",
"script-src 'self' 'unsafe-inline'",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: https:",
"object-src 'none'",
"frame-ancestors 'none'",
].join('; ');
response.headers.set('Content-Security-Policy', csp);
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
return response;
}
Next.js keeps environment variables private on the server unless you prefix the variable name with NEXT_PUBLIC_. Never add NEXT_PUBLIC_ to database passwords, JWT secrets, or private API tokens.
DATABASE_URL="postgresql://user:pass@localhost:5432/app"
STRIPE_SECRET_KEY="sk_live_example_key"
NEXT_PUBLIC_SITE_URL="https://example.com"
If you must render rich HTML authored by users or a third-party editor, sanitize the markup with isomorphic-dompurify before using dangerouslySetInnerHTML.
// app/components/SafeRichText.tsx
import DOMPurify from 'isomorphic-dompurify';
export default function SafeRichText({ html }: { html: string }) {
const cleanHtml = DOMPurify.sanitize(html);
return <div dangerouslySetInnerHTML={{ __html: cleanHtml }} />;
}
'use client' files: Install the server-only package and import 'server-only' at the top of secret modules so builds fail fast if accidentally bundled for the browser..env.local files to Git: Keep .env* secrets out of version control and store production keys in your hosting provider's secret manager.Next.js verifies the Origin and Host headers on Server Action POST requests and restricts them to POST, helping mitigate CSRF by default.
server-only add anything to my runtime bundle?No, server-only is a zero-runtime marker package that triggers a clear build error if a Client Component imports that file.
No, map database rows into explicit DTO objects containing only public fields before passing props to 'use client' components.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With