X-Frame-Options Express Middleware

raw JSON →
1.0.0 verified Thu Apr 23 auth: no javascript maintenance

The `x-frame-options` package provides a simple Express middleware to set the `X-Frame-Options` HTTP response header, a security mechanism designed to prevent clickjacking attacks by controlling whether a page can be rendered within `<iframe>`, `<frame>`, `<embed>`, or `<object>` elements. Currently at version 1.0.0, the package was last published over a decade ago. While still functional, the `X-Frame-Options` header itself is considered a legacy solution in modern web development. For comprehensive and more granular protection against framing-based attacks, the `frame-ancestors` directive within Content Security Policy (CSP) is the recommended approach. This package is typically used for supporting older browsers that might not fully support CSP, often in conjunction with CSP `frame-ancestors` to ensure broad compatibility. The middleware defaults the `X-Frame-Options` header value to 'Deny', offering the strongest initial protection.

error Refused to display 'https://example.com/sensitive-page' in a frame because it set 'X-Frame-Options' to 'DENY'.
cause The `x-frame-options` middleware (or another mechanism) has set the `X-Frame-Options` header to 'DENY', explicitly preventing the page from being embedded in any iframe.
fix
If the embedding is intentional and secure, modify the x-frame-options middleware to use SAMEORIGIN (if the embedding page is on the same origin) or, preferably, migrate to Content-Security-Policy: frame-ancestors 'self' or specify trusted origins for frame-ancestors.
error Refused to display 'https://example.com/page' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.
cause The page is attempting to be embedded in an iframe from a different origin, but the `X-Frame-Options` header is set to 'SAMEORIGIN'.
fix
Ensure the embedding page is served from the exact same origin (protocol, domain, port). If cross-origin embedding is required, you must move to Content-Security-Policy with a flexible frame-ancestors directive to whitelist allowed origins, as X-Frame-Options 'ALLOW-FROM' is deprecated and unreliable.
deprecated The `X-Frame-Options` header itself is considered a legacy security header. Modern web applications should primarily rely on the `frame-ancestors` directive within the Content Security Policy (CSP) for comprehensive clickjacking protection, as it offers more granular control and is the current best practice.
fix Prioritize `Content-Security-Policy` with the `frame-ancestors` directive. Consider using `X-Frame-Options` only as a fallback for very old browsers, and ensure consistent policies across both headers. For Express, use a more comprehensive security middleware like `helmet` which includes `frameguard` for managing `X-Frame-Options` alongside other headers.
breaking The `ALLOW-FROM` directive for `X-Frame-Options` is deprecated and has inconsistent browser support across modern browsers. Browsers that do not recognize `ALLOW-FROM` will silently ignore the entire `X-Frame-Options` header, leaving your site unprotected.
fix Avoid using `ALLOW-FROM`. If you need to allow framing from specific external origins, use the `frame-ancestors` directive in your Content Security Policy (CSP) instead, which supports multiple origins and wildcards.
gotcha The `X-Frame-Options` header cannot be set via `<meta>` tags in HTML; it must be delivered as an HTTP response header by the server. Attempts to set it via meta tags will be ignored by browsers.
fix Always configure `X-Frame-Options` (or `Content-Security-Policy`) as an HTTP response header on your server (e.g., using this middleware in Express, or server configurations in Nginx/Apache).
gotcha If both `X-Frame-Options` and `Content-Security-Policy` with `frame-ancestors` are present, modern browsers will prioritize the `frame-ancestors` directive. Ensure that the policies defined by both headers are consistent to avoid unexpected blocking or reduced protection.
fix Always set matching policies for `X-Frame-Options` and `CSP frame-ancestors` if you choose to implement both. For example, `X-Frame-Options: DENY` should correspond to `Content-Security-Policy: frame-ancestors 'none'`.
npm install x-frame-options
yarn add x-frame-options
pnpm add x-frame-options

Demonstrates how to integrate the `x-frame-options` middleware into an Express application, showing both default ('DENY') and 'SAMEORIGIN' configurations, and how to verify the header is set.

const express = require('express');
const xFrameOptions = require('x-frame-options');

const app = express();

// Use the middleware to add X-Frame-Options header (defaults to 'DENY')
app.use(xFrameOptions());

// Or configure it with 'SAMEORIGIN'
// app.use(xFrameOptions('SAMEORIGIN'));

app.get('/', (req, res) => {
  res.send('Hello World! This page has X-Frame-Options set.');
});

app.get('/test-header', (req, res) => {
  const xfoHeader = res.get('X-Frame-Options');
  res.send(`X-Frame-Options header value: ${xfoHeader || 'Not Set'}`);
});

const port = 3000;
app.listen(port, () => {
  console.log(`Express app listening at http://localhost:${port}`);
});