NodeJS - __proto__ & prototype Pollution
Objets en JavaScript
Les objets en JavaScript sont essentiellement des collections de paires clé-valeur, connues sous le nom de propriétés. Un objet peut être créé en utilisant Object.create
avec null
comme argument pour produire un objet vide. Cette méthode permet la création d'un objet sans aucune propriété héritée.
Un objet vide est similaire à un dictionnaire vide, représenté comme {}
.
Fonctions et Classes en JavaScript
En JavaScript, les classes et les fonctions sont étroitement liées, les fonctions servant souvent de constructeurs pour les classes. Malgré l'absence de support natif des classes en JavaScript, les constructeurs peuvent émuler le comportement des classes.
Prototypes en JavaScript
JavaScript permet la modification, l'ajout ou la suppression des attributs de prototype à l'exécution. Cette flexibilité permet l'extension dynamique des fonctionnalités de classe.
Des fonctions comme toString
et valueOf
peuvent être modifiées pour changer leur comportement, démontrant la nature adaptable du système de prototype de JavaScript.
Héritage
En programmation basée sur les prototypes, les propriétés/méthodes sont héritées par les objets à partir de classes. Ces classes sont créées en ajoutant des propriétés/méthodes soit à une instance d'une autre classe, soit à un objet vide.
Il convient de noter que lorsqu'une propriété est ajoutée à un objet servant de prototype pour d'autres objets (comme myPersonObj
), les objets héritants ont accès à cette nouvelle propriété. Cependant, cette propriété n'est pas affichée automatiquement à moins d'être explicitement invoquée.
Pollution de __proto__
Exploration de la pollution de prototype en JavaScript
Les objets JavaScript sont définis par des paires clé-valeur et héritent du prototype d'objet JavaScript. Cela signifie que modifier le prototype d'objet peut influencer tous les objets dans l'environnement.
Utilisons un exemple différent pour illustrer :
L'accès au prototype de l'objet est possible à travers :
En ajoutant des propriétés au prototype de l'objet, chaque objet JavaScript héritera de ces nouvelles propriétés :
pollution de prototype
Pour un scénario où l'utilisation de __proto__
est restreinte, la modification du prototype d'une fonction est une alternative :
Cela affecte uniquement les objets créés à partir du constructeur Vehicle
, leur donnant les propriétés beep
, hasWheels
, honk
et isElectric
.
Deux méthodes pour affecter globalement les objets JavaScript via la pollution de prototype incluent :
Polluer directement le
Object.prototype
:
Polluer le prototype d'un constructeur pour une structure couramment utilisée :
Après ces opérations, chaque objet JavaScript peut exécuter les méthodes goodbye
et greet
.
Polluer d'autres objets
D'une classe à Object.prototype
Dans un scénario où vous pouvez polluer un objet spécifique et que vous devez accéder à Object.prototype
, vous pouvez le rechercher avec un code similaire à ce qui suit :
Pollution des éléments du tableau
Notez que comme vous pouvez polluer les attributs des objets en JS, si vous avez accès pour polluer un tableau, vous pouvez également polluer les valeurs du tableau accessibles par index (notez que vous ne pouvez pas écraser les valeurs, donc vous devez polluer les index qui sont d'une manière ou d'une autre utilisés mais pas écrits).
Pollution des éléments Html
Lors de la génération d'un élément HTML via JS, il est possible de surcharger l'attribut innerHTML
pour le faire écrire du code HTML arbitraire. Idée et exemple de cet article.
Exemples
Exemple de base
Une pollution de prototype se produit en raison d'une faille dans l'application qui permet d'écraser les propriétés de Object.prototype
. Cela signifie que puisque la plupart des objets dérivent de leurs propriétés de Object.prototype
L'exemple le plus simple est d'ajouter une valeur à un attribut non défini d'un objet qui va être vérifié, comme suit :
Si l'attribut admin
est indéfini, il est possible d'exploiter une pollution de prototype et de le définir sur True avec quelque chose comme :
Le mécanisme derrière cela implique de manipuler les propriétés de telle sorte que si un attaquant a le contrôle sur certaines entrées, il peut modifier le prototype de tous les objets de l'application. Cette manipulation implique généralement de définir la propriété __proto__
, qui, en JavaScript, est synonyme de modifier directement le prototype d'un objet.
Les conditions dans lesquelles cette attaque peut être exécutée avec succès, telles que décrites dans une étude spécifique, comprennent :
Effectuer une fusion récursive.
Définir des propriétés en fonction d'un chemin.
Cloner des objets.
Fonction de remplacement
Pollution du prototype pour RCE
Prototype Pollution to RCEPollution du prototype côté client pour XSS
Client Side Prototype PollutionCVE-2019–11358 : Attaque de pollution du prototype via jQuery $ .extend
Pour plus de détails, consultez cet article En jQuery, la fonction $ .extend
peut entraîner une pollution du prototype si la fonction de copie profonde est utilisée de manière incorrecte. Cette fonction est couramment utilisée pour cloner des objets ou fusionner des propriétés à partir d'un objet par défaut. Cependant, lorsqu'elle est mal configurée, les propriétés destinées à un nouvel objet peuvent être assignées au prototype à la place. Par exemple :
Cette vulnérabilité, identifiée sous le nom CVE-2019-11358, illustre comment une copie profonde peut modifier involontairement le prototype, entraînant des risques potentiels en matière de sécurité, tels que l'accès administrateur non autorisé si des propriétés comme isAdmin
sont vérifiées sans une vérification d'existence appropriée.
CVE-2018-3721, CVE-2019-10744 : Attaque de pollution de prototype via lodash
Pour plus de détails, consultez cet article
Lodash a rencontré des vulnérabilités similaires de pollution de prototype (CVE-2018-3721, CVE-2019-10744). Ces problèmes ont été résolus dans la version 4.17.11.
Un autre tutoriel avec des CVE
Outils pour détecter la Pollution de Prototype
Server-Side-Prototype-Pollution-Gadgets-Scanner : Extension de Burp Suite conçue pour détecter et analyser les vulnérabilités de pollution de prototype côté serveur dans les applications web. Cet outil automatise le processus de numérisation des requêtes pour identifier les problèmes potentiels de pollution de prototype. Il exploite des gadgets connus - des méthodes pour exploiter la pollution de prototype afin d'exécuter des actions nuisibles - en se concentrant particulièrement sur les bibliothèques Node.js.
server-side-prototype-pollution : Cette extension identifie les vulnérabilités de pollution de prototype côté serveur. Elle utilise des techniques décrites dans la pollution de prototype côté serveur.
Pollution de Prototype AST en NodeJS
NodeJS utilise largement les Arbres de Syntaxe Abstraite (AST) en JavaScript pour des fonctionnalités telles que les moteurs de modèles et TypeScript. Cette section explore les vulnérabilités liées à la pollution de prototype dans les moteurs de modèles, en particulier Handlebars et Pug.
Analyse de la Vulnérabilité de Handlebars
Le moteur de modèles Handlebars est susceptible à une attaque de pollution de prototype. Cette vulnérabilité provient de fonctions spécifiques dans le fichier javascript-compiler.js
. Par exemple, la fonction appendContent
concatène pendingContent
si elle est présente, tandis que la fonction pushSource
réinitialise pendingContent
à undefined
après avoir ajouté la source.
Processus d'Exploitation
L'exploitation tire parti de l'AST (Arbre de Syntaxe Abstraite) produit par Handlebars, en suivant ces étapes :
Manipulation du Parseur : Initialement, le parseur, via le nœud
NumberLiteral
, impose que les valeurs soient numériques. La pollution de prototype peut contourner cela, permettant l'insertion de chaînes non numériques.Traitement par le Compilateur : Le compilateur peut traiter un objet AST ou un modèle de chaîne. Si
input.type
est égal àProgram
, l'entrée est traitée comme pré-analysée, ce qui peut être exploité.Injection de Code : En manipulant
Object.prototype
, on peut injecter du code arbitraire dans la fonction de modèle, ce qui peut entraîner une exécution de code à distance.
Un exemple illustrant l'exploitation de la vulnérabilité de Handlebars :
Ce code montre comment un attaquant pourrait injecter du code arbitraire dans un modèle Handlebars.
Référence externe: Un problème lié à la pollution de prototype a été trouvé dans la bibliothèque 'flat', comme détaillé ici: Problème sur GitHub.
Référence externe: Problème lié à la pollution de prototype dans la bibliothèque 'flat'
Exemple d'exploitation de la pollution de prototype en Python:
Vulnérabilité de Pug
Pug, un autre moteur de template, est confronté à un risque similaire de pollution de prototype. Des informations détaillées sont disponibles dans la discussion sur l'injection AST dans Pug.
Exemple de pollution de prototype dans Pug:
Mesures Préventives
Pour réduire le risque de pollution de prototype, les stratégies énumérées ci-dessous peuvent être mises en œuvre :
Immutabilité des Objets : L'
Object.prototype
peut être rendu immuable en appliquantObject.freeze
.Validation des Entrées : Les entrées JSON doivent être rigoureusement validées par rapport au schéma de l'application.
Fonctions de Fusion Sécurisées : L'utilisation non sécurisée de fonctions de fusion récursives doit être évitée.
Objets sans Prototype : Des objets sans propriétés de prototype peuvent être créés en utilisant
Object.create(null)
.Utilisation de Map : Au lieu d'
Object
,Map
devrait être utilisé pour stocker des paires clé-valeur.Mises à Jour des Bibliothèques : Les correctifs de sécurité peuvent être incorporés en mettant régulièrement à jour les bibliothèques.
Outils de Linting et d'Analyse Statique : Utilisez des outils comme ESLint avec des plugins appropriés pour détecter et prévenir les vulnérabilités de pollution de prototype.
Revues de Code : Mettez en place des revues de code approfondies pour identifier et remédier aux risques potentiels liés à la pollution de prototype.
Formation en Sécurité : Sensibilisez les développeurs aux risques de pollution de prototype et aux meilleures pratiques pour écrire un code sécurisé.
Utilisation Prudente des Bibliothèques : Soyez prudent lors de l'utilisation de bibliothèques tierces. Évaluez leur posture en matière de sécurité et examinez leur code, en particulier ceux qui manipulent des objets.
Protection à l'Exécution : Employez des mécanismes de protection à l'exécution tels que l'utilisation de packages npm axés sur la sécurité qui peuvent détecter et prévenir les attaques de pollution de prototype.
Références
Last updated