x frame options update

This commit is contained in:
Nate Kelley 2025-03-18 14:47:51 -06:00
parent 027f3e6361
commit 035e86b6ae
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
2 changed files with 49 additions and 5 deletions

View File

@ -1,6 +1,7 @@
import { NextRequest } from 'next/server';
import { isEmbedPage } from './publicPageMiddleware';
const cspHeader = {
const defaultCspHeader = {
'Content-Security-Policy': [
// Default directives
"default-src 'self'",
@ -12,7 +13,7 @@ const cspHeader = {
"img-src 'self' blob: data: https://*.vercel.app https://*.supabase.co",
// Fonts
"font-src 'self' https://fonts.gstatic.com",
// Frame ancestors
// Frame ancestors - no embedding for non-embed routes
"frame-ancestors 'none'",
// Connect sources for API calls
"connect-src 'self' https://*.vercel.app https://*.supabase.co wss://*.supabase.co",
@ -29,12 +30,48 @@ const cspHeader = {
].join('; ')
};
const embedCspHeader = {
'Content-Security-Policy': [
// Default directives
"default-src 'self'",
// Scripts
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://*.vercel.app",
// Styles
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
// Images
"img-src 'self' blob: data: https://*.vercel.app https://*.supabase.co",
// Fonts
"font-src 'self' https://fonts.gstatic.com",
// Frame ancestors - allow embedding from any domain for /embed routes
'frame-ancestors *',
// Connect sources for API calls
"connect-src 'self' https://*.vercel.app https://*.supabase.co wss://*.supabase.co",
// Media
"media-src 'self'",
// Object
"object-src 'none'",
// Form actions
"form-action 'self'",
// Base URI
"base-uri 'self'",
// Manifest
"manifest-src 'self'"
].join('; ')
};
export const cspPolicyMiddleware = (request: NextRequest) => {
// Add CSP headers
request.headers.set('Content-Security-Policy', cspHeader['Content-Security-Policy']);
const isEmbedRoute = isEmbedPage(request);
// Add CSP headers based on route
request.headers.set(
'Content-Security-Policy',
isEmbedRoute
? embedCspHeader['Content-Security-Policy']
: defaultCspHeader['Content-Security-Policy']
);
// Add additional security headers
request.headers.set('X-Frame-Options', 'SAMEORIGIN');
if (!isEmbedRoute) request.headers.set('X-Frame-Options', 'DENY');
request.headers.set('X-Content-Type-Options', 'nosniff');
request.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');

View File

@ -29,3 +29,10 @@ export const assetPermissionCheck = (request: NextRequest): boolean => {
const matchedRoute = createPathnameToBusterRoute(route);
return assetCheckPages.includes(matchedRoute);
};
const embedPages: BusterRoutes[] = Object.values(BusterEmbedRoutes);
export const isEmbedPage = (request: NextRequest): boolean => {
const route = request.nextUrl.pathname;
const matchedRoute = createPathnameToBusterRoute(route);
return embedPages.includes(matchedRoute);
};