Contaminación de Prototipos en JavaScript

Rate this content
Bookmark

En 2018, se publicó un nuevo vector de ataque contra los códigos JavaScript: la Contaminación de Prototipos.
A primera vista, parecía bastante limitado en su impacto: básicamente sería una buena forma de hacer que algunos códigos se bloqueen. Sin embargo, se han producido múltiples casos de Ejecuciones de Código Remoto basados en este vector.
En esta charla, aclararemos qué son las contaminaciones de prototipos, su impacto real y cómo evitar que ocurran en su código.

27 min
14 Apr, 2023

Video Summary and Transcription

Esta charla discute la producción de prototipos en JavaScript y se centra en el concepto de contaminación de prototipos. Explica el impacto de la contaminación de prototipos y formas de evitarla. La charla también destaca ejemplos del mundo real de vulnerabilidades de contaminación de prototipos en Kibana y MongoDB. Proporciona recomendaciones para prevenir y mitigar la contaminación de prototipos, como filtrar las funciones de fusión y usar objetos defensivos. La charla concluye con una discusión sobre herramientas como Semgrep para análisis estático y la importancia de la sanitización y validación en la prevención de ataques externos.

Available in English

1. Introducción

Short description:

Hablaremos sobre la producción de prototipos en JavaScript, pero antes de eso, abordemos algo importante. El orador habla sobre su situación actual, estar desempleado y trabajar en la creación de una empresa.

Muchas gracias. Hablaremos sobre la producción de prototipos en JavaScript, pero antes de hacerlo, hablemos sobre algo muy importante, yo. Así que la biografía está un poco desactualizada y eso es culpa mía. Ya no trabajo en Datadog, desde hace dos semanas. Y estoy trabajando en una empresa llamada QueryTails, que ni siquiera es una empresa que necesite decirle al abogado que la incorpore. Y ni siquiera es una asociación porque básicamente soy yo mismo. Así que si quieres sentirte triste por mí, debes saber que me siento tan solo que hago mis reuniones de seguimiento con Chad GPT por la mañana. Y hablando del logotipo de las empresas, eso también lo diseñó otra IA. Así que básicamente soy yo estando desempleado en Twitter, dinero del desempleo francés, intentando

2. Understanding Prototype Pollution

Short description:

Hablemos sobre la contaminación de prototipos. Primero, aprendamos qué son los prototipos. También discutiremos el impacto de la contaminación de prototipos y cómo evitarla en JavaScript. JavaScript es basado en prototipos y algo tipado. Tenemos el operador typeof para verificar los tipos de variables. Los objetos en JavaScript tienen prototipos y cuando un método o propiedad no se encuentra en un objeto, se busca en el prototipo. Verificaremos de forma recursiva la cadena de prototipos hasta encontrar el método o propiedad. Si no se encuentra en ninguna parte de la cadena de prototipos, es undefined.

para construir una empresa. Pero hablemos sobre la contaminación de prototipos. Primero que nada, antes de contaminar prototipos, aprendamos qué son los prototipos. Incluso si esta es una conferencia de JavaScript, no está de más repasar. También puedes notar que no hay diseño en mis diapositivas en absoluto, ya que diseñar estas diapositivas consistió en eliminar el logotipo y el esquema de colores de Datadog ayer por la noche en el avión. Luego hablaremos sobre el impacto de la contaminación de prototipos y cómo evitar la contaminación de prototipos en JavaScript. Y esta charla ha sido diseñada para veinticinco minutos y solo tenía veinte. JavaScript es basado en prototipos y algo tipado. OK, ¿qué quiero decir? Comencemos con la parte de los tipos porque probablemente sea la más controvertida. Bueno, tienes el operador typeof y puedes verificar los tipos de variables. Entonces, el tipo de true es booleano, el tipo de null es un objeto que se llama el místico de mil millones de dólares, pero ese no es el tema de esta charla. El tipo de 10 es número, el tipo de 10n es bigint y así sucesivamente. Incluso tenemos el tipo undefined para cosas que están indefinidas. JavaScript es tan genial. Y prácticamente todo lo demás es un objeto. Entonces, los objetos son objetos. Los objetos de cadena son objetos. Las expresiones regulares son objetos, null es un objeto y los objetos son objetos. Obviamente, nuevamente, y los objetos tienen métodos, como si creas el objeto Foo1 y llamas a hasOnProperty en él, devolverá true. Y si creas el objeto Foo1 y verificas hasOnProperty, hasOnProperty, devolverá false porque el método hasOnProperty no pertenece al objeto Foo. Entonces, ¿a dónde pertenece? Usemos la mejor herramienta en la historia de la programación, el depurador. Y podemos verificar nuestro objeto y ver que el método hasOnProperty existe en algo que se llama un prototipo y el prototipo se puede acceder desde el objeto directamente. Entonces, ¿qué son los prototipos? En JavaScript, los objetos tienen prototipos. Cuando un método o propiedad no se encuentra en un objeto, se busca en el prototipo. Pero los prototipos son objetos. Entonces, si un método o propiedad no se encuentra en un prototipo, lo verificamos en su prototipo. Pero los prototipos son objetos. Entonces, si un método o propiedad no se encuentra en el prototipo, podemos verificar en el prototipo. Y eso es lo que llamamos la cadena de prototipos. Significa que verificaremos de forma recursiva toda la cadena de prototipos hasta llegar a null, para encontrar un método o una propiedad. Y si no se encuentra en ninguna parte de la cadena de prototipos, es undefined y undefined no es una función.

