Javascript : Qu’est-ce que le XSSI et comment l’éviter

Le 14 février 2013 — par

La beauté de l’AJAX vous permet de récupérer des données de manière asynchrone et de les afficher à vos visiteurs.

Mais qu’en est-il de la sécurité ?

Admettons que vous êtes un vilain pirate, et que vous souhaitez récupérer la liste des amis Facebook de votre cible. Facebook fait la plupart de ses requêtes avec de l’AJAX, pour notre exemple disons que l’URL AJAX pour récupérer les amis Facebook est :

https://www.facebook.com/ajax/getFriends.php

La sécurité par défaut des navigateurs nous empêche évidemment de faire directement une requête AJAX sur un domaine différent de celui du site qui est en train d’être visité. Si vous le tentez vous aurez une erreur du genre :

Error: uncaught exception: Permission denied to call method XMLHttpRequest.open

Heureusement car comme vos cookies sont toujours valides sur le domaine facebook.com, n’importe qui aurait accès à vos données en faisant de simples appels AJAX.

Cependant il existe un autre moyen pour une personne mal intentionnée de vous voler vos données JSON sans faire de requête AJAX. JavaScript a été créé pour être « si souple » qu’on peut même réécrire les fonctions de base. Ainsi vous pouvez tout à faire écrire :

function Object() {
    alert('Tiens tu viens de créer un objet !');
}

A priori rien de bien utile, sauf que dans le cas où l’on veut récupérer des données chargées côté client c’est un moyen très efficace. Au lieu de faire un appel AJAX, j’appelle le JSON comme un simple fichier JavaScript :

<script type="text/javascript" src="https://www.facebook.com/ajax/getFriends.php"></script>

Et si le JSON est censé me retourner un objet, la fonction que j’ai créée juste avant va être invoquée à la place de la fonction de base JavaScript. Ma fonction est innocente mais je vous laisse imaginer ce qu’on peut faire avec un this.

Cette technique est résumée par les initiales XSSI pour Cross-Site Script Inclusion.

Que faire pour éviter le XSSI ? Les services sensibles qui utilisent le JSON comme les services Google ou Facebook ont trouvé une astuce qui marche à tous les coups.

Comme le fichier JSON est chargé uniquement côté client, le pirate ne peut pas le modifier et compte sur le bon fonctionnement du moteur JavaScript pour lire le JSON comme un fichier JavaScript classique.

Donc, si le fichier JSON n’est pas du JavaScript correct impossible d’en récupérer ses données.

C’est pourquoi si vous regardez par exemple un fichier JSON renvoyé par Google Calendar, vous verrez en début de chaîne :

while(1);[['u',[['smsSentFlag','false'],['hideInvitations','false'],['remindOnRespondedEventsOnly','true'],['hideInvitations_remindOnRespondedEventsOnly','false_true'],['Calendar ID stripped for privacy','false'],['smsVerifiedFlag','true']]]]

Le while(1); entraînera une erreur Infinite Loop et le fichier JSON ne sera pas lu. D’autres sites rajoutent des caractères aléatoires pour entraîner une erreur de syntaxe, le principe est le même.

Comme le serveur d’origine fait une requête AJAX, il a accès à tout le contenu et peut facilement enlever ces premiers caractères pour parser le JSON ensuite, alors qu’un site malveillant ne le pourra jamais. Nous voilà protégés du XSSI.

S'abonner au flux RSS du blog
Recevoir les nouveaux articles par e-mail :