El triste estado de las revocaciones SSL en Internet

Este artículo está inspirado en el muy recomendable podcast Security Now, más concretamente en los programas Certificate Revocation Part 1 (29 de abril de 2014), Certificate Revocation Part 2 (6 de mayo de 2014) y Listener Feedback #187 (13 de mayo de 2014). Tenéis las transcripciones online.

Heartbleed

Hasta mi abuela ha oído hablar de Heartbleed, pero si te has pasado el último mes secuestrado en una cueva te lo resumo: Se trata de un fallo de seguridad en la librería OpenSSL que permite obtener fragmentos aleatorios de 64 Kbytes de la memoria del servidor. Las consecuencias son inmensas, porque los datos filtrados son impredecibles. En muchos casos será basura inútil, pero hay ejemplos de filtrado masivo de claves. El atacante sólo necesita insistir hasta que uno de los bloques obtenidos sea útil.

¿Qué se puede hacer, una vez solucionado el bug? Pues la cosa es complicada, porque básicamente no sabemos si hemos sido atacados y, si hemos sido atacados, qué información ha obtenido el atacante. Es muy difícil justificar acciones costosas (en dinero o en imagen) sin saber si realmente alguien nos ha atacado exitosamente. Cambio de claves de millones de usuarios, reemplazo de tokens hardware, y vete tú a saber qué más.

Y, el tema principal de este artículo, el reemplazo del certificado SSL del servidor.

Porque sí, uno de los datos confidenciales que se ha podido filtrar es la propia clave privada del certificado SSL del servidor. En palabras llanas, eso permite que un atacante se haga pasar por tu banco, por ejemplo, y que tu navegador te confirme fuera de todas dudas que sí, es tu banco.

Por tanto, lo primero que tendrían que haber hecho los administradores de los sistemas afectados sería revocar el certificado SSL antiguo y adquirir y desplegar un certificado SSL nuevo.

No voy a entrar en este artículo sobre si se está haciendo o si se está haciendo bien. Me voy a centrar en la operativa de la revocación.

¿Qué es la revocación de certificados SSL?

Tu navegador web acepta el certificado SSL de un servidor web porque está firmado por una entidad de certificación reconocida por él. Se supone que dicha entidad de certificación ha comprobado la identidad del propietario del certificado firmado y, por tanto, lo "avala".

(El mundo de las entidades de certificación merece una miriada de artículos de escarnio público, pero no es el tema de este documento. Ya les llegará su hora, ya...)

Este "aval" se incluye en el certificado que el servidor te envía cuando te conectas a él y suele durar un año o dos. Pasado ese tiempo, es necesario renovar el "aval" para que tu navegador siga aceptándolo.

Pero hay situaciones en las que el "aval" debe revocarse. Cambio de administradores web, por ejemplo. O el tener una intrusión en un sistema, donde el atacante ha podido copiar la clave secreta del certificado SSL del servidor y, por tanto, puede hacerse pasar por él. Pensad, por ejemplo, en lo que supondría haber copiado la clave de un banco, o de Facebook, o de Google, e irse a una red WIFI abierta (hotel, cafetería, restaurante) y dedicarse a capturar tráfico o a hacerse pasar por ese servidor. Y los navegadores de las víctimas, como se les presenta un certificado SSL válido y "avalado", lo dan por bueno. Lo siento, game over.

Por tanto, los "avales" son revocables. Una entidad de certificación puede anunciar al mundo que un certificado firmado por ellos ya no es válido, aunque el "aval" en sí todavía no haya caducado.

¿Cómo se verifica la revocación de un certificado X.509?

En el principio de los tiempos se creó una extensión X.509 para que los certificados indiquen dónde reside su Certificate Revocation List. La extensión se llama CRL Distribution Points y proporciona una lista de URLs que el navegador puede usar para descargar la lista de números de serie revocados. Cada certificado firmado por una entidad de certificación contiene un número de serie diferente, y la Certificate Revocation List es la lista de números de serie cuyos "avales" han sido revocados, por el motivo que sea.

