---
title: Embedded app missing frame-ancestors CSP directive
description: >-
  Detects embedded apps that set document response headers but omit
  `frame-ancestors`.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/security/app-security-checks/missing-embedded-csp
  md: >-
    https://shopify.dev/docs/apps/build/security/app-security-checks/missing-embedded-csp.md
---

# Embedded app missing frame-ancestors CSP directive

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

| Detail | Value |
| - | - |
| Check ID | `MISSING_EMBEDDED_CSP` |
| Severity | Medium |
| How it runs | Agent review |

***

## Vulnerable example

## app/entry.server.tsx

```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.
}
```

***

## How to fix

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

For more detail, see [Set up iframe protection](https://shopify.dev/docs/apps/build/security/set-up-iframe-protection).

## app/entry.server.tsx

```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.
```

***

## Related

* [`shopify app security check`](https://shopify.dev/docs/api/shopify-cli/app/app-security-check), the command that runs this check
* [All app security checks](https://shopify.dev/docs/apps/build/security/app-security-checks)

***
