javascript node.js ssl openssl tls1.2

javascript - Evite enviar TLS_EMPTY_RENEGOTIATION_INFO_SCSV cifra en TLS Client Hello



node.js ssl (1)

Dado que este problema está relacionado con Node.js, hay un método simple para tratar su problema sin realmente profundizar en él:

Coloque un proxy web delante de su proceso Node.js y permita que maneje la conexión SSL completa. En el código de Node.js, solo enviarías una solicitud a un servidor HTTP local.

Ejemplo de configuración con nginx (dentro de la directiva http):

server { listen 8080; location / { resolver 8.8.8.8; proxy_pass https://www.howsmyssl.com$uri$is_args&args; proxy_ssl_protocols TLSv1.2; proxy_ssl_ciphers AESGCM:!aNULL; } }

Y cambie el nodejs a:

var request = require(''request''); var options = { url: ''http://localhost:8080/a/check'' }; request(options, function (error, response, body){ if (!error) { console.log(body); } else { console.log(error); } });

Desafortunadamente, aunque hice esto, el resultado fue el mismo:

{"given_cipher_suites":["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_DH_DSS_WITH_AES_256_GCM_SHA384","TLS_DHE_DSS_WITH_AES_256_GCM_SHA384","TLS_DH_RSA_WITH_AES_256_GCM_SHA384","TLS_DHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384","TLS_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_DH_DSS_WITH_AES_128_GCM_SHA256","TLS_DHE_DSS_WITH_AES_128_GCM_SHA256","TLS_DH_RSA_WITH_AES_128_GCM_SHA256","TLS_DHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256","TLS_RSA_WITH_AES_128_GCM_SHA256","TLS_EMPTY_RENEGOTIATION_INFO_SCSV"],"ephemeral_keys_supported":true,"session_ticket_supported":true,"tls_compression_supported":false,"unknown_cipher_suite_supported":false,"beast_vuln":false,"able_to_detect_n_minus_one_splitting":false,"insecure_cipher_suites":{},"tls_version":"TLS 1.2","rating":"Probably Okay"}

Esto básicamente significa que probablemente sea el comportamiento estándar de OpenSSL.

Hay opciones que se pueden configurar en OpenSSL usando SSL_CTX_set_options

Aquí es especialmente interesante la sección SEGURO DE RENEGOCIACIÓN y esta opción:

SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION

Permitir la renegociación heredada insegura entre OpenSSL y los clientes o servidores sin parchear. Vea la sección SEGURO DE RENEGOCIACIÓN para más detalles.

Aunque no estoy seguro si esto realmente impide que se envíe el cifrado de renegociación. Si esta opción es realmente correcta, puede haber una forma de parchear Node.js para usar esa opción o recompilar OpenSSL con esa opción.

Por supuesto, también existiría la opción de usar una versión vieja no parcheada. Desde mi punto de vista, aunque TLS_EMPTY_RENEGOTIATION_INFO_SCSV no está relacionado con POODLE, sino desde una solución anterior:

CVE-2009-3555 (aviso de OpenSSL) 5 de noviembre de 2009:
Implemente RFC5746 para abordar vulnerabilidades en la renegociación SSL / TLS. Se corrigió en OpenSSL 0.9.8m (afectado 0.9.8l, 0.9.8k, 0.9.8j, 0.9.8i, 0.9.8h, 0.9.8g, 0.9.8f, 0.9.8e, 0.9.8d, 0.9.8c, 0.9. 8b, 0.9.8a, 0.9.8)

El Node.js moderno viene con un OpenSSL enlazado estáticamente y no es compatible con OpenSSL 0.9.8, por lo que necesitaría una versión anterior de Node.js independientemente ... o usar las cosas nginx con un OpenSSL sin parchear ...

Esto es algo de lo que estoy atascado. No es realmente una respuesta completa, pero creo que al menos vale la pena compartirla.

Sin embargo, para resumir, creo que si quieres hacer esto sin recompilar utiliza nginx con OpenSSL sin parchear y configura varios servidores, uno para cada cliente que quieras imitar.

Si necesita que esto se haga solo en el nodo, su mejor opción es parchear OpenSSL allí directamente y recompilar el nodo.

Node.js envía el cifrado TLS_EMPTY_RENEGOTIATION_INFO_SCSV de forma predeterminada para protegerse contra el ataque de POODLE .

Estoy tratando de evitar el envío de este cifrado (aunque esto puede suponer un riesgo para la seguridad) anulando los sistemas de cifrado TLS con una lista personalizada de cifrados.

Sin embargo, Node.js sigue enviando el cifrado TLS_EMPTY_RENEGOTIATION_INFO_SCSV sin importar lo que haga. Intento evitar deliberadamente enviar este cifrado para imitar la negociación TLS de Firefox / Chrome.

Este es el código que uso para modificar y verificar qué cifrado está enviando Node:

var request = require(''request''); var ciphers = [ ''ECDHE-ECDSA-AES128-GCM-SHA256'', ''ECDHE-RSA-AES128-GCM-SHA256'', ''ECDHE-ECDSA-AES256-SHA'', ''ECDHE-ECDSA-AES128-SHA'', ''ECDHE-RSA-AES128-SHA'', ''ECDHE-RSA-AES256-SHA'', ''DHE-RSA-AES128-SHA'', ''DHE-RSA-AES256-SHA'', ''AES128-SHA'', ''AES256-SHA'', ''DES-CBC3-SHA'' ].join('':''); var options = { ciphers: ciphers, secureProtocol: ''TLSv1_2_method'', url: ''https://www.howsmyssl.com/a/check'' }; request(options, function (error, response, body){ if (!error) { console.log(body); } else { console.log(error); } });

¿Hay alguna forma de desactivar el envío de este cifrado en Node.js?