Ce que vous devez savoir sur la pollution des prototypes et son impact sur JavaScript

Non, il ne s’agit pas de déchets solides générés par la production de prototypes ou de modèles pour différents produits. La pollution prototype fait ici référence à une cybermenace critique notée 10/10 sur l’échelle de gravité CVSS.

Dans un article publié en juillet de cette année, intitulé “Silent Spring : Prototype Pollution Leads to Remote Code Execution in Node.js”, des chercheurs en sécurité ont révélé une vulnérabilité qui affecte les langages basés sur des prototypes comme JavaScript et la plateforme Node.js. Cette menace consiste à injecter des propriétés dans le prototype racine d’un objet lors de l’exécution et provoque l’exécution de gadgets de code légitimes.

Les chercheurs ont développé un cadre basé sur CodeQL pour détecter la pollution prototype en utilisant à la fois une analyse dynamique et statique. À l’aide de ce cadre, ils ont pu identifier 11 gadgets universels pouvant potentiellement permettre l’exécution de code à distance dans l’API code Node.js.

Qu’est-ce que la pollution prototype exactement ?

Comme mentionné, la pollution prototype est une cyber-vulnérabilité conçue pour permettre aux pirates d’exploiter les runtimes JavaScript. Il en résulte des compromis de sécurité car il permet l’introduction de propriétés dans les prototypes de construction JavaScript existants.

Le nom de cette menace est en fait une description de son fonctionnement. Il permet d’injecter des valeurs qui écrasent le “prototype” d’un objet de base. Cela signifie qu’un prototype est essentiellement “pollué”, ce qui entraîne la création d’un prototype malveillant qui pourrait ensuite être transmis à d’autres objets qui héritent du prototype.

Les acteurs de la menace étant capables de contrôler les valeurs des propriétés des objets, ils peuvent modifier la logique d’une application et lancer des attaques telles que le déni de service, l’élévation des privilèges et l’exécution de code à distance, entre autres.

L’émergence d’une pollution prototype

Avant de discuter des détails de la façon dont la pollution prototype a eu lieu, voici une définition des termes importants impliqués dans l’existence de la pollution prototype.

  • Objet — Cela fait référence à tout ce qui est saisi en JavaScript, à l’exception des primitives.
  • Prototype — Il s’agit d’un mécanisme qui permet aux objets JavaScript d’adopter les fonctionnalités d’autres objets.
  • __proto__ — Il s’agit d’un attribut qui a été standardisé sur tous les navigateurs. Il fait référence aux prototypes d’un objet.

La pollution de prototype se produit lorsqu’un acteur menaçant parvient à prendre le contrôle de l’attribut __proto__, ayant la capacité de manipuler les valeurs de cet attribut. Ils le font généralement en ajoutant un nouveau prototype dans l’attribut __proto__. L’introduction d’un nouveau prototype a pour effet de faire hériter tous les objets du prototype injecté puisque chaque objet JavaScript a déjà l’attribut __proto__ et hérite des prototypes.

La manipulation de l’attribut __proto__ permet la modification des propriétés d’un code JavaScript existant, ce qui peut entraîner un certain nombre de conséquences possibles, notamment le déni de service (DoS), l’exécution de code à distance (RCE), l’injection SQL, le cross-site scripting (XSS), escalade de privilèges et autres résultats indésirables.

De l’exploitation à l’attaque

Pour souligner, la pollution prototype n’est pas elle-même l’attaque. C’est une vulnérabilité qui peut entraîner des cyberattaques lorsqu’elle est exploitée. Lorsque l’exploitation de la vulnérabilité entraîne le plantage d’un serveur, un DoS se produit. Le déni de service peut ne pas sembler si menaçant, mais une étude du Ponemon Institute indique qu’un DoS peut coûter 22 000 $ pour chaque minute d’indisponibilité.

