Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
proposal-symbol-proto — TC39 proposal for mitigating prototype pollution | Kitploit
Outils/GitHubGitHub/tc39/proposal-symbol-proto
Vulnerability AnalysisWeb SecurityPapers & ResearchLearning & Education
GitHubtc39/proposal-symbol-proto

proposal-symbol-proto

TC39 proposal for mitigating prototype pollution

Voir le dépôt
532il y a 2 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Atténuation de la pollution des prototypes / Symbol.proto

Auteurs : Santiago Díaz (Google)

Champion : Shu-yu Guo (Google)

Stade : 1

Sommaire

  • Description du problème
    • Action fantôme à distance
    • Attaques par données uniquement
  • Problèmes avec freeze, seal et preventExtensions
    • L'erreur d'override
    • Granularité grossière
    • Points de gel
    • Types d'applications
  • Solution proposée
    • Fournir des API de réflexion
    • Fonctionnalité opt-in
      • Refactorisation automatique
    • Que signifie supprimer ?
  • Bases de code incompatibles
  • Annexe
    • Et la pollution du constructeur ?
    • Accès calculé dans le JS minimisé
    • Exemples de vulnérabilités

tl;dr

Cette proposition vise à atténuer une vulnérabilité au niveau du langage connue sous le nom de pollution des prototypes, grâce à un mécanisme qui complète les primitives de gel et à un mécanisme pour rendre la plupart des bases de code compatibles avec elle. Elle décrit une fonctionnalité opt-in qui rend les prototypes disponibles uniquement via les API de réflexion. Ainsi, l'instruction obj[key] ne peut plus accéder aux prototypes. Les bases de code compatibles avec cette fonctionnalité sont plus intentionnelles dans leur façon d'utiliser les prototypes.

Description du problème

Action fantôme à distance

Les vulnérabilités PP permettent aux attaquants de manipuler des objets qu'ils ne contrôlent pas ou auxquels ils n'ont pas accès à l'exécution. Cette primitive d'« action fantôme à distance » peut être utilisée pour modifier la forme d'autres objets et remplacer leurs propriétés, contaminant ainsi les objets dans l'environnement d'exécution.

Les objets contaminés invalident les hypothèses sous-jacentes du code qui serait autrement sûr/correct et peuvent conduire à une exécution de code arbitraire et à un large éventail d'autres problèmes de sécurité dans les bases de code JS. Les bugs de pollution des prototypes se manifestent souvent dans les applications web, mais affectent également les environnements d'exécution JS non web.

Les propriétés des objets en JS sont modifiables par tout code qui peut y faire référence. En particulier, si de nombreux objets reposent sur une propriété partagée, n'importe lequel d'entre eux peut entraîner des changements sur tous les autres.

Attaques par données uniquement

Une propriété particulière de la PP est qu'il s'agit d'une attaque par données uniquement, permettant d'atteindre l'exécution de code purement via les données. Par exemple, voyez le code vulnérable suivant et l'exploit correspondant :

root@kitploit:~
// source is attacker-controlled
function merge(target, source) {
  for (let key in source) {
    if (typeof source[key] === 'object')  {
      if(target[key] === undefined) {
        target[key] = {};
      }
      target[key] = merge(target[key], source[key]);
    } else {
      target[key] = source[key];
    }
  }
  return target;
}

// User input comes as a string
const userSuppliedObj = JSON.parse('{"__proto__": {"polluted": true}}');
// Trigger prototype pollution
merge({}, userSuppliedObj);
// Create a brand new object
const newObj = {};
// Has polluted property
console.log(newObj.polluted); // true

Notez que l'exploit parvient à contaminer la création de nouveaux objets sans injecter aucun code étranger.

En raison de cette propriété particulière, les atténuations modernes contre les problèmes d'exécution de code — comme la Content Security Policy ou les Trusted Types — ne suffisent pas à protéger contre la PP, car elles se concentrent sur l'application de la provenance du code.

Notez que les attaques par données uniquement sont pertinentes dans les situations où le code exécuté sur la machine virtuelle est fiable et où l'exécution de code arbitraire a un impact sur la sécurité.

Problèmes avec freeze, seal et preventExtensions

Les primitives de gel existantes souffrent de problèmes de conception importants qui rendent leur adoption généralisée peu probable. Elles peuvent être utiles aux utilisateurs experts, mais ne conviennent pas à la majorité des développeurs, qui attendent raisonnablement que les prototypes soient mutables :

L'erreur d'override

Les API de gel souffrent de l'erreur d'override et d'autres incohérences qui introduisent des bugs dans les bases de code existantes, les faisant échouer ou, pire, échouer silencieusement en mode non strict. Une enquête précédente sur l'erreur d'override a conclu que l'erreur d'override se déclenche sur ~10 % des bases de code en mode strict et 20 % en mode non strict. L'enquête a été abandonnée peu après.

