Proteger Apache contra ataques de clickjacking a través de las cabeceras X-FRAME-OPTIONS y Content Security Policy (CSP) frame-ancestors
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:
Paso 2: Editar el archivo
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:
Paso 3: Reiniciar Apache:
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:
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.
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
En nuestro 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