In modern web security, protecting your site from clickjacking attacks is a critical priority. X-Frame-Options is one of the fundamental HTTP response headers designed to guard your content from being unexpectedly embedded in external frames. Although there is a more up-to-date method available through the frame-ancestors directive in a Content-Security-Policy header, the X-Frame-Options header is still widely used to offer a basic layer of protection.
X-Frame-Options is an HTTP response header that dictates whether browsers should allow a web page to render within a <frame>, <iframe>, <embed>, or <object>. By specifying how your content can be framed, you minimize the risk of malicious sites embedding your pages for fraudulent or dangerous purposes, commonly referred to as clickjacking attacks.
The browser must support X-Frame-Options for it to be effective. Most modern browsers do, but keep in mind that outdated browsers might not provide the same level of protection.
When a user's browser makes an HTTP request for a page, the server can include the X-Frame-Options header in its response. The browser then reads this header to decide if the page is allowed to be displayed within a frame.
X-Frame-Options: DENY
This directive forbids the page from appearing in any frame—regardless of whether the request originates from the same site or a different domain.
X-Frame-Options: SAMEORIGIN
This directive allows a page to be framed only if the site embedding it is the exact same origin (domain, protocol, and port) as the site serving the page.
Attackers can trick users into performing unintended purchases or financial transactions.
Malicious sites can overlay your login forms to capture credentials or session information.
Users can be tricked into clicking buttons or links they didn't intend to interact with.
Add to your .htaccess file or VirtualHost configuration:
# For SAMEORIGIN
Header always set X-Frame-Options "SAMEORIGIN"
# For DENY
Header set X-Frame-Options "DENY"
Add to your server or location block:
# For SAMEORIGIN
add_header X-Frame-Options SAMEORIGIN always;
# For DENY
add_header X-Frame-Options DENY always;
Add to your Web.config file:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
</system.webServer>
Add to your frontend, listen, or backend configuration:
# For older versions
rspadd X-Frame-Options:\ SAMEORIGIN
# For newer versions
http-response set-header X-Frame-Options SAMEORIGIN
Using Helmet middleware:
const helmet = require("helmet");
const express = require("express");
const app = express();
app.use(
helmet({
xFrameOptions: { action: "sameorigin" },
})
);
Although X-Frame-Options provides an important safeguard, it's considered a legacy solution compared to the frame-ancestors directive in Content-Security-Policy (CSP). CSP offers more precise controls and is better suited for modern browsers. However, including X-Frame-Options is still beneficial for maintaining compatibility and an extra layer of security against framing attacks.
Use both X-Frame-Options and CSP's frame-ancestors (where feasible) to cover a wider range of browsers and enhance your security posture.
Learn about other HTTP security headers to strengthen your website's security: