Hardening - Mejorando configuraciones SSL/TLS

Los protocolos criptográficos SSL/TLS sirven para cifrar comunicaciones en la red y nos ayudan a proteger para que cualquier tipo de dato que un usuario escriba en un sitio web, no pueda ser accedido por otro usuario de la red.

Generalmente pensaríamos que los datos como contraseñas o números de tarjetas de crédito son los únicos que deberían ser protegidos, sin embargo cualquier página que tenga un formulario debería tener un certificado SSL. Google sabe muy bien esto y desde la versión 56 de Chrome comenzó a marcar los sitios web HTTP que contengan formulario de contraseñas y tarjetas de crédito como “Not secure” y partir de la versión 62, todos los sitios web (HTTP) que contengan cualquier formulario, será marcada como no segura.

Esto representa un reto para las empresas y organizaciones que hasta el momento no tienen en sus portales y sistemas web certificados SSL/TLS (HTTPS).

Ahora bien, tenemos que tener en cuenta que los portales y sistemas web que ya cuentan con conexiones HTTPS, de igual forma están expuestos a una serie de ataques.

Algunos ataques significativos a protocolos criptográficos SSL/TLS:

  • Ataques de renegociación
  • Ataques de reversión de versiones
  • Ataque BEAST
  • Ataques CRIME y BREACH
  • Ataques de relleno
  • Ataque POODLE
  • Ataque RC4
  • Fallo Heartbleed

Teniendo en cuenta todo lo anterior, desde GuayoyoLabs vamos a proponer algunas configuraciones SSL/TLS en los servidores web, para mejorar la postura de seguridad frente a estos ataques.

Lo primero que vamos hacer es utilizar una herramienta muy intuitiva de la empresa Qualys, para ver el estatus de nuestras configuraciones https://www.ssllabs.com/ssltest/ recuerda marcar la opción “Do not show the results on the boards”.

Ahora vamos con las configuraciones que puedes emplear en tu servidores web para mitigar varios de los ataques a estos protocolos.

Apache:

Se configura en /etc/httpd/conf.d/ssl.conf recomendamos estas configuraciones a partir de las versiones de Apache 2.4

SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4
SSLProtocol All -SSLv2 -SSLv3 -TLSv1
SSLHonorCipherOrder On
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Content-Type-Options nosniff
# Requires Apache >= 2.4
SSLCompression off
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
# Requires Apache >= 2.4.11
SSLSessionTickets Off
# Requiere Apache 2.4.8
#Usar una clave Diffie-Hellman > 2048, se puede generar con el comando
##cd /etc/ssl/certs; openssl dhparam -out dhparams.pem 4096
#SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"

Nginx:

ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

#Para compatibilidad con IE6 y WINXP los siguientes
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

#Usar una clave Diffie-Hellman > 2048, se puede generar con el comando
# cd /etc/ssl/certs; openssl dhparam -out dhparams.pem 4096
ssl_dhparam /etc/ssl/certs/dhparam.pem;

#No usar SSLv2 / SSLv3 / TLSv1
ssl_protocols TLSv1.1 TLSv1.2;

#Usar la preferencia del servidor y no la del cliente.
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

#Otras recomendaciones cabeceras HTTP
ssl_session_timeout 10m;
# X-Frame-Options is to prevent from clickJacking attack
add_header X-Frame-Options SAMEORIGIN;
# disable content-type sniffing on some browsers.
add_header X-Content-Type-Options nosniff;
# This header enables the Cross-site scripting (XSS) filter
add_header X-XSS-Protection "1; mode=block";
# This will enforce HTTP browsing into HTTPS and avoid ssl stripping attack
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

ssl_session_tickets off;
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on;
keepalive_timeout 60;

No te olvides de reiniciar los servidores web para que puedan cargar los cambios que estás realizando.

Algunas consideraciones importantes:

¿Ésta es la mejor configuración para HTTPS que puedo tener?

La respuesta es un absoluto NO. Recuerda que ninguna configuración puede garantizar la seguridad al 100%.

Al aplicar configuraciones para HTTPS se deben tener en cuenta algunas consideraciones, las cuales se aplican para mejorar la seguridad. Éstas también van a impedir que muchos usuarios que utilizan dispositivos viejos puedan acceder a tu sistema por HTTPS y es aquí donde nos preguntaríamos:

¿Deseo bloquear a todos estos usuarios que utilizan dispositivos viejos para estar más seguro, o deseo relajar un poco los requisitos de seguridad para asegurarme que más personas tengan acceso al sitio web?

Claramente la mayoría de las veces esta es una decisión comercial. Si habláramos de un portal web común que no afectaría a gran cantidad de usuarios, la decisión sería mucho más fácil. Pero si tenemos un sistema con una gran cantidad de usuarios, tendríamos que verificar y estar conscientes de las tecnologías y versiones viejas que quedarían excluidas.

La decisión comercial de seguro siempre será dar acceso a la mayor cantidad de usuarios posibles y es aquí donde entramos en el dilema:

Seguridad vs. Flexibilidad

No contar con buenas configuraciones o mecanismos de seguridad puede ser una fortuna caprichosa que golpea en el momento más inesperado. No debemos caer en el error de que mientras todo funcione la seguridad parece ser un desperdicio de recursos, porque cuando los planetas se alinean y los protocolos comienzan a hablar con los atacantes, de seguro nos vamos a encontrar a milímetros de la tragedia y en ese momento la seguridad si va a parecer atractiva, elegante y necesaria.

Otra punto a tomar en cuenta es que los vendors de estos productos o tecnologías que se encuentran viejas, constantemente están trabajando para que los usuarios utilicen las versiones más actuales, entonces sería un poco ilógico pensar que es imposible que los usuarios se puedan actualizar pero siempre van a quedar atados a una versión vieja.

Nuevamente, esta es una decisión comercial y depende de cuánta seguridad está dispuesto a sacrificar para permitir el acceso a más clientes. Si eres el administrador del sistema, probablemente sea una buena idea consultar bien antes de tomar esta decisión por su cuenta.

Mozilla tiene un sitio web dedicado a ayudar a los administradores de servidores web a elegir la configuración HTTPS más adecuada, puedes verlo aquí.