El tamaño de una CRL suele estar limitado porque las revocaciones son escasas (comparado con el número de certificados generados), y el número de serie de un certificado revocado solo necesita permanecer en la CRL hasta que el certificado original expira (la duración habitual de un certificado es un año). Pero ante eventos inesperados y masivos como Heartbleed, las CRL se vuelven enormes y difíciles de distribuir.

Hay miles de millones de navegadores web por el mundo. Se supone que antes de entrar en una web HTTPS habría que verificar si el certificado está revocado. Eso supone latencia y volumen de descarga, tanto para el usuario como para la propia entidad de certificación. Si el navegador web emplea mecanismos de cacheo para mejorar la velocidad de respuesta percibida por el usuario, un certificado revocado puede parecer válido para el navegador durante días, hasta que refresca sus CRL.

Además, como hay una infinidad de entidades de certificación intermedias, existen también una infinidad de CRL que tu navegador debe verificar y mantener actualizados.

En pocas palabras, las CRL no escalan y existe una ventana durante la cual el certificado está revocado pero tu navegador no se ha enterado aún.

Mal.

Estos problemas son conocidos desde siempre. A alguna gente no le dejaba dormir por las noches, e inventaron un protocolo específico para dormir mejor: OCSP (Online Certificate Status Protocol). La extensión X.509 se llama Authority Information Access.

OCSP es un protocolo relativamente ligero que permite que un navegador pregunte a la entidad de certificación correspondiente si un certificado SSL específico está revocado o no. En vez de bajarnos CRL enteros, nuestro navegador consulta los certificados de los servidores HTTPS específicos a los que se conecta. Lo que estaría bien si no fuese porque sigue habiendo un problema de latencia (teóricamente el navegador no debería cargar la página hasta que la entidad de certificación nos confirma que su certificado no ha sido revocado). Aunque el problema de la latencia es solucionable con cacheo en el navegador, esto vuelve a introducir el problema del retardo entre que se revoca un certificado y nuestro navegador se entera.

Pero la cosa es más grave aún. Un navegador podría refrescar sus CRL periódicamente por su cuenta, para mejorar la latencia, pero OCSP requiere una respuesta en tiempo real. Glup, miles de millones de navegadores haciendo consultas OCSP y queriendo la respuesta YA :).

Es más, y esto me parece absolutamente crítico (y no recuerdo que se haya mencionado en el podcast de Security Now), usando Online Certificate Status Protocol le estamos diciendo a la entidad de certificación, y a todos los nodos y redes intermedias hasta ella, a qué servidores HTTPS nos estamos conectando, cuándo lo hacemos, y desde dónde. Una apabullante intrusión en la privacidad del usuario.

Una de las mejoras disponibles en Apache 2.4 (y otros servidores web, claro) es la disponibilidad de OCSP Stapling. Básicamente consiste en que cuando el servidor HTTPS nos envía su certificado SSL, nos envía también la respuesta OCSP de la entidad de certificación, para que el navegador no necesite consultar a nadie más.

A primera vista, esta solución es perfecta: el navegador no introduce latencia extra al usuario porque la comprobación de la revocación del certificado ya la envía el propio servidor (que no puede falsificarla, porque esa respuesta la ha firmado la propia entidad de certificación). No hay compromiso de privacidad porque quien hace la petición OCSP es el propio servidor web, no el usuario. Es más, el coste de soporte de la entidad de certificación sería proporcional al número de certificados emitidos (y, por tanto, al dinero ingresado), y no proporcional al número de usuarios de una web HTTPS concreta, éxito sobre el que no tienen control y del que no se beneficia económicamente.

El servidor web hace la petición OCSP periódicamente (digamos, cada hora) y esa respuesta vale durante -digamos- ocho horas. Se la guarda y la incluye en todas las conexiones HTTPS que recibe. Perfecto.

