Confundió a intermediarios maliciosos con HTTPS y HTTP con Seguridad de transporte estricta

Dada la cantidad de datos personales que fluyen a través de la gran serie de tubos que es Internet, la encriptación no es algo que podamos o deberíamos ignorar a la ligera. Los navegadores modernos ofrecen varios mecanismos para garantizar que los datos de los usuarios estén seguros mientras están en tránsito: las cookies seguras y la seguridad de transporte estricta son dos de las más importantes. Te permiten proteger sin problemas a tus usuarios, actualizar sus conexiones a HTTPS y proporcionar la garantía de que los datos del usuario nunca se enviarán de forma clara.

¿Por qué debería importarte? Piensa en este ejemplo:

Entregar una página web a través de una conexión HTTP no encriptada es más o menos lo mismo que entregar un sobre sin sellar a la primera persona que ves en la calle y que parece que camina en dirección a la oficina de correo. Si tienes suerte, ella misma puede llevarlo hasta allí o podría entregarlo a la siguiente persona que vea que va en la dirección correcta. Esa persona podría hacer lo mismo y así sucesivamente.

La mayoría de los desconocidos de esta cadena improvisada son confiables y nunca leerían tu carta abierta ni la modificarían. Sin embargo, cuantas más veces cambie la letra, mayor será la cantidad de personas con acceso completo a la carta que estás enviando. Al final, es muy probable que el destinatario previsto de tu carta reciba algo por el correo, pero si eso es mismo, algo que entregaste en primer lugar es una pregunta abierta. Quizá deberías haber sellado ese sobre...

Intermediarios

Para bien o peor, amplias secciones de Internet se basan en la confiabilidad de los extraños. Los servidores no están conectados directamente entre sí, pero pasan solicitudes y respuestas de un router a otro en un enorme juego de llamadas.

Con traceroute, puedes ver estos saltos en acción. La ruta desde mi computadora hasta HTML5Rocks se ve de la siguiente manera:

$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
 1  router1-lon.linode.com (212.111.33.229)  0.453 ms
 2  212.111.33.233 (212.111.33.233)  1.067 ms
 3  217.20.44.194 (217.20.44.194)  0.704 ms
 4  google1.lonap.net (193.203.5.136)  0.804 ms
 5  209.85.255.76 (209.85.255.76)  0.925 ms
 6  209.85.253.94 (209.85.253.94)  1.226 ms
 7  209.85.240.28 (209.85.240.28)  48.714 ms
 8  216.239.47.12 (216.239.47.12)  22.575 ms
 9  209.85.241.193 (209.85.241.193)  36.033 ms
10  72.14.233.180 (72.14.233.180)  43.222 ms
11  72.14.233.170 (72.14.233.170)  43.242 ms
12  *
13  lb-in-f102.1e100.net (173.194.71.102)  44.523 ms

13 saltos no está mal, en realidad. Sin embargo, si envío solicitudes a través de HTTP, cada uno de esos routers intermedios tiene acceso completo a mis solicitudes y a las respuestas de los servidores. Todos los datos se transfieren como texto sin formato sin encriptar, y cualquiera de esos intermediarios podría actuar como intermediario, leer los datos o incluso manipularlos en tránsito.

Peor aún, este tipo de intercepción es prácticamente indetectable. Una respuesta HTTP modificada de forma malintencionada se parece exactamente a una respuesta válida, ya que no existe un mecanismo que te permita asegurarte de que los datos recibidos sean exactamente los datos enviados. Si alguien decide dar rienda suelta a mi Internet, yo no tengo suerte.

¿Esta es una línea segura?

Cambiar de HTTP de texto simple a una conexión HTTPS segura ofrece tu mejor defensa contra los intermediarios. Las conexiones HTTPS encriptan todo el canal de extremo a extremo antes de que se envíen datos, lo que hace imposible que las máquinas entre tú y tu destino lean o modifiquen datos en tránsito.

El cuadro multifunción de Chrome ofrece bastante información detallada sobre el estado de la conexión.
El cuadro multifunción de Chrome ofrece bastante detalle sobre el estado de una conexión.

La seguridad que proporciona HTTPS se basa en el concepto de claves criptográficas públicas y privadas. Un análisis detallado de los detalles está (afortunadamente) fuera del alcance de este artículo, pero la premisa principal es bastante directa: los datos encriptados con una clave pública determinada solo se pueden desencriptar con la clave privada correspondiente. Cuando un navegador inicia un protocolo de enlace HTTPS para crear un canal seguro, el servidor proporciona un certificado que brinda al navegador toda la información necesaria para verificar su identidad comprobando que el servidor posea la clave privada adecuada. Todas las comunicaciones a partir de ese momento están encriptadas, de manera que se demuestre que las solicitudes se entregan y las respuestas que se reciben del servidor autenticado.

Por lo tanto, HTTPS te garantiza que estás hablando con el servidor al que crees que lo estás hablando y que nadie más está escuchando ni manipulando bits en el cable. Este tipo de encriptación es un requisito previo absoluto para la seguridad en la Web. Si tu aplicación no se entrega actualmente a través de HTTPS, es vulnerable a ataques. Soluciónalo Ars Technica tiene una excelente guía para obtener e instalar un certificado (gratis) que te recomendamos que consultes para obtener detalles técnicos. La configuración diferirá de un proveedor a otro y de un servidor a otro, pero el proceso de solicitud de certificado es el mismo en todas partes.

Seguridad predeterminada

Una vez que hayas solicitado e instalado un certificado, asegúrate de que tus usuarios se beneficien de tu arduo trabajo: migra a tus usuarios existentes a conexiones HTTPS con transparencia mediante la magia del redireccionamiento HTTP y asegúrate de que las cookies solo se entreguen a través de conexiones seguras.

