| | |
| | | |
| | | 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' |
| | | |
| | | const wrapResponseWithXFrameOptions = (response: NextResponse, pathname: string) => { |
| | | // prevent clickjacking: https://owasp.org/www-community/attacks/Clickjacking |
| | | // Chatbot page should be allowed to be embedded in iframe. It's a feature |
| | | if (process.env.NEXT_PUBLIC_ALLOW_EMBED !== 'true' && !pathname.startsWith('/chat') && !pathname.startsWith('/workflow') && !pathname.startsWith('/completion')) |
| | | response.headers.set('X-Frame-Options', 'DENY') |
| | | |
| | | return response |
| | | } |
| | | export function middleware(request: NextRequest) { |
| | | const { pathname } = request.nextUrl |
| | | const requestHeaders = new Headers(request.headers) |
| | | const response = NextResponse.next({ |
| | | request: { |
| | | headers: requestHeaders, |
| | | }, |
| | | }) |
| | | |
| | | const isWhiteListEnabled = !!process.env.NEXT_PUBLIC_CSP_WHITELIST && process.env.NODE_ENV === 'production' |
| | | if (!isWhiteListEnabled) |
| | | return wrapResponseWithXFrameOptions(response, pathname) |
| | | return NextResponse.next() |
| | | |
| | | const whiteList = `${process.env.NEXT_PUBLIC_CSP_WHITELIST} ${NECESSARY_DOMAIN}` |
| | | const nonce = Buffer.from(crypto.randomUUID()).toString('base64') |
| | |
| | | style-src 'self' 'unsafe-inline' ${scheme_source} ${whiteList}; |
| | | worker-src 'self' ${scheme_source} ${csp} ${whiteList}; |
| | | media-src 'self' ${scheme_source} ${csp} ${whiteList}; |
| | | img-src * data:; |
| | | img-src 'self' ${scheme_source} ${csp} ${whiteList}; |
| | | font-src 'self'; |
| | | object-src 'none'; |
| | | base-uri 'self'; |
| | |
| | | .replace(/\s{2,}/g, ' ') |
| | | .trim() |
| | | |
| | | const requestHeaders = new Headers(request.headers) |
| | | requestHeaders.set('x-nonce', nonce) |
| | | |
| | | requestHeaders.set( |
| | |
| | | contentSecurityPolicyHeaderValue, |
| | | ) |
| | | |
| | | const response = NextResponse.next({ |
| | | request: { |
| | | headers: requestHeaders, |
| | | }, |
| | | }) |
| | | response.headers.set( |
| | | 'Content-Security-Policy', |
| | | contentSecurityPolicyHeaderValue, |
| | | ) |
| | | |
| | | return wrapResponseWithXFrameOptions(response, pathname) |
| | | return response |
| | | } |
| | | |
| | | export const config = { |