Next.js中CSP Header实现疑问:Nonce不显示及unsafe-*使用问题
CSP配置问题解答
1. 正确的CSP实现方式
优先采用Middleware + Nonce的方案,这是生产环境最安全的实现方式,你之前的代码问题在于没有将构建好的CSP头添加到响应中。
修正后的Middleware配置示例
import { NextRequest, NextResponse } from 'next/server'; import crypto from 'crypto'; export function middleware(request: NextRequest) { // 生成随机Nonce const nonce = Buffer.from(crypto.randomUUID()).toString('base64'); // 构建CSP规则,移除换行并格式化 const cspHeader = ` default-src 'self' https://www.google.com/ https://test.com https://*.stripe.com; script-src 'self' 'nonce-${nonce}' 'strict-dynamic' https://test.com https://*.stripe.com https://js.stripe.com; style-src 'self' 'nonce-${nonce}' https://test.com https://*.stripe.com https://js.stripe.com; connect-src 'self' https://test.com https://*.stripe.com https://js.stripe.com; img-src 'self' blob: data:; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests; `.replace(/\n/g, '').trim(); // 创建响应并设置CSP头 const response = NextResponse.next(); response.headers.set('Content-Security-Policy', cspHeader); // 将Nonce传递给页面,用于script/style标签 response.headers.set('X-Nonce', nonce); return response; } // 匹配所有路由应用Middleware export const config = { matcher: ['/:path*'], };
关于Next.config配置的说明
next.config.mjs中直接配置CSP的方式仅适合临时调试场景:
- 这种方式无法动态生成Nonce,只能依赖
unsafe-inline/unsafe-eval放行所有内联代码,安全性极低; - 使用
strict-dynamic时客户端组件加载失败,是因为Next.js客户端组件会生成合法的内联脚本,但未被CSP授权——必须配合Nonce或哈希才能让这些脚本通过校验,而静态配置的CSP无法做到这一点。
2. 使用unsafe-eval和unsafe-inline的风险
这两个指令会彻底削弱CSP的核心防护能力:
unsafe-inline允许任何内联脚本、样式执行,XSS攻击者可直接注入恶意内联代码绕过防护;unsafe-eval允许使用eval()、new Function()等动态代码执行方式,给攻击者提供了执行恶意代码的入口。
生产环境绝对禁止使用这两个指令,Next.js的客户端组件不需要依赖它们,只要通过Middleware正确配置Nonce + strict-dynamic,就能合法放行所有必要的内联代码。
内容的提问来源于stack exchange,提问作者Sriram Prasanth
相关产品推荐
相关产品推荐