3. Comprendiendo la Cadena de Prototipos

Short description:

La cadena de prototipos forma una estructura de árbol. Los objetos creados con diferentes métodos pueden o no compartir prototipos. El ítem tres tiene un prototipo, mi proto, mientras que el ítem uno y el ítem dos tienen el prototipo de la clase uno. El prototipo de la clase de estilo antiguo todavía está en la cadena. El método bar no está disponible en cl.prototype pero sí está disponible en old style class.prototype.

Entonces, la cadena de prototipos, básicamente, es un árbol. En el lado izquierdo, he definido un prototipo en mi proto. Lo uso para crear objetos. He definido una clase con un constructor, una clase de estilo antiguo. Le doy un prototipo directamente e incluso defino una clase con la palabra clave class. Básicamente, cuando creo objetos en el lado derecho con estos, compartirán o no compartirán prototipos. Bien, vamos un poco más profundo. El ítem tres tiene un prototipo, mi proto, porque en la línea ocho del código del lado derecho, establecemos objects.setPrototypeof en este objeto. Así que tenemos un método para poner arbitrariamente un prototipo en un objeto, pero el ítem uno y el ítem dos tienen el prototipo de la clase uno, porque los creamos con new y llamamos al constructor de la clase en la parte inferior del lado izquierdo. Pero como esta clase extiende la clase de estilo antiguo, bueno, el prototipo de la clase de estilo antiguo definido en las líneas ocho a trece del lado izquierdo todavía está en la cadena. Así que si quiero verificar el método bar en el ítem uno o el ítem dos, no estará disponible en cl.prototype pero sí estará disponible en old style class.prototype. ¿Está claro? Espero que sí. Por favor, no me arrojen cosas. Gracias.

4. Accediendo a los Prototipos de los Objetos

Short description:

Para acceder al prototipo de un objeto en JavaScript, existen múltiples formas. Podemos utilizar el método Object.getPrototypeOf(), la propiedad __proto__ o la propiedad constructor.prototype. Es importante tener en cuenta que hay una única instancia del prototipo en el montón de memoria.

Entonces, ¿cómo accedemos al prototipo de un objeto? Sí. Pero las personas que me dicen que está claro, saben todo sobre prototipos. Entonces, ¿cómo accedemos al prototipo de un objeto? Tenemos múltiples formas. Así que vamos a tener una clase llamada mi clase porque soy muy original en la forma en que nombro mis clases y crear dos elementos, mi elemento y mi elemento dos. Si verificamos si show prop, que es un método de la clase, está disponible en este objeto, no lo están, porque has on property en la línea 13 nos dice que no está disponible en el objeto directamente. Pero si hacemos object get prototype of my item, esto devolverá el prototipo de la clase. Y esto tiene la propiedad propia show prop, eso es lo que estamos en la línea 14. También podemos acceder a un prototipo con guión bajo, guión bajo, proto guión bajo, guión bajo. Así que si hacemos my item, guión bajo, guión bajo, proto, guión bajo, guión bajo, eso tiene la propiedad show prop, devolverá true. Y si hacemos console.log my item.constructor.prototype tiene la propiedad show prop, también devolverá true. Y lo que vale la pena destacar es que hay una única instancia de este prototipo en el montón de memoria, lo que significa que my item punto guión bajo, guión bajo proto guión bajo, guión bajo, es exactamente lo mismo que my item two guión bajo, guión bajo, proto, guión bajo, guión bajo. Bastante seguro de que nadie ha dicho prototipos tantas veces en su vida en un corto período de tiempo.

5. Prototype Pollution en JavaScript

Short description:

La contaminación de prototipos ocurre cuando una carga arbitraria puede sobrescribir propiedades o métodos en la cadena de prototipos de objetos. Esto puede suceder al usar una función de fusión. Se muestra un ejemplo específico con la biblioteca Hook, donde se utiliza una carga maliciosa para modificar la cadena de prototipos. El impacto de la contaminación de prototipos puede ser grave, con más de 200 vulnerabilidades reveladas desde 2018, incluyendo la ejecución remota de código en Kibana y el servidor PaaS.