L’exécution de code à distance peut être déclenchée par la création d’un reverse shell similaire à ce qui s’est passé avec la bibliothèque de visualisation de données appelée Kibana. De plus, les cybercriminels peuvent lancer une attaque par injection SQL comme ce qui s’est passé il y a quelques années avec la bibliothèque JavaScript TypeORM. De plus, les auteurs de menaces peuvent déclencher l’exécution de code JavaScript côté client en exploitant la vulnérabilité du prototype de pollution dans les gadgets qui reposent sur la propriété d’un objet.

Pendant ce temps, les attaquants ayant des connaissances plus avancées sur la pollution des prototypes peuvent entreprendre une exploitation côté serveur, qui a généralement un impact plus grave par rapport à ses homologues côté client. L’exploitation côté serveur peut également entraîner une injection SQL, l’exécution de code à distance et le contournement de l’autorisation et de l’authentification.

Comment lutter contre la pollution des prototypes

La pollution prototype est un problème complexe, mais qui n’est pas sans solutions. Il existe trois façons principales de l’éviter et d’atténuer son impact.

  • S’assurer de la sécurité des bibliothèques open source utilisées — L’utilisation de bibliothèques open source est une pratique normale, mais cela ne signifie pas qu’il s’agit principalement d’une pratique sûre et sécurisée. Il est recommandé de revérifier les sources des bibliothèques à utiliser pour s’assurer qu’elles sont exemptes de vulnérabilités pouvant entraîner des compromis de sécurité. Souvent, les problèmes qu’ils contiennent ne sont pas délibérément ajoutés, mais ils se développent à la suite de différents événements, notamment la fusion de deux objets, le clonage en profondeur d’objets et la génération d’objets via la fermeture récursive de propriétés avec des valeurs.
  • Évitez de créer des objets avec des prototypes Java — Au lieu d’utiliser le constructeur d’objet “Object() ou le littéral d’objet {}” lors de la création d’un nouvel objet, il est préférable d’utiliser “Object.create()”. Cette méthode est préférable car elle permet de définir le prototype de l’objet créé à l’aide du premier argument passé à l’objet. Avec cela, passer une valeur nulle signifie qu’il n’y aura pas de prototype pour l’objet créé. Par conséquent, le nouvel objet devient exempt de pollution possible car il n’y a pas de prototype à polluer en premier lieu.
  • Restreindre toutes les modifications au prototype — JavaScript permet de bloquer toutes les modifications tentées sur un prototype via Object.freeze(). Cela empêche toutes les modifications possibles des attributs d’un objet. Alternativement, le package nopp npm peut être installé. Faire cela gèle automatiquement tous les prototypes d’objets communs, pour empêcher tout changement dans le prototype.
  • Validation du schéma d’entrée JSON — Cette approche rejette les attributs inutiles d’être adopté. Pour avoir une validation de schéma de l’entrée JSON, il est important d’utiliser une bibliothèque sur npm telle que ajv. La validation de schéma vérifie que les données JSON possèdent tous les attributs attendus, y compris le type de données approprié.
  • Utiliser la carte au lieu de l’objet — Chaque fois qu’une structure clé/valeur est produite, il est conseillé d’utiliser “map” au lieu de “object”. Cette solution fonctionne comme un HashMap à l’exception qu’elle ne peut être consommée que

Points clés à retenir

La pollution prototype n’est pas une menace mineure. C’est une vulnérabilité qui peut avoir de graves conséquences lorsqu’elle est exploitée. Cela peut entraîner des interruptions coûteuses en raison d’un déni de service. De plus, il est rassurant de savoir qu’il existe des moyens relativement simples de régler ce problème. Mieux encore, il existe des solutions avancées complètes qui peuvent protéger JavaScript des attaques et empêcher l’exploitation de la vulnérabilité du prototype de pollution.

Crédit d’image : Pixabay

Peter Davidson travaille en tant qu’associé principal pour aider les marques et les start-ups à prendre des décisions commerciales efficaces et à planifier des stratégies commerciales appropriées. C’est un grand fan de gadgets qui aime partager son point de vue sur les dernières technologies et applications.

Leave a Comment