Skip to main content

Embedded app missing frame-ancestors CSP directive

Detects embedded apps that set document response headers but omit frame-ancestors.

DetailValue
Check IDMISSING_EMBEDDED_CSP
SeverityMedium
How it runsAgent review

app/entry.server.tsx

export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
reactRouterContext: EntryContext,
) {
// Document headers are set here, but Shopify's headers are
// never added, so no frame-ancestors directive reaches the
// response and any site can iframe the embedded app.
responseHeaders.set("Cache-Control", "no-store");

// ... the rest of the template's handleRequest is unchanged.
}

Add frame-ancestors to the CSP, restricted to the authenticated shop domain and admin.shopify.com.

For more detail, see Set up iframe protection.

app/entry.server.tsx

import { addDocumentResponseHeaders } from "./shopify.server";

export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
reactRouterContext: EntryContext,
) {
// This is what emits the Content-Security-Policy, with
// frame-ancestors scoped to admin.shopify.com and the
// authenticated shop. The template calls it here already.
addDocumentResponseHeaders(request, responseHeaders);

// ... the rest of the template's handleRequest is unchanged.
}

// boundary.headers in app/routes/app.tsx is a different job: it
// propagates route headers onto thrown responses. It does not
// create a CSP.


Was this page helpful?