tiempo. Entonces, ¿qué es la contaminación de prototipos? Bueno, la contaminación de prototipos ocurre cuando una carga arbitraria manejada por la base de código JavaScript puede sobrescribir propiedades o métodos en algún lugar de la cadena de prototipos de uno o varios objetos. Esto suele ocurrir cuando usamos una función de fusión y veremos en detalle por qué. Entonces, ¿qué quiero decir? Tomemos un ejemplo. Tomemos la biblioteca Hook en la versión 4.1.2, 4.2.0 y tenemos algo llamado carga maliciosa en la línea dos y eso es una cadena que contiene guión bajo guión bajo proto guión bajo guión bajo oops funciona, y luego creamos un objeto llamado A y este objeto no tiene nada que ver con la carga maliciosa. En esta base de código, nunca se llama en la misma función que la carga maliciosa. No sabe nada sobre la carga maliciosa. Así que console.log A.oops y es undefined porque oops no está presente en el objeto A. Tampoco está presente en su cadena de prototipos porque hereda de la cadena de prototipos predeterminada de cualquier objeto en JavaScript. Luego llamamos a hug.merge en un objeto completamente nuevo, sin relación con A y no pasamos la carga maliciosa a JSON. Y después de eso, cuando llamamos a A.oops, devolverá funciona. Porque el prototipo de todos los objetos, el prototipo de los objetos, el prototipo principal del montón de esta base de código de JavaScript, ahora tiene la propiedad oops. ¿Cómo es eso? Bueno, es debido a una recursión.

Entonces, esta es la función de fusión que hemos visto en la línea cinco en la diapositiva anterior. Y esta función realiza una fusión recursiva, lo que significa que si quieres fusionar dos objetos, y tienen propiedades que pueden ser comunes en sus subobjetos, los verificará recursivamente. Pero debido a que __proto__ es una propiedad accesible en la mayoría de los objetos, la función dirá, Oh, tengo algo en proto para escribir en este objeto y este objeto tiene proto. Entonces tomará el valor del prototipo del objeto y comenzará a escribir cosas en eso. Entonces, lo que quiero decir es que a través de la función de fusión, debido a esta llamada recursiva en la línea 18, subimos por la cadena de prototipos y escribimos, oops. Y eso también funcionó en lodash, porque quiero asustar a todos. Quiero decir, en versiones antiguas de lodash, tienes otro constructor de carga, prototipo, isAdmin. Recuerdas que mostré que podemos acceder al prototipo de una función de un objeto yendo a través de constructor.prototype. Bueno, hacemos exactamente lo mismo. Tenemos un objeto B, B.isAdmin es undefined. Usamos lodash.merge en un objeto que no tiene nada que ver con B y la carga como segundo argumento. Y luego B.isAdmin es true. Y, oh, lo siento. Y lodash es increíblemente popular, esta diapositiva no es para el código de JavaScript, es para el código de seguridad. Todos saben que lodash es increíblemente popular y genial.

Entonces, ¿cuál es el impacto de la contaminación de prototipos? Porque suena como una buena manera de meterse con el código de alguien, pero ¿puede ser malicioso? Desde 2018, ha habido más de 200 CVE, CVE significa vulnerabilidades públicas reveladas para que todos las conozcan y no todas las vulnerabilidades reciben un CVE. Así que eso probablemente es la punta del iceberg. Ha habido algunas ejecuciones de código remoto en Kibana y el servidor PaaS, y no, ya no trabajo en Datadog, así que puedo decir lo que pienso sobre Kibana sin preocuparme tanto.

6. Contaminación de Prototipos en Kibana y Parse Server

Short description:

La Universidad KTH publicó un interesante artículo sobre la contaminación de prototipos en Kibana. Los procesos secundarios de Node.js en Kibana comparten el entorno del proceso principal a través de un objeto JavaScript. La variable de entorno Node.option permite pasar argumentos de línea de comandos. La opción -e permite ejecutar código pasado como una cadena. La contaminación de prototipos en Kibana permitía escribir Node.option en la cadena de prototipos. Esto permitía ejecutar código arbitrario en el servidor y generar procesos secundarios. La opción -e ya no está permitida en Node.option, pero existe un bypass. Kibana ha solucionado el problema de la contaminación de prototipos. Parse es un proyecto backend para aplicaciones móviles que expone una API frente a MongoDB.

