Optimizing Software Security Practices

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

¿Recuerdas aquella vez que una simple vulnerabilidad XSS expuso millones de registros de usuarios? ¿O cuando una variable de entorno mal configurada llevó a comprometer por completo la base de datos? Es la pesadilla de un desarrollador frontend, y ocurre más a menudo de lo que crees.

React te proporciona algunas herramientas de seguridad de serie, pero seamos sinceros: no son suficientes. Si estás construyendo algo más que una aplicación básica, necesitas mejorar tu juego de seguridad.

Esta sesión revelará 7 técnicas poderosas para fortalecer tus aplicaciones frontend contra los ataques más comunes.

This talk has been presented at React Summit US 2024, check out the latest edition of this React Conference.

David Mytton
David Mytton
29 min
22 Nov, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Esta charla cubre siete pasos para asegurar aplicaciones React, incluyendo la gestión de dependencias, validación, gestión de secretos, exposición de código, seguridad de contenido, implementación de seguridad y medidas de seguridad adicionales. Se enfatiza la importancia de comprender las dependencias y los riesgos, utilizando herramientas como NPM Audit y Socker.dev. También se destaca la necesidad de validación de dependencias y espacio de nombres de paquetes, así como la validación de entrada utilizando bibliotecas como Zod y Valobot. Los secretos deben ser gestionados utilizando herramientas como .env y un gestor de secretos, mientras que la exposición de código puede ser minimizada separando el código del lado del servidor y del lado del cliente. Se recomiendan políticas de seguridad de contenido y herramientas como Next Safe y Helmet para su implementación. Medidas adicionales incluyen análisis profundo de código, monitoreo de ejecución de código y políticas de seguridad de contenido estrictas.

1. Securing React Apps: Dependencies and Updates

Short description:

Esta charla trata sobre cómo asegurar tus aplicaciones de React, específicamente siete pasos para tener aplicaciones de React más seguras. Vamos a hablar sobre dependencias, validación de código y riesgos, consideraciones de implementación y la centralización del código.

Esta charla trata sobre cómo asegurar tus aplicaciones de React, específicamente siete pasos para tener aplicaciones de React más seguras. Ahora, vamos a hablar de algunas cosas diferentes y cubrir diferentes áreas y entrar en algunos detalles técnicos.

Primero, vamos a hablar sobre dependencias y algunas cosas que puedes hacer para pensar en la cadena de suministro de tus aplicaciones. Y luego vamos a adentrarnos en el código que estás escribiendo y pensar en la validación, cómo manejar secretos y variables de entorno, y luego considerar, bueno, ¿cuáles son los riesgos de exponerlos a través de la exposición del código? Y luego veremos algunos aspectos de la implementación, por lo que pensar en las cabeceras de seguridad y finalmente volveremos al código y pensar en la filosofía detrás de la centralización del código y en lo que tu editor de código puede hacer para ayudarte con todo esto.

Así que como una breve introducción, mi nombre es David Mitton. Soy el fundador de Artjet, que es un producto de seguridad como código. Es un SDK que los desarrolladores pueden instalar para ayudarles a construir cosas como protección de bots y prevención de ataques en sus aplicaciones. Y también escribo el boletín DevTools de console.dev, que se envía gratis todas las semanas. Así que vamos a meternos en el tema y hablar de las dependencias.

Ahora, cualquier aplicación que haga algo serio probablemente tendrá un gran número de dependencias. Y por lo tanto, el desafío aquí es mantenerse actualizado. El principio principal es entender de quién dependes, porque ejecutar npm install X o cualquier gestor de paquetes que estés usando está trayendo código de terceros que en teoría podrías leer, pero la mayoría de las veces no lo harás, ciertamente no a lo largo de la vida útil de un proyecto a medida que tus dependencias se actualizan regularmente. Y por lo tanto, esta es un área de riesgo grave, porque traer código de terceros que va a ejecutarse como parte de tu aplicación tiene el mismo acceso que si fuera el código que tú mismo has escrito. Y por lo tanto, lo que está en el archivo package JSON es realmente importante.

