Skip to main content

Proteger Apache contra ataques de clickjacking a través de las cabeceras X-FRAME-OPTIONS y Content Security Policy (CSP) frame-ancestors

En nuestro post anterior escribimos sobre los ataques de clickjacking: su definición, cómo saber si un sitio o aplicación web es vulnerable y diferentes técnicas de protección [1]. En este post vamos a ver como configurar el servidor web Apache para que esté protegido contra este tipo de ataque.

Como vimos, no existe un único mecanismo que permita defenderse contra todos los posibles ataques de clickjacking, pero una buena medida es el uso de la cabecera X-Frame-Options [2] en conjunto con la directiva frame-ancestors de la cabecera Content Security Policy (CSP) [3]. Por suerte, se puede configurar Apache para que agregue ambas cabeceras a todas sus respuestas HTTP/HTTPS, de forma no se depende de que el programador del sitio o la aplicación web lo haga dentro de su código.

En las distribuciones basadas en Debian (incluidas Ubuntu) para hacer que Apache agregue estas dos cabeceras HTTP hay que hacer lo siguiente:

Paso 1: Si no está activado, activar el módulo headers en la configuración de Apache:
 # sudo a2enmod headers

Paso 2: Editar el archivo /etc/apache2/conf-available/security.conf y agregar las siguientes dos líneas:
Header set X-Frame-Options: "SAMEORIGIN"
Header set Content-Security-Policy: "frame-ancestors 'self';"

Por lo general la primera línea ya está incluida en el archivo pero comentada. En tal caso y por una cuestión de orden, conviene descomentar la línea que ya está en el archivo y agregar la segunda línea inmediatamente después. Es importante destacar que el valor asignado en ambas líneas debe tener el mismo significado. Como vimos en nuestro post anterior, tanto el valor SAMEORIGIN como el valor 'self' especifican que el sitio o aplicación web sólo puede ser embebido dentro de sí mismo [1]. Si se asignaran valores con distinto significado, como por ejemplo SAMEORIGIN en X-Frame-Options y none en frame-ancestors, daría lugar a un comportamiento inestable ya que en algunos navegadores tiene precedencia una cabecera y en otros otra. A continuación incluimos una tabla con la equivalencia entre los posibles valores para ambas cabeceras:

X-Frame-Options frame-ancestors Significado
DENY 'none' El sitio web no puede ser embebido.
SAMEORIGIN 'self' El sitio web sólo puede ser embebido dentro de sí mismo.
ALLOW-FROM uri uri El sitio web sólo puede ser embebido dentro del sitio especificado por el identificador uniforme de recursos (uri).

Paso 3: Reiniciar Apache:
 # sudo systemctl restart apache2

Con estos tres pasos Apache ya queda configurado para agregar las cabeceras HTTP en todas las respuestas a las peticiones que recibe.

Paso 4: Siempre que se aplican cambios en las configuraciones de los servicios hay que verificar que las mismas hayan tenido el impacto deseado. Por lo tanto, se puede verificar si Apache está agregando las cabeceras en sus respuestas utilizando el comando curl [4] de la siguiente manera:
 # curl -I -L https://www.openminds.com.ar

En este caso, la opción -I del comando curl le solicita al servidor web sólo las cabeceras HTTP del sitio web. La salida debería ser como la siguiente, en donde se deberían poder visualizar las dos líneas correspondientes a las cabeceras X-Frame-Options y 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

Otra forma de verificar si Apache está agregando las cabeceras en sus respuestas es a través de la aplicación web de clickjacker.io [5]. Cualquiera de los dos métodos es válido para verificar que los cambios realizados tuvieron efecto.

Esperamos que este post les haya sido útil y nos leemos pronto!


Referencias:
[1] https://blog.openminds.com.ar/2019/11/ataques-de-clickjacking-definicion-y.html
[2] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
[3] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors
[4] https://linux.die.net/man/1/curl
[5] https://clickjacker.io