Así que espero algunas diapositivas sobre eso y la Universidad KTH publicó un artículo muy interesante sobre este tema el verano pasado. El caso de Kibana CVE-2019-7609, básicamente es muy, muy divertido. Me encanta. Kibana utiliza procesos secundarios de Node.js para ciertas cosas. Por ejemplo, si quieres hacer algún cálculo en Kibana, generará un proceso secundario. Y cuando generas un proceso secundario desde Node.js, compartirá el entorno del proceso principal con el proceso secundario a través de un objeto JavaScript. ¿Ves hacia dónde va esto? Hay una variable de entorno en Node.js llamada Node.option que puedes usar para pasar argumentos de línea de comandos al binario de Node. En lugar de hacer Node --algo, puedes hacer Node.option, poner tu --algo en él, y cuando inicies Node, lo capturará. También está la opción -e o --evil en la línea de comandos de Node que te permite ejecutar código pasado como una cadena en la línea de comandos. El ejemplo aquí es Node -e console.log('hello') que realmente inicia un proceso de Node y ejecuta console.log('hello'). Vamos a contaminar este prototipo. Bueno, ¿por qué tengo, ah sí, me falta algo. Está bien. Me falta una diapositiva. Lo siento por eso. Básicamente hubo una contaminación de prototipos en Kibana y podías escribir Node.option en la cadena de prototipos. Sabes, contaminarías el prototipo y cada objeto JavaScript en este montón. Cuando verificas si Node.option está definido, responderá con, oh sí, hay una ejecución de grabación de ejecución maliciosa con la cadena. Y eso es básicamente lo que le sucedió a Kibana. Así que si tenías acceso a un servidor de Kibana a una interfaz de usuario de Kibana, podías ejecutar código arbitrario en el servidor y luego generar otro proceso con tus argumentos compartidos en todo lo que quisieras. Así que lo arreglamos. La opción -e ya no está permitida en Node.option, pero hay un bypass y es público, pero no hablaré de eso. Y Kibana ha solucionado la contaminación de prototipos. El artículo original es muy interesante, muy accesible y también hay una charla, seguramente sobre ese tema, muy, muy interesante de ver.

Parse server. ¿Quién está familiarizado con Parse aquí? Fue muy, muy popular hace un tiempo. Básicamente es un proyecto backend para aplicaciones móviles que expone una API frente a un servidor MongoDB, siendo adquirido por Facebook, cerrado por Facebook, y ahora solo hay una versión de código abierto que solo a Google se le ocurre cerrar productos que la gente ama. Y básicamente es una API frente a MongoDB. Puedes almacenar objetos.

7. Contaminación de Prototipos en MongoDB

Short description:

Puedes solicitar un objeto de MongoDB a través de una API. Antes de ser corregido, era vulnerable a la contaminación de prototipos. La biblioteca utilizada, bsonjs, permite almacenar funciones en MongoDB. De forma predeterminada, las funciones no se deserializan. Sin embargo, si la opción de función eval para la biblioteca bson es verdadera, se pueden evaluar funciones arbitrarias. Esto puede llevar a la ejecución de código arbitrario al recuperar objetos de la base de datos.

Puedes solicitar un objeto de MongoDB a través de una API. Antes de ser corregido, era vulnerable a la contaminación de prototipos, por supuesto. Y utiliza una biblioteca llamada bsonjs. Entonces, bson es un formato para almacenar objetos en MongoDB. Significa JSON binario o algo así. Pero, bson te permite almacenar funciones que se almacenarán en MongoDB y se pueden deserializar. Pero de forma predeterminada, no se deserializan. Porque deserializar una función que proviene de una base de datos básicamente significa, hagamos eval en esa cadena que proviene de la base de datos de la que no tengo idea, y no quieres eso como predeterminado. Pero si la opción eval function en el objeto utilizado como opción para la biblioteca bson es verdadera, bueno, evaluarás esas funciones arbitrarias. Y como Parse te permite escribir prácticamente cualquier cosa que desees en tu base de datos desde la red, porque es Parse, en realidad podrías ejecutar código arbitrario cuando se recupera el objeto, lo cual es, oh dios mío, eso se debe a que verifican el hack de desviación.

8. Prevención de la Contaminación de Prototipos

Short description:

Para prevenir la contaminación de prototipos, filtra las funciones de fusión y elimina específicamente underscore, underscore, proto, underscore, underscore. Lodash ha corregido todas las instancias de contaminación de prototipos. Al usar una propiedad propia, asegúrate de que exista en el objeto y no en su cadena de prototipos. La creación de objetos defensivos utilizando Object.create o Object.createNull puede prevenir la contaminación de prototipos. La sanitización y validación de datos son cruciales para prevenir ataques externos. Considera el uso de bibliotecas como joy para la sanitización de datos al construir un servidor web Node.js. Node.js tiene una opción para deshabilitar proto, underscore, underscore, proto, underscore, underscore, pero ten cuidado, ya que puede romper algún código.

