The X-Frame-Options header is a critical security measure that protects your website from clickjacking attacks. When set correctly, this header prevents your web pages from being embedded in an <iframe>
on another site. Without it, your web application is at risk, leaving users vulnerable to hidden overlays and potentially malicious activity.
In this guide, we'll walk through how to set the X-Frame-Options header in various popular frameworks and server setups, such as Express.js, Django, Flask, Spring Boot, and Nginx. We’ll explore the purpose of the header, the different directives it can take, and provide step-by-step solutions for each framework.
Why Use the X-Frame-Options Header?
The X-Frame-Options header provides instructions to the browser on whether your site’s content can be embedded in an <iframe>
. Without it, your application is vulnerable to clickjacking, a technique where attackers load your application into a hidden frame, tricking users into clicking on elements they can’t see. Setting this header enhances the security of your site by ensuring that it can only be embedded in ways you approve.
The header can take three main values:
DENY
: Prevents any domain from embedding your content.SAMEORIGIN
: Allows only the same domain to embed your content.ALLOW-FROM uri
: Permits a specified URI to embed your content (deprecated and only supported in some browsers).
How to Check if the X-Frame-Options Header is Missing
- Open your browser’s Developer Tools (usually accessible with
F12
). - Navigate to the Network tab and reload your page.
- Click on your page request, go to Headers, and look for
X-Frame-Options
under the Response Headers section.
If it’s missing, you’ll need to add it manually to prevent potential clickjacking attacks. Let’s look at how to set this header in different environments.
Setting the X-Frame-Options Header in Next.js (JavaScript)
In Next.js (JavaScript), you can set custom HTTP headers by modifying the next.config.js
file. This file allows you to define custom headers that will be applied to all routes in your application.
Open your
next.config.js
file (or create it if it doesn't exist).Add the following configuration to set the
X-Frame-Options
header:
module.exports = {
async headers() {
return [
{
source: '/(.*)', // Apply to all routes
headers: [
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN', // or 'DENY'
},
],
},
];
},
};
This code ensures that every response from your Next.js application includes the X-Frame-Options
header set to SAMEORIGIN
, which prevents your pages from being embedded in iframes on other domains. You can change 'SAMEORIGIN'
to 'DENY'
if you want to restrict embedding from all domains.
Setting the X-Frame-Options Header in Next.js (TypeScript)
In Next.js (TypeScript), the process is the same as in JavaScript, but you will be working with a .ts
configuration file. The following steps apply:
Open or create your
next.config.ts
file.Add the same header configuration as follows:
import { NextConfig } from 'next';
const nextConfig: NextConfig = {
async headers() {
return [
{
source: '/(.*)', // Apply to all routes
headers: [
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN', // or 'DENY'
},
],
},
];
},
};
export default nextConfig;
This TypeScript version of the next.config.ts
file ensures that the X-Frame-Options
header is applied to all routes, helping to secure your Next.js application from clickjacking attacks.
Setting the X-Frame-Options Header in Express.js
If you're using Express.js for a Node.js application, you can use the helmet
package, which provides easy security headers.
Install helmet
with npm:
npm install helmet
Then, add the following code to your Express app:
const express = require('express');
const helmet = require('helmet');
const app = express();
app.use(helmet.frameguard({ action: 'SAMEORIGIN' })); // or 'DENY'
app.get('/', (req, res) => {
res.send('X-Frame-Options header is set!');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
This will add the X-Frame-Options: SAMEORIGIN
header to all responses by default. You can change 'SAMEORIGIN'
to 'DENY'
if you want to restrict all framing entirely.
Setting the X-Frame-Options Header in Django
For Django applications, setting the X-Frame-Options header is straightforward. Since Django 1.10, the X-Frame-Options
header is set to DENY
by default. However, if you need a different setting, you can update it in your settings file.
Open settings.py
and add the following:
# settings.py
X_FRAME_OPTIONS = 'SAMEORIGIN' # Options: 'DENY', 'SAMEORIGIN'
To check if this works, restart your Django server and inspect the response headers in your browser.
Setting the X-Frame-Options Header in Flask
For Flask, you can manually set the header for all responses. One way to do this is to create a custom response header in your Flask application.
from flask import Flask, make_response
app = Flask(__name__)
@app.after_request
def apply_x_frame_options(response):
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
return response
@app.route('/')
def home():
return 'X-Frame-Options header is set!'
if __name__ == '__main__':
app.run()
This code snippet sets the X-Frame-Options
header to SAMEORIGIN
for all responses. Change it to 'DENY'
if you want no external framing at all.
Setting the X-Frame-Options Header in Spring Boot
For Spring Boot, setting the X-Frame-Options header requires adjusting the application’s security configuration. Spring Security provides a simple way to add this header.
First, ensure that Spring Security is configured in your project. Then, add the following configuration:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.frameOptions()
.sameOrigin(); // Use .deny() for DENY
}
}
This configuration will add the X-Frame-Options: SAMEORIGIN
header to all responses. Switch .sameOrigin()
to .deny()
if you prefer DENY
.
Setting the X-Frame-Options Header in Nginx
To set the X-Frame-Options header in Nginx, you can add it directly to your Nginx configuration file.
- Open your Nginx configuration file, typically found in
/etc/nginx/nginx.conf
or/etc/nginx/conf.d/default.conf
. - Add the following line in the server block:
add_header X-Frame-Options "SAMEORIGIN";
- Save the file and restart Nginx:
sudo systemctl restart nginx
This will set the X-Frame-Options
header to SAMEORIGIN
for all responses served by Nginx.
Conclusion
Adding the X-Frame-Options header is a crucial step in securing your web application against clickjacking. By following the steps above, you can quickly and effectively set this header in Next js, Express.js, Django, Flask, Spring Boot, and Nginx. Remember to check that your header is set correctly by Scanning Again. This simple addition can go a long way in safeguarding your users and enhancing your application’s overall security.