Skip to content
jsonforge.app
Retour au blog
Guide7 min de lecture

Sécurité JSON : vulnérabilités courantes et comment les éviter

JSON lui-même ne contient pas de code exécutable, contrairement à XML avec ses risques d'entités externes ou YAML avec ses surprises de coercition de types — il a donc la réputation d'être intrinsèquement sûr à analyser. Cette réputation est globalement méritée pour l'étape d'analyse elle-même, mais c'est ce que votre code fait de l'objet analysé ensuite qu'habitent les vraies vulnérabilités.

Pollution de prototype via une entrée JSON

Les objets JavaScript héritent d'une chaîne de prototypes partagée. Si du JSON non fiable contient une clé comme "__proto__" et que votre code la fusionne dans un objet existant sans se protéger contre les clés spéciales, un attaquant peut injecter des propriétés sur Object.prototype lui-même — affectant tous les objets de votre application, pas seulement celui fusionné.

Une charge utile malveillante ciblant une fonction de fusion profonde naïve.
json
{
  "__proto__": {
    "isAdmin": true
  }
}

Si cela est fusionné en profondeur dans un objet utilisateur avec une fusion récursive qui ne traite pas spécialement les clés __proto__, constructor ou prototype, chaque objet du processus — y compris ceux qui n'ont jamais touché cette charge utile précise — peut soudainement avoir une propriété isAdmin à true. Cela a été une véritable classe de vulnérabilités dans plusieurs bibliothèques npm populaires de fusion/extension.

Comment éviter la pollution de prototype

Utilisez Object.create(null) pour les maps construites à partir de clés non fiables, car il n'a pas de prototype que la pollution puisse atteindre. Préférez Map aux objets simples quand les clés viennent d'une saisie utilisateur et que vous n'avez pas besoin de sérialisation JSON sur le résultat. Si vous devez fusionner en profondeur du JSON non fiable dans un objet existant, utilisez un utilitaire de fusion qui bloque explicitement __proto__, constructor et prototype comme clés — vérifiez si votre dépendance a corrigé cela (la plupart des grandes bibliothèques l'ont fait dans les versions récentes) au lieu de supposer que c'est géré. Gardez vos dépendances à jour : cette classe de vulnérabilité exacte a été corrigée plusieurs fois dans des paquets populaires au fil des nouvelles techniques de contournement découvertes.

Désérialisation non sûre au-delà du simple JSON.parse

Le simple JSON.parse() ne produit jamais que des données brutes — chaînes, nombres, booléens, null, objets simples et tableaux. Il ne peut pas construire des instances de classes arbitraires ni exécuter de code, contrairement à d'autres formats de sérialisation (le pickle de Python, par exemple, peut exécuter du code arbitraire pendant la désérialisation). Le risque apparaît quand une fonction reviver ou une étape en aval reconstruit des instances de classes ou exécute de la logique fondée sur des valeurs de champs non fiables — par exemple, un champ "type" du JSON utilisé pour faire un require() dynamique ou un dispatch vers un gestionnaire par nom de chaîne, sans valider que la chaîne figure sur une liste d'autorisation.

Valider contre un schéma avant de faire confiance au JSON non fiable

JSON.parse() ne garantit que la validité syntaxique — il ne dit rien de la conformité des données à la forme attendue par votre code. Un corps de requête qui est du JSON valide mais privé d'un champ obligatoire, ou avec une chaîne là où un nombre était attendu, peut faire planter le code en aval ou produire silencieusement un comportement erroné. Valider le JSON entrant contre un schéma (JSON Schema, Zod, Joi ou similaire) avant de l'utiliser intercepte les structures malformées ou inattendues à la frontière, donne un point de rejet clair avec un message d'erreur utile au lieu d'un plantage confus trois fonctions plus loin, et sert de surcroît de documentation vivante de la forme réellement attendue par le point de terminaison.

Une liste de contrôle pratique

Validez le JSON non fiable contre un schéma à la frontière, avant qu'il n'atteigne la logique métier. Ne fusionnez jamais en profondeur du JSON non fiable dans des objets durables sans un utilitaire de fusion qui bloque les clés dangereuses. Évitez les fonctions reviver ou le dispatch dynamique fondé sur des champs de chaînes non fiables, sauf si les valeurs sont vérifiées contre une liste d'autorisation. Gardez à jour les dépendances manipulant du JSON (analyseurs, utilitaires de fusion, validateurs de schéma) — c'est une classe de vulnérabilités en évolution active. Fixez des limites de taille raisonnables aux corps de requête JSON pour réduire l'exposition aux attaques par épuisement de ressources via des charges utiles très imbriquées ou extrêmement volumineuses.

FAQ

JSON.parse() lui-même est-il vulnérable à l'exécution de code, comme eval() ?
Non. JSON.parse() ne produit jamais que des structures de données brutes (chaînes, nombres, booléens, null, objets simples, tableaux) et n'exécute jamais de code, contrairement à l'analyse JSON via eval() que de très vieilles bases de code utilisaient avant que JSON.parse() natif ne soit standard. Le JSON.parse() moderne est sûr vis-à-vis de l'exécution de code ; les risques abordés ici vivent dans ce que votre code fait du résultat analysé ensuite.
Qu'est-ce que la pollution de prototype en termes simples ?
C'est une vulnérabilité où une entrée contrôlée par l'attaquant (souvent du JSON avec une clé __proto__) est fusionnée dans un objet par un code qui ne se protège pas contre les noms de propriétés spéciaux, laissant l'attaquant ajouter ou écraser des propriétés sur l'objet de base partagé dont tous les objets JavaScript héritent — affectant toute l'application, pas seulement un objet.
Ai-je besoin de validation par schéma si j'utilise déjà TypeScript ?
Oui — les types TypeScript sont effacés à la compilation et offrent zéro protection à l'exécution. Une charge utile JSON malformée ou malveillante arrivant par HTTP n'est vérifiée par rien à l'exécution, sauf si vous la validez explicitement avec une bibliothèque comme Zod, Joi ou un validateur JSON Schema. TypeScript vous empêche d'écrire du code qui manipule mal la forme attendue ; il ne vérifie nullement que les données réelles correspondent à cette forme.
YAML ou XML sont-ils plus sûrs que JSON à analyser ?
Pas intrinsèquement — ils ont leurs propres classes de vulnérabilités. Les analyseurs YAML de certains langages prennent en charge la coercition de types et des tags pouvant construire des objets arbitraires s'ils ne sont pas configurés en mode « safe load » restreint. Les analyseurs XML sont vulnérables aux attaques XXE (XML External Entity) si l'expansion des entités n'est pas désactivée. Le système de types plus simple de JSON (pas de tags, pas d'entités) supprime ces surfaces d'attaque spécifiques, mais les risques de désérialisation et de fusion couverts ici s'appliquent toujours.

Essayez ces outils

Articles associés