Cómo prevenir la contaminación de prototipos porque soy una persona responsable, no quiero que te sientas asustado y digas , sabes, usemos un lenguaje sin prototipos como Python. ¿Cómo prevenir? Bueno, filtremos, ya sabes, las funciones de fusión. Verás, por ejemplo, en la línea nueve aquí, línea nueve, nueve, tres, o en la línea cuatro aquí, que filtramos, underscore, underscore, proto, underscore, underscore. Y eso es lo que hemos estado corrigiendo en muchas bibliotecas. Lodash ha corregido más instancias de contaminación de prototipos que cualquier otra biblioteca que conozco, y todas han sido corregidas una por una. Si encuentras una nueva, siéntete libre de revelarla de manera responsable a su mantenedor, sin importar qué biblioteca sea.

A veces, sabrás que tu camino de código es crítico y quieres asegurarte de que estás usando una propiedad propia. Bueno, bueno, una propiedad propia puede ser manipulada con ataques de terceros, pero eso es algo diferente. Así que asegúrate de que si esperas que una propiedad exista en un objeto, te asegures de que exista en el objeto y no en su cadena de prototipos. Además, me gusta esto. Es lo que llamo construir un objeto defensivo. No sé si ese es el término académico, pero puedes usar Object.create y eso creará un nuevo objeto con sus argumentos como prototipo. Bueno, null es un objeto. Así que puedes hacer Object.createNull. Estos objetos no tendrán todos los métodos que esperas que tengan como propiedad propia, símbolos propios, descriptores de propiedad propia, pero este objeto estará a salvo de la contaminación de prototipos porque no tiene ningún prototipo.

Sanitización, asegúrate de que lo que ingresa a tu proceso desde el exterior sea seguro. Realiza validación de datos. Me encanta la biblioteca joy porque soy un niño feliz y gordo, pero hay muchas bibliotecas increíbles para realizar sanitización de datos. Úsalas. Son muy geniales. Y de todos modos, deberías usarlas si estás construyendo un servidor web con Node.js. Como se mencionó, eso también probablemente reducirá tu superficie de ataque a la inyección de secretos. Así que adelante.

Conclusiones. Oh dios mío, llego a tiempo. ¿Qué sigue? Monitorea los objetos entrantes. Node.js tiene una opción para deshabilitar proto, underscore, underscore, proto, underscore, underscore. Puede romper algún código. Así que ten en cuenta que puede romper algún código debido a Internet, pero puedes usarlo. Y para la sanitización y objetos sin prototipos. Oh, ¿recuerdas por qué te dije que deberías usar Python? Eso fue una broma en enero.

9. Mitigación de la Contaminación de Prototipos

Short description:

Alguien publicó un artículo sobre la contaminación de clases en Python. No hay pruebas de uso real en la naturaleza para ataques maliciosos, pero destaca la vulnerabilidad. Es importante verificar de dónde provienen tus objetos en tu código, especialmente para aplicaciones web que aceptan objetos desde el exterior. Ten precaución con los ataques de terceros desde módulos de NPM y las entradas de la red. Sanitiza y valida los objetos que ingresan a tu aplicación para prevenir inyecciones y asegurarte de que cumplan con tus expectativas. Utiliza herramientas como Sneak Audit y NPM Audit para verificar vulnerabilidades conocidas en tu código.

Alguien publicó un artículo. No hay pruebas de uso real en la naturaleza para ataques maliciosos, pero ha habido un artículo sobre la contaminación de clases diciendo que, básicamente, Python también es vulnerable a eso. Así que no hay un lugar seguro.

Algunos enlaces. Las diapositivas estarán en Twitter. Por favor, solicita las diapositivas en Twitter si las deseas. Mantengámonos en contacto. Puedes encontrar mi Twitter con esta URL corta.

Espero que hayas disfrutado esta presentación y que tengas preguntas que pueda responder. Muchas gracias por ser un grupo increíble. Abordaremos esta pregunta en su debido momento. Hubo muchas sugerencias sobre cómo mitigar los riesgos causados por la contaminación de prototipos. Si nuestra audiencia regresara a casa y fuera a sus bases de código en las que están trabajando actualmente y con las preocupaciones que pueden tener ahora, ¿cuál sería lo primero que les animarías a hacer? Tal vez sea una acción simple y fácil o comenzar un trabajo más significativo.

