Les réponses JSON peuvent être exploitées en remplaçant les constructeurs Array ou si les valeurs hostiles ne sont pas protégées par une chaîne JavaScript.
Supposons que ces deux vecteurs sont traités normalement. Il est notoire que Google intercepte le sourçage direct des réponses JSON en préfixant tous les JSON avec quelque chose comme:
throw 1; < don't be evil' >
Et ensuite le reste du JSON suit. Donc, Dr. Evil ne peut pas, en utilisant le type d’exploitation discuté ici http://sla.ckers.org/forum/read.php?2,25788 obtenir votre cookie (en supposant que vous soyez connecté) en mettant le suivant sur son site:
<script src="http://yourbank.com/accountStatus.json">
En ce qui concerne les règles d'échappement des chaînes, eh bien, si nous utilisons des guillemets doubles, nous devons préfixer chacun avec une barre oblique inverse, et chaque barre oblique inverse avec une autre barre oblique inverse, etc.
Mais ma question est la suivante: et si vous faisiez tout cela?
Burpsuite (outil de sécurité automatisé) détecte les tentatives XSS incorporées renvoyées par une réponse JTH sans échappe au format HTML et le signale comme une vulnérabilité XSS. Je signale que mon application contient des vulnérabilités de ce type mais je ne suis pas convaincu. Je l'ai essayé et je ne peux pas faire un exploit.
Donc, je ne pense pas que cela soit correct, mais je vous demande à la communauté StackOverflow de peser.
Il y a un cas spécifique, celui du sniffing de type MIME IE qui, à mon avis, pourrait donner lieu à un exploit. Après tout, IE 7 possédait toujours la "fonctionnalité" selon laquelle les balises de script intégrées aux commentaires d'image étaient exécutées indépendamment de l'en-tête Content-Type. Laissons aussi de prime abord ce comportement clairement stupide.
JSON serait sûrement analysé par l’analyseur JavaScript natif (Window.JSON dans Firefox) ou par eval () conformément à l’ancien comportement jQuery par défaut. Dans aucun des deux cas l'expression suivante n'entraînera l'exécution de l'alerte:
{"myJSON": "legit", "someParam": "12345<script>alert(1)</script>"}
Ai-je raison ou ai-je tort?
Pour mémoire, bien que j'aie accepté une réponse, pour la question littérale que je pose, j'avais raison et il n'y avait aucune vulnérabilité en raison de la présence de code HTML non échappé en HTML mais correctement échappé en JSON dans les valeurs JSON. Il pourrait y avoir un bogue ici si cette valeur était insérée dans le DOM sans échappement côté client, mais Burpsuite a peu de chance de savoir si cela se produirait simplement en regardant le trafic réseau.
Dans le cas général de détermination de ce qui constitue une vulnérabilité de sécurité dans ces circonstances, il est instructif de reconnaître que, si le contenu de la réponse d'une valeur JSON peut sembler insatisfaisant, il peut être légitimement reconnu que son contenu de réponse ne contient aucune entrée d'utilisateur et est destiné à être déjà rendu HTML pour être inséré en toute sécurité dans le DOM sans échappement. Échapper à ce serait un bug (non de sécurité) comme je l'ai mentionné dans un autre commentaire.
Cette vulnérabilité potentielle xss peut être évitée en utilisant le Content-Type
correct. Basé sur RFC-4627 , toutes les réponses JSON doivent utiliser le type application/json
. Le code suivant est non vulnérable à xss, allez le tester:
<?php
header('Content-type: application/json');
header("x-content-type-options: nosniff");
print $_GET['json'];
?>
L'en-tête nosniff
permet de désactiver le contrôle de contenu sur les anciennes versions d'Internet Explorer. Une autre variante est la suivante:
<?php
header("Content-Type: application/json");
header("x-content-type-options: nosniff");
print('{"someKey":"<body onload=alert(\'alert(/ThisIsNotXSS/)\')>"}');
?>
lorsque le code ci-dessus est affiché par un navigateur, l'utilisateur est invité à télécharger un fichier JSON. JavaScript n'a pas été exécuté sur les versions modernes de Chrome, FireFox et Internet Explorer. Cela constituerait une violation de RFC.
Si vous utilisez JavaScript pour eval()
le JSON ci-dessus ou écrivez la réponse dans la page, il devient DOM Based XSS . Le logiciel XSS basé sur DOM est corrigé sur le client en désinfectant le code JSON avant d’agir sur ces données.
Burpsuite (outil de sécurité automatisé) détecte les tentatives XSS intégrées qui sont renvoyés par un échappement unHTML dans une réponse JSON et il le signale en tant que vulnérabilité XSS.
Peut-être tente-t-il d’empêcher la vulnérabilité décrite dans la règle 3.1 de OWASP XSS Cheat Sheet .
Ils donnent l'exemple suivant de code vulnérable:
<script>
var initData = <%= data.to_json %>;
</script>
Même si les guillemets doubles, les barres obliques et les retours à la ligne sont correctement protégés, vous pouvez quitter JSON s'il est incorporé au format HTML:
<script>
var initData = {"foo":"</script><script>alert('XSS')</script>"};
</script>
jsFiddle .
La fonction to_json()
peut éviter ce problème en préfixant chaque barre oblique par une barre oblique inverse. Si JSON est utilisé dans l'attribut HTML, l'intégralité de la chaîne JSON doit être HTML. S'il est utilisé dans un attribut href="javascript:"
, il doit être échappé par une URL.
Si nous limitons notre portée à IE (toutes les versions), supposons que vous exécutiez un site basé sur PHP ou ASP.NET et ignoriez le filtre anti-xss IE, vous êtes faux: vos utilisateurs sont vulnérables. Définir 'Content-type: application/json' ne vous aidera pas non plus.
Cela est dû (comme vous l'avez mentionné) au comportement de détection de contenu d'IE, qui va au-delà de la détection de balises HTML dans le corps de la réponse pour inclure l'analyse URI.
Ce billet de blog explique très bien ceci:
http://blog.watchfire.com/wfblog/2011/10/json-based-xss-exploitation.html