Granularité grossière

Les API de gel confient aux développeurs la lourde responsabilité de savoir quels prototypes doivent être gelés pour maintenir une base de code sécurisée, en supposant que les développeurs sont des experts en sécurité. Ces API décrivent le quoi mais pas le comment de la sécurité. Geler Object n'est certainement pas suffisant, car de nombreux exploits abusent d'Array. Qu'en est-il d'Error, Date, Reflect ou Proxy ? Ou des futurs types natifs ? Les API de gel ne fournissent aucune réponse à ces questions.

Points de gel

Les API de gel supposent un point de gel stable : un moment fixe à l'exécution où les prototypes se sont stabilisés et peuvent être gelés. En pratique, ce point est volatile et change au fil du temps dans les bases de code activement développées. Bien que l'on puisse trouver un tel point dans de nombreuses applications aujourd'hui, l'ajout de nouvelles dépendances, de polyfills, de changements de structure de code et de fonctionnalités avancées comme le hotswapping et les outils de développement font des points de gel une cible mouvante.

Types d'applications

Les API de gel ne peuvent pas protéger la chaîne de prototypes complète. En JS, des objets peuvent être ajoutés ou retirés de la chaîne de prototypes à tout moment. Pour protéger la chaîne complète, il faut toujours se souvenir de geler les objets ajoutés à la chaîne, un processus sujet aux erreurs. Une fois retirés de la chaîne, ils ne peuvent plus être dégelés.

Solution proposée

En résumé : une fonctionnalité qui n'expose les prototypes qu'aux API de réflexion. Si les prototypes n'étaient pas disponibles via des propriétés comme __proto__ ou prototype, ils ne seraient pas exposés aux problèmes liés aux données uniquement.

Ceci est mieux compris à travers un exemple : l'instruction obj[one][two] = value est vulnérable à la PP via obj.__proto__.polluted. Si l'on supprime la propriété Object.prototype.__proto__, la même instruction n'est plus vulnérable car elle ne peut pas utiliser le seul autre moyen d'atteindre les prototypes, à savoir obj.constructor.prototype.polluted. Notez que le prototype ne peut pas être supprimé.

Cette proposition peut être mise en œuvre en fournissant des API de réflexion et en créant une nouvelle fonctionnalité d'encapsulation opt-in qui supprime les propriétés de prototype. Une description de chaque étape suit.

Fournir des API de réflexion

__proto__ est un nom de propriété hérité qui peut être supprimé, mais l'emplacement interne qui le sous-tend peut toujours être lu via Object/Reflect.getPrototypeOf et écrit via Object/Reflect.setPrototypeOf, ce qui continuera simplement à rendre cette propriété accessible au code déjà en cours d'exécution.

Nous proposons la création de nouvelles API pour prototype, par exemple getClassPrototypeOf et setClassPrototypeOf, qui permettraient de supprimer ce nom de propriété sans modifier en quoi que ce soit le fonctionnement de cette propriété spéciale et le support de la VM.

Les API de réflexion peuvent être polyfillées, ce qui permet aux bases de code durcies de fonctionner dans tous les navigateurs, y compris les versions plus anciennes.

Fonctionnalité opt-in

Une nouvelle « fonctionnalité d'encapsulation » opt-in où aucun nom de propriété n'est créé pour les fonctions getter et setter des emplacements de prototype, ce qui est désormais possible car les références à ces propriétés peuvent utiliser les API de réflexion à la place.

La fonctionnalité est activée via un drapeau hors bande :

  • Dans les contextes navigateur, via un en-tête HTTP comme X-Encapsulate-Prototype: true
  • Dans les autres contextes, via un indicateur de fonctionnalité comme --encapsulate-prototype

Lorsque l'encapsulation est désactivée, les prototypes sont disponibles à la fois via les propriétés et les API de réflexion.

Lorsque l'encapsulation est activée, les prototypes ne sont disponibles que via les API de réflexion, après avoir supprimé à la fois __proto__ et prototype.

L'encapsulation inclut également la fonctionnalité de refactorisation automatique suivante :

Refactorisation automatique

Lorsque l'encapsulation est activée, les moteurs JS chargeant un nouveau code source activent une étape supplémentaire dans leurs phases d'analyse qui enregistre toute la notation par points vers les propriétés de prototype comme s'il s'agissait d'appels à leurs API de réflexion. Cette étape peut être implémentée efficacement et permet aux bases de code avec des dépendances tierces, transitives ou chargées dynamiquement d'être compatibles avec l'encapsulation.

À l'avenir, ce changement ouvrira la voie au marquage de prototype comme obsolète.

Que signifie supprimer ?

Les propriétés de prototype pourraient simplement être undefined lorsque l'encapsulation est activée, mais elles pourraient lever une erreur en cas de tentative de lecture/écriture. Cela signifierait échouer plus rapidement et de manière bruyante, et permettrait de tester les migrations vers les API de réflexion/encapsulation.