Bueno, no del todo. Hay cuatro problemas básicos:

  1. Hay clientes SSL que no saben interpretar una respuesta OCSP Stapling, así que habrá que soportar CRL y OCSP durante un tiempo indefinidamente largo, por compatibilidad con los clientes legacy.
  2. El handshake SSL se alarga un poco y mide más. Puede ser aceptable para los navegadores de escritorio, pero en un móvil pagas por byte recibido. Puede ser un coste aceptable, no obstante, y si se combina con TLS session tickets, podría desaparecer. Desconozco la interacción entre OCSP Stapling y TLS session tickets. Si los TLS session tickets nos ahorran recursos, introducirán retardo entre la revocación de un certificado y la detección por parte del navegador. Si no nos evitan la recepción del OCSP Stapling entonces no ahorraremos tráfico por su causa.
  3. Si la respuesta OCSP dura unas pocas horas (deseable) y la entidad de certificación tiene problemas y no responde, o quiebra o algo similar... estamos acabados. Los usuarios se quedarán fuera de innumerables servicios HTTPS. Puede ser catastrófico.
  4. Pero el mayor problema de todos es que ante un ataque Man in the Middle, el atacante sencillamente no nos enviará el resultado OCSP Stapling, y nos devolverá al punto 1.

Un detalle del que me enteré en el podcast Security Now del que hablé al principio es la iniciativa OCSP Must Staple. Consiste en añadir una extensión más al certificado SSL firmado por la entidad de certificación que indica que el certificado solo es válido si se verifica conjuntamente con una respuesta OCSP. En este caso, si el atacante no incluye una respuesta OCSP reciente, el navegador consideraría que el certificado está revocado. La idea es buena, pero el borrador de estándar caducó hace un año y no parece haber más actividad en este campo. ¿Ha muerto?.

Actualización 2014-05-28: He escrito otro artículo sobre la conveniencia de emplear OCSP Stapling, desde el punto de vista de la privacidad: OCSP Stapling y la privacidad de tus usuarios.

¿Y qué pasa con los navegadores?

Pues es un desastre.

Todo lo dicho está muy bien, y aunque he indicado problemas con la tecnología actual de revocación, el problema real es que a nadie le importa una mierda.

Android no realiza ningún tipo de verificación de revocaciones, a menos que el usuario esté usando Firefox for Android, que es algo opcional (supone una instalación explícita por parte del usuario) y minoritario.

iOS sólo comprueba los certificados EV (Extended Validation Certificate).

En el escritorio Firefox es el único navegador que hace algún esfuerzo al respecto. Aprobado. Chrome usa una lista negra interna mantenida a mano (actualizada cuando actualizas el navegador, que con suerte haces una vez al mes) que solo contendrá revocaciones de certificados llamativos, famosos o especialmente relevantes. Desde luego, no todas las revocaciones realizadas en el mundo, y el porcentaje cubierto será aún menor ante eventos masivos pero puntuales como Heartbleed.

Es más, todos los navegadores que soportan revocación, o ésta es opcional y está desactivada por defecto, o está activada pero configurada como soft-fail que básicamente significa que si no se recibe una respuesta de la entidad de certificación, da el certificado por bueno. Y, justamente cuando tenemos un Man in the Middle en curso es cuando el atacante controla nuestras comunicaciones y puede, sin muchos problemas, filtrar esas peticiones a la entidad de certificación. Pensamos, por ejemplo, en un entorno de WIFI abierto en un centro comercial.

Un desastre. Un desastre que no le importa a nadie.

El futuro

¿Qué se puede hacer?. El legacy es importante, pero tarde o temprano queda atrás, aunque sea porque se va estropeando y reemplazando. Pero pasarán muchos años antes de poder prescindir de CRL o OCSP. Conviene recordar, no obstante, que para cambiar el futuro hay que dar pasos hoy. Hoy, no mañana.

Personalmente me parece que OCSP Stapling junto a OCSP Must Staple pueden ser las tecnologías a empujar. Está por ver el coste de ancho de banda en los dispositivos móviles y la dependencia crítica de que la entidad de certificación no deje de responder peticiones OCSP.

La otra alternativa es prescindir de las entidades de certificación y tirar por DNSSEC + DANE, que es mi empeño actual y que será tema de futuros artículos.

Detalles finales

En todo este artículo hablo de navegadores y de servidores HTTPS. Hago hincapié en ellos porque es lo que usa la mayoría de los usuarios. Naturalmente hay muchos más entornos en los que se usa SSL/TLS, y cada uno de ellos tiene necesidades especiales al respecto de la revocación.

Tampoco digo nada de qué pasa con los certificados privados de uso interno en las organizaciones.

La vida es corta y llevo ya tres horas escribiendo... :-)