|
import type { NextRequest } from 'next/server' |
|
import { NextResponse } from 'next/server' |
|
|
|
const NECESSARY_DOMAIN = '*.sentry.io http://localhost:* http://127.0.0.1:* https://analytics.google.com googletagmanager.com *.googletagmanager.com https://www.google-analytics.com https://api.github.com' |
|
|
|
export function middleware(request: NextRequest) { |
|
const isWhiteListEnabled = !!process.env.NEXT_PUBLIC_CSP_WHITELIST && process.env.NODE_ENV === 'production' |
|
if (!isWhiteListEnabled) |
|
return NextResponse.next() |
|
|
|
const whiteList = `${process.env.NEXT_PUBLIC_CSP_WHITELIST} ${NECESSARY_DOMAIN}` |
|
const nonce = Buffer.from(crypto.randomUUID()).toString('base64') |
|
const csp = `'nonce-${nonce}'` |
|
|
|
const scheme_source = 'data: mediastream: blob: filesystem:' |
|
|
|
const cspHeader = ` |
|
default-src 'self' ${scheme_source} ${csp} ${whiteList}; |
|
connect-src 'self' ${scheme_source} ${csp} ${whiteList}; |
|
script-src 'self' ${scheme_source} ${csp} ${whiteList}; |
|
style-src 'self' 'unsafe-inline' ${scheme_source} ${whiteList}; |
|
worker-src 'self' ${scheme_source} ${csp} ${whiteList}; |
|
media-src 'self' ${scheme_source} ${csp} ${whiteList}; |
|
img-src 'self' ${scheme_source} ${csp} ${whiteList}; |
|
font-src 'self'; |
|
object-src 'none'; |
|
base-uri 'self'; |
|
form-action 'self'; |
|
upgrade-insecure-requests; |
|
` |
|
|
|
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 |
|
} |
|
|
|
export const config = { |
|
matcher: [ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
source: '/((?!_next/static|_next/image|favicon.ico).*)', |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
], |
|
} |
|
|