Esa es una muy buena pregunta. Creo que lo primero que debes hacer después de asistir a una conferencia sobre seguridad en Node en general, cuando regreses, es verificar de dónde provienen tus objetos, y eso es cierto para mitigar la contaminación de prototipos, pero también para todas las inyecciones en general. Cuando digo eso, me refiero a que en algún momento, si tienes una aplicación web, es posible que acepte objetos desde el exterior. Pueden ser las cadenas de consulta, pueden ser el cuerpo. En algún momento, hay una biblioteca en tu base de código que pasará una solicitud HTTP de texto y devolverá un objeto de JavaScript. Esa es probablemente la principal fuente de entradas maliciosas. Porque tu aplicación puede ser vulnerable a ataques de terceros desde tus módulos de NPM o desde las entradas que provienen de la red. Y a mí me gusta pensar en las cosas que provienen de la red, hablar con ZB Si estás interesado en el otro modelo de amenaza, la parte del modelo de amenaza. Así que verifica el objeto que ingresa a tu aplicación y verifica qué estás haciendo con ellos. ¿Los estás sanitizando? ¿Conoces su estructura? ¿Hay un error en tu código cuando no se parecen a lo que esperas? Eso significa métodos que, propiedades que esperas del objeto, pero también, ¿estás seguro de que el objeto no tiene propiedades que no esperas? Por lo tanto, los objetos que ingresan a tu aplicación deben tener una apariencia conocida. Y eso será la primera forma de saber que nadie está inyectando algún tipo de guion bajo, guion bajo, proto o elementos de constructor en tus objetos. Genial.

Muchas gracias. Entonces, algunas preguntas de la audiencia, ¿hay alguna forma fácil, creo que mencionaste esto, pero haré la pregunta explícitamente de todos modos. ¿Hay alguna forma fácil de verificar si mi servicio es vulnerable a este ataque, alguien que usa muchos módulos de terceros de NPM? Sneak Audit, NPM Audit, ya conocerás los métodos vulnerables, si se conocen. Verifica si estás utilizando métodos de fusión en tu propio código, pero sí, básicamente asegurarte de que no tienes vulnerabilidades conocidas en tu base de código es el primer paso. Idealmente, los marcos de trabajo deberían poder manejar este tipo de cosas por nosotros.

QnA

Preguntas y Respuestas

Short description:

¿Existen equivalentes a Express o Fastify que prevengan la contaminación de prototipos? No estoy seguro, pero vale la pena revisar la documentación. El argumento -e en las opciones de nodo permite pasar una cadena de código JavaScript en lugar de un archivo. Object.assign puede no crear prototipos contaminados, pero se necesita más investigación. Otras formas de lograr RCE con la contaminación de prototipos dependen de las capacidades de evaluación de cadenas de la aplicación. Considera usar mapas en lugar de objetos para evitar la contaminación, pero asegúrate de que no haya contaminación intrínseca. No está claro si fusionar objetos con el operador de propagación nativo está protegido contra la contaminación. Es importante explorar diferentes soluciones y no asumir la vulnerabilidad. Las reglas de ES lint que detectan estos problemas pueden requerir seguimiento de contaminación.

¿Existen equivalentes a Express o Fastify que prevengan la contaminación de prototipos? Hasta donde sé ahora, no estoy al tanto de la documentación de Fastify o la documentación de Express, estoy al tanto porque no ha cambiado en cinco o seis años, pero no creo que existan. Ese es un buen punto, supongo que Matteo dirá que se aceptan solicitudes de extracción, así que siéntete libre de hacer una solicitud de extracción para Fastify.

La siguiente pregunta es algo que mencionaste en tu charla, pero ha recibido varios pulgares arriba. Así que quiero hacerla de todos modos. ¿Qué es el argumento "-e" en las opciones de nodo? Bueno, "-e" es una abreviatura de "-eval" y básicamente te brinda la oportunidad de pasar una cadena como argumento en lugar de un archivo y ejecutar esta cadena como si fuera un archivo JavaScript. Entonces, en lugar de hacer "node index.js", haces "node -e" y colocas una cadena con todo tu código JavaScript y eso lo ejecutará. Genial. Gracias.

