diff --git a/src/app/layout.tsx b/src/app/layout.tsx index ffe2f24..fbef143 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -31,7 +31,7 @@ export default function RootLayout({ }; const { storeHash } = useAppContext(); - const allowedParents = () => [ + const frameAncestors = [ `https://store-${storeHash}.mybigcommerce.com`, `https://store-${storeHash}.my-staging.com`, `https://store-${storeHash}.my-integration.com` @@ -42,7 +42,7 @@ export default function RootLayout({ + frame-ancestors={frameAncestors} /> diff --git a/src/middleware.ts b/src/middleware.ts index 662c8fd..5230871 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -17,7 +17,34 @@ export async function middleware(request: NextRequest) { return new NextResponse('invalid csrf token', { status: 403 }); } - return response; + const nonce = Buffer.from(crypto.randomUUID()).toString('base64'); + const cspHeader = ` + script-src 'self' 'nonce-${nonce}' 'strict-dynamic'; + frame-ancestors: 'https://store-*.mybigcommerce.com' 'https://store-*.my-integration.zone' 'https://store-*.my-staging.zone'; + `; + 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 newResponse = NextResponse.next({ + request: { + headers: requestHeaders, + }, + }) + newResponse.headers.set( + 'Content-Security-Policy', + contentSecurityPolicyHeaderValue + ) + + return newResponse } export const config = {