我已将 CSP 添加到我的 Nextjs (v14.0.4) 项目中。当我在开发模式下运行项目时,我可以看到随机数被添加。但是,当我构建并启动项目时,随机数不会添加到下一个脚本中。在控制台中显示以下错误:
拒绝应用内联样式,因为它违反了以下内容安全策略指令:“style-src 'self' 'nonce-ODkxM2Y4NGEtN2Q3MS00N2E4LWIwOTktODc2YzFjMzFhNjg5'”。启用内联执行需要“unsafe-inline”关键字、哈希值(“sha256-zlqnbDt84zf1iSefLU/ImC54isoprH/MRiVZGskwexk=”)或随机数(“nonce-...”)。请注意,哈希不适用于事件处理程序、样式属性和 javascript: 导航,除非存在“unsafe-hashes”关键字。
这是我的代码。我在 NextJs 中间件中调用这个函数:
function addCspHeaders(request: NextRequest) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
const isDev = process.env.NODE_ENV !== 'production'
const nextCsp = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic' ${isDev ? "'unsafe-eval'" : ''};
style-src 'self' 'nonce-${nonce}';
img-src 'self';
font-src 'self' data:;
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`
const cspHeader = nextCsp
const contentSecurityPolicyHeaderValue = cspHeader
.replace(/\s{2,}/g, ' ')
.trim()
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-nonce', nonce)
requestHeaders.set(
'Content-Security-Policy',
contentSecurityPolicyHeaderValue,
)
const response = NextResponse.next({
request: {
headers: requestHeaders,
},
})
response.headers.set(
'Content-Security-Policy',
contentSecurityPolicyHeaderValue,
)
return response
}
如何让我的代码在生产中运行?如果我将“unsafe-inline”添加到 script-src,它确实可以在生产环境中工作,但我不想将“unsafe-inline”添加到我的 CSP。
事实证明文档其实给出了答案:
Every time a page is viewed, a fresh nonce should be
generated. This means that you must use dynamic rendering to add nonces.
https://nextjs.org/docs/app/building-your-application/configuring/content-security-policy#nonces
我必须将以下行添加到我的根布局.tsx
export const dynamic = "force-dynamic"