Étapes de la reproduction
La fonction merge() d'AngularJS, qui est utilisée pour combiner plusieurs objets en un seul nouvel objet, est vulnérable à cette vulnérabilité de haut niveau. La commande peut être utilisée pour ajouter ou modifier les propriétés de Object.prototype.
Javascript permet de fusionner toutes les propriétés d'un objet, y compris les propriétés magiques __proto__, constructor et prototype. Plus précisément, avec cet exploit, il est possible de fusionner une propriété __proto__, altérant ainsi l'Object.prototype et exposant une vulnérabilité. Les propriétés Object.prototype étant héritées par tous les objets Javascript, l'attaquant dispose d'une grande latitude pour impacter l'exécution de code. Cela peut conduire à l'exécution de code à distance ou même à un déni de service via le déclenchement d'exceptions Javascript.
Plus d'informations sur GitHub.
Aborder la question
L'exploit existe dans toutes les versions d'AngularJS antérieures à la version 1.7.9. Pour ceux qui ne peuvent pas mettre à jour, les clients de HeroDevs Never-Ending Support for AngularJS ont accès à une version fixe d'AngularJS qui est compatible avec Angular 1.5. Les cibles vulnérables à l'attaque sont :
- le serveur web
- le serveur d'application
- le navigateur web.
Apprentissage et prévention
Il existe plusieurs moyens de prévenir ce type d'attaque :
- Geler le prototype. L'utilisation de Object.freeze(Object.prototype) est une mesure drastique qui réduit considérablement la flexibilité du programme, mais elle permet d'éviter ce type d'attaque.
- Exiger la validation du schéma. Les entrées JSON peuvent être analysées ("sanitized") de manière à ne pas inclure l'attribut __proto__.
- Éviter d'utiliser des fonctions de fusion récursives non sûres. Bien que valable, cette recommandation a une applicabilité limitée car le problème ne réside pas dans la nature des fonctions de fusion récursives, mais dans le fait que les fonctions de fusion(), récursives ou non, copient aveuglément l'attribut dangereux dans Object.prototype.
- Utilisez des objets sans prototypes. Pensez à Object.create(null), à des objets proxy ou à une classe personnalisée pour créer un objet qui n'utilise pas de prototypes. Un objet qui n'hérite pas de Object.prototype n'est pas susceptible d'être pollué.
- Utiliser des tableaux et la fonction map(). Au lieu d'utiliser des objets et la fonction merge(), utilisez des tableaux et la fonction map() pour éviter toute pollution des prototypes.
Conclusion
Le correctif décrit dans cette vulnérabilité est présent dans la version 1.7.9 et est également disponible immédiatement pour les clients de HeroDevs AngularJS Never-Ending Support qui sont encore sur Angular 1.5. Si vous souhaitez obtenir de l'aide pour éviter des attaques potentiellement coûteuses, contactez HeroDevs dès aujourd'hui.
Ressources
NIST BDSA-2019-10768 entrée
Soyez alerté chaque fois qu'une nouvelle vulnérabilité est corrigée dans les logiciels open source que nous soutenons.