Cross-Site Scripting (XSS), malicious script injection, and third-party dependency hijacking remain among the top vulnerabilities targeting modern full-stack web applications. In a React and Next.js 15 environment where inline scripts, hydration payloads, and analytics trackers are routinely rendered into the DOM, relying on default security configurations leaves your users vulnerable to session hijacking and credential theft. In 2026, implementing a strict, dynamic Content Security Policy (CSP) with cryptographic nonces is mandatory for enterprise security.
Historically, configuring a strict CSP on modern single-page applications broke inline styles and hydration scripts unless developers dangerously allowed 'unsafe-inline'. Next.js 15 introduces seamless support for generating per-request cryptographic nonces inside Edge Middleware, attaching nonces to all internal scripts and enforcing strict origin verification. This production hardening guide walks through complete middleware implementation, Subresource Integrity (SRI) hashing, and HTTP security header configuration.
The Anatomy of a Production-Grade Content Security Policy
A zero-trust CSP restricts resource loading to explicitly verified origins and cryptographic hashes:
| CSP Directive | Security Bound Enforced | Risk Mitigated |
|---|---|---|
default-src 'self' |
Restricts all unspecified resources to the same origin | Prevents unauthorized external asset loading |
script-src 'nonce-{RANDOM}' 'strict-dynamic' |
Executes ONLY scripts carrying the exact matching per-request nonce | Completely neutralizes XSS; blocks malicious injected script tags |
object-src 'none' |
Disables plugins like Flash, Java, or embedded ActiveX | Eliminates legacy browser plugin exploits |
base-uri 'self' |
Restricts URLs allowed in document <base> elements |
Prevents base-tag hijacking of relative hyperlinks |
Step 1: Generating Per-Request Cryptographic Nonces in Middleware
In Next.js 15, generate a random Base64 cryptographic nonce in middleware.ts using the native Web Crypto API and inject it into both the CSP header and internal request headers:
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// 1. Generate 128-bit cryptographically secure random nonce
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
// 2. Construct strict Content Security Policy
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic' https: http: 'unsafe-inline';
style-src 'self' 'nonce-${nonce}' https://fonts.googleapis.com;
img-src 'self' blob: data: https:;
font-src 'self' https://fonts.gstatic.com;
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`.replace(/\s{2,}/g, ' ').trim();
// 3. Set request headers for internal Next.js layout consumption
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-nonce', nonce);
requestHeaders.set('Content-Security-Policy', cspHeader);
const response = NextResponse.next({
request: {
headers: requestHeaders,
},
});
// 4. Attach security headers to outgoing response
response.headers.set('Content-Security-Policy', cspHeader);
response.headers.set('X-Frame-Options', 'DENY');
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
response.headers.set(
'Strict-Transport-Security',
'max-age=63072000; includeSubDomains; preload'
);
return response;
}
export const config = {
matcher: [
{
source: '/((?!api|_next/static|_next/image|favicon.ico).*)',
missing: [
{ type: 'header', key: 'next-router-prefetch' },
{ type: 'header', key: 'purpose', value: 'prefetch' },
],
},
],
};
Step 2: Reading the Nonce Inside the Root Layout
Read the generated nonce from request headers and attach it to your application shell and inline scripts:
// app/layout.tsx
import { headers } from 'next/headers';
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const nonce = headers().get('x-nonce') || undefined;
return (
<html lang="en">
<head nonce={nonce}>
<meta charSet="utf-8" />
</head>
<body nonce={nonce} className="bg-slate-950 text-slate-100">
{children}
</body>
</html>
);
}
Subresource Integrity (SRI) for Third-Party Scripts
When loading third-party scripts from external CDNs (e.g., Stripe.js or payment gateways), enforce Subresource Integrity hashes to ensure compromised CDN files cannot execute malicious code:
<!-- Cryptographic verification of external script payload -->
<script
src="https://cdn.jsdelivr.net/npm/chart.js@4.4.2/dist/chart.umd.min.js"
integrity="sha384-2N+60n...your_sha384_hash_here..."
crossorigin="anonymous">
</script>
Testing CSP Compliance with Automated Scanners
Verify your security posture using Mozilla Observatory or Google’s CSP Evaluator. A properly nonced Next.js 15 deployment achieves an A+ Security Rating with zero high-severity findings.
Conclusion
Web security cannot rely on wishful thinking; it requires programmatic defense-in-depth. By automating cryptographic nonces in Next.js 15 Edge Middleware, enforcing strict CSP directives, and applying Subresource Integrity, you construct an impenetrable perimeter that defends user data and maintains institutional trust.

Saizul Amin is a digital growth strategist and SEO consultant specialising in search engine optimisation, web development, AI-powered automation, and online income systems. With 8 years of hands-on experience helping businesses and individual creators grow their online presence, Saizul combines technical expertise with practical, results-driven strategy.
Experience & Background
Saizul started his digital career in 2017, initially working with Bioscope Limited to build and optimise websites for organic search traffic. Over the years, he has worked across industries including DGHS, NAVANA, UNICampus, UNIPathways, UniqueMark, developing a deep understanding of what it takes to rank, convert, and grow sustainably online.
His work spans the full digital stack — from technical SEO audits and content strategy to WordPress development, marketing automation, and AI tool integration for small businesses and startups.
What He Covers on This Blog
Every article on SaizulAmin.com is written from direct experience. Saizul does not publish theoretical content — every guide, tool recommendation, and strategy shared here has been tested and applied in real projects. Topics include:
- Search engine optimisation (on-page, technical, and content SEO)
- Digital marketing strategy and growth systems
- AI tools and automation for business productivity
- Web development, WordPress, and website building
- Making money online through freelancing and affiliate marketing
Why Trust This Content
All recommendations on this site reflect tools and strategies Saizul actively uses or has personally evaluated. Where affiliate relationships exist, they are clearly disclosed. Content is regularly reviewed and updated to reflect current best practices and algorithm changes.
