¿Te ha gustado el artículo?
0
¿Te ha gustado el artículo?
0

HPKP: todo sobre la extensión HTTP Public Key Pinning

Un requisito sine qua non para el trabajo con datos digitales es disponer de canales de transmisión seguros que garanticen la seguridad durante todo el trayecto que sigue la información. No es casualidad que la información confidencial se transmita únicamente a través de conexiones VPN o SSL/TLS. Las empresas y organizaciones se aseguran de que estos protocolos sean casi intocables implementando servidores DNS propios, así como determinados mecanismos de certificación. Sin embargo, los usuarios activos fuera de estas estructuras están sujetos a las jerarquías de los DNS y certificados públicos, aumentando considerablemente la posibilidad de ser víctimas de ataques man in the middle.

La razón principal del aumento de los riesgos de seguridad es la emisión de certificados falsos por parte de entidades dudosas o malintencionadas. Por su parte, el usuario confía en que la conexión y los datos están seguros, mientras que, paradójicamente, la supuesta y respetada entidad de confianza se encarga de lo contrario. Con el llamado HTTP Public Key Pinning (HPKP), Google presenta una solución que entretanto ya ha sido especificada como estándar en el RFC 7469.

¿Qué es el HPKP?

El Public Key Pinning es una extensión del protocolo HTTP (Hypertext Transfer Protocol) que permite definir el juego de claves públicas (Public Key Set) para las futuras conexiones SSL/TLS con un host. De esta manera el cliente puede saber, en su primera toma de contacto, en qué claves públicas puede confiar mientras se establece la conexión a este host. Este procedimiento se conoce como modelo “Trust On First Use” (en español: confianza en la primera aplicación). Cada entrada de una clave verificada se denomina “pin” (de ahí el nombre de “pinning” dado a este mecanismo). Todos los pines creados se envían al cliente en el encabezado HTTP y se guardan aquí durante un determinado periodo de tiempo.

Cuando se realiza una nueva solicitud de conexión, el cliente comprueba si la cadena de certificación propuesta para la transmisión SSL/TLS contiene una clave pública (key) filtrada previamente a través de HPKP. Si no es así, por ejemplo en el caso de un certificado falso, se genera un mensaje de error y no se establece la conexión. Este proceso de verificación se conoce también como validación de pin. Este que sigue es un ejemplo de las entradas de los pines en el encabezado HTTP:

Public-Key-Pins:
  pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=";
  pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
  pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=";
  max-age=2592000; includeSubDomains; report-uri="http://example.com/pkp-report"

El ejemplo muestra las cuatro directrices que debe contener una entrada pin en el encabezado HTTP:

  • pin: la directiva pin es la parte más importante de la entrada. Como tal, está compuesta por un nombre y un valor. El nombre proporciona indicios sobre el algoritmo utilizado para el cifrado. Hasta la fecha solo es posible usar SHA256. El valor hash, que se encuentra dentro de las comillas, es una cadena Base64 codificada que también se conoce como huella digital (Fingerprint). Es necesario fijar una directiva pin propia para cada llave (backups).
  • max-age: la directiva max-age especifica el periodo de validez de un pin en segundos e indica al cliente cuánto tiempo debe considerar como clave segura a una Public Key determinada. En el ejemplo mencionado, los pines enumerados se descartarán después de 30 días (2.592.000 de segundos).
  • includeSubDomains: esta directiva es opcional y no requiere ningún valor. Esta es la encargada de señalar al cliente que las reglas de certificación definidas no solo se aplican al dominio solicitado, sino también a todos los subdominios pertenecientes al host.
  • report-uri: si se fija la directiva report-uri, cualquier error de validación del pin se enviará al URL especificado. Este no necesariamente tiene que estar en el mismo dominio de Internet que el host contactado para informarle de los intentos fallidos de configuración.

¿Cómo funciona el Certificate Pinning en el propio servidor?

Para aprovechar las posibilidades de HPKP, primero se debe considerar a qué claves públicas se quiere “pinear”. En principio, puedes seleccionar cualquier clave pública incluida en la cadena de certificación, ya sea de raíz (root), intermedia o del certificado del servidor. Sin embargo, si se seleccionan organismos de certificación externa, se debe tener en cuenta que todos los certificados de este sitio van a ser considerados válidos por los clientes y van a conducir a la validación del pin.

En caso de asignar un pin a la clave del servidor, pesará mucho si la clave se vuelve inutilizable o si se pierde debido a un defecto de hardware. Debido a que en el primer contacto los clientes han almacenado el pin por el periodo de validez especificado, estos no aceptan un nuevo pin hasta que no se haya vencido el plazo previamente determinado. Como consecuencia para los usuarios, su servidor no sería accesible. Para evitar esta situación, el estándar HPKP (RFC 7569) proporciona un pin de respaldo que se entrega en el encabezado HTTP y, en caso de que se presente algún problema, se puede utilizar para emitir un nuevo certificado para el dominio correspondiente. Esta operación se denomina solicitud de firma de certificado (CSR o Certificate Signing Request).

