Presentamos las políticas experimentales de integridad para Node.js
21 de marzo de 2019
0 minutos de lecturaUna función experimental reciente para incorporar políticas de integridad llegó al núcleo de Node.js 11.8.0. Esta capacidad, incluida en una versión que aún no es LTS, verifica la integridad del entorno de ejecución de Node.js al cargar módulos para confirmar que su código no haya sido manipulado.
Bradley Farias presentó este cambio en octubre de 2018 y tomó la idea de una función de seguridad similar que existe en los navegadores: Subresource Integrity.
Subresource Integrity
El World Wide Web Consortium (W3C) propuso un nuevo campo integrity para la especificación HTML que permitirá verificar los subrecursos de un documento HTML. Las páginas web pueden indicar al navegador que cargue recursos mediante etiquetas script o link; sin embargo, si estos elementos HTML no usan un campo de integridad, no hay forma de verificar si un recurso fue manipulado.
Las páginas web cargan recursos propios o de terceros desde un servidor remoto; lo más común es hacerlo mediante una red de distribución de contenido (CDN). Al cargar estos recursos, verificar la integridad de sus archivos ayuda a protegerse de actores maliciosos. Algunos ejemplos son:
Un servidor remoto comprometido que podría entregar copias modificadas del archivo del recurso
Un medio de transporte comprometido y su archivo de recurso
Políticas de integridad para módulos de Node.js
Inspirados en el mecanismo de seguridad de los navegadores para hacer cumplir la integridad de los recursos, ¿qué pasaría si Node.js pudiera hacer lo mismo con los módulos de terceros que requiere el código del programa y verificarlos antes de cargarlos en memoria y ejecutarlos?
La nueva función experimental de políticas de Node.js 11.8.0 permite hacer cumplir este comportamiento mediante la marca de línea de comandos --experimental-policy, que requiere un manifiesto de políticas para todos los recursos de un proyecto. ¡Veamos cómo funciona!
Un manifiesto de políticas de Node.js
La versión 11.8.0 solo ofrece la aplicación de políticas en el cargador de módulos, pero Node.js aún no puede procesar el manifiesto de políticas. Para administrar el archivo de políticas, podemos usar la herramienta CLI node-policy de Bradley:
Al ejecutar el comando integrity:add de node-policy, podemos crear un manifiesto de políticas que contenga todos los hashes criptográficos generados para los archivos del directorio actual. Esto incluye desde el directorio .git/ hasta todo el contenido de node_modules/, así que generar todo puede tardar un poco.
Para mostrar cómo funciona, lo usaremos con un módulo CLI de Node.js que creé para ayudarme a exportar los resultados de encuestas de typeform.
Ejecuta node-policy para que cree un archivo de manifiesto de integridad para todos los archivos del directorio actual (indicado por el último argumento, el punto) y especifica un algoritmo para usar como función hash criptográfica. Las opciones disponibles son sha256, sha384 y sha512, que corresponden a la especificación HTML de Subresource Integrity.

El archivo de políticas generado para el proyecto se guarda en el directorio de inicio del usuario. Este es un fragmento de .node-policy.json donde podemos ver la estructura del archivo de manifiesto, con las URL de los archivos y el hash de integridad correspondiente:
Si ejecutáramos la CLI de node-policy en otros directorios de proyectos, se agregarían más archivos a este manifiesto de políticas. Esta es la implementación de node-policy, no una especificación ni una guía.
¿Por qué node-policy crea el archivo de políticas en el directorio de inicio del usuario? Aunque aún no se han estandarizado las prácticas recomendadas integrales para las políticas de integridad, dado que este archivo es la fuente de verdad de los recursos confiables, lo mejor es protegerlo para evitar que alguien lo manipule. Algunas prácticas recomendadas son establecer el archivo como de solo lectura y guardarlo fuera de cualquier directorio al que se pueda acceder.
Para simular la manipulación de un archivo y mostrar cómo Node.js detecta el problema, hice una pequeña actualización de código en bin/cli.js, que forma parte del proyecto CLI. Al ejecutar Node.js para correr el código JavaScript del ejecutable CLI, detecta que el hash es diferente antes de cargar este módulo CommonJS y genera un error que devuelve Node.js al símbolo del sistema.

La implementación actual permite registrar las discrepancias de integridad en lugar de generar un error o salir del programa. Esto es posible con una propiedad onerror que se puede agregar al objeto de nivel superior del archivo de manifiesto de políticas.
Resumen
El trabajo continuo para incorporar funciones de seguridad en Node.js es prometedor y, sin duda, veremos más novedades en un futuro cercano. Ten en cuenta que la función de políticas de integridad aún es experimental y solo está disponible a partir de Node.js 11.8.0.
Empieza con los desafíos de Capture the Flag
Aprende a resolver desafíos de captura la bandera con nuestro taller virtual introductorio a pedido.



