---
title: "Refuse to be framed · Agent Wranglers"
url: https://agentwranglers.se/playbook/application-security/browser-security-headers/frame-ancestors
id: APS-28
level: Required
applies: accounts
risk: takeover
updated: 2026-10-27
build: a2a6bdfed830
tokens: 872
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Refuse to be framed

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Browser security headers](https://agentwranglers.se/playbook/application-security/browser-security-headers.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: APS-28
- Level: Required
- Chapter: [Browser security headers](https://agentwranglers.se/playbook/application-security/browser-security-headers.md)
- Rule: Stop other sites from showing yours inside a frame. Use `frame-ancestors 'none'` (or a list) in the CSP, plus `X-Frame-Options` for older browsers.
- Check: `curl -sI` on a page and an error page shows `frame-ancestors` in the CSP and `X-Frame-Options`. A test page on another origin that frames the site shows a blocked frame.
- Risk: An account or system taken over
- Applies when: The project has user accounts.
- How: Add `frame-ancestors 'none'` to the Content-Security-Policy header and send `X-Frame-Options: DENY`. If partners must embed you, list their origins instead. This directive works without a strict script policy. Send it on day one, even before [Allow only the scripts you wrote](https://agentwranglers.se/playbook/application-security/browser-security-headers/content-security-policy.md) is ready. When both are ready, they share one header. Test it with the attack in [Send the security headers as one set](https://agentwranglers.se/playbook/application-security/browser-security-headers/header-set.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### HTTP example

```http
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY
```

## Sources

- [CSP Level 3 (the frame-ancestors directive)](https://www.w3.org/TR/CSP3/#directive-frame-ancestors)
- [OWASP HTTP Headers Cheat Sheet (X-Frame-Options)](https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-frame-options)

## Related rules

- APS-25 [Allow only the scripts you wrote](https://agentwranglers.se/playbook/application-security/browser-security-headers/content-security-policy.md) in Application security
- APS-100 [Send the security headers as one set](https://agentwranglers.se/playbook/application-security/browser-security-headers/header-set.md) in Application security
- APS-39 [Check the sender of every window message](https://agentwranglers.se/playbook/application-security/browser-security-headers/postmessage-origin.md) in Application security

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/application-security/browser-security-headers/frame-ancestors">Agent Wranglers application security playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Stop browsers guessing file types](https://agentwranglers.se/playbook/application-security/browser-security-headers/x-content-type-options.md)
- Next: [Refuse odd requests from other sites](https://agentwranglers.se/playbook/application-security/browser-security-headers/fetch-metadata.md)
- [Browser security headers](https://agentwranglers.se/playbook/application-security/browser-security-headers.md)