Ahora, hay un par de cosas diferentes que puedes hacer para gestionar esto. La que probablemente todos conocen es una herramienta de GitHub llamada Dependabot. Esto debería estar habilitado de forma predeterminada y debería ser una práctica estándar en cada repositorio que crees tener a Dependabot gestionando las actualizaciones de todas tus dependencias. Esta es la forma más fácil de introducir vulnerabilidades en tu código, pero también es la forma más fácil de mitigarlas, porque tener software actualizado es una de las formas más comunes en que ocurren los ataques. Y por lo tanto, mantener tus dependencias actualizadas es muy importante. Dependabot automatiza eso. Es bastante difícil estar al tanto de cada paquete que estás usando, en varios lenguajes de programación, tal vez, pero ciertamente dentro del ecosistema de JavaScript. Y Dependabot simplemente lo automatiza. Puedes configurarlo para que te dé actualizaciones todos los días o todas las semanas, y para agruparlas y hacer más fácil su gestión. Pero esencialmente abrirá solicitudes de extracción en tu repositorio con las últimas actualizaciones. Eso es genial, porque automáticamente ejecutará cualquier prueba que tengas. Creará una rama. Puedes implementarlo en un entorno de vista previa y puedes fusionar fácilmente las actualizaciones menores. Y esperemos que las actualizaciones mayores no causen cambios que rompan. Pero esta es una forma realmente fácil de mantenerse actualizado. Está disponible de forma gratuita en GitHub.

2. Securing React Apps: Gestión de Dependencias

Short description:

Si no quieres usar Dependabot de GitHub, entonces una alternativa está integrada en la CLI de NPM, NPM Audit. Hace algo muy similar. La herramienta que usamos en Artjet, junto con Dependabot, es Socker.dev. Y esta es una herramienta realmente útil. Cuando llega una nueva actualización a tu repositorio, escaneará la actualización en busca de actividad sospechosa. Es importante entender si algo ha cambiado en la dependencia entre versiones. Otro tipo de vulnerabilidad que esto puede detectar se llama vulnerabilidad de confusión de paquetes.

Si no quieres usar Dependabot de GitHub, entonces una alternativa está integrada en la CLI de NPM, NPM Audit. Hace algo muy similar. No es tan completo y profundo, y no es tan fácil simplemente hacer una nueva solicitud de extracción. Pero te da una vista de todas tus dependencias y si hay alguna vulnerabilidad de seguridad. La herramienta que usamos en Artjet, junto con Dependabot, es Socker.dev. Y esta es una herramienta realmente útil. De nuevo, está disponible de forma gratuita para paquetes de código abierto, aunque es un producto comercial. No tengo ninguna participación en ello. Solo soy un fan. Solo soy un usuario de ella. Pero cuando llega una nueva actualización a tu repositorio, escaneará la actualización en busca de actividad sospechosa. Ahora, esta es una captura de pantalla de una solicitud de extracción. Esta es una de hace uno o dos meses en nuestro repositorio en una de nuestras aplicaciones de Next.js. Y el primer comentario muestra que se agregaron algunas nuevas dependencias. Esto es útil para hacer un análisis de riesgo básico, porque puedes ver la dependencia que se agregó. Y también puedes ver las capacidades que tiene. Así que en este caso, la herramienta de registro PNO puede acceder al entorno y tiene acceso a evaluar y parte del sistema de archivos. Esto es solo una verificación rápida que puedes ver para asegurarte de que está haciendo lo que esperas que haga. Otra herramienta útil que viene con la detección de problemas de seguridad. Y esto es realmente importante para entender si algo ha cambiado en la dependencia entre versiones. Aquí se resalta que una de las dependencias es potencialmente un paquete trivial, mientras que otra es un nuevo autor que lo ha publicado, mientras que el autor anterior era alguien diferente. Ahora, en este caso, sabemos que el nuevo autor, Matteo Colino, es un miembro conocido de la comunidad de JavaScript, por lo que esto no representa un riesgo. Pero hay casos en los que un paquete puede cambiar repentinamente de propietario, y esto puede presentar un problema si no sabes quién es esa persona, y es posible que desees verificar para ver cuáles fueron sus confirmaciones iniciales. Ahora, otro tipo de vulnerabilidad que esto puede detectar se llama vulnerabilidad de confusión de paquetes. Ahora, esta es una captura de pantalla de un archivo package JSON de una de las dependencias que usamos en Artjet. Esto es algo que verás todo el tiempo. Y si pausas este video y echas un vistazo rápido, podrás tal vez detectar cuál es la vulnerabilidad de seguridad. Es bastante sutil aquí. Así que en este proyecto, tenemos un monorepositorio, y esto asume que hemos creado algunos paquetes locales porque queremos traer alguna configuración que queremos compartir en diferentes paquetes dentro del repositorio. Ahora, un enfoque común para esto es simplemente hacer referencia al nombre del paquete que tienes que encontrar localmente.

