Prototype pollution côté client via sanitisation défectueuse

Client-side prototype pollution via flawed sanitization

1) Contexte et idée générale

L’application lit les paramètres d’URL puis les transforme en objet JavaScript via deparam(...) :

  • Elle construit config = { params: deparam(...) }

  • Ensuite, elle utilise config.transport_url pour charger un <script src="...">

Pour éviter la prototype pollution, les devs ont ajouté sanitizeKey() qui supprime les sous-chaînes suivantes dans les clés : constructor, __proto__, prototype.

Problème : cette “sanitisation” fait juste un replaceAll. Si on découpe le mot interdit en morceaux, après remplacement il peut se reconstituer.

2) Source : contourner le filtre et polluer Object.prototype

Le filtre enlève __proto__ si c’est présent tel quel. On le reconstruit en mettant __proto__ au milieu d’une clé plus grande, de manière à ce que, après suppression, la clé finale devienne exactement __proto__.

Payload (contournement) :

Après sanitisation :

  • __pro__proto__to__ → (suppression de __proto__) → __proto__

Donc ça revient à faire :

  • ?__proto__[foo]=bar → pollution du prototype global

Vérification dans la console :

4) Exploit final : déclencher alert()

On pollue transport_url avec un schéma data: qui exécute du JS quand le script est chargé :

Mis à jour