De esta manera,

Cuando un usuario visite http://example.com/, redirecciónalo a https://example.com/ mediante el envío de una respuesta 301 Moved Permanently con un encabezado Location adecuado:

$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/

Puedes configurar este tipo de redireccionamiento fácilmente en servidores como Apache o Nginx. Por ejemplo, una configuración de Nginx que redirecciona de http://example.com/ a https://example.com/ se ve de la siguiente manera:

server {
    listen [YOUR IP ADDRESS HERE]:80;
    server_name example.com www.example.com;
    location "/" {
        rewrite ^(.*) https://www.example.com$1 permanent;
    }
}

Las cookies nos brindan la capacidad de proporcionar a los usuarios experiencias de acceso sin inconvenientes a través del protocolo HTTP sin estado. Los datos almacenados en cookies, incluida la información sensible, como los IDs de sesión, se envían junto con cada solicitud, lo que permite que el servidor sepa a qué usuario está respondiendo en ese momento. Una vez que nos aseguramos de que los usuarios acceden a nuestro sitio a través de HTTPS, también debemos asegurarnos de que los datos sensibles almacenados en las cookies solo se transfieran a través de una conexión segura y nunca se envíen de forma clara.

Por lo general, configurar una cookie implica un encabezado HTTP similar al siguiente:

set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT

Puedes indicarle al navegador que restrinja el uso de la cookie a fin de proteger las sesiones. Para ello, agrega una sola palabra clave:

Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure

Las cookies establecidas con la palabra clave secure nunca se enviarán a través de HTTP.

Cerrando la ventana abierta

El redireccionamiento transparente a HTTPS significa que la gran mayoría de las veces que los usuarios están en tu sitio usarán una conexión segura. Sin embargo, existe una pequeña oportunidad de ataque: la conexión HTTP inicial es muy abierta y es vulnerable a la eliminación de SSL y a los ataques relacionados. Dado que un intermediario tiene acceso completo a la solicitud HTTP inicial, puede actuar como un proxy entre tú y el servidor, lo que te mantiene en una conexión HTTP insegura, independientemente de las intenciones del servidor.

Para mitigar el riesgo de esta clase de ataque, solicita al navegador que aplique HTTP con Seguridad de Transporte Estricta (HSTS). El envío del encabezado HTTP Strict-Transport-Security le indica al navegador que realice el redireccionamiento de HTTP a HTTPS del cliente, sin tocar la red (esto también es excelente para el rendimiento, ya que la mejor solicitud es aquella que no tienes que hacer):

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Los navegadores compatibles con este encabezado (actualmente Firefox, Chrome y Opera: caniuse tiene detalles) registrarán que este sitio en particular solicitó acceso solo con HTTPS. Esto significa que, independientemente de cómo acceda el usuario al sitio, lo hará a través de HTTPS. Incluso si escribe http://example.com/ en el navegador, terminará en HTTPS sin tener que establecer una conexión HTTP. Mejor aún, si el navegador detecta un certificado no válido (posiblemente que intenta falsificar la identidad de tu servidor), los usuarios no podrán continuar a través de HTTP; es excelente.

El estado de HSTS del servidor vencerá después de max-age segundos (alrededor de un mes en este ejemplo). Establece este valor en un valor razonablemente alto.

Para asegurarte de que todos los subdominios de un origen estén protegidos, también puedes agregar la directiva includeSubDomains al encabezado:

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Avanza con seguridad

HTTPS es la única forma de asegurarse de que los datos que envíes lleguen intactos al destinatario deseado. Deberías configurar conexiones seguras para tus sitios y aplicaciones hoy mismo. Es un proceso bastante sencillo y te ayudará a proteger los datos de tus clientes. Una vez que tengas un canal encriptado, debes redireccionar a los usuarios de manera transparente a esta conexión segura, sin importar cómo ingresan a tu sitio, mediante el envío de una respuesta HTTP 301. Luego, asegúrate de que toda la información sensible de la sesión de los usuarios use solo esa conexión segura. Para ello, agrega la palabra clave secure cuando configures cookies. Una vez que hayas hecho todo, asegúrate de que tus usuarios nunca se caigan por accidente del autobús: para protegerlos, asegúrate de que el navegador haga lo correcto enviando un encabezado Strict-Transport-Security.

Configurar HTTPS no es demasiado trabajo y tiene enormes beneficios para tu sitio y sus usuarios. Vale la pena el esfuerzo.

Recursos

  • StartSSL ofrece certificados gratuitos verificados por el dominio. Es inigualable. Pasar a calificaciones más altas de verificación, por supuesto, es posible y a un precio razonable.
  • Prueba del servidor SSL: Una vez que hayas configurado HTTPS para tus servidores, verifica que lo hayas hecho correctamente ejecutando el protocolo mediante la prueba del servidor de SSL Labs. Obtendrás un informe bien detallado que te mostrará si ya estás funcionando.
  • Vale la pena leer el artículo reciente de Ars Technica "Securing your Web Server with SSL/TLS", para obtener un poco más de información general sobre los aspectos básicos de la configuración de un servidor.
  • Vale la pena leer la especificación de HTTP con Seguridad de Transporte Estricta (RFC6797) para obtener toda la información técnica sobre el encabezado Strict-Transport-Security que podrías querer.
  • Una vez que realmente sepas lo que estás haciendo, un posible paso siguiente sería anunciar que solo se debería poder acceder a tu sitio mediante un conjunto específico de certificados. Hay cierto trabajo en curso en el IETF que te permitiría hacerlo a través del encabezado Public-Key-Pins; aún es reciente, pero es interesante y vale la pena seguir.