Cela implique de rendre les getters et setters de __proto__ et prototype conditionnels à l'encapsulation, en utilisant un hook hôte, de la même manière que la fonction eval lève une exception sous Content Security Policy.

Bases de code incompatibles

Le code qui repose sur l'accès par propriété calculée pour référencer les prototypes n'est pas compatible avec l'encapsulation ni avec la refactorisation automatique. Il doit être refactorisé pour faire explicitement référence aux prototypes lorsqu'ils sont utilisés. Cette refactorisation permet en réalité au code d'exprimer son intention, ce qui rend les schémas dangereux visibles pour l'analyse statique. En pratique, les bases de code présentant cette caractéristique sont généralement des frameworks de réflexion, des outils de débogage et d'autres cas d'utilisation fortement basés sur la réflexion, qui sont très probablement conscients de la manière dont ils utilisent les prototypes.

Les bases de code qui utilisent le mot prototype pour définir des propriétés personnalisées ne sont pas compatibles. Ces bases de code peuvent être rendues compatibles avec l'encapsulation si cette propriété est toujours définie/lue via la notation par crochets. Historiquement, et d'après les requêtes HTTP Archive, un faible pourcentage de bases de code sont incompatibles pour cette raison.

Annexe

Et la pollution du constructeur ?

Certaines modifications de la propriété constructor peuvent également avoir une action fantôme à distance. Au cours de nos recherches, nous n'avons trouvé aucune vulnérabilité pratique affectée par ce phénomène.

Le seuil est considérablement élevé pour que cette attaque fonctionne : comme dans la PP, il faut trouver une application avec des gadgets permettant à la fois d'écrire et de lire des propriétés arbitraires. Mais dans la pollution du constructeur, le gadget de lecture doit lire depuis constructor.polluted au lieu de polluted. Cela réduit considérablement le nombre de gadgets utiles.

Accès calculé dans le JS minimisé

Certains JS minimisés peuvent être incompatibles avec le mode d'encapsulation, car l'accès statique aux propriétés pourrait être minifié en accès calculé. Nous avons interrogé le HTTP Archive pour obtenir une estimation de ce phénomène en pratique. Le tableau suivant montre que les pages présentant ce comportement sont constamment en dessous de 1 % au cours des 12 derniers mois pour toutes les pages explorées avec un navigateur de bureau :

Exemples de vulnérabilités

Google a observé une tendance à la hausse des bugs soumis à notre programme de récompenses pour les vulnérabilités : 1 en 2020, 3 en 2021 et 5 jusqu'à présent en 2022. Nous en avons identifié plusieurs autres dans nos recherches internes.

Les exemples de vulnérabilités incluent :

  1. Sur le Web : Plusieurs problèmes de XSS dans des services qui auraient dû être protégés car ils utilisent Strict CSP, ainsi qu'une large gamme de bibliothèques vulnérables connues.
  2. Sur le bureau : Un bug dans une application de bureau appartenant à Google où les utilisateurs pouvaient recevoir un objet JSON malveillant pouvant permettre la fuite de fichiers locaux en raison d'une vulnérabilité de pollution. (Actuellement non public, divulgation à déterminer.)
  3. Dans les fonctionnalités de sécurité : De multiples contournements dans les sanitizers, y compris la Sanitizer API de Chrome, DOMPurify et le sanitizer de Closure.
  4. Dans le navigateur : Une évasion du bac à sable de Firefox menant à une exécution de code à distance.
  5. Dans NodeJS : Plusieurs RCE ont été découvertes.

Nous nous attendons à ce que le nombre d'applications vulnérables augmente à mesure que les applications JavaScript sont déployées dans davantage d'environnements (par exemple Electron, Cloudflare Workers, etc.). Par conséquent, une solution au niveau du langage est nécessaire pour atténuer les attaques dans tous les environnements.

Télécharger l’outil
TableauDocuments accédant dynamiquement à __proto__ ou constructorNombre total de documents explorésRatio
2023_03_01_desktop5,407,936609,469,4580.89%
2023_02_01_desktop4,842,383549,089,7080.88%
2023_01_01_desktop5,283,826589,519,1600.90%
2022_12_01_desktop5,161,471577,073,8830.89%
2022_11_01_desktop5,023,169561,726,2390.89%
2022_10_01_desktop4,393,377476,880,6240.92%
2022_09_01_desktop4,239,257466,278,7620.91%
2022_08_01_desktop4,259,814463,784,0470.92%
2022_07_01_desktop3,011,137339,468,6150.89%
2022_06_01_desktop2,301,317257,501,2220.89%
2022_04_01_desktop2,368,577263,144,6570.90%
2022_03_01_desktop2,319,518259,249,0130.89%