Il empêche la divulgation de la réponse via le détournement JSON.
En théorie, le contenu des réponses HTTP est protégé par la même politique d'origine: les pages d'un domaine ne peuvent pas obtenir d'informations à partir des pages de l'autre domaine (sauf autorisation explicite).
Un attaquant peut demander des pages sur d'autres domaines en votre nom, par exemple en utilisant une balise <script src=...>
ou <img>
, mais il ne peut obtenir aucune information sur le résultat (en-têtes, contenu).
Ainsi, si vous visitez la page d'un attaquant, il ne pourra pas lire votre e-mail depuis gmail.com.
Sauf que lors de l'utilisation d'une balise de script pour demander du contenu JSON, le JSON est exécuté en Javascript dans un environnement contrôlé par un attaquant. Si l'attaquant peut remplacer le constructeur Array ou Object ou une autre méthode utilisée pendant la construction de l'objet, tout élément du JSON passerait par le code de l'attaquant et serait divulgué.
Notez que cela se produit au moment où le JSON est exécuté en Javascript, pas au moment de son analyse.
Il existe plusieurs contre-mesures:
S'assurer que le JSON ne s'exécute jamais
En plaçant une while(1);
déclaration avant les données JSON, Google s'assure que les données JSON ne sont jamais exécutées en Javascript.
Seule une page légitime peut obtenir l'intégralité du contenu, le while(1);
supprimer et analyser le reste en JSON.
Des choses comme for(;;);
ont été vues sur Facebook par exemple, avec les mêmes résultats.
S'assurer que le JSON n'est pas valide Javascript
De même, l'ajout de jetons invalides avant le JSON, comme &&&START&&&
, garantit qu'il n'est jamais exécuté.
Toujours renvoyer JSON avec un objet à l'extérieur
C'est OWASP
le moyen recommandé de se protéger contre le détournement JSON et c'est le moins intrusif.
Semblable aux contre-mesures précédentes, il s'assure que le JSON n'est jamais exécuté en Javascript.
Un objet JSON valide, lorsqu'il n'est entouré de rien, n'est pas valide en Javascript:
eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :
C'est cependant du JSON valide:
JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}
Donc, assurez-vous de toujours renvoyer un objet au niveau supérieur de la réponse, assurez-vous que le JSON n'est pas du Javascript valide, tout en étant un JSON valide.
Comme indiqué par @hvd dans les commentaires, l'objet vide {}
est du Javascript valide, et savoir que l'objet est vide peut lui-même être une information précieuse.
Comparaison des méthodes ci-dessus
La méthode OWASP est moins intrusive, car elle ne nécessite aucune modification de la bibliothèque cliente et transfère un JSON valide. Cependant, il n'est pas sûr que les bogues du navigateur passés ou futurs puissent échouer. Comme l'a noté @oriadam, il n'est pas clair si les données pourraient être divulguées dans une erreur d'analyse via une gestion des erreurs ou non (par exemple window.onerror).
Pour Google, la bibliothèque cliente doit prendre en charge la désérialisation automatique et peut être considérée comme plus sûre contre les bogues du navigateur.
Les deux méthodes nécessitent des modifications côté serveur pour éviter que les développeurs envoient accidentellement du JSON vulnérable.