X-Frame-Options
Description
The X-Frame-Options
response header controls whether a browser should be allowed to render a page in a <frame>
, <iframe>
, <embed>
, or <object>
. This security feature helps protect against clickjacking attacks, where malicious sites might try to embed your site to steal user interactions or data.
Clickjacking (also known as a UI redress attack) is a technique where an attacker tricks a user into clicking on something different from what the user perceives they are clicking on. For example, an attacker might overlay an invisible iframe containing your site over a deceptive button on their malicious site, causing users to unknowingly interact with your site when they believe they're interacting with the attacker's site.
By setting the X-Frame-Options
header appropriately, website owners can prevent their content from being embedded into other sites, thus mitigating clickjacking risks.
Syntax
The X-Frame-Options
header accepts one of three values:
DENY
: The page cannot be displayed in a frame, regardless of the site attempting to do so.SAMEORIGIN
: The page can only be displayed in a frame on the same origin as the page itself.ALLOW-FROM uri
: The page can only be displayed in a frame on the specified origin. (Note: This option is deprecated and not supported in many modern browsers.)
Example Syntax
This example allows the page to be framed only by pages from the same origin.
Examples
Complete Frame Restriction Example
A response that completely prevents framing:
HTTP/1.1 200 OK
Date: Tue, 03 Jun 2025 02:00:00 GMT
Content-Type: text/html; charset=UTF-8
X-Frame-Options: DENY
Content-Length: 1234
<!DOCTYPE html>
<html>
<head><title>No Framing Allowed</title></head>
<body>
<h1>Protected Content</h1>
<p>This page is protected against clickjacking attacks.</p>
</body>
</html>
In this example, the header prevents the page from being embedded in any frame, regardless of the origin of the parent document.
Same-Origin Framing Example
A response allowing framing only from the same origin:
HTTP/1.1 200 OK
Date: Tue, 03 Jun 2025 02:10:30 GMT
Content-Type: text/html; charset=UTF-8
X-Frame-Options: SAMEORIGIN
Content-Length: 1345
<!DOCTYPE html>
<html>
<head><title>Internal Frame Content</title></head>
<body>
<h1>Internal Content</h1>
<p>This page can be framed by pages from the same origin.</p>
</body>
</html>
This example allows the page to be embedded only in frames from the same origin, which is useful for sites that legitimately use frames within their own domain.
Bank Security Example
A response from a banking application:
HTTP/1.1 200 OK
Date: Tue, 03 Jun 2025 02:20:45 GMT
Content-Type: text/html; charset=UTF-8
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
X-Content-Type-Options: nosniff
Content-Length: 2456
<!DOCTYPE html>
<html>
<head><title>Online Banking Portal</title></head>
<body>
<h1>Welcome to Secure Banking</h1>
<p>Your account is protected with multiple security measures.</p>
<!-- Banking application content -->
</body>
</html>
This example shows a bank's website using multiple security headers together, including X-Frame-Options: DENY
to prevent clickjacking attacks. The response also includes the newer Content-Security-Policy: frame-ancestors 'none'
directive, which provides similar protection with more capabilities and better browser support.
API Response Example
A response from a JSON API:
HTTP/1.1 200 OK
Date: Tue, 03 Jun 2025 02:30:15 GMT
Content-Type: application/json
X-Frame-Options: DENY
Content-Length: 178
{
"status": "success",
"user": {
"id": 123,
"name": "John Doe",
"permissions": ["read", "write"]
}
}
Even for non-HTML responses like JSON API endpoints, it's good practice to include the X-Frame-Options
header as part of a defense-in-depth security strategy.
Summary
The X-Frame-Options
response header is an important security feature for preventing clickjacking attacks by controlling whether a browser should be allowed to render a page in a frame. By setting this header to DENY
or SAMEORIGIN
, website owners can significantly reduce the risk of their content being maliciously embedded in other sites. While the X-Frame-Options
header is still widely supported, modern web applications should also consider using the more versatile Content-Security-Policy
header with the frame-ancestors
directive, which provides similar protection with more configuration options. As part of a comprehensive security strategy, the X-Frame-Options
header should be included in responses for any pages where user interactions could have security implications, particularly those involving authentication, financial transactions, or sensitive data.