Denegación de Servicio
Prototype pollution, una vulnerabilidad crítica en aplicaciones JavaScript, puede llevar a DoS, entre otras consecuencias. Esto ocurre cuando un atacante manipula el prototipo de un objeto ampliamente utilizado, causando que la aplicación se comporte inesperadamente o que incluso crashee. En JavaScript, los objetos heredan propiedades y métodos de los prototipos, y alterar estos prototipos afecta directamente a los objetos.
Por ejemplo, si un atacante contamina el método Object.prototype.toString, cada llamada posterior a este método por parte de cualquier objeto ejecutará el comportamiento alterado. En una aplicación compleja donde toString es frecuentemente usada, esto puede llevar a resultados inesperados, potencialmente causando que la aplicación funcione mal. El método toString es usado universalmente en JavaScript.
Si el método contaminado lleva a un procesamiento ineficiente o a un bucle infinito, puede agotar los recursos del sistema causando un DoS. Además, puede interferir con la lógica de negocio.
Ejemplo Práctico
- De nuevo, visitaremos
http://IP:5000y veremos si podemos crashear el servidor. Como ya hemos hablado, tenemos el métodoObject.prototype.toString. - Visitamos la página del perfil de cualquier amigo y podemos ver que así es como se comporta el cliente:
<form action="/clone-album/1" method="post" class="mb-4"> <h2 class="mb-3">Clone Album of Josh</h2> <div class="form-group"> <label for="selectedAlbum">Select an Album to Clone:</label> <select class="form-control" name="selectedAlbum" id="selectedAlbum"> <option value="Trip to US"> Trip to US </option> </select> </div> <div class="form-group"> <label for="newAlbumName">New Album Name:</label> <input type="text" class="form-control" name="newAlbumName" id="newAlbumName" placeholder="Enter new album name"> </div> <button type="submit" class="btn btn-primary">Clone Album</button> </form>
- Vemos que esta función lama a la función
merge. ¿Qué pasa si intentamos mandar un payload que sobrescriba una función existente comotoString()y luego la llamamos desde un objeto? - Para preparar el payload tomaremos un simple JSON:
{"__proto__": {"toString": "Just crash the server"}}
- Vamos al perfil e introducimos el payload en lugar del nombre del álbum.

- Decodearemos el payload una vez que
app.jsreciba la petición, parsee el JSON y asigne el valor de la funcióntoStringen la propiedad__proto__del objetofriend. - Esto crea un comportamiento abrupto ya que
toStringes ampliamente utilizada por diferentes objetos. Podemos hacer click en clonar el álbum y pasa lo siguiente:
- El
TypeErrorque obtenemos esObject.prototype.toString.callis not a function, ya que hemos sobrescrito la función usando PP. - Puedes sobrescribir muchas otras funciones incrustadas como
toJSON,valueOf,constructor, etc, pero la aplicación no crasheará siempre. Depende de cuánto se use la función que sobrescribes.
