Skip to main content

Plugins para integrar la seguridad y observabilidad de aplicaciones Node.js en tu IDE

Escrito por
blog feature javascript review

23 de agosto de 2021

0 minutos de lectura

Como desarrolladores, pasamos mucho tiempo en nuestros IDE escribiendo código nuevo, refactorizando, agregando pruebas, corrigiendo errores y mucho más. En los últimos años, los IDE se han convertido en herramientas potentes que nos ayudan con todo, desde interactuar con solicitudes HTTP hasta aumentar nuestra productividad en general. Así que vale la pena preguntarse: ¿y si también pudiéramos evitar problemas de seguridad en nuestro código antes de publicarlo? ¿Y si pudiéramos ver lo que ocurre dentro de nuestras aplicaciones en producción, a nivel de código y directamente en el IDE?

Aquí es donde entra en juego la magia de las herramientas diseñadas para desarrolladores. Con el plugin adecuado para tu IDE, la observabilidad y la seguridad pueden integrarse directamente en el trabajo diario de los desarrolladores, justo donde resultan más eficaces.

En esta publicación, veremos lo siguiente:

  • Cómo obtener observabilidad del código en tiempo real para tus estructuras de datos directamente en el IDE

  • Cómo encontrar entradas de usuario dañinas en una aplicación Node.js en producción

  • Cómo detectar y corregir problemas de seguridad en tu código y dependencias de código abierto

Cómo obtener observabilidad de aplicaciones en tiempo real desde tu IDE

Esto es lo que necesitas para seguir los pasos de esta publicación:

  1. IntelliJ IDEA (Lightrun pronto incorporará compatibilidad con Visual Studio Code. Regístrate aquí para la beta y sé de los primeros en probarlo.)

  2. Una cuenta de Lightrun, el plugin de Lightrun para IntelliJ y el agente de Node.js, que todavía está en versión beta

Una vez instalado el plugin de IntelliJ IDEA, haz clic en el botón Register. Se iniciará un proceso de registro sencillo en el navegador:

IDE con tema oscuro que muestra código JavaScript, un panel de bienvenida de Lightrun con botones para iniciar sesión y registrarse, y un panel de análisis de seguridad de Snyk

A continuación, debemos instalar y configurar el agente de Lightrun para Node.js en la aplicación Node.js. Verás las instrucciones durante el proceso de registro, pero si no las viste, aquí están de nuevo:

  1. Instala el agente de Lightrun en la carpeta de nuestro proyecto con este comando: npm install lightrun

  2. Inicializa el agente de Lightrun al principio del código base de nuestra aplicación Node.js, en el código de entrada del archivo app.js, de la siguiente manera (durante el proceso de registro verás en pantalla los valores <YOUR-COMPANY-NAME> y <YOUR-COMPANY-SECRET>):

    require('lightrun').start({ company: '', apiEndpoint: 'app.lightrun.com', lightrunSecret: '', caPath: '',});

No estaría haciendo justicia al tema si no mencionara las advertencias sobre secretos en el código. Así que lo primero que quiero señalar ahora que llegaste hasta aquí es que actualices esa línea de código para que lightrunSecret quede así:

require('lightrun').start({
    company: '<YOUR-COMPANY-NAME>',
    apiEndpoint: 'app.lightrun.com',
    lightrunSecret: '<YOUR-COMPANY-SECRET>',
    caPath: '',
});

Luego, cuando inicies la aplicación localmente, recuerda primero poner a disposición esta variable de entorno. Si ejecutas la aplicación desde la línea de comandos, puedes hacerlo así:

lightrunSecret: process.env.LIGHTRUN_API_KEY

Nota: Solo necesitas ejecutar el comando export una vez. Estará disponible en la sesión de tu terminal mientras sigas usando la misma.

Una vez que inicies la aplicación, notarás en la barra lateral derecha que el plugin de Lightrun ya está bien configurado y conectado, como indica el nombre de tu máquina (la mía es “Lirans-MBP”):

export LIGHTRUN_API_KEY=<YOUR-COMPANY-SECRET>
npm run start

Cómo encontrar entradas de usuario dañinas en una aplicación Node.js en producción

