Skip to main content

Embedded app frame-ancestors uses a wildcard

Detects literal wildcard or clearly permissive frame-ancestors policies in embedded app code.

DetailValue
Check IDSTATIC_FRAME_ANCESTORS
SeverityHigh
How it runsDeterministic scan and agent review
Applies toEmbedded apps

app/entry.server.tsx

export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
reactRouterContext: EntryContext,
) {
// A hand-written wildcard policy: any origin can frame the
// embedded app, which is what clickjacking needs. "https:",
// "*", and "https://*.myshopify.com" all count as permissive.
responseHeaders.set("Content-Security-Policy", "frame-ancestors *");

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

Restrict frame-ancestors to Shopify Admin and the authenticated shop origin.

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,
) {
// Let Shopify build the policy: it restricts frame-ancestors to
// admin.shopify.com and the shop this request authenticated as.
// Drop any hand-written wildcard policy elsewhere in the app.
addDocumentResponseHeaders(request, responseHeaders);

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

// Written by hand, the only acceptable shape names both origins
// explicitly, with no wildcard:
//
// frame-ancestors https://admin.shopify.com https://<shop>.myshopify.com


Was this page helpful?