~5 دقیقه مطالعه • بروزرسانی ۴ آبان ۱۴۰۴
تنظیم CSP بدون استفاده از nonce
اگر اپلیکیشن شما به اجرای اسکریپتهای inline نیازی ندارد، میتوانید هدر CSP را مستقیماً در فایل next.config.js تنظیم کنید:
const cspHeader = `
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`
module.exports = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Content-Security-Policy',
value: cspHeader.replace(/\n/g, ''),
},
],
},
]
},
}استفاده از Subresource Integrity (SRI)
Next.js بهصورت آزمایشی از SRI برای CSP مبتنی بر هش پشتیبانی میکند. این روش امکان استفاده از رندرینگ استاتیک و کش CDN را فراهم میسازد.
فعالسازی SRI
در فایل next.config.js تنظیم زیر را اضافه کنید:
const nextConfig = {
experimental: {
sri: {
algorithm: 'sha256',
},
},
}
module.exports = nextConfigپیکربندی CSP همراه با SRI
میتوانید همچنان از سیاستهای CSP خود استفاده کنید. SRI بهصورت مستقل هشهای امنیتی را به اسکریپتها اضافه میکند:
const cspHeader = `
default-src 'self';
script-src 'self';
style-src 'self';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`
module.exports = {
experimental: {
sri: {
algorithm: 'sha256',
},
},
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Content-Security-Policy',
value: cspHeader.replace(/\n/g, ''),
},
],
},
]
},
}مزایای SRI نسبت به nonce
- پشتیبانی از رندرینگ استاتیک
- سازگاری با کش CDN
- عملکرد بهتر بدون نیاز به SSR در هر درخواست
- امنیت در زمان build با تولید هشهای رمزنگاریشده
محدودیتهای SRI
- آزمایشی بودن ویژگی
- فقط در Webpack فعال است (نه Turbopack)
- فقط در App Router پشتیبانی میشود
- فقط در زمان build قابل استفاده است
تفاوت محیط توسعه و تولید
محیط توسعه
در حالت توسعه، برای پشتیبانی از ابزارهای دیباگ باید 'unsafe-eval' فعال باشد:
const isDev = process.env.NODE_ENV === 'development'
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic' ${isDev ? "'unsafe-eval'" : ''};
style-src 'self' ${isDev ? "'unsafe-inline'" : `'nonce-${nonce}'`};
...
`محیط تولید
- اطمینان حاصل کنید که Proxy روی همهٔ مسیرهای لازم اجرا میشود
- مطمئن شوید که CSP اجازهٔ بارگذاری فایلهای استاتیک Next.js را میدهد
- دامنههای اسکریپتهای ثالث را به CSP اضافه کنید
اسکریپتهای ثالث و CSP
برای استفاده از سرویسهایی مانند Google Tag Manager:
import { GoogleTagManager } from '@next/third-parties/google'
import { headers } from 'next/headers'
export default async function RootLayout({ children }) {
const nonce = (await headers()).get('x-nonce')
return (
<html lang="en">
<body>
{children}
<GoogleTagManager gtmId="GTM-XYZ" nonce={nonce} />
</body>
</html>
)
}نمونهٔ CSP برای اسکریپتهای گوگل
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic' https://www.googletagmanager.com;
connect-src 'self' https://www.google-analytics.com;
img-src 'self' data: https://www.google-analytics.com;
`خطاهای رایج در CSP
- استایلهای inline: از کتابخانههایی استفاده کنید که از nonce پشتیبانی میکنند یا استایلها را به فایل خارجی منتقل کنید
- importهای پویا: مطمئن شوید که در
script-srcمجاز هستند - WebAssembly: در صورت نیاز
'wasm-unsafe-eval'را اضافه کنید - Service Worker: سیاستهای مناسب برای اسکریپتهای آن را تنظیم کنید
تاریخچه نسخهها
| نسخه | تغییرات |
|---|---|
| v14.0.0 | افزوده شدن پشتیبانی آزمایشی از SRI برای CSP مبتنی بر هش |
| v13.4.20 | پیشنهاد شده برای مدیریت صحیح nonce و هدرهای CSP |
جمعبندی
اگر اپلیکیشن شما به nonce نیاز ندارد، میتوانید با استفاده از SRI و تنظیم مستقیم هدر CSP امنیت را حفظ کرده و از مزایای رندرینگ استاتیک و کش CDN بهرهمند شوید. این روش برای اپلیکیشنهایی که به عملکرد بالا و امنیت در زمان build نیاز دارند، بسیار مناسب است.
نوشته و پژوهش شده توسط دکتر شاهین صیامی