La aplicación Node.js con la que vamos a experimentar es Goof, la aplicación TODO de Snyk: una aplicación integral para tomar notas de tareas, creada con JavaScript y Node.js.

Puedes obtener una copia clonando el proyecto de GitHub y seguir las instrucciones habituales de instalación de dependencias de proyectos npm para comenzar. Ten en cuenta que también necesita conectarse a una base de datos MongoDB al iniciarse.

Una vez que esté en marcha, debería verse como en la captura de pantalla siguiente. Notarás que la aplicación tiene una función interesante. Si le envío una tarea como Get my app secured in 15 minutes, usa el paquete npm de código abierto humanize-ms para transformar el texto 15 minutes en un formato como [15m]. El paquete humanize-ms tiene alrededor de 4,500,000 descargas semanales, así que parece una buena opción.

Ventana del navegador que muestra una aplicación «Goof TODO» con tareas sobre seguridad de aplicaciones, un plugin para IDE y observabilidad, además de seguridad.

Ahora bien, si te interesa la seguridad y has desarrollado aplicaciones backend, probablemente te habrías asegurado de que las entradas cumplieran ciertas validaciones y un esquema esperado.

Sin embargo, esta aplicación ya está en producción y, aunque no sé qué tipo de entradas está recibiendo, no quiero interrumpir ninguna funcionalidad. Dicho esto, sí quiero tener visibilidad de las entradas de usuario potencialmente peligrosas que podría recibir. ¡Aquí es donde Lightrun destaca!

Quiero capturar alertas por si alguien envía una entrada de usuario con más de 10,000 caracteres. Para hacerlo, agregaré en IntelliJ un registro de Lightrun con una condición, justo en la línea de código que analiza el texto de entrada del usuario. Así se ve:

Editor de código que muestra el menú de Lightrun con opciones para registros, puntos de interrupción virtuales, métricas, instantáneas, configuración y cerrar sesión

Para hacerlo, elige el tipo de anotación Log al hacer clic derecho en la línea de código y configura la regla de registro de la siguiente manera: item.length>10000

Editor de código que muestra un cuadro de diálogo «Crear registro» configurado para la línea 162 de index.js, con la condición item.length > 10000.

Esto básicamente configura una alerta en mi aplicación Node.js que se está ejecutando en vivo. Así, cualquier solicitud que llegue a esta ruta del código y active la condición con una entrada de más de 10,000 caracteres generará una alerta.

Una vez que agrego la acción, aparece esta pequeña anotación sobre esa línea de código, junto con el usuario que la agregó. Es una buena forma de llamar la atención y brindar información valiosa a los desarrolladores responsables de la deuda técnica y la refactorización en el futuro:

Editor de código con tema oscuro que muestra JavaScript para analizar la entrada del usuario y guardar una nueva tarea con contenido y fecha de actualización

Agregar una alerta desde el IDE es genial, pero ¿sabes qué lo hace aún mejor? Poder ver esas alertas directamente en la consola del IDE, en lugar de abrir una nueva página web para consultar los registros.

Para lograrlo, ve a la barra lateral derecha del plugin de Lightrun y, en la entrada del agente, haz clic en el ícono que está más a la derecha y dice PIPE. Luego, haz clic en el botón Both. Esto significa que los registros de alertas se enviarán tanto a la aplicación SaaS de Lightrun como directamente a la ventana de la consola de Lightrun en mi IDE. ¡Genial!

Interfaz oscura de una aplicación que muestra el agente de producción Lirans-MBP, la línea 162 de index.js y un menú abierto con las opciones App, Plugin y Both.

Ahora que configuramos una alerta, probemos a enviar cargas útiles grandes. Para enviarlas, usaré algunas herramientas útiles de línea de comandos que tengo a mi disposición:

  1. Configuración del shell Oh My Zsh (¿a quién no le gusta un prompt elegante?)

  2. La herramienta HTTPie para enviar la solicitud HTTP que agrega una tarea

  3. La herramienta de Unix seq para repetir fácilmente un carácter una cantidad X de veces

Con estas herramientas, enviaré la carga útil con el siguiente comando:

echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutes' | http --form http://localhost:3001/create -v

Esto crea el texto de tarea Buy milk in 500000... minutes, donde el número 5 va seguido de otros 60,000 ceros: una cadena bastante larga.

En la interfaz de la aplicación, se ve así:

Ventana del navegador que muestra una app «Goof TODO» con tareas como comprar leche, proteger una app, descargar un complemento para el IDE y agregar observabilidad y seguridad.

Como puedes ver, la aplicación no falló, la base de datos MongoDB tampoco y, al parecer, el único efecto secundario es que el paquete npm humanize-ms simplemente analiza ese tiempo y lo convierte en la palabra Infinity. En general, tiene sentido y no parece ser un problema real.

¿Recuerdas que configuramos una alerta para esto en el IDE?

Veamos cómo se ve…

¿Ves la línea resaltada en la ventana de la consola de Lightrun? Estamos recibiendo alertas que cumplen una condición de registro para una solicitud HTTP enviada a una aplicación en ejecución, directamente en el IDE. ¡Es bastante (y muy útil también!).

Editor de código con tema oscuro que muestra JavaScript y un panel de Lightrun, junto con una consola que muestra una advertencia sobre una entrada de usuario potencialmente larga y peligrosa.

Pero ¿a qué viene tanto entusiasmo por esta alerta? Sigue leyendo...

Cómo detectar y corregir problemas de seguridad en tu código y dependencias de código abierto

Al parecer, esa versión del paquete npm humanize-ms tiene algunas vulnerabilidades de seguridad indirectas. ¡Las 4,500,000 descargas semanales eran engañosas! La vulnerabilidad de seguridad de ese paquete podría tener consecuencias graves para cualquier aplicación web de Node.js.

¿Cómo lo sé? Porque instalé el plugin de Snyk para IntelliJ y dejé que analizara mi proyecto; detectó esta y algunas otras vulnerabilidades. Veamos cómo ejecutar un análisis y también qué tan grave es esta vulnerabilidad de seguridad, usando la alerta de carga útil grande de usuario en Lightrun.

Una vez que hayas instalado y autenticado el plugin de Snyk para IntelliJ (consulta esta guía paso a paso para instalar el plugin), haz clic en el botón verde Play de la ventana del plugin de Snyk para iniciar un análisis de seguridad.

El análisis buscará los siguientes posibles problemas de seguridad:

  1. Vulnerabilidades de seguridad en bibliotecas de código abierto de terceros, como los paquetes npm que importas a tu código base. Si analizas proyectos de otros lenguajes, como Java, Ruby o Python, Snyk también detectará automáticamente el archivo de manifiesto del paquete y lo analizará.

  2. Problemas de seguridad del código en tu propio código, actualmente con compatibilidad para JavaScript, TypeScript, Java y Python.

Estos son los resultados del análisis de seguridad de Snyk Open Source para los paquetes npm de terceros que agregué como dependencias a este proyecto TODO:

Editor de código JavaScript que muestra una función para guardar tareas junto a un panel de Snyk con una lista de vulnerabilidades de seguridad de código abierto

Al revisar estos resultados, puedes ver que esta aplicación TODO tiene bastantes vulnerabilidades de seguridad. Es una aplicación vulnerable de forma intencional, para que podamos demostrar, practicar y aprender sobre estas vulnerabilidades y cómo corregirlas.

¿Recuerdas el paquete npm humanize-ms que usamos para analizar y dar formato a cadenas de tiempo? Al parecer, incluye una vulnerabilidad de denegación de servicio por expresión regular (ReDOS), porque depende de un rango de versiones vulnerable del popular paquete npm ms:

Editor de código con tema oscuro que muestra resultados de vulnerabilidades de Snyk: secuencias de comandos entre sitios, contaminación de prototipos y denegación de servicio por expresiones regulares.

Volvamos a la carga útil de nuestro exploit de seguridad y examinémosla de nuevo:

echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutes' | http --form http://localhost:3001/create -v

Como recordarás, al ejecutar este comando, envió una cadena muy larga como tarea, pero por lo que pudimos observar, no causó ningún tipo de denegación de servicio. La aplicación siguió procesando solicitudes con normalidad y la aplicación Node.js respondió casi de inmediato.