3. Securing React Apps: Validación de Dependencias

Short description:

Si publicas un paquete privado como un paquete de código abierto, la dependencia privada no existirá y se utilizará en su lugar el paquete público de npm. Esto puede introducir riesgos de seguridad, especialmente si el paquete es propiedad de un autor desconocido y no se ha actualizado durante mucho tiempo. Asigna un espacio de nombres a tus paquetes y coloca las dependencias locales en la sección de dependencias de desarrollo. Utiliza Semgrep para detectar y marcar cualquier instancia de uso de la propiedad dangerously set inner HTML en React. Utiliza una biblioteca de validación como Zod o Valobot para validar la entrada del usuario y combínala con un ORM como Drizzle para generar automáticamente el esquema.

Si resaltamos dónde está el problema, podemos ver que este paquete personalizado de eslintconfig está utilizando un espacio de nombres global y está en la sección de dependencias en lugar de las dependencias de desarrollo. La forma en que esto normalmente funcionaría es si eres el mantenedor de este repositorio y ejecutas npm install, ya tienes el paquete personalizado de eslintconfig localmente porque es un paquete privado. Y así, este package JSON lo cargará como esperas. Pero tan pronto como lo publiques públicamente, si alguien más depende de este paquete, entonces el paquete personalizado de eslintconfig no existe. No está disponible porque es solo un paquete privado. Sin embargo, está en la sección de dependencias, lo que significa que se implementará como parte de tus dependencias de producción. Ahora, en este caso, el paquete realmente existe. Simplemente no es el paquete que esperabas. Debido a que el paquete no ha sido asignado a un espacio de nombres, en realidad lo obtendrá de npm. Y en este caso, es un paquete que es propiedad de un autor desconocido y no ha sido actualizado durante dos años. Y lo que llamaríamos una dependencia trivial porque el tamaño del paquete es solo de 400 bytes. Ahora, este es un error legítimo. El desarrollador quizás no entendió que debía asignarle un espacio de nombres porque asumía que npm simplemente resolvería el paquete localmente, lo cual es cierto cuando está utilizando su monorepo. Pero cuando publicas esto como un paquete de código abierto, esa dependencia privada no existe. Por lo tanto, buscará el paquete público de npm. Y podemos ver aquí que hay otros 74 paquetes que han cometido el mismo error. Algunos de estos parecen ser paquetes de criptografía. Y aunque esta dependencia en realidad no está haciendo nada, podrías ver legítimamente los problemas que esto podría introducir porque este autor podría actualizar el paquete en algún momento. Recibe casi 50,000 descargas cada semana. Y una vez que encuentren otro paquete que dependa de él y que esté haciendo algo importante, como una billetera de criptomonedas o algo que maneje pagos en un formulario de tarjeta de crédito, podrían inyectar fácilmente código y robar los tokens de las billeteras de las personas o las tarjetas de crédito de las personas. Por lo tanto, lo importante aquí en un monorepo es siempre asignar un espacio de nombres a tus paquetes y colocar las cosas que solo estás usando localmente en esa sección de dependencias de desarrollo.

