A comprehensive guide to fix clickjacking
- Introduction
- X-Frame-Options
- Content-Security-Policy
- Frame-Busting
- Code Snippets
- NodeJS
- Java
- PHP
- Web server & frameworks config
- Apache
- Nginx
- Wordpress
This is detailed guide with code and config snippets for developers and system admins who want help in fixing clickjacking vulnerability. This page has in various languages, web servers and frameworks. In order to fix the issue, we must know the underlying reason that is causing the issue. Clickjacking is caused due to allowing permission to a third party website to embed the vulnerable site using Iframe. Disallowing this can be done by setting HTTP headers that direct browser to not allow the target website to be iframed. This can be done by configuring server on the following two response headers: X-Frame-Options Content-Security-Policy. It can also be done using JavaScript code that kills the iframe. So the third solutions is: JavaScript code to burst the frame. We will explore all the solutions in this guide.
X-Frame-Options
X-Frame-Options is a response header. Developers can use it to protect their site against clickjacking. It can be used to indicate whether or not a browser should be allowed to render a page in an Iframe by have its value set as any of the following:
X-FRAME-OPTIONS: DENY
By specifying DENY, no site will be allowed to load the page in a frame.
X-FRAME-OPTIONS: SAMEORIGIN
On the other hand, if you specify SAMEORIGIN, you can still use the page in a frame as long as the site including it in a frame is the same as the one serving the page.
X-FRAME-OPTIONS: ALLOW-FROM uri
If you specify this, then the site can be displayed in a frame only by uri specified. However, this is an obsolete directive that no longer works in modern browsers.
Note: The Content-Security-Policy HTTP header has a frame-ancestors directive which obsoletes this header for supporting browsers. It is the next header that we are going to discuss.
Content-Security-Policy
The HTTP Content-Security-Policy response header allows web site administrators to control resources the user agent is allowed to load for a given page. It is used for a vast number of security vulnerabilities other than clickjacking such as XSS. However our guide will be focussed on its use in protection against clickjacking only. The HTTP Content-Security-Policy (CSP) frame-ancestors directive specifies valid parents that may embed a page using an Iframe. It can be used to indicate whether or not a browser should be allowed to render a page in an Iframe by have its value set as any of the following:
Content-Security-Policy:frame-ancestors 'none'
By specifying ‘none’, no site will be allowed to load the page in a frame.
Content-Security-Policy:frame-ancestors 'self'
On the other hand, if you specify ‘self’, you can still use the page in a frame as long as the site including it in a frame is the same as the one serving the page.
Content-Security-Policy: frame-ancestors uri
If you specify this, then the site can be displayed in a frame only by uri specified. For example: If you implement the below header directive, then your site will be allowed to be iframed only by the specified url i.e. https://google.com
Content-Security-Policy:frame-ancestors https://google.com
Frame-Busting
In this technique, JavaScript that runs on user’s browser is used to stop itself being embeded into iframe and escape out of it. When the page loads, this JS code will check if the domain of the page matches the domain of the browser window. If it does then no problem, if it does not then it will escape out of the iframe and load the site in the browser by replacing the site trying to load it in the Iframe.
<style>
/* Hide page by default */
html { display : none; }
</style>
<script>
if (self == top) {
// Everything checks out, show the page.
document.documentElement.style.display = 'block';
} else {
// Break out of the frame.
top.location = self.location;
}
</script>
Code-Snippets
In this section, there are code snippets which will be handy for developers to fix clickjacking. These code snippets will basically set the HTTP response headers responsible for mitigating clickjacking. The headers are the ones that we earlier discussed in earlier in this guide.
NodeJS
response.setHeader("X-Frame-Options", "DENY");
response.setHeader("Content-Security-Policy", "frame-ancestors 'none'");
Java
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
response.addHeader("X-Frame-Options", "DENY");
response.addHeader("Content-Security-Policy", "frame-ancestors 'none'");
}
PHP
response.setHeader("X-Frame-Options", "DENY");
response.setHeader("Content-Security-Policy", "frame-ancestors 'none'");
Web server & frameworks config
In this section, there are config snippets useful handy for system admins to fix clickjacking. These code snippets will basically set the HTTP response headers responsible for mitigating clickjacking. The headers are the ones that we earlier discussed in earlier in this guide.
Apache
Enable mod_headers using this commanda2enmod headers
Restart the apache serversudo service apache2 restart
Open and edit the config file in sites-available foldersudo nano 000-default.conf
Add the following lines in <Virtual host>Header set X-Frame-Options "DENY"
Header set Content-Security-Policy "frame-ancestors 'none'"
Again restart the apache serversudo service apache2 restart
Nginx
Open and edit the config file in sites-available foldersudo nano default
Add the following lines in {Server block}add_header X-Frame-Options "DENY";
add_header Content-Security-Policy "frame-ancestors 'none'";
Restart the nginx serversudo service nginx restart
Wordpress
Open and edit the wp-config.php filesudo nano wp-config.php
Add the following lines in the end of the fileheader('X-Frame-Options: SAMEORIGIN');
header("Content-Security-Policy: frame-ancestors 'none'");
The code and techniques that developers and system admins need.