Pourquoi Google ajoute-t-il while(1);
à ses réponses JSON (privées)?
Par exemple, voici une réponse lors de l'activation et de la désactivation d'un calendrier dans Google Agenda :
while (1);
[
['u', [
['smsSentFlag', 'false'],
['hideInvitations', 'false'],
['remindOnRespondedEventsOnly', 'true'],
['hideInvitations_remindOnRespondedEventsOnly', 'false_true'],
['Calendar ID stripped for privacy', 'false'],
['smsVerifiedFlag', 'true']
]]
]
Je suppose que c'est pour empêcher les gens d'en faire un eval()
, mais tout ce que vous auriez vraiment à faire est de remplacer le while
et ensuite vous seriez prêt. Je suppose que la prévention eval est de s'assurer que les gens écrivent du code d'analyse JSON sûr.
J'ai également vu cela utilisé dans quelques autres endroits, mais beaucoup plus avec Google (Mail, Calendrier, Contacts, etc.) Curieusement, Google Docs commence par à la &&&START&&&
place et Google Contacts semble commencer par while(1); &&&START&&&
.
Que se passe t-il ici?
javascript
json
ajax
security
Jess
la source
la source
)]}'
maintenant au lieu dewhile(1);
? Les réponses seraient-elles les mêmes?)]}'
peut aussi être d'économiser des octets, comme Facebook utiliséfor(;;);
qui enregistre un octet :)JSON hijacking
Réponses:
Il empêche le détournement JSON , un problème de sécurité JSON majeur qui est formellement résolu dans tous les principaux navigateurs depuis 2011 avec ECMAScript 5.
Exemple artificiel: supposons que Google ait une URL comme celle
mail.google.com/json?action=inbox
qui renvoie les 50 premiers messages de votre boîte de réception au format JSON. Les sites Web malveillants sur d'autres domaines ne peuvent pas faire de demandes AJAX pour obtenir ces données en raison de la même politique d'origine, mais ils peuvent inclure l'URL via une<script>
balise. L'URL est visitée avec vos cookies, et en remplaçant le constructeur de tableau global ou les méthodes d'accesseur, ils peuvent avoir une méthode appelée chaque fois qu'un attribut d'objet (tableau ou hachage) est défini, leur permettant de lire le contenu JSON.Le
while(1);
ou&&&BLAH&&&
empêche cela: une requête AJAXmail.google.com
aura un accès complet au contenu texte et pourra le supprimer. Mais une<script>
insertion de balise exécute aveuglément le JavaScript sans aucun traitement, ce qui entraîne soit une boucle infinie soit une erreur de syntaxe.Cela ne résout pas le problème de la contrefaçon de demande intersite .
la source
for(;;);
le même travail? J'ai vu cela dans les réponses ajax de Facebook.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:
C'est cependant du JSON valide:
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.
la source
script
balise ou laeval
fonction. Les accolades{}
peuvent être interprétées comme un bloc de code ou un littéral d'objet, et en soi, JavaScript préfère le premier. En tant que bloc de code, il est bien sûr invalide. Par cette logique, je ne vois aucun changement prévisible dans le comportement futur du navigateur.window.onerror
) Je ne sais pas quel est le comportement desonerror
erreurs de syntaxe. Je suppose que Google n'était pas sûr non plus.{}
), qui est également un bloc vide valide. Si le fait de savoir que l'objet est vide peut être en soi une information précieuse, cela peut être exploitable.C'est pour s'assurer qu'un autre site ne peut pas faire de trucs désagréables pour essayer de voler vos données. Par exemple, en remplaçant le constructeur du tableau , puis en incluant cette URL JSON via une
<script>
balise, un site tiers malveillant pourrait voler les données de la réponse JSON. En mettant unwhile(1);
au début, le script se bloque à la place.Une demande de même site utilisant XHR et un analyseur JSON distinct, d'autre part, peut facilement ignorer le
while(1);
préfixe.la source
<script>
élément, pas un XHR.<script>
tagCe serait difficile pour un tiers d'insérer la réponse JSON dans un document HTML avec la
<script>
balise. N'oubliez pas que la<script>
balise est exemptée de la politique de même origine .la source
Object
etArray
, exécuter une réponse JSON valide comme s'il s'agissait de JavaScript serait totalement inoffensif en toutes circonstances. Oui, lewhile(1);
empêche la réponse d'être exécutée en JavaScript si elle est ciblée par une<script>
balise, mais votre réponse n'explique pas pourquoi c'est nécessaire.Remarque : à partir de 2019, la plupart des anciennes vulnérabilités qui conduisent aux mesures préventives discutées dans cette question ne sont plus un problème dans les navigateurs modernes. Je vais laisser la réponse ci-dessous comme une curiosité historique, mais vraiment tout le sujet a radicalement changé depuis 2010 (!!) lorsque cela a été demandé.
Il l'empêche d'être utilisé comme cible d'une simple
<script>
balise. (Eh bien, cela ne l'empêche pas, mais cela le rend désagréable.) De cette façon, les méchants ne peuvent pas simplement mettre cette balise de script dans leur propre site et s'appuyer sur une session active pour permettre de récupérer votre contenu.modifier - notez le commentaire (et les autres réponses). Le problème concerne les installations intégrées subverties, en particulier les constructeurs
Object
etArray
. Ceux-ci peuvent être modifiés de telle sorte que JSON autrement inoffensif, une fois analysé, pourrait déclencher le code de l'attaquant.la source
Object
etArray
, exécuter une réponse JSON valide comme s'il s'agissait de JavaScript serait totalement inoffensif en toutes circonstances. Oui, lewhile(1);
empêche la réponse d'être exécutée en JavaScript si elle est ciblée par une<script>
balise, mais votre réponse n'explique pas pourquoi c'est nécessaire.Étant donné que la
<script>
balise est exemptée de la même politique d'origine qui est une nécessité de sécurité dans le monde Web,while(1)
lorsqu'elle est ajoutée à la réponse JSON, elle empêche son utilisation abusive dans la<script>
balise.la source
Référence: Livre de recettes des tests de sécurité Web: Techniques systématiques pour détecter rapidement les problèmes
la source