JSON : les bonnes pratiques indispensables Utiliser JSON de manière sûre

JSON est particulièrement facile à utiliser dans les applications web parce que JSON est du JavaScript. Un texte JSON peut être transformé en une structure de données utile avec la fonction eval :

 var myData = eval('(' + myJSONText + ')');

(La concaténation des parenthèses autour du texte JSON est une solution de contournement pour résoudre une ambiguïté de la grammaire JavaScript.)

La fonction eval pose cependant de terribles problèmes de sécurité. Est-il prudent d'utiliser eval pour parser un texte JSON ? À l'heure actuelle, la meilleure technique pour récupérer des données d'un serveur dans un navigateur web consiste à utiliser XMLHttpRequest. XMLHttpRequest ne peut obtenir de données que du même serveur que celui qui a produit le HTML. Le fait de traiter le texte avec eval n'est pas moins sécurisé que le HTML d'origine. Mais ce raisonnement suppose que le serveur est malveillant. Qu'en est-il s'il est simplement incompétent ?

Un serveur incompétent peut ne pas effectuer un encodage JSON correct. S'il élabore des textes JSON en flanquant des chaînes les unes avec les autres au lieu d'utiliser un encodeur JSON digne de ce nom, il peut involontairement transmettre des données dangereuses. S'il agit comme proxy et passe simplement le texte JSON sans déterminer s'il est bien formé, il peut retransmettre des données dangereuses de nouveau.

Le danger peut être évité en utilisant la méthode JSON.parse au lieu de la méthode eval (voir sur JSON.org). JSON.parse lève une exception si le texte contient quoi que ce soit de dangereux. Il est conseillé de toujours utiliser JSON.parse au lieu d'eval afin de se prémunir contre l'incompétence du serveur. Il est également de bon usage de procéder ainsi en prévision du jour où le navigateur pourrait offrir à d'autres serveurs un accès aux données sécurisées.

Il existe un autre danger en ce qui concerne l'interaction entre les données externes et innerHTML. L'un des patterns Ajax courants amène le serveur à envoyer un fragment de texte HTML qui est attribué à la propriété innerHTML d'un élément HTML. Il s'agit là d'un très mauvais usage. Si le texte HTML contient une balise <script> ou son équivalent, un script maléfique s'exécutera. Cela encore peut être dû à l'incompétence du serveur.

Quel est précisément le danger ? Si un script malveillant est exécuté sur votre page, il obtient l'accès à tout élément relatif à l'état et aux capacités de la page. Il peut interagir avec votre serveur, et votre serveur ne pourra pas distinguer les requêtes malveillantes des requêtes légitimes. Le script malveillant aura accès à l'objet global, ce qui lui donnera accès à toutes les données dans l'application sauf aux variables cachées dans les fermetures. Il aura accès à l'objet document, ce qui lui donnera accès à tout ce que l'utilisateur peut voir. Cela donnera aussi au script malveillant la possibilité de dialoguer avec l'utilisateur. La barre d'adresse du navigateur et tous les indicateurs antiphishing indiqueront à l'utilisateur que la boîte de dialogue est de confiance. L'objet document lui donnera également accès au réseau, en lui permettant de charger d'autres scripts malveillants, de rechercher des sites dans votre pare-feu ou d'envoyer des données secrètes qu'il aura découvertes vers n'importe quel serveur dans le monde.

Ce danger est une conséquence directe de l'objet global JavaScript, qui est de très loin le pire de ses défauts. Ces dangers ne sont pas causés par Ajax, JSON, XMLHttpRequest ou bien encore le Web2.0 (quoi que cela désigne par ailleurs). Ces dangers sont logés dans le navigateur depuis l'introduction du JavaScript et y resteront jusqu'à ce que le JavaScript soit remplacé. Soyez donc prudent.