Security Header Guide

X-Frame-Options Guide

Master the X-Frame-Options header for effective clickjacking protection

Understanding X-Frame-Options

The X-Frame-Options HTTP response header is a security mechanism that helps protect your website from clickjacking attacks. It indicates whether your site should be allowed to be displayed in an iframe, frame, or object on other websites.

Originally developed by Microsoft for Internet Explorer 8, X-Frame-Options has been widely adopted by all major browsers and remains one of the most effective ways to prevent clickjacking attacks.

Why X-Frame-Options Matters

Clickjacking attacks rely on embedding legitimate websites in invisible iframes. X-Frame-Options directly prevents this by telling browsers not to display your site in frames.

Directive Values

DENY

The most restrictive option. Prevents your site from being displayed in any iframe.

X-Frame-Options: DENY

SAMEORIGIN

Allows your site to be framed only by pages from the same origin.

X-Frame-Options: SAMEORIGIN

ALLOW-FROM (Deprecated)

Allows framing by specific origins. Not supported in modern browsers.

X-Frame-Options: ALLOW-FROM https://trusted-site.com

Apache Configuration

Add X-Frame-Options headers to your Apache configuration:

# In httpd.conf or .htaccess file
Header always set X-Frame-Options "DENY"

# SAMEORIGIN configuration
Header always set X-Frame-Options "SAMEORIGIN"

# Conditional configuration
<If "%{HTTP_HOST} == 'admin.example.com'">
    Header always set X-Frame-Options "DENY"
</If>
<Else>
    Header always set X-Frame-Options "SAMEORIGIN"
</Else>

Nginx Configuration

Configure X-Frame-Options in your Nginx server block:

# In nginx.conf or site configuration
add_header X-Frame-Options "DENY" always;

# SAMEORIGIN configuration
add_header X-Frame-Options "SAMEORIGIN" always;

# Conditional configuration
server {
    listen 443 ssl;
    server_name admin.example.com;
    add_header X-Frame-Options "DENY" always;
}

server {
    listen 443 ssl;
    server_name app.example.com;
    add_header X-Frame-Options "SAMEORIGIN" always;
}

Node.js / Express Implementation

Use helmet middleware for Express.js applications:

const express = require('express');
const helmet = require('helmet');
const app = express();

// Basic helmet configuration
app.use(helmet({
  frameguard: { action: 'deny' }
}));

// Manual header setting
app.use((req, res, next) => {
  res.setHeader('X-Frame-Options', 'DENY');
  next();
});

PHP Implementation

Set headers in PHP applications:

<?php
// Basic header setting
header("X-Frame-Options: DENY");

// SAMEORIGIN
header("X-Frame-Options: SAMEORIGIN");

// WordPress functions.php
add_action('send_headers', function() {
    header('X-Frame-Options: DENY');
});

// Laravel middleware
class XFrameOptionsMiddleware
{
    public function handle($request, Closure $next, $option = 'DENY')
    {
        $response = $next($request);
        $response->header('X-Frame-Options', $option);
        return $response;
    }
}

Browser Compatibility

BrowserVersionDENYSAMEORIGIN
Chrome4.0+
Firefox3.6.9+
Safari4.0+
EdgeAll

Important Notes

  • • ALLOW-FROM is deprecated in Chrome, Firefox, and Safari
  • • Use CSP frame-ancestors for modern granular control
  • • Internet Explorer 8 was the first browser to support X-Frame-Options

Test Your X-Frame-Options Implementation

Verify your X-Frame-Options header is properly configured and working.