Content Security Policy
İçerik Güvenliği Politikası (CSP) Next.js uygulamanızı siteler arası komut dosyası oluşturma (XSS), clickjacking ve diğer kod enjeksiyon saldırıları gibi çeşitli güvenlik tehditlerine karşı korumak için önemlidir.
Geliştiriciler CSP'yi kullanarak içerik kaynakları, komut dosyaları, stil sayfaları, görüntüler, yazı tipleri, nesneler, medya (ses, video), iframe'ler ve daha fazlası için hangi kökenlere izin verileceğini belirleyebilirler.
Examples
Nonces
Nonce tek seferlik kullanım için oluşturulmuş benzersiz, rastgele bir karakter dizisidir. CSP ile birlikte, katı CSP yönergelerini atlayarak belirli satır içi komut dosyalarının veya stillerin yürütülmesine seçici olarak izin vermek için kullanılır.
Why use a nonce?
CSP'ler kötü amaçlı komut dosyalarını engellemek için tasarlanmış olsa da, satır içi komut dosyalarının gerekli olduğu meşru senaryolar vardır. Bu gibi durumlarda nonce'lar, doğru nonce'a sahip olmaları halinde bu komut dosyalarının çalışmasına izin vermenin bir yolunu sunar.
Adding a nonce with Middleware
Ara yazılım, sayfa oluşturulmadan önce başlıklar eklemenize ve nonces oluşturmanıza olanak tanır.
Bir sayfa her görüntülendiğinde, yeni bir nonce oluşturulmalıdır. Bu, nonce eklemek için dinamik işleme kullanmanız gerektiği anlamına gelir.
Örneğin:
import { NextRequest, NextResponse } from 'next/server'
export function middleware(request: NextRequest) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
style-src 'self' 'nonce-${nonce}';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
block-all-mixed-content;
upgrade-insecure-requests;
`
// Replace newline characters and spaces
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
}
Varsayılan olarak, Middleware tüm isteklerde çalışır. Middleware'i belirli yollarda çalışacak şekilde filtreleyebilirsiniz. matcher
.
Eşleşen prefetch'leri ( next/link
adresinden) ve CSP başlığına ihtiyaç duymayan statik varlıkları göz ardı etmenizi öneririz.
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
{
source: '/((?!api|_next/static|_next/image|favicon.ico).*)',
missing: [
{ type: 'header', key: 'next-router-prefetch' },
{ type: 'header', key: 'purpose', value: 'prefetch' },
],
},
],
}
Reading the nonce
Artık nonce'u bir Sunucu Bileşeninden şu şekilde okuyabilirsiniz headers
:
import { headers } from 'next/headers'
import Script from 'next/script'
export default function Page() {
const nonce = headers().get('x-nonce')
return (
<Script
src="https://www.googletagmanager.com/gtag/js"
strategy="afterInteractive"
nonce={nonce}
/>
)
}
Without Nonces
Nonces gerektirmeyen uygulamalar için CSP başlığını doğrudan next.config.js
Dosya:
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';
block-all-mixed-content;
upgrade-insecure-requests;
`
module.exports = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Content-Security-Policy',
value: cspHeader.replace(/\n/g, ''),
},
],
},
]
},
}
Version History
Nonce'ları düzgün bir şekilde işlemek ve uygulamak için Next.js'nin v13.4.20+
adresini kullanmanızı öneririz.