Block your pages from being framed
headers-xfo
With no frame-ancestors or X-Frame-Options rule your pages load invisibly inside another site, and clicks land on actions you own.
CDN and edge
Web servers
Frameworks
Cloudflare
- 1 Cloudflare does not set X-Frame-Options by default
- 2 Use Transform Rules to add it, or set frame-ancestors in CSP instead
Header: X-Frame-Options
Value: DENY
# Better: use CSP frame-ancestors
Content-Security-Policy: frame-ancestors 'none'AWS CloudFront
- 1 Create a Response Headers Policy in CloudFront
- 2 Attach the policy to your distribution's behavior
Custom header:
Name: X-Frame-Options
Value: DENY
Override origin: YesVercel
- 1 Add a headers entry to your vercel.json
- 2 Redeploy
json
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Frame-Options", "value": "DENY" }
]
}
]
}Netlify
- 1 Add a headers section to your netlify.toml or _headers file
- 2 Redeploy
toml
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"Nginx
- 1 Add the header directive to your server or location block
- 2 Test config with nginx -t, then reload
nginx
add_header X-Frame-Options "DENY" always;Apache
- 1 Make sure mod_headers is enabled
- 2 Add the Header directive to your .htaccess or VirtualHost
apacheconf
Header always set X-Frame-Options "DENY"Caddy
- 1 Add a header directive to your Caddyfile
- 2 Reload Caddy
caddyfile
header X-Frame-Options "DENY"Next.js
- 1 Add a headers function to your next.config.js
- 2 Rebuild and redeploy
javascript
// next.config.js
module.exports = {
async headers() {
return [{
source: "/(.*)",
headers: [
{ key: "X-Frame-Options", value: "DENY" },
],
}];
},
};Express
- 1 Use the helmet middleware (recommended) or set the header manually
- 2 Restart your server
javascript
// Using helmet (recommended)
const helmet = require("helmet");
app.use(helmet());
// Or manually
app.use((req, res, next) => {
res.setHeader("X-Frame-Options", "DENY");
next();
});Django
- 1 Django sets X-Frame-Options via XFrameOptionsMiddleware
- 2 Make sure the middleware is in MIDDLEWARE
python
# settings.py
X_FRAME_OPTIONS = 'DENY'
# Ensure 'django.middleware.clickjacking.XFrameOptionsMiddleware' is in MIDDLEWARELaravel
- 1 Add a middleware that sets the header
- 2 Register it in your HTTP kernel
php
// app/Http/Middleware/SecurityHeaders.php
public function handle($request, Closure $next)
{
$response = $next($request);
$response->headers->set('X-Frame-Options', 'DENY');
return $response;
}Rails
- 1 Set the header in your ApplicationController or config
ruby
# config/application.rb
config.action_dispatch.default_headers.merge!(
'X-Frame-Options' => 'DENY'
)Spring Boot
- 1 Spring Security sets X-Frame-Options: DENY by default
- 2 If it's missing, ensure default headers are not disabled
java
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.headers(h -> h
.frameOptions(fo -> fo.deny())
);
return http.build();
}WordPress
- 1 Add the header via your theme's functions.php or .htaccess
- 2 A security plugin like HTTP Headers can also help
php
# .htaccess (Apache)
Header always set X-Frame-Options "DENY"
# Or in functions.php
add_action('send_headers', function() {
header('X-Frame-Options: DENY');
});Nuxt
- 1 Add the header to your nuxt.config.ts routeRules
- 2 Rebuild and redeploy
typescript
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/**': {
headers: { 'X-Frame-Options': 'DENY' },
},
},
});ASP.NET
- 1 Add middleware in your Program.cs or Startup.cs
csharp
app.Use(async (context, next) =>
{
context.Response.Headers.Append("X-Frame-Options", "DENY");
await next();
});Does your app still have this?
Scan your domain