Reports
BAJA[TLS Y CRIPTOGRAFÍA]#3973176

curl ignoraba la verificación de clave de host SSH al seguir una redirección de HTTPS a SFTP o SCP

Si curl empezaba con una URL HTTPS y seguía una redirección a SFTP, no aplicaba --knownhosts ni --hostpubsha256: un servidor SSH suplantado podía recibir credenciales y servir contenido falso.

Resumen
Resumen en castellano de un reporte público, no una traducción literal. El código y los comandos se mantienen como en el original.

Resumen

La herramienta de línea de comandos de curl permite fijar cómo se verifica la identidad de un servidor SSH con --knownhosts, --hostpubsha256 o --hostpubmd5. El problema estaba en que esas opciones solo se trasladaban a la conexión si la URL inicial era scp:// o sftp://.

La función responsable es ssh_setopts(), en src/config2setopts.c, que abandona sin hacer nada cuando el protocolo de partida no es SSH:

if(use_proto != proto_scp && use_proto != proto_sftp)
  return CURLE_OK;

La variable use_proto se calcula a partir de la URL escrita en la línea de órdenes. Si esa URL es HTTPS, nunca se configuran CURLOPT_SSH_KNOWNHOSTS, CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 ni CURLOPT_SSH_HOST_PUBLIC_KEY_MD5. Como las redirecciones las resuelve libcurl internamente sin volver a pasar por config2setopts(), cuando el servidor HTTPS responde con Location: sftp://… y el usuario ha permitido ese salto con --location --proto-redir +sftp, la conexión SFTP se abre sin ninguna política de verificación de la clave del host. En modo detallado, curl lo deja ver con el mensaje SSH: no knownhosts file configured.

Datos del caso:

  • CVE asignado: CVE-2026-86410.
  • Antecedente: el commit ab3bb8cd8be8f9d4acb97da0418abc279182041e corrigió CVE-2026-12064, un fallo relacionado con --proto-default, pero no tocó esta comprobación que provoca la variante por redirección.
  • Versiones afectadas según el investigador: curl CLI de la 7.81.0 a la 8.21.0, además de la 8.22.0 afectada. El código vulnerable estaba en la etiqueta curl-8_21_0 y en la rama principal en el momento del reporte.
  • Debilidad: validación incorrecta de certificado con discrepancia de host (CWE-297).
  • Enviado el 27 de agosto de 2026 y divulgado el 14 de octubre de 2026.

Pasos de reproducción

  1. Compilar una versión afectada de la herramienta curl (desde la 7.81.0) con soporte SFTP mediante libssh2 o libssh y soporte HTTPS con algún backend TLS.
  2. Levantar un servidor SFTP con una clave de host conocida, credenciales de prueba válidas y un fichero con datos reconocibles.
  3. Preparar un fichero known_hosts para ese nombre de host y puerto que contenga, a propósito, una clave de host distinta.
  4. Levantar un servidor HTTPS con un certificado que curl valide sin problemas.
  5. Configurar ese servidor HTTPS para que responda con una redirección cuya cabecera Location apunte al fichero del servidor SFTP.
  6. Control directo: ejecutar curl contra la URL SFTP usando el --knownhosts con la clave equivocada.
  7. Comprobar que esta transferencia directa falla en la verificación de la clave de host y no descarga nada. Esto demuestra que el fichero es válido y se aplica cuando el protocolo inicial es SFTP.
  8. Ejecutar curl contra la URL HTTPS con la verificación de certificados activa, siguiendo redirecciones, con SFTP permitido explícitamente en --proto-redir y con el mismo --knownhosts erróneo.
  9. Resultado vulnerable: curl sigue la redirección, se autentica en el servidor SFTP, descarga el fichero y termina con éxito pese a que la clave no coincide.
  10. Repetir con salida detallada y comprobar que la conexión SFTP redirigida informa de que no hay fichero de hosts conocidos configurado.
  11. Repetir la transferencia redirigida con un valor de --hostpubsha256 deliberadamente incorrecto, en lugar del known_hosts erróneo o además de él.
  12. Comprobar que la transferencia redirigida también ignora ese anclaje de clave, mientras que una petición SFTP directa sí lo aplica.
  13. Control de política de protocolos: quitar SFTP de la lista permitida de redirecciones y repetir la petición HTTPS.
  14. Comprobar que curl rechaza la redirección, lo que confirma que el ataque requiere que el usuario haya permitido el salto de HTTP(S) a SFTP.
  15. Para validar una corrección, instalar las opciones SSH en el handle con independencia del protocolo de la URL inicial, sin el retorno anticipado para HTTP o HTTPS.
  16. Repetir el caso con redirección y verificar que ahora la conexión SFTP aplica la política de clave de host y falla antes de autenticarse o transferir el fichero.

Resultado esperado: las opciones de verificación de host SSH indicadas en la línea de órdenes deben aplicarse siempre que la transferencia acabe en SCP o SFTP, también cuando se llega mediante una redirección permitida.

Resultado vulnerable: curl solo configuraba la verificación SSH cuando la URL inicial era SSH, así que un handle HTTP o HTTPS redirigido a SFTP se conectaba sin el fichero de hosts conocidos ni el anclaje de clave pedidos.

Impacto

Un atacante capaz de hacerse pasar por el servidor SFTP al que apunta una redirección desde un origen HTTPS de confianza podía:

  • Saltarse la verificación de clave de host que el usuario había pedido de forma explícita con --knownhosts o --hostpubsha256, sin que curl avisara.
  • Recibir la autenticación de curl en su servidor SSH, con la posible exposición de las credenciales SFTP.
  • Sustituir el contenido descargado mientras curl informa de que la transferencia ha ido bien.

Las condiciones necesarias reducen mucho la superficie de ataque:

  1. curl compilado con SSH (libssh2 o libssh).
  2. Uso de --location --proto-redir +sftp, es decir, el usuario habilita expresamente las redirecciones a SFTP.
  3. Un origen HTTPS de confianza que redirija a SFTP.
  4. Credenciales válidas para el servidor SFTP.
  5. Un atacante en posición de suplantar el servidor SSH.

Por eso el investigador estimó la severidad como baja, dejando la clasificación final al equipo de seguridad.

Remediación

El reporte figura como resuelto. La corrección propuesta por el investigador es eliminar la comprobación de protocolo en ssh_setopts() para que las opciones SSH se instalen siempre en el handle: este puede acabar en SCP o SFTP tras una redirección, y las opciones SSH no tienen efecto en una transferencia que no sea SSH. También propone añadir pruebas de regresión para una redirección de HTTPS a SFTP con --knownhosts y --hostpubsha256 que no coincidan.

Qué aprender de este caso

  • Cuando una herramienta configura las opciones de seguridad según el protocolo de la URL de partida, revisa qué ocurre si una redirección cambia de protocolo a mitad de transferencia: las comprobaciones del tipo if (protocolo != X) return son el sitio exacto donde mirar.
  • Si la lógica de redirección vive en una capa inferior (aquí libcurl) y la configuración en otra (la CLI), la configuración no se vuelve a evaluar al redirigir. Las políticas de verificación deben fijarse desde el principio para todos los protocolos a los que se pueda llegar.
  • Un parche para una variante (--proto-default en CVE-2026-12064) no cubre necesariamente las demás. Tras un CVE, busca otras rutas que lleven al mismo código con un protocolo distinto del inicial.
  • Al probar la verificación de host, monta siempre los dos casos de control: conexión directa con una clave errónea (debe fallar) y la misma clave errónea llegando por redirección. Si solo falla la primera, la política se está perdiendo por el camino.