The X-Frame-Options
header is used to prevent click-jacking attacks. Setting this header makes the browser to recognize whether a page can be rendered using of these tags <frame>
, <iframe>
, <embed>
and <object>
.
- What Is Clickjacking and How Does It Work?
- What Does the
X-Frame-Options
Header Do? X-Frame-Options
Directives- How To Set
X-Frame-Options
In Nginx - How To Set
X-Frame-Options
In Apache - How To Set
X-Frame-Options
In Flask Applications - Complete Flask Application That Uses HSTS and X-Frame-Options
- How To Set
X-Frame-Options
In NodeJS applications - How To Test If a Website is Sending
X-Frame-Options
Header - Did this work for you?
What Is Clickjacking and How Does It Work?
In clickjacking, a malicious webpage tricks a user into clicking an element which is invisible or disguised as another element. Users can download malware, trojans or accidentally enter their credentials or make online purchases because they think this is a legitimate website.
A scammer can create a webpage that promises something great, maybe an expensive freebie or a vacation. Upon visiting the webpage, in the background, the malicious code will check if the user is logged into their bank or credit card website. If they are logged in, the browser navigates to the payment page of that bank or credit card website. This is done inside an invisible iframe above the freebie page with the payment button aligned over the freebie button. When the victim clicks on the freebie button, in reality, they have actually clicked on the payment button, and the money is transferred to the scammer. The victim is then redirected to the information page about the freebie. The victim essentially made a valid payment done via a scam webpge.
What Does the X-Frame-Options
Header Do?
To protect against clickjacking, the webserver or application can send a response with HTTP header X-Frame-Options
. This can be done at webserver level or application level. In this case, we will show you how to do it using web servers Nginx or Apache, and from a Flask application.
X-Frame-Options
Directives
The possible directives for X-Frame-Options
are:
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
There was a third directive:
X-Frame-Options: ALLOW-FROM origin
But this directive has been made obselete.
X-Frame-Options: DENY
This directive is used to prevent the webpage load fail if called from within an iframe.
X-Frame-Options: SAMEORIGIN
This directive is used to make the webpage load and load only if all parent and ancestor frames are from the same domain itself.
How To Set X-Frame-Options
In Nginx
To configure Nginx to send the X-Frame-Options
header with SAMEORIGIN
, include this line of code in nginx's http block or the virtual host's server block:
add_header x-frame-options "SAMEORIGIN" always;
To deny:
add_header x-frame-options "DENY" always;
How To Set X-Frame-Options
In Apache
To configure Apache to send the X-Frame-Options
header with SAMEORIGIN
for all pages, include this line of code in Apache's http block:
Header always set X-Frame-Options "SAMEORIGIN"
To deny:
Header set X-Frame-Options "DENY"
How To Set X-Frame-Options
In Flask Applications
If you have a Python Flask application running and it returns the headers directly use this code, you can add it in an after_request
decorator.
To enable X-Frame-Options
for same origin:
@app.after_request
def after_request(response):
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
return response
To enable X-Frame-Options
and block frames from embedding it:
@app.after_request
def after_request(response):
response.headers['X-Frame-Options'] = 'DENY'
return response
Complete Flask Application That Uses HSTS and X-Frame-Options
This is a fully working Flask program that has enabled HSTS and X-Frame-Options (same origin).
app.py
from flask import Flask
app = Flask(__name__)
@app.after_request
def after_request(response):
response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains; preload'
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
return response
@app.route("/")
def index():
return 'Hello'
if __name__ == "__main__":
app.run()
Output of curl -I
$ curl -I http://127.0.0.1:5000 HTTP/1.1 200 OK Server: Werkzeug/3.0.1 Python/3.12.4 Date: Mon, 26 Aug 2024 20:52:34 GMT Content-Type: text/html; charset=utf-8 Content-Length: 5 Strict-Transport-Security: max-age=31536000; includeSubDomains; preload X-Frame-Options: SAMEORIGIN Connection: close
How To Set X-Frame-Options
In NodeJS applications
If you have a NodeJS application running on ExpressJS and it returns the headers directly, you can use Helmet library. This code should work:
const helmet = require("helmet");
...
app.use(
helmet({
xFrameOptions: { action: "sameorigin" },
}),
);
How To Test If a Website is Sending X-Frame-Options
Header
To test if a website (say aruljohn.com) is sending X-Frame-Options
, run this on the command line:
curl -sI https://aruljohn.com | grep -i 'x-frame'
The output will be like this:
$ curl -sI https://aruljohn.com | grep -i 'x-frame' x-frame-options: SAMEORIGIN
If the webserver or web application does not have X-Frame-Options
set, the response of this command will be blank.
Did this work for you?
If this did not work for you or you have any questions, always feel free to contact me and I will try to reply within 24-48 hours.
Related Posts
If you have any questions, please contact me at arulbOsutkNiqlzziyties@gNqmaizl.bkcom. You can also post questions in our Facebook group. Thank you.