Revisión de Seguridad de Nym
Auditoría de seguridad de los componentes principales de Nym
Introducción
En julio de 2021, Nym se sometió a una auditoría de seguridad por Jean-Philippe Aumasson, un renombrado experto en seguridad. El objetivo era identificar posibles vulnerabilidades y defectos en la base de código de Nym, centrándose en criptografía, seguridad del código y seguridad del protocolo. La revisión tuvo como objetivo asegurar la integridad y robustez del sistema, cubriendo aspectos clave de su arquitectura e implementación. Puedes ver el informe de auditoría completo aquí.
Resumen de la Auditoría
La auditoría tuvo lugar en el verano de 2021. El alcance de la auditoría cubrió múltiples repositorios del proyecto Nym, incluyendo:
- Repositorio principal de Nym: nymtech/nym, que implementa los servicios de nodo de mezcla, puerta de enlace y validador.
- Formato de paquete de la Mixnet Sphinx: nymtech/sphinx, usado por los mixnodes.
- Protocolo de firma ciega de umbral Coconut: nymtech/coconut, usado por la emisión de credenciales.
La auditoría implicó la revisión de la última versión del código en la rama de desarrollo, que se actualizaba regularmente debido a la rápida evolución del proyecto. El equipo de Nym proporcionó a JP Aumasson acceso completo a la base de código, especificaciones detalladas del proyecto, documentos de investigación y documentación de apoyo.
Áreas clave de enfoque de la auditoría
La auditoría se centró en tres áreas principales: seguridad del código, criptografía y diseño de protocolo. Los auditores examinaron minuciosamente la base de código de Nym para identificar vulnerabilidades, buscando problemas comunes como patrones de codificación inseguros y errores mal gestionados. Se prestó especial atención a la seguridad de la memoria y a evitar trampas como los desbordamientos de enteros.
La revisión criptográfica cubrió una amplia gama de primitivas centrales empleadas por Nym, tales como AES-128-CTR, BLAKE2b, ChaCha, Ed25519 y otros. El objetivo era garantizar la implementación adecuada de estos algoritmos y verificar su resistencia a ataques de canal lateral, uso indebido de parámetros y fallas en la generación de aleatoriedad.
Además de revisar los componentes individuales, la auditoría también examinó los protocolos que definen la funcionalidad principal de Nym. Esto implicó examinar el formato de paquete Sphinx y el protocolo de firma ciega de umbral Coconut para identificar cualquier debilidad que pudiera comprometer la privacidad o la seguridad. La revisión se centró en posibles fugas de información que amenazan el anonimato del usuario, así como en vulnerabilidades como las omisiones de verificación MAC, los ataques de subgrupos pequeños y los fallos en las operaciones criptográficas como la aritmética BLS12-381 y las pruebas de conocimiento cero.
Resumen de los hallazgos.
Se descubrieron nueve vulnerabilidades de seguridad durante la auditoría. Ninguna fue calificada como crítica, dos como altas, una como media y seis como bajas. Además, se hicieron 17 observaciones, ofreciendo recomendaciones para fortalecer aún más la red Nym. A continuación, proporcionamos una descripción general de las correcciones implementadas para abordar todas las vulnerabilidades de seguridad identificadas.
S-SPHX-01: Falta de validaciones de claves (Baja)
El problema identificado en nymtech/sphinx con respecto a la validación insuficiente de claves privadas y públicas se ha abordado mediante la migración a la biblioteca x25519, que inherentemente impone la validez de las claves a través de su diseño. La implementación de x25519 asegura que las claves privadas se sujeten correctamente, lo que significa que se restringen automáticamente a un subconjunto válido de escalares, eliminando el riesgo de usar claves privadas no válidas. Además, si bien x25519 no valida explícitamente las claves públicas, su implementación de escalera de Montgomery inherentemente evita que se utilicen ciertos puntos de curva no válidos. Esto mitiga el riesgo de encontrar puntos en el infinito u otras claves públicas mal formadas. Además, el proceso de intercambio de claves asegura que un secreto compartido de todos ceros pueda ser detectado y rechazado si es necesario. Al aprovechar ´x25519`, hemos mejorado significativamente la validación de claves, reduciendo el riesgo de que se utilicen claves no válidas o con un formato incorrecto dentro del sistema. Esto resuelve eficazmente las preocupaciones planteadas en la auditoría con respecto a la validación de claves.
S-COCO-01: Distribución sesgada de hash a escalar (Baja)
El proceso de hash para derivar un escalar en el campo BLS12-381 anteriormente involucraba mapear la salida de una función hash directamente a un elemento del campo escalar. Sin embargo, este enfoque introdujo sesgos debido a la operación de reducción modular (mod p), que puede resultar en una distribución no uniforme cuando la salida del hash no se alinea perfectamente con el módulo primo del campo. Para abordar este problema, reemplazamos la función hash a escalar existente con la función hash_to_field función de el bls12_381 crate. Esta función sigue la especificación estandarizada de hash-to-field, garantizando un mapeo uniforme e imparcial de las salidas del hash a los elementos del campo. Además, el protocolo zk-Nym, que reemplazó al protocolo Coconut, también se basa en esta función para sus operaciones de hashing, garantizando consistencia y corrección en los cálculos criptográficos.
S-COCO-02: permisos de archivos de claves keygen-cli (Bajo)
Los auditores notaron que los archivos de claves de keygen-cli tienen permisos predeterminados, pero deberían tener permisos más restringidos para una mejor seguridad. Este problema no requirió ningún cambio, ya que keygen-cli solo se utilizó en las primeras etapas de nuestra implementación de Coconut. Ya no forma parte del repositorio principal de Nym y no está en uso activo. Dado que la herramienta quedó obsoleta, no se necesitó ninguna acción adicional con respecto a sus permisos de archivo.
S-CRYP-01: Potencial reutilización del vector de inicialización (IV) en el cifrado de flujo (Alto).
El problema involucra una función que cifra datos utilizando un vector de inicialización (IV). Si no se proporciona un IV, la función utiliza por defecto un IV de ceros, lo que podría resultar en la reutilización del IV. Este problema se ha resuelto introduciendo el protocolo AES-GCM-SIV durante la fase de registro. Para prevenir ataques de degradación, hemos eliminado la opción de usar la clave AES-128-CTR heredada para la comunicación entre el cliente y el gateway. Siempre y cuando tanto el cliente como el gateway estén actualizados, siempre generarán un IV aleatorio y no nulo.
S-PROT-01: Potencial doble gasto de credenciales (Alto)
Los auditores notaron que la versión revisada de Coconut carecía de un mecanismo de detección de doble gasto, lo que podría haber permitido que múltiples gateways validaran incorrectamente una credencial como no utilizada al mismo tiempo. Sin embargo, el contrato de ancho de banda de Coconut se actualizó posteriormente para rastrear el uso de credenciales almacenando el estado en la cadena, abordando este problema. Además, Coconut ha sido reemplazado desde entonces por el protocolo zk-nyms, que incluye funcionalidad integrada de detección de doble gasto.
S-NYM-01: Dependencias con vulnerabilidades conocidas (Media)
Los auditores identificaron que varios componentes en el proyecto Nym dependían de versiones antiguas de dependencias con vulnerabilidades de seguridad conocidas. Por ejemplo, el repositorio Sphinx usaba una versión insegura de la crate generic-array, el repositorio principal de Nym dependía de una versión obsoleta de tokio, y el cliente de Nym tenía varias crates con problemas de seguridad conocidos, algunos de los cuales parecían ser explotables dentro del contexto de Nym. Siguiendo la recomendación de los auditores, actualizamos las dependencias regularmente. Ahora gestionamos activamente nuestras dependencias a través de Dependabot, que monitorea continuamente y detecta automáticamente paquetes obsoletos o vulnerables en nuestros repositorios. Ver las correcciones de Dependabot aplicadas continuamente en nuestro repositorio.
S-NYM-02: Fallo de descifrado no gestionado (Bajo)
El problema identificado en el código ocurre en la función recover_identifier en nym/common/nymsphinx/acknowledgments/identifier.rs, donde los fallos de descifrado, como parámetros no válidos, no se gestionan adecuadamente. Esto puede llevar a pánico (del programa) u otros estados inseguros. Un problema similar existe en la función recover_plaintext en nym/common/nymsphinx/src/receiver.rs. El no gestionar los errores de descifrado podría potencialmente resultar en que el sistema entre en un estado inestable o inseguro. Después de revisar cuidadosamente las funciones, concluimos que el primer ejemplo proporcionado, en recover_identifier, no representa un problema. Es imposible proporcionar parámetros incorrectos, ya que todo está parametrizado con AckEncryptionAlgorithm (link), lo que significa que cualquier valor no válido se detectaría en tiempo de compilación.
El segundo caso que mencionaron, recover_plaintext, ya no existe. Sin embargo, el código que lo reemplazó, recover_plaintext_from_regular_packet, tenía un caso de fallo teóricamente posible si modificáramos algunos parámetros a valores inusuales. Hemos abordado esto añadiendo un [manejo de errores] (https://github.com/nymtech/nym/blob/50b044a100ca1fa4b4cd8ddc37b63d9bfbf140ac/common/nymsphinx/src/receiver.rs#L101) adecuado para asegurar que el sistema permanezca estable, incluso en casos extremos.
S-NYM-03: Pánico en la generación de IDs de fragmento (Bajo)
El código utilizado para generar nuevos IDs de fragmento selecciona aleatoriamente un valor i32 y toma su valor absoluto. Sin embargo, este enfoque puede provocar un pánico (del programa) en los casos en que el valor elegido aleatoriamente sea i32::MIN, ya que su valor absoluto no se puede representar dentro de los límites de un i32. Esto resulta en un error de "intento de negación con desbordamiento" debido a las limitaciones de la codificación de complemento a dos.
Estamos de acuerdo en que la calificación de severidad establecida para este problema es demasiado baja, ya que la probabilidad de encontrar este caso es de aproximadamente 1 en 4 mil millones. Sin embargo, hemos abordado el problema implementando la corrección recomendada por el auditor para prevenir posibles pánicos y fallos inesperados, especialmente cuando millones de usuarios generan miles de IDs de fragmento.
S-NYM-04: Mnemónico no puesto a cero (Bajo)
El problema identificado resaltó que el mnemónico BIP39 utilizado para conectar el servicio nymd no se estaba poniendo a cero después de su uso, lo que resultaba en múltiples copias del mnemónico persistiendo en la memoria. Esto aumentó el riesgo de exposición, ya que los mnemónicos son más fácilmente identificables en la memoria en comparación con las claves criptográficas sin procesar. Para abordar esto, hemos implementado varias mitigaciones. En los componentes de Rust, hemos integrado [zeroize] (https://github.com/nymtech/nym/blob/5f2740bf668102a07f8480434102e866f7d4c52a/Cargo.toml#L206) crate para asegurar que cualquier memoria que contenga el mnemónico se borre de forma segura tan pronto como salga de su ámbito. Dado que JavaScript es un lenguaje con recolección de basura y no proporciona control directo sobre la eliminación de memoria, hemos adoptado un enfoque diferente para mitigar la exposición en el entorno de ejecución de JavaScript. Específicamente, hemos modificado el sistema para que el entorno de ejecución de JavaScript termine una vez que el mnemónico se haya pasado a la capa de Rust. Esto asegura que todas las instancias del mnemónico dentro de la memoria de JavaScript se borren al cerrar el entorno de ejecución. El mnemónico se transfiere a Rust lo antes posible, reduciendo su exposición en JavaScript. Una vez dentro de Rust, zeroize asegura que todas las instancias del mnemónico se borren de forma segura una vez que ya no sean necesarias. Con estos cambios, hemos minimizado significativamente la presencia del mnemónico en la memoria, reduciendo el riesgo de exposición y asegurando que los datos sensibles se gestionen y borren de forma segura.
Últimas palabras
Nos gustaría agradecer a JP Aumasson por su experiencia y dedicación a lo largo de este proceso de auditoría. También apreciamos la colaboración y profesionalismo demostrados durante las etapas de planificación y ejecución de la auditoría. Nuestro compromiso continuo con la seguridad sigue siendo una prioridad máxima, y esperamos seguir colaborando con expertos en seguridad para mantener los más altos estándares para nuestro ecosistema.