Consejo

Navegadores como Mozilla Firefox y Google Chrome se basan en el estándar RFC 7469 y, por lo tanto, ignoran los encabezados HPKP o muestran mensajes de error cuando se implementa un único pin. Para el soporte óptimo del navegador (HPKP browser support) siempre es necesario especificar al menos dos claves públicas válidas o un pin de respaldo para que la validación del pin funcione.

Cálculo de los pines para claves públicas

Si el HTTP Public Key Pinning ha de funcionar en tu servidor es necesario que HTPPS se haya configurado previamente. Debido a que se tienen que “pinear” al menos dos claves públicas, generar los pines es el primer paso a seguir. La solución más sencilla para calcular los valores hash de las claves públicas es la aplicación de código abierto openssl, que se puede utilizar en la consola de línea de comandos de tu sistema. RFC 7469 proporciona el comando estándar para los certificados X.509 de la siguiente manera:

openssl x509 -noout -in certificate.pem -pubkey | \
  openssl asn1parse -noout -inform pem -out public.key
openssl dgst -sha256 -binary public.key | openssl enc -base64

De esta forma puedes crear la secuencia Base64 para el certificado de ejemplo certificate.pem para la clave public.key. Este se emite en la salida estándar y termina siempre con el signo de igual (“=”).

En un siguiente paso configura la solicitud de firma de certificado (aquí: backup.csr) para tu clave de respaldo (aquí: backup.key):

openssl genrsa -out backup.key 2048
openssl req -new -key backup.key -out backup.csr

A continuación, utiliza openssl para calcular el valor hash de esta clave:

openssl req -noout -in backup.csr -pubkey | \
  openssl asn1parse -noout -inform pem -out backup.key
openssl dgst -sha256 -binary backup.key | openssl enc -base64

Protección del backup pin

Puesto que la razón de ser de la clave de respaldo de HPKP es reemplazar a la clave predeterminada en caso de fallos, es útil almacenarlas por separado. Para una mayor efectividad, elije una plataforma de almacenamiento externo a la que puedas acceder en cualquier momento y desde cualquier lugar. Adicionalmente, se recomienda utilizar un administrador de contraseñas. Si, además, proteges la solicitud de firma de certificado y su respectiva clave con un software en una base de datos separada, el nivel de seguridad aumenta y las claves backup están listas para usarse.

La crítica al Public Key Pinning

Gracias al enfoque “Trust On First Use”, el HPKP se involucra desde el primer contacto con el cliente. Sin embargo, la primera visita en la que el servidor transmite las claves fijadas no está protegida por el método mismo. No obstante, esta pequeña brecha solo conduce a problemas en casos aislados, mientras que un gran número de ataques inadvertidos a las conexiones SSL/TLS de tu proyecto web es casi imposible. La principal crítica al Public Key Pinning tiene lugar en el siguiente escenario de ataque, que solo es posible una vez se ha implementado la tecnología pinning:

  1. Un atacante obtiene acceso a tu servidor.
  2. Este instala un nuevo certificado SSL/TLS y crea su propio par de claves.
  3. Para la clave pública, este genera el valor hash apropiado y lo coloca en el lugar correspondiente dentro del encabezado del Certificate Pinning.
  4. Los usuarios o clientes que acceden por primera vez a tu proyecto web reciben el pin incorrecto y no pueden establecer una conexión segura con tu servidor.
  5. Si el atacante elimina el certificado del servidor, a dichos usuarios se les deniega el acceso a su web hasta que el periodo de validez del pin incorrecto haya caducado.
  6. Además de los daños resultantes por la pérdida de tráfico, el atacante también tiene la posibilidad de exigir dinero y chantajearte para liberar el certificado falso.

Incluso si este escenario es teóricamente posible, no es en ningún momento un argumento contra el uso de HTTP Public Key Pinning. Esto se debe a que el atacante siempre podría configurar la extensión del protocolo HTTP si logra acceder al servidor. El problema demuestra la importancia de la protección contra ataques de hackers. Si utilizas pins, deberás asegurarte de que tu software de monitoreo esté en situación de informarte con prontitud cuando se realicen cambios en los encabezados HPKP para, así, poder intervenir a tiempo. Un posible enfoque para solucionar este problema desde el lado del cliente serían los mecanismos pin reset, que se encargan de eliminar los pines “maliciosos” regularmente.

Otras críticas negativas son principalmente el bajo nivel de distribución y la complejidad asociada con la configuración del Public Key Pinning. Las razones para esto son probablemente el hecho de que el estándar es, a menudo, poco conocido o totalmente desconocido.

Seguridad