Skip to main content

Secure Apache from clickjacking attacks using X-FRAME-OPTIONS y Content Security Policy (CSP) frame-ancestors HTTP headers

In an earlier post, we wrote about clickjacking attacks: its definition, how to know if a website or a web application is vulnerable and different protection techniques [1]. In this post we will demonstrate how to configure the Apache web server in order to protect it against these kind of attacks.

As we have seen, there is not a unique mechanism to protect Apache from all the possible clickjacking attacks, but a good alternative is the use of the X-Frame-Options header[2] together with the frame-ancestors directive of the Content Security Policy (CSP) header [3]. Luckily, Apache can be configured to add both headers to all its HTTP/HTTPS responses in order not to depend on the programmer of the website or the web application to do it inside their code.

To make Apache add these two HTTP headers in Debian-based distributions (Ubuntu included) the following has to be done:

Step 1: Activate the headers module in the Apache configuration, if not active already:
 # sudo a2enmod headers

Step 2: Edit the file /etc/apache2/conf-available/security.conf and add these two lines:
Header set X-Frame-Options: "SAMEORIGIN"
Header set Content-Security-Policy: "frame-ancestors 'self';"

Generally the first line is already included in the file but commented out. In this case, it is convenient to uncomment the line already in the file and add the second line immediately after. It is important to note that the value assigned in both lines must have the same meaning. As it was seen in our earlier post on clickjacking, the values SAMEORIGIN and 'self' specify the website or web application can only be embedded within itself [1]. If values with different meaning were assigned, as for example SAMEORIGIN in X-Frame-Options and none in frame-ancestors, this would lead to unstable behavior because in some browsers these headers are prioritized differently. In the following chart we include the equivalency between the possible values for both headers:

X-Frame-Options frame-ancestors Significado
DENY 'none' The website cannot be embedded.
SAMEORIGIN 'self' The website can only be embedded within itself.
ALLOW-FROM uri uri The website can only be embedded within the specified site by the uniform resource identifier (uri).

Step 3: Restart Apache:
 # sudo systemctl restart apache2

With these three steps Apache is configured to add the HTTP headers in all the responses to the requests it receives.

Step 4: Whenever changes to the services' configurations are applied, it is necessary to verify they have had the desired impact. Therefore, it can be verified if Apache is adding the two headers to its responses using the command curl [4] in the following way:

 # curl -I -L

In this case, the option -I of the command curl requests the web server only the HTTP headers of the website. The output should be as follows, where it could be visualized the two corresponding lines to the headers  X-Frame-Options and Content-Security-Policy: frame-ancestors.

 HTTP/1.1 200 OK
 Date: Tue, 11 Feb 2020 19:18:53 GMT
 Server: Apache
 Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
 Last-Modified: Wed, 05 Feb 2020 14:25:25 GMT
 Accept-Ranges: bytes
 Content-Length: 34045
 Vary: Accept-Encoding
 X-Content-Type-Options: nosniff
 X-Frame-Options: SAMEORIGIN
 Content-Security-Policy: frame-ancestors 'self';
 X-XSS-Protection: 1; mode=block
 Content-Type: text/html

Another way of verifying if Apache is adding the headers to its responses is through the web application [5]. Any of the two methods is valid to verify that the changes have had the desired effect.

We hope this post has been useful and we'll be back soon!