Pour ce genre de cas, il faut considérer deux possibilités :
Ces limitations risquent-elles de faire échouer le décodage d'un code JSON valable?
Dans le cas d'un code non-valable (autrement dit, conçu expressément pour faire échouer le parser), est-ce que cela constitue une faille de sécurité? Cette faille peut principalement prendre deux formes : A) permettre l'accès à une zone non autorisée de la mémoire voire, pire, une exécution de commande à distance ou B) crasher le parser et provoquer à la longue un DDoS.
Personnellement, je réponds à (1) par la négative. Plus de 100 niveaux d'intrication au minimum avant un crash (on parle de près de 1000 pour Python) n'est pas limitatif pour l'extrême majorité des usages.
En ce qui concerne (2), je pense que 2A est fort peu probable (à moins qu'un langage soit assez mal conçu pour laisser aller un débordement de pile sans conséquence). 2B est possible, mais il présuppose que l'attaquant contrôle le JSON parsé, ce qui n'est pas forcément évident.
En ce qui concerne la résolution, une possibilité éventuelle est de réécrire le code sous la forme d'une boucle et d'une pile explicite. Au lieu d'appeler récursivement une nouvelle fonction à chaque ouverture de liste ou de dictionnaire rencontrée, on ajoute le symbole d'ouverture sur la pile. Lorsque l'on rencontre un symbole de fermeture, on dépile et on s'assure que le précédent symbole d'ouverture correspond bien (sinon c'est une erreur de syntaxe). À la fin du décodage, la pile devrait être vide (sinon c'est toujours une erreur). La taille de cette pile peut être dynamiquement agrandie au fil de l'exécution.
Le code résultant est moins joli et plus difficilement extensible cependant. Je pense que la plupart des implémentations ont cependant fait le choix de la clarté. L'important est que l'erreur éventuelle soit claire. Par exemple, dans le cas de Python (je n'ai pas testé les autres), une exception est levée :
RecursionError: maximum recursion depth exceeded while decoding a JSON array from a unicode string
Ce qui est très clair, facilement attrapable si besoin est par le programmeur d'une section critique d'une application et ne cause aucun effet de bord indésirable.
Je ne sais pas si c'est la même chose pour tous les parsers, mais de manière générale je ne m'inquièterais pas trop de ce problème.
# Pas convaincu
Posté par Kalenx . En réponse au journal Tous les parsers JSON sont mauvais. Évalué à 10.
Pour ce genre de cas, il faut considérer deux possibilités :
Personnellement, je réponds à (1) par la négative. Plus de 100 niveaux d'intrication au minimum avant un crash (on parle de près de 1000 pour Python) n'est pas limitatif pour l'extrême majorité des usages.
En ce qui concerne (2), je pense que 2A est fort peu probable (à moins qu'un langage soit assez mal conçu pour laisser aller un débordement de pile sans conséquence). 2B est possible, mais il présuppose que l'attaquant contrôle le JSON parsé, ce qui n'est pas forcément évident.
En ce qui concerne la résolution, une possibilité éventuelle est de réécrire le code sous la forme d'une boucle et d'une pile explicite. Au lieu d'appeler récursivement une nouvelle fonction à chaque ouverture de liste ou de dictionnaire rencontrée, on ajoute le symbole d'ouverture sur la pile. Lorsque l'on rencontre un symbole de fermeture, on dépile et on s'assure que le précédent symbole d'ouverture correspond bien (sinon c'est une erreur de syntaxe). À la fin du décodage, la pile devrait être vide (sinon c'est toujours une erreur). La taille de cette pile peut être dynamiquement agrandie au fil de l'exécution.
Le code résultant est moins joli et plus difficilement extensible cependant. Je pense que la plupart des implémentations ont cependant fait le choix de la clarté. L'important est que l'erreur éventuelle soit claire. Par exemple, dans le cas de Python (je n'ai pas testé les autres), une exception est levée :
Ce qui est très clair, facilement attrapable si besoin est par le programmeur d'une section critique d'une application et ne cause aucun effet de bord indésirable.
Je ne sais pas si c'est la même chose pour tous les parsers, mais de manière générale je ne m'inquièterais pas trop de ce problème.