Al pensar en la validación, esto es algo que probablemente todos hayan escuchado, pero no necesariamente se hace de manera religiosa. Pero es otro paso fácil para asegurarte de que el contenido malicioso no pueda ingresar a tu aplicación. React hace mucho por ti de forma predeterminada. Hace que sea mucho más difícil hacer cosas como vulnerabilidades de scripting entre sitios. La única forma en que realmente es posible hacerlo es si usas la propiedad dangerously set inner HTML en uno de los componentes de React. Y hay una razón por la que tiene `dangerously` como prefijo, porque estás evitando todas las protecciones que React te brinda de forma predeterminada. Una forma rápida de protegerte contra esto es usar Semgrep, que es una herramienta de análisis estático de código abierto, para detectar y marcar cualquier instancia de uso de esta propiedad en particular. Y cuando aceptes la entrada del usuario, debes usar una biblioteca de validación como Zod o Valobot para definir un esquema de exactamente lo que esperas, los tipos de cadena, la longitud de la cadena, si debe ser un número o un booleano, y para validar la entrada del usuario antes de que llegue a tu código de base de datos o antes de realizar cualquier manipulación en esa entrada. Ahora, si estás utilizando un ORM como Drizzle, puedes combinar Zod con Drizzle para generar automáticamente el esquema basado en el esquema de tu base de datos.

4. Securing React Apps: Validación de Entrada y Secretos

Short description:

Combinando la estructura de la base de datos con la validación de entrada utilizando Zod. Evita usar variables de entorno para secretos, ya que pueden ser expuestas accidentalmente y difíciles de rastrear o rotar. Carga los secretos en tiempo de ejecución.

Y esta es una forma realmente buena de combinar el formato estructurado de una base de datos con la validación de entrada, como Zod. En este caso, tenemos una base de datos donde hay diferentes tablas. En este caso, es una tabla de equipos. Y en la parte inferior, tengo un esquema que se basa en la estructura de esa tabla de la base de datos. Y en este caso, esperamos que cuando creemos un nuevo equipo, proporcionemos un nombre, que debe ser una cadena con una longitud mínima y máxima, y luego eliminaremos cualquier espacio en blanco. Esto se genera automáticamente y se encuentra junto con el esquema de tu base de datos. Por lo tanto, cuando realices cambios en la base de datos, puedes regenerar fácilmente el esquema de Zod y estará disponible para la validación cuando se envíe un formulario en tu aplicación web.

