Security Header Guide

CSP frame-ancestors Guide

Master the Content Security Policy frame-ancestors directive for modern clickjacking protection

Understanding CSP frame-ancestors

The Content Security Policy (CSP) frame-ancestors directive is the modern, flexible replacement for the X-Frame-Options header. It provides granular control over which websites are allowed to embed your content in iframes, frames, or objects.

Unlike X-Frame-Options, CSP frame-ancestors offers more sophisticated control mechanisms, including the ability to specify multiple allowed domains, use wildcards, and combine with other CSP directives for comprehensive security policies.

Why CSP frame-ancestors is Superior

CSP frame-ancestors provides the flexibility needed for modern web applications while maintaining strong security. It is the recommended approach for new applications and offers future-proof protection against clickjacking attacks.

Directive Values

'none'

Prevents your site from being displayed in any iframe. Equivalent to X-Frame-Options: DENY.

Content-Security-Policy: frame-ancestors 'none';

'self'

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

Content-Security-Policy: frame-ancestors 'self';

Specific Domains

Allows your site to be framed only by specific, trusted domains.

Content-Security-Policy: frame-ancestors 'self' https://trusted.com;

Wildcards

Use wildcards to allow framing by multiple domains matching patterns.

Content-Security-Policy: frame-ancestors *.example.com;

Apache Configuration

Configure CSP frame-ancestors in Apache:

# In httpd.conf or .htaccess file
Header always set Content-Security-Policy "frame-ancestors 'none';"

# 'self' configuration
Header always set Content-Security-Policy "frame-ancestors 'self';"

# Specific domains
Header always set Content-Security-Policy "frame-ancestors 'self' https://trusted.com;"

# Multiple domains with wildcards
Header always set Content-Security-Policy "frame-ancestors 'self' https://*.partner.com;"

# Combined with other CSP directives
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; frame-ancestors 'none';"

Nginx Configuration

Set CSP frame-ancestors in Nginx:

# In nginx.conf or site configuration
add_header Content-Security-Policy "frame-ancestors 'none';" always;

# 'self' configuration
add_header Content-Security-Policy "frame-ancestors 'self';" always;

# Specific domains
add_header Content-Security-Policy "frame-ancestors 'self' https://trusted.com;" always;

# Full CSP policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; frame-ancestors 'none';" always;

# Location-specific configuration
location /admin/ {
    add_header Content-Security-Policy "frame-ancestors 'none';" always;
}

Node.js / Express Implementation

Use helmet middleware for Express.js:

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

// Basic CSP configuration
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      frameAncestors: ["'none'"],
    },
  },
}));

// 'self' configuration
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      frameAncestors: ["'self'"],
    },
  },
}));

// Specific domains
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      frameAncestors: ["'self'", "https://trusted.com"],
    },
  },
}));

PHP Implementation

Set CSP headers in PHP applications:

<?php
// Basic CSP header
header("Content-Security-Policy: frame-ancestors 'none';");

// 'self' configuration
header("Content-Security-Policy: frame-ancestors 'self';");

// Specific domains
header("Content-Security-Policy: frame-ancestors 'self' https://trusted.com;");

// WordPress functions.php
add_action('send_headers', function() {
    header('Content-Security-Policy: frame-ancestors 'none';');
});

// Laravel middleware
class CSPFrameAncestorsMiddleware
{
    public function handle($request, Closure $next, $policy = "'none'")
    {
        $response = $next($request);
        $response->header('Content-Security-Policy', "frame-ancestors $policy;");
        return $response;
    }
}

Migrating from X-Frame-Options

Direct Equivalents

X-Frame-Options: DENYframe-ancestors 'none'
X-Frame-Options: SAMEORIGINframe-ancestors 'self'

Best Practice: Dual Implementation

For maximum compatibility during transition, implement both headers:

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

Test Your CSP Implementation

Verify your Content-Security-Policy frame-ancestors header is properly configured.