¿Object.assign también crea prototipos contaminados? Esa es una buena pregunta. Quiero decir que no, pero no estoy seguro. Esa es tu tarea para esta noche. No creo, pero lo estoy verificando. No pensé que vinieras a ningún congreso por esa tarea. ¿Existen otras formas de hacer RCE con la contaminación de prototipos sin opciones de nodo como en el ejemplo de Cabana? Bueno, hubo el ejemplo de bison con una función que se serializaba. Así que supongo que sí, de alguna manera, eso realmente depende de la aplicación que estés atacando. ¿Esta aplicación tiene evaluación de cadenas en algún momento, ya sea a través de variables de entorno, eval, con VM o transcodificación? En ese caso, sí, pero depende mucho de la lógica empresarial. Gracias. Tengo algunas más, ¿quieres seguir adelante? En base a tu charla, ¿deberíamos usar mapas en lugar de objetos para evitar estos problemas? Quiero decir, sí. Sí. Quiero decir, solo asegúrate de que, si eres muy cauteloso al respecto, debes asegurarte de que no haya contaminación intrínseca, lo que significa que alguien anula los métodos basados en mapas, no pueden hacerlo hasta donde sé con la contaminación de prototipos, pero pueden hacerlo con un tercero malintencionado. El código de Node.js es realmente defensivo contra eso, así que puedes verificarlo. Pero sí, los mapas probablemente sean una de las cosas más inteligentes que puedes hacer en tu aplicación web, en lo que a mí respecta, me encantan los mapas. Si has asistido a la charla de James sobre almacenamiento asíncrono, la primera versión que propuse del almacenamiento asíncrono te obligaba a usar un mapa como almacenamiento, como amante de los mapas, diría que sí, pero estoy sesgado. Solo un poco. ¿Y si fusiono un objeto con el operador de propagación nativo en lugar de la antigua versión, una versión antigua de lodash? Creo que estás a salvo de la contaminación de prototipos, pero es como el objeto asignado de datos, nunca lo he intentado, así que no puedo afirmarlo con certeza. Creo que con muchas de estas preguntas, probablemente se trata de probar todas las soluciones y ver cuál es el resultado, ¿verdad? Además, espero que si estas formas fueran vulnerables a la contaminación de prototipos, lo sabríamos ampliamente como comunidad, por eso tiendo a pensar que estamos seguros, pero como persona de seguridad, no quiero asumir las cosas. Y tampoco quieres asumir. ¿Existen o podrían existir reglas de ES lint que detecten estos problemas? Buena pregunta. Podría haber una necesidad. Es difícil porque requiere un poco de seguimiento de contaminación.

Semgrep y Fusión de Objetos

Short description:

Semgrep es una poderosa herramienta de análisis estático de código que puede encontrar vulnerabilidades ejecutando parte de tu código en una máquina virtual. Es de código abierto y está diseñado para verificar si estás fusionando objetos basados en objetos entrantes.

Podría haber al menos una regla de semgrep que verifique que estás fusionando objetos basados en objetos entrantes. Entonces, semgrep, para aquellos que no están familiarizados, es una herramienta de análisis estático de código. Es de código abierto. Está escrito en Okeanos, construido en la costa oeste, es realmente genial y está diseñado para encontrar vulnerabilidades. Pero es un poco inteligente. Es más poderoso que la mayoría de las herramientas de linting porque tiene algún tipo de motor de ejecución simbólica y puede ejecutar parte de tu código en una máquina virtual, es decir, ejecuta parte de tu código y decide si es vulnerable. No estoy seguro acerca del linter, pero estoy bastante seguro acerca de semgrep. Genial. Asombroso. La última pregunta que tenemos en esta lista. ¿Qué pasa si fusionamos constructor.prototype en lugar de usar underscore proto underscore? ¿Pasaría a través del filtro underscore underscore proto underscore underscore y funcionaría? ¿Puedes repetir eso? No estoy seguro. ¿Qué pasa si fusionamos constructor.prototype en lugar de usar underscore proto? Depende de la vulnerabilidad. Si entiendo correctamente la pregunta, así es como se ha solucionado en lodash. Depende de cómo funcionan realmente estas funciones de fusión y queremos poder fusionar prototipos para construir mixins de todos modos, así que no queremos evitar eso por completo. Sí, genial. Muchas gracias. Gracias a todos, wow, pasamos de solo hacer algunas preguntas a una enorme lista de preguntas y eso es increíble. En nombre de toda nuestra audiencia, gracias nuevamente por una charla realmente provocadora y táctica sobre cómo mitigar los riesgos en la contaminación de prototipos. Así que muchas gracias por tenerme y gracias por ser una audiencia increíble. Hagamos un gran aplauso grupal. ¡Un diez!

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
Do you have a large product built by many teams? Are you struggling to release often? Did your frontend turn into a massive unmaintainable monolith? If, like me, you’ve answered yes to any of those questions, this talk is for you! I’ll show you exactly how you can build a micro frontend architecture with Remix to solve those challenges.
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Top Content
Remix is a web framework that gives you the simple mental model of a Multi-Page App (MPA) but the power and capabilities of a Single-Page App (SPA). One of the big challenges of SPAs is network management resulting in a great deal of indirection and buggy code. This is especially noticeable in application state which Remix completely eliminates, but it's also an issue in individual components that communicate with a single-purpose backend endpoint (like a combobox search for example).
In this talk, Kent will demonstrate how Remix enables you to build complex UI components that are connected to a backend in the simplest and most powerful way you've ever seen. Leaving you time to chill with your family or whatever else you do for fun.
JSNation Live 2021JSNation Live 2021
29 min
Making JavaScript on WebAssembly Fast
Top Content
JavaScript in the browser runs many times faster than it did two decades ago. And that happened because the browser vendors spent that time working on intensive performance optimizations in their JavaScript engines.Because of this optimization work, JavaScript is now running in many places besides the browser. But there are still some environments where the JS engines can’t apply those optimizations in the right way to make things fast.We’re working to solve this, beginning a whole new wave of JavaScript optimization work. We’re improving JavaScript performance for entirely different environments, where different rules apply. And this is possible because of WebAssembly. In this talk, I'll explain how this all works and what's coming next.
React Summit 2023React Summit 2023
24 min
Debugging JS
Top Content
As developers, we spend much of our time debugging apps - often code we didn't even write. Sadly, few developers have ever been taught how to approach debugging - it's something most of us learn through painful experience.  The good news is you _can_ learn how to debug effectively, and there's several key techniques and tools you can use for debugging JS and React apps.