Ahora, las variables de entorno son una forma común de configurar aplicaciones. Es muy común tener un archivo .env donde colocarás una cadena de conexión de la base de datos o una configuración de idioma. Esto es bastante común porque la configuración se puede cargar en tiempo de ejecución y luego puedes tener una configuración diferente localmente en tu computadora. Puede ser diferente en el entorno de preparación, puede ser diferente en producción. Sin embargo, es una mala práctica utilizar variables de entorno para secretos. Los secretos no deben estar en variables de entorno. Hay varias razones para esto. Si estás utilizando un framework como Next.js, algunos de estos frameworks facilitan exponer accidentalmente el secreto públicamente. Ahora, si prefijas una variable de entorno con next public, entonces estará automáticamente disponible en el paquete firmado por el cliente. Esta es una falla común que he visto donde un desarrollador tiene un problema para conectarse a la base de datos y accidentalmente agrega el prefijo next public a su cadena de conexión de la base de datos mientras intenta depurarla. Eso lo hace disponible como parte del paquete que se envía al navegador de cada usuario, y luego expondrá tu base de datos. Ahora, incluir las variables de entorno como parte del paquete o en una caché, si estás utilizando Turbo, por ejemplo, puede ser muy fácil exponer accidentalmente esos secretos. Igualmente, podrías tener un console.log que te hayas olvidado en algún lugar y que los secretos se registren en un sistema de registro de terceros o en la consola del navegador. Idealmente, el desafío con el uso de variables de entorno es que es muy difícil rastrear dónde están porque son solo cadenas que se encuentran en el sistema operativo o donde se está ejecutando la aplicación. Es muy difícil auditarlos porque no sabes cuándo se acceden a ellos debido a que no se realiza un seguimiento de ellos, y eso significa que también es muy difícil rotarlos porque no sabes dónde están, y el sistema que estás utilizando, solo es una cadena en memoria, no tiene forma de rotarlos automáticamente manteniendo la validez del valor anterior. Ahora, solo como ejemplo de esto, abre una terminal en tu computadora y ejecuta env. Verás una salida como esta, que simplemente muestra que son cadenas simples, y esperemos que no haya nada confidencial allí. Pero si haces esto al final del día y te has estado conectando a AWS, o has estado haciendo cosas en un entorno de desarrollo local, es posible que tengas secretos que aparezcan en tu terminal.

5. Securing React Apps: Gestión de Secretos

Short description:

La biblioteca .env te permite importar automáticamente secretos, lo que proporciona una mejor seguridad contra la ejecución remota de código. El uso de un gestor de secretos minimiza el riesgo y proporciona una capa de gestión para el ciclo de vida de las vulnerabilidades. 1Password y el sistema de AWS ofrecen registro y auditoría para una mejor trazabilidad.

La biblioteca .env tiene una forma de hacer esto. Es un servicio y te permite configurar la biblioteca para importar automáticamente los secretos cuando la aplicación se inicia. Esto es mucho más difícil de infiltrar que simplemente tener un secreto en memoria, porque acceder a la memoria que no sea solo ejecutar env o tener la variable de entorno allí es mucho más desafiante. Esto ayuda a proteger contra ataques de ejecución remota de código, porque acceder a un servidor específico o a un contenedor no suele ser el objetivo final. Todo se trata del movimiento lateral.

Cuando estás haciendo cualquier tipo de hacking challenge o eventualmente tienes una vulnerabilidad real, el objetivo del atacante es obtener acceso al sistema y luego utilizar ese acceso para elevar sus privilegios y convertirse en root o para acceder a una database. Acceder a un contenedor bloqueado realmente no ayuda. Pero si la cadena de conexión de la database está disponible solo como una variable de entorno, entonces es muy fácil establecer una conexión con esa database. Quieres minimizar la disponibilidad de esos secretos.

El uso de un gestor de secretos como AWS Secrets Manager, Dockler, 1Password y la herramienta de gestión de secretos de Physical o Hashcorp minimiza el riesgo que tienes allí. Pero también te proporciona una capa de gestión. Esto es realmente importante para gestionar el ciclo de vida de las vulnerabilidades. Si tienes una vulnerabilidad, realmente quieres poder responder a la pregunta de qué se accedió, quién lo accedió y cuándo. Y al tener variables de entorno que solo contienen los secretos, no puedes responder ninguna de esas preguntas. En cambio, el uso de algo como 1Password o el sistema de AWS te brinda un registro completo y auditoría de cada acceso a esos sistemas.

6. Securing React Apps: Exposición de Código

Short description:

La exposición de código es un desafío interesante con el desarrollo de frameworks sofisticados. Separar el código del lado del servidor del código del lado del cliente es crucial para proteger los secretos. El módulo Solo-Servidor evita que el código se implemente en el cliente. Las cabeceras de seguridad como strict transport security, content type options, permissions policy, referrer policy y content security policy ayudan a mejorar la seguridad de la aplicación.

