Publicado por emboss el 2014-05-09
Traducción de David Padilla
Recientemente fuimos informados de una posible vulnerabilidad de seguridad que ha sido publicada como CVE-2014-2734. Sin embargo, basados en un análisis detallado, no consideramos que Ruby sea vulnerable.
Esta vulnerabilidad podría permitir a cualquier atacante a crear certificados raíz arbitrarios modificando la firma de el certificado y remplazando la llave privada del certificado original con cualquier otra elegida por el atacante.
Prueba de el concepto
A continuación veremos nuestro análisis de CVE-2014-2734 en una versión reducida, pero que creemos captura la esencia de el análisis original:
Puede que sea una sorpresa que X509Certificate#verify
regresa true
.
El certificado original puede contener
información de la llave pública
que apunta a la llave pública original la cual es diferente a la llave pública
de forge_key
. Claramente, el par público / privado que fue usado para firmar
de nuevo el certificado no concuerda con la llave pública referenciada en
la información original. Entonces, ¿Por qué #verify
regresa true
?
Como es que las llaves son verificadas
X509Certificate#verify
utiliza la función de OpenSSl
X509_verify
internamente, la cual delega a
ASN1_item_verify
.
Estas funciones establecen la validez de la firma de acuerdo a la llave pública
que fue presentada. Sin embargo, no verifican si la llave concuerda con alguna
llave pública referenciada en el certificado.
Esto significa que regresar true
es comportamiento deseado para X509Certificate#verify
en este escenario. Omitir esta verificación no tiene impacto significante en el
modelo de seguridad de confianza X.509.
La sección 4.1.1.3 del RFC 5280 explícitamente dice que al procesar la firma de algún certificado, la CA confirma que la información que contiene el certificado sea correcta. Aunque este principio es violado en el código de ejemplo, esto no presenta una amenaza a la seguridad. Un certificado falso o modificado de esta manera no puede ser explotado a menos que alguien pueda convencerte de que explícitamente confíes en un certificado que viola este principio.
Riesgos Potenciales
Existen dos casos a considerar:
Volver a firmar un certificado de raíz
Como usuarios, confiamos en los certificados de raíz incondicionalmente. Incluso si no contienen información válida, el estado de ser un certificado de raíz reconocido públicamente es lo que los mantiene originales. Son valores preconfigurados en los almacenamientos de confianza de nuestros navegadores y sistemas operativos. Simplemente teniendo acceso a ellos establece su estado como anclas válidas de confianza. Por ejemplo, OpenSSL no revisa la firma de los certificados de raíz firmados por uno mismo por defecto por las mismas razones. X509_V_FLAG_CHECK_SS_SIGNATURE documentation.
Un certificado de raíz que ha sido firmado de nuevo, se convierte por defecto en un certificado “auto-firmado” (por lo tanto con información incorrecta de llave pública). Esto no es más peligroso que un certificado de raíz “auto-firmado” normal. De hecho, cualquiera puede crear certificados de raíz auto-firmados los cuales pueden concordar con aquel de un certificado de raíz valido, excepto por la firma. Como confiamos en los certificados de raíz simplemente por poseerlos, cualquier certificado impostor carece de valor sin que el cliente activamente decida confiar en el.
Firmado de un certificado intermedio
Tampoco volver a firmar un certificado que no es de raíz viola la seguridad de el sistema de confianza X.509. Aunque no tenemos en nuestro poder este tipo de certificados por adelantado, su validez puede ser comprobada durante el proceso de validación. La firma de cualquier certificado que no es de raíz es verificada utilizando la llave publica de el certificado que lo expidió. Si este es falso, en algún momento de la cadena de certificados será detectado como un valor de firma de certificado inválida.
Conclusión
En conclusión, creemos que X509Certificate#verify
funciona como es debido.
Otros han llegado a la misma conclusión y por lo tanto hemos disputado el CVE-2014-2734 y pedido su cancelación. Puedes encontrar nuestro análisis completo de la prueba de concepto original aquí incluyendo algunos comentarios adicionales.