Asegurando las cabeceras de respuestas HTTP en servidores web Apache y NGINX

Las Cabeceras HTTP son los parámetros que se envían en una petición o respuesta HTTP al cliente o al servidor, para proporcionar información esencial sobre la transacción en curso.

En este artículo nos enfocaremos en las cabeceras de respuesta que nos dan los servidores web, estos encabezados de respuesta HTTP son pares de nombre-valor de cadenas enviadas desde un servidor con el contenido que solicitó. Normalmente se usan para transferir información técnica, por ejemplo: cómo un navegador debe almacenar en caché el contenido, qué tipo de contenido es, el software que se ejecuta en el servidor y mucho más.

Cabecera de respuesta HTTP NGINX

Esta información es de gran valor para un atacante, ya que estos mensajes de bienvenida del servidor web son la pista principal para conocer qué servicio es el que se ofrece, qué tecnología se está utilizando y ver los posibles errores al manipular peticiones. Podemos decir que sería una de las principales actividades que realizaría un atacante durante la fase de reconocimiento.

Cabecera de respuesta HTTP Apache

Conociendo las posibles actividades que realizaría un atacante, nosotros vamos a reforzar estos encabezados de respuesta HTTP para hacer su sitio más seguro y proporcionar al navegador más información sobre cómo deseamos que se comporte con respecto a nuestro sitio.

Básicamente vamos a transmitir políticas de seguridad al navegador del cliente. Al pasar las políticas de seguridad al cliente, se podría garantizar una experiencia de navegación mucho más segura ya que podemos establecer opciones de configuración e inhabilitar características del navegador que no desea habilitar para nuestro sitio.

Desde Guayoyo Labs vemos que este problema está presente en una gran cantidad de servidores web expuestos a Internet, y con esta guía queremos aportar algunas soluciones para corregir estos errores en los encabezados y así agregar otra capa de seguridad a nuestros servidores web.

Content Security Policy

El encabezado CSP le permite definir una lista blanca de fuentes de contenido aprobadas para su sitio. Al restringir los activos que un navegador puede cargar para su sitio, como JS y CSS, CSP puede actuar como una contramedida efectiva para los ataques XSS.

Nginx:

add_header Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'" always;

Apache:

Header always set Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'"

HTTP Strict Transport Security (HSTS)

HSTS permite decirle a un navegador que siempre quiere que un usuario se conecte usando HTTPS en lugar de HTTP. Esto significa que cualquier marcador, enlace o dirección forzará a los usuario a usar HTTPS, incluso si especifican HTTP.

NginX:

add_header Strict-Transport-Security "max-age=31536000; includeSubdomains" always;

Apache:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

X-Frame-Options

El encabezado X-Frame-Options ( RFC ) protege a los visitantes contra ataques de clickjacking. Un atacante puede cargar un iFrame en su sitio y establecer su sitio web como la fuente. Es bastante fácil, por ejemplo: <iframe src="https://tudominio.com"></iframe>.

Posibles valores para la cabecera X-Frame-Options:

DENY: Esta configuración es la más restrictiva e impide que la página del sitio se incluya en un iFrame. Esta opción es óptima si no tiene usuarios válidos para un iFrame.
SAMEORIGIN: Si una página padre es para el mismo dominio que la página del sitio, la página del sitio puede incluirse en el iFrame.
ALLOW-FROM: Puede especificar una URI única permitida para enmarcar la página del sitio.

NginX:

add_header X-Frame-Options "SAMEORIGIN" always;

Apache:

Header always set X-Frame-Options "SAMEORIGIN"

X-Xss-Protection

Este encabezado se usa para configurar la protección contra un XSS reflejado. Las configuraciones válidas para el encabezado son:

  • 0 desactiva la protección
  • 1 habilita la protección
  • 1; mode=block le dice al navegador que bloquee la respuesta si detecta un ataque en lugar de desinfectar el script.

NginX:

add_header X-Xss-Protection "1; mode=block" always;

Apache:

Header always set X-Xss-Protection "1; mode=block"

X-Content-Type-Options

Esta cabecera sólo tiene un valor válido, nosniff. Impide que Google Chrome e Internet Explorer intenten detectar el tipo de contenido de una respuesta distinta de la que el servidor declara.

Nginx:

add_header X-Content-Type-Options "nosniff" always;

Apache:

Header always set X-Content-Type-Options "nosniff"

Eliminemos algunas cabeceras

Ahora vamos a reducir la cantidad de información que las cabeceras pueden estar divulgando sobre su servidor y lo que se ejecuta en él. Los servidores normalmente revelan qué software se está ejecutando en ellos, qué versiones del software hay allí y qué frameworks se está utilizando. Reducir la cantidad de información que divulga siempre es muy beneficioso.

Apache:

Hay dos directivas que necesitas agregar, o cambiar en el archivo de configuración /etc/apache/conf.d/security y estas son: ServerTokens y ServerSignature.

ServerSignature Off
ServerTokens Prod

El ServerSignature aparece en la parte inferior de las páginas generadas por Apache, por ejemplo al mostrar el error 404 (documento no encontrado).

La directiva ServerTokens sirve para determinar lo que pondrá Apache en la cabecera de la respuesta HTTP del servidor.

Nginx:

Para cambiar el valor del encabezado del servidor en Nginx no es tan fácil pero aquí traemos dos opciones:

Opción 1: Si el servidor ya está compilado, o no se puede re-compilar, aquí solo nos quedaría quitar la versión que muestra nginx, esto lo hacemos en el archivo de configuración nginx.conf

server_tokens off;

También es posible que se observen mensajes de error del servicio con alguna información de NGINX. Para asegurar que no se reporta en ningún momento lo mejor es modificar en el archivo src/http/ngx_http_special_response.clas siguientes líneas:

static u_char ngx_http_error_full_tail[ ] =
“<hr><center>” NGINX_VER “</center>” CRLF
“</body>” CRLF
“</html>” CRLF
;
static u_char ngx_http_error_tail[ ] =
“<hr><center>nginx</center>” CRLF
“</body>” CRLF
“</html>” CRLF
;

Por otras que no incluyan la variable NGINX_VER:

static u_char ngx_http_error_full_tail[ ] = CRLF;
static u_char ngx_http_error_tail[ ] = CRLF;

Opción 2: Para eliminar la cadena “nginx” de la cabecera Server antes de compilar el servidor, es necesario modificar el código fuente en el archivo src/http/ngx_http_header_filter_module.c las siguientes líneas y luego compilar:

static char ngx_http_server_string[ ] = “Server: nginx” CRLF;
static char ngx_http_server_full_string[ ] = “Server: “ NGINX_VER CRLF;

Por

static char ngx_http_server_string[ ] = “Server: httpd” CRLF;
static char ngx_http_server_full_string[ ] = “Server: httpd” CRLF;

Con los cambios que vimos anteriormente, buscamos incorporar algunas configuraciones que nos ayuden a mejorar la postura de seguridad de nuestros servidores web.

Este artículo es el primero de una serie de publicaciones dedicadas al Hardening, estamos convencidos que es una de las principales actividades que se debe tomar en cuenta para asegurar un sistema y reducir sus vulnerabilidades.