La exposición de código también es un desafío interesante y se ha vuelto mucho más relevante con el desarrollo de diferentes frameworks que se están volviendo mucho más sofisticados. Si observamos esta captura de pantalla, que es de la documentación de Next.js, mi pregunta es, ¿qué código se ejecuta en el lado del servidor y cuál se ejecuta en el cliente? A primera vista, es muy difícil saberlo. Incluso con solo 20 líneas de código, es difícil determinar qué está sucediendo en el lado del servidor versus en el cliente. Por lo tanto, es necesario poder separar estas dos preocupaciones porque los secretos, por ejemplo, que se acceden en el servidor no son un problema, mientras que los secretos que están disponibles en el paquete del cliente sí lo son.

La solución simple para esto es evitar que suceda en el momento de la compilación. Existe un módulo disponible llamado Solo-Servidor que hace esto realmente simple. Solo tienes que importarlo en el código que sabes que solo debe estar en el servidor en tu capa de acceso a la base de datos, por ejemplo, o donde estés trabajando con claves de API para hacer una solicitud remota a una API de terceros. Ese es el tipo de código que solo debe ejecutarse en tu servidor. Y si está en el cliente, cometiste un error. ¿Cómo detectas eso? Una importación de Solo-Servidor causará un error de compilación, por lo que si ese código se incluye accidentalmente en el cliente, obtendrás un error en tus registros y no se implementará.

Pensando más en tu aplicación una vez que está implementada, hay una serie de cabeceras de seguridad que debes revisar y configurar para mejorar la seguridad general de tu aplicación. Ahora, gran parte de esto ayuda a prevenir errores, porque no hay una sola cosa que asegure tu aplicación. La seguridad no es un estado binario. No es seguro o inseguro. Se trata de tener diferentes capas de seguridad para mejorar gradualmente tu postura, porque cuando una de ellas falla, quieres tener algo más que brinde una capa de protección.

La primera de estas es la seguridad de transporte estricta. Esta es una configuración muy simple que es mucho más fácil hoy en día que hace unos años, porque le indica a los navegadores que tu sitio solo debe ser accedido a través de HTTPS. Esto casi es lo predeterminado ahora para las aplicaciones, e incluso los navegadores comenzarán a mostrar advertencias cuando se accede a contenido a través de HTTP, por lo que es menos una configuración inusual. Pero te permite establecer este valor predeterminado para que un navegador nunca acceda a tu sitio o tu aplicación a través de HTTP.

Las opciones de tipo de contenido también vale la pena configurarlas porque previenen vulnerabilidades relacionadas con la detección de contenido. Esto es bastante sofisticado en términos de los ataques y requiere ciertas vulnerabilidades que existan en tu código, pero es una configuración de seguridad agradable para ayudar a evitarlos. Ahora, la política de permisos y la política de referencia se refieren al aspecto de privacidad. La política de permisos establece una lista específica de funciones y API a las que tu sitio desea acceder. Por ejemplo, si no necesitas la cámara web y no necesitas la ubicación del usuario, simplemente no las incluyas en la política de permisos y el navegador evitará que tu sitio acceda a ellas. Esto es útil para prevenir el riesgo de que se inyecte malware en tu sitio, tal vez a través de una violación de CDN de terceros, y minimizará el riesgo, minimizará el impacto de una violación si eso sucede. Por último, la política de seguridad de contenido es quizás la más importante de todas, pero también la más difícil, porque la política predeterminada romperá la mayoría de las aplicaciones a menos que se haya implementado desde el principio, porque lo predeterminado es no permitir nada.

7. Securing React Apps: Content Security

Short description:

Previene el cross-site scripting, la inyección de malware y el robo de datos controlando el contenido cargado en tu página. Establece una política estricta, habilita gradualmente las funciones deseadas y omite opciones obsoletas como XFrames y la protección XSS.