Sin embargo, las expresiones regulares son… complicadas. Si no están escritas correctamente, pueden ser vulnerables a un retroceso catastrófico, lo que básicamente significa que, para una entrada lineal, el cálculo toma un tiempo superlineal.

Para atacar esta aplicación de manera efectiva, solo necesito cambiar una cosa en la carga útil del exploit: reemplazar la palabra minutes por minutea y ejecutar el comando. Para mostrarte el antes y el después, mira esta captura de pantalla, tomada antes de enviar la solicitud, donde el comando htop muestra la actividad normal de la CPU en mi laptop:

Espacio de trabajo de un desarrollador con código JavaScript, procesos de terminal y un panel de Snyk que detalla una vulnerabilidad de denegación de servicio por expresión regular.

Lo que espero que ocurra con una vulnerabilidad ReDOS es que la aplicación Node.js tarde mucho en calcular la expresión regular y que, debido a la arquitectura de Node.js de un solo hilo, todas las solicitudes posteriores se queden esperando. El uso de la CPU se disparará al 100 % mientras consume todos los recursos disponibles para calcular la expresión regular, en vano.

Enviemos la carga útil de nuestro exploit ReDOS:

echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutea' | http --form http://localhost:3001/create -v

¡Mira! La terminal de la esquina superior derecha muestra la solicitud HTTP enviada, sin respuesta inmediata, y la terminal de la esquina inferior izquierda muestra el proceso de Node.js como la entrada resaltada en verde en la parte superior de la tabla, con un consumo del 98.4 % de los recursos de CPU:

Espacio de trabajo de un desarrollador en modo oscuro con código JavaScript, procesos de terminal, una consola llena de caracteres repetidos y detalles de vulnerabilidades de Snyk.

Lo siguiente, por supuesto, es corregir este y los demás problemas de seguridad que tengo. Una vez que importas tus proyectos a la aplicación de Snyk, se analizan y monitorean continuamente en segundo plano. Además, se crean automáticamente pull request para tus repositorios de Git, ya sea en GitHub o en otro lugar, para actualizar las versiones vulnerables de tus proyectos. Encontrarás más información en el artículo sobre cómo comenzar a usar Snyk Open Source.

Seguridad y observabilidad diseñadas para desarrolladores

Las herramientas diseñadas para desarrolladores, como Lightrun y Snyk, los ayudan a ser más productivos en su trabajo diario al acercarles los datos, en lugar de alejarlos de sus flujos de trabajo.

Aprovechar la observabilidad y la seguridad directamente en el IDE de IntelliJ o en la línea de comandos ayuda a los desarrolladores a monitorear el tráfico en tiempo real, así como a detectar y corregir problemas de seguridad antes de que lleguen al servidor de integración continua, y mucho antes de llegar a producción.

Para empezar a usar ambas soluciones, consulta estos recursos:

  1. Primeros pasos con Snyk

  2. Primeros pasos con Lightrun

Empieza con Capture the Flag

Aprende a resolver desafíos de Capture the Flag viendo nuestro taller virtual introductorio a pedido.

Leer más

Blog

Los modelos de frontera encontraron las vulnerabilidades. Solo el atacante encontró las cadenas.

El análisis estático encontró las fallas, pero solo las pruebas de ataque en vivo demostraron cómo podían encadenarse para provocar brechas. Una comparación de Evo COS, Claude Security y Claude Code Security.

feature insights context
Blog

Los ataques autónomos ya están aquí. La defensa debe estar a su altura.

Los atacantes autónomos están reduciendo el tiempo disponible para defenderse. Descubre cómo el descubrimiento, la corrección, la validación y la prevención continuos pueden ayudar a los equipos de seguridad a seguirles el ritmo.

Blog

Por qué los agentes de programación con IA siguen generando fallas de control de acceso

Los agentes de programación con IA pueden generar lógica de autorización que compila y supera la revisión, pero expone los datos de un inquilino a otro. Descubre por qué es difícil detectar el control de acceso roto y cómo prevenirlo.