Workshops on related topic

React Day Berlin 2022React Day Berlin 2022
86 min
Using CodeMirror to Build a JavaScript Editor with Linting and AutoComplete
Top Content
WorkshopFree
Using a library might seem easy at first glance, but how do you choose the right library? How do you upgrade an existing one? And how do you wade through the documentation to find what you want?
In this workshop, we’ll discuss all these finer points while going through a general example of building a code editor using CodeMirror in React. All while sharing some of the nuances our team learned about using this library and some problems we encountered.
TestJS Summit - January, 2021TestJS Summit - January, 2021
173 min
Testing Web Applications Using Cypress
WorkshopFree
This workshop will teach you the basics of writing useful end-to-end tests using Cypress Test Runner.
We will cover writing tests, covering every application feature, structuring tests, intercepting network requests, and setting up the backend data.
Anyone who knows JavaScript programming language and has NPM installed would be able to follow along.
Node Congress 2023Node Congress 2023
63 min
0 to Auth in an Hour Using NodeJS SDK
WorkshopFree
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool.
We will enhance a full-stack JS application (Node.JS backend + React frontend) to authenticate users with OAuth (social login) and One Time Passwords (email), including:- User authentication - Managing user interactions, returning session / refresh JWTs- Session management and validation - Storing the session for subsequent client requests, validating / refreshing sessions
At the end of the workshop, we will also touch on another approach to code authentication using frontend Descope Flows (drag-and-drop workflows), while keeping only session validation in the backend. With this, we will also show how easy it is to enable biometrics and other passwordless authentication methods.
Table of contents- A quick intro to core authentication concepts- Coding- Why passwordless matters
Prerequisites- IDE for your choice- Node 18 or higher
React Summit US 2023React Summit US 2023
96 min
Build a powerful DataGrid in few hours with Ag Grid
WorkshopFree
Does your React app need to efficiently display lots (and lots) of data in a grid? Do your users want to be able to search, sort, filter, and edit data? AG Grid is the best JavaScript grid in the world and is packed with features, highly performant, and extensible. In this workshop, you’ll learn how to get started with AG Grid, how we can enable sorting and filtering of data in the grid, cell rendering, and more. You will walk away from this free 3-hour workshop equipped with the knowledge for implementing AG Grid into your React application.
We all know that rolling our own grid solution is not easy, and let's be honest, is not something that we should be working on. We are focused on building a product and driving forward innovation. In this workshop, you'll see just how easy it is to get started with AG Grid.
Prerequisites: Basic React and JavaScript
Workshop level: Beginner
Node Congress 2023Node Congress 2023
49 min
JavaScript-based full-text search with Orama everywhere
Workshop
In this workshop, we will see how to adopt Orama, a powerful full-text search engine written entirely in JavaScript, to make search available wherever JavaScript runs. We will learn when, how, and why deploying it on a serverless function could be a great idea, and when it would be better to keep it directly on the browser. Forget APIs, complex configurations, etc: Orama will make it easy to integrate search on projects of any scale.
Node Congress 2022Node Congress 2022
128 min
Back to the basics
WorkshopFree
“You’ll never believe where objects come from in JavaScript.”
“These 10 languages are worse than JavaScript in asynchronous programming.”
Let’s explore some aspects of JavaScript that you might take for granted in the clickbaitest nodecongress.com workshop.
To attend this workshop you only need to be able to write and run NodeJS code on your computer. Both junior and senior developers are welcome.
Objects are from Mars, functions are from Venus
Let’s deep-dive into the ins and outs of objects and then zoom out to see modules from a different perspective. How many ways are there to create objects? Are they all that useful? When should you consider using them?
If you’re now thinking “who cares?“, then this workshop is probably for you.
Asynchronous JavaScript: the good? parts
Let’s have an honest conversation.
I mean… why, oh why, do we need to bear with all this BS? My guess is that it depends on perspective too. Let’s first assume a hard truth about it: it could be worse… then maybe we can start seeing the not-so-bad-even-great features of JavaScript regarding non-blocking programs.