Esto evita el cross-site scripting, la inyección de malware y el robo de datos, ya que asegura que solo se cargue el contenido esperado en tu página. Por ejemplo, denegará todo el JavaScript, denegará todo el CSS, denegará todas las imágenes. Probablemente eso no es exactamente lo que deseas, pero cada una de estas opciones tiene ajustes diferentes que puedes hacer, por lo que puedes permitir el JavaScript, pero solo si coincide con este hash, o si coincide con estas características específicas, o puedes permitir el CSS, pero solo si proviene de este dominio en particular. Esto realmente se trata de asegurar lo que se carga en tu página.

Ahora, el enfoque recomendado para esto es establecer una política muy estricta, para que todo se deniegue de forma predeterminada. Luego lo cargas en un navegador con las herramientas de desarrollo abiertas, y te mostraremos exactamente qué políticas se han aplicado, y gradualmente puedes flexibilizar la security habilitando las diferentes funciones que te brindan exactamente lo que esperas. Por último, estas dos opciones, XFrames y la protección XSS, han sido obsoletas, porque la funcionalidad se ha trasladado a la política de contenido security, por lo que si solo esperas que los navegadores modernos accedan a tu sitio, no necesitas prestar demasiada atención a ellas.

8. Securing React Apps: Security Implementation

Short description:

Establece encabezados CSP utilizando herramientas como Next Safe o Helmet, y utiliza la herramienta de evaluación de Google para ajustar las políticas. Implementa la funcionalidad de seguridad en un lugar central para facilitar la auditoría y las pruebas. Elige opciones de código abierto como NextAuth o herramientas comerciales como Clark, Oso y PyMet para la autenticación y autorización. Utiliza trunk.io para gestionar linters y reglas de código en diferentes lenguajes y herramientas. Trivy analiza la infraestructura como código en busca de errores comunes, evitando la inclusión de secretos en el código fuente en GitHub.

Ahora, por supuesto, puedes establecer estos encabezados manualmente, pero hay un par de herramientas que facilitan mucho hacer esto, en lugar de definir las políticas manualmente, y en algunos casos te brindarán seguridad de tipo en las opciones. La primera es, si estás utilizando Next.js, entonces el complemento Next Safe es una buena opción, pero si estás utilizando JavaScript en general, entonces Helmet es una excelente opción. Estas se incluyen en tu código, y como parte de tu configuración, defines la política CSP que deseas. Luego puedes utilizar la herramienta de evaluación de Google. Una vez que se ha generado una política, puedes ingresarla en el evaluador y te dará una explicación sobre las diferentes configuraciones y te ayudará a ajustarla si hay alguna recomendación.

Luego pasamos a cómo pensar en la seguridad en general en toda tu aplicación, y el principio aquí es la centralización. Aquí es donde implementas tu funcionalidad de seguridad en un solo lugar de tu aplicación y luego la llamas en otros lugares. Básicamente, construyes una biblioteca para tu seguridad y luego la importas. Esto facilita mucho más adelante cuando necesitas hacer cambios, porque todo está en un solo lugar. Es mucho más fácil auditarlo, tanto cuando haces solicitudes de extracción internamente, como si tienes pruebas de penetración externas o auditorías, es mucho más fácil y menos tiempo consumidor para esos equipos. Y también es mucho más fácil de probar, porque puedes escribir pruebas para una sola parte de tu código base, en lugar de tenerlo disperso en diferentes áreas. Esto significa autenticación, el inicio de sesión en tu aplicación, y autorización, que son los roles y los permisos que las personas tienen una vez que han iniciado sesión. Ahora hay opciones de código abierto para construir esto. Por ejemplo, NextAuth, que se está convirtiendo en AuthJS, es un gran proyecto de código abierto que te permite implementar la autenticación. Clark también hace esto, es una herramienta comercial popular. Y luego están Oso y PyMet, que son herramientas comerciales para implementar la autorización.

Y luego lo último de lo que hablaremos es cómo tu editor de código puede ayudar realmente con todo esto. La herramienta que siempre uso, que he estado usando durante un tiempo, se llama trunk.io. En realidad, soy inversor en la empresa, pero eso fue después de haberlo estado usando. Es esencialmente una herramienta de nivel superior, es una CLI que te ayuda a gestionar todos tus linters y las reglas de código en todo. En lugar de tener que configurar cada uno individualmente y para todos los diferentes lenguajes y herramientas que estás utilizando, puedes tener la configuración gestionada por Trunk. Se ejecuta localmente y también puede integrarse en CI y señalar cosas a medida que se envían a las solicitudes de extracción. Sin embargo, si quieres utilizar estas herramientas individualmente, hay un par que recomiendo específicamente. Trivy, que es una herramienta de análisis estático para la infraestructura como código, analiza los cambios que utilizaste para configurar tu aplicación, ya sea algo como Terraform o diferentes marcos, para asegurarte de que se eviten prácticas comunes o errores comunes. Y luego un problema clásico es incluir accidentalmente secretos en el código fuente. Git está diseñado como una base de datos inmutable. No lo es del todo, pero una vez que envías el código a GitHub, especialmente si es un repositorio público, es esencialmente permanente. Y lo que quieres hacer es evitar enviar secretos a GitHub. GitHub tiene su propio escaneo de secretos y también los valida. Entonces, si envías una clave de AWS, verificará que todavía sea válida.

9. Securing React Apps: Additional Security Measures

Short description:

Marca la casilla para bloquear la inserción de código secreto. Utiliza Truffle Hog y GitLeaks para un análisis profundo del código. SemGrep aplica reglas y señala errores comunes. Asegura las aplicaciones con la gestión de dependencias, validación, sanitización, seguridad de variables de entorno, monitoreo de ejecución de código y políticas de seguridad de contenido estrictas. Centraliza la funcionalidad para facilitar las pruebas y auditorías. Instala Trunck y configura Semgrep para obtener sugerencias de código.

En muchos casos, puedes marcar una casilla y evitar que se inserte código con un secreto, lo cual es un gran avance. Sin embargo, también existen herramientas de código abierto que analizan más a fondo tu código o diferentes áreas de tu aplicación. Truffle Hog y GitLeaks son ejemplos de esto. Truffle Hog, por ejemplo, puede examinar todos tus activos de construcción. Entonces, si creas un contenedor y has incluido accidentalmente un secreto en una variable de entorno que luego se incorpora al contenedor, Truffle Hog te ayudará a encontrarlo.

La última herramienta que recomendaría es una herramienta llamada SemGrep, que es un análisis estático. La mencioné anteriormente cuando hablábamos de la propiedad dangerously set innerHTML. Básicamente, aplica reglas a tu código y puede señalar en tu editor cualquier tipo de error común que puedas cometer, sin importar el lenguaje de programación que estés utilizando.

Hemos hablado de siete formas diferentes de asegurar tus aplicaciones, desde las dependencias y el uso de herramientas como Socket y Dependabot. La importancia de la validación y sanitización, asegurándote de que la entrada que llega a tu aplicación sea la esperada. Utiliza algo como Zod para definir esquemas. Y piensa en tus variables de entorno, evitando poner secretos en ellas y utilizando algo como el Gestor de Secretos de AWS o 1Password para gestionarlos. Mantén un ojo en dónde se está ejecutando tu código, asegurándote de que no se exponga accidentalmente en el cliente. Y cuando implementes tu aplicación, considera las cabeceras de seguridad y, idealmente, comienza con una política de seguridad de contenido muy estricta y luego ve abriéndola gradualmente.

Y cuando estés escribiendo tu código, es importante centralizar toda esa funcionalidad para facilitar las pruebas y auditorías más adelante, y permitir que tu editor te ayude. Instala algo como Trunck y configura Semgrep para obtener sugerencias de código mientras escribes, de modo que no tengas que volver más tarde a solucionar problemas que podrían haberse detectado antes. Eso es todo. Muchas gracias.