42 votes

Pourquoi le cross-domain Ajax est un problème de sécurité ?

Pourquoi a-t-il été décidé que l'utilisation XMLHTTPRequest pour faire des appels XML ne devrait pas faire des appels à travers la frontière du domaine ? Vous pouvez récupérer du JavaScript, des images, des CSS, des iframes et à peu près tout autre contenu auquel je peux penser à partir d'autres domaines. Pourquoi les requêtes HTTP Ajax ne sont-elles pas autorisées à franchir les limites du domaine ? Cette limitation semble étrange, car la seule façon d'en abuser serait d'injecter du JavaScript dans la page. Toutefois, dans ce cas, il suffirait d'ajouter un élément img, script ou iframe au document pour qu'il demande l'URL du tiers et l'envoie au serveur.

[Edit]

Certaines des réponses indiquent les raisons suivantes, soulignons les raisons pour lesquelles elles ne créent pas une raison majeure pour interdire cela.

XSRF (Cross Site Request Forgery, également connu sous le nom de CSRF, XSRF)

Vous pouvez faire des attaques XSRF sans utiliser cela du tout. En règle générale, XMLHTTPRequest n'est pas utilisé du tout, simplement parce qu'il est très difficile de créer un XMLHTTPRequest compatible avec les principaux navigateurs. Il est beaucoup plus facile d'ajouter une balise img à l'URL si vous voulez qu'ils chargent votre URL.

Publication sur le site d'un tiers

<script type="text/javascript">
  $.post("http://some-bank.com/transfer-money.php", 
         { amount: "10000", to_account: "xxxx" })
</script>

Cela pourrait être accompli avec

<body onload="document.getElementById('InvisbleForm').submit()"
    <div style="display:none">
        <form id="InvisbleForm" action="http://some-bank.com/transfer-money.php" method="POST">
            <input type="hidden" name="amount" value="10000">
            <input type="hidden" name="to_account" value="xxxxx">
        </form>
    </div>
</body>

JPunyon : pourquoi laisser la vulnérabilité dans une nouvelle fonctionnalité ?

Vous ne créez pas plus d'insécurité. Vous ne faites que gêner les développeurs qui veulent l'utiliser pour le bien. Ceux qui veulent utiliser cette fonctionnalité à des fins maléfiques (ou géniales) n'ont qu'à utiliser une autre méthode pour le faire.

Conclusion

Je marque la réponse de bobince comme correct parce qu'il a souligné le problème critique. Comme XMLHTTPRequest vous permet de poster, avec des informations d'identification (cookies) sur le site de destination, et de lire les données renvoyées par le site, tout en envoyant les informations d'identification de la personne, vous pourriez orchestrer un javascript qui soumettrait une série de formulaires, y compris des formulaires de confirmation, avec toutes les clés aléatoires générées qui ont été mises en place pour essayer d'empêcher un XSRF. De cette façon, vous pourriez naviguer sur le site cible, comme une banque, et le serveur web de la banque serait incapable de dire qu'il ne s'agit pas d'un simple utilisateur qui soumet tous ces formulaires.

36voto

bobince Points 270740

Pourquoi les requêtes HTTP Ajax ne sont-elles pas autorisées à traverser les frontières des domaines ?

Parce que les requêtes AJAX sont (a) soumises avec les informations d'identification de l'utilisateur, et (b) permettent à l'appelant de lire les données renvoyées.

C'est la combinaison de ces facteurs qui peut entraîner une vulnérabilité. Il existe des propositions visant à ajouter une forme d'AJAX inter-domaine qui omet les informations d'identification de l'utilisateur.

vous pourriez simplement ajouter un élément img, script, ou iframe au document

Aucune de ces méthodes ne permet à l'appelant de lire les données renvoyées.

(Sauf scripts où soit il est délibérément configuré pour permettre cela, pour permettre le scripting inter-domaine - soit quelqu'un a fait une terrible erreur).

Vous pouvez réaliser des attaques XSS sans utiliser ce système. Publication sur un site tiers

Ce n'est pas une attaque XSS. Il s'agit d'une attaque par falsification de requête intersite (XSRF). Il existe des moyens connus de résoudre les attaques XSRF, comme l'inclusion de jetons à usage unique ou cryptographiques pour vérifier que la soumission provient délibérément de l'utilisateur et n'a pas été lancée à partir d'un code attaquant.

Si vous autorisiez AJAX inter-domaines, vous perdriez cette protection. Le code attaquant pourrait demander une page du site bancaire, lire les jetons d'autorisation qu'elle contient et les soumettre dans une deuxième demande AJAX pour effectuer le transfert. Et cela serait être une attaque de scripting intersite.

8voto

Kirill Kobelev Points 6124

Une différence importante entre le POST :

<body onload="document.getElementById('InvisbleForm').submit()" ...

et Ajax est qu'après avoir fait n'importe quel POST le navigateur remplacera la page et après avoir fait l'appel Ajax - pas. Le résultat du POST sera :

  1. Clairement visible pour l'utilisateur.
  2. L'attaque sera bloquée à ce stade parce que la page de réponse de my-bank.com prendra le contrôle. Aucune banque ne mettra en place un transfert en un clic .

Le scénario de XSRF, si l'Ajax interdomaines est autorisé, ressemblera à ce qui suit :

  1. L'utilisateur visite d'une manière ou d'une autre www.bad-guy.com .
  2. S'il n'y a pas de page ouverte pour my-bank.com dans une autre instance du navigateur, l'attaque échoue.
  3. Mais si une telle page est ouverte et que l'utilisateur a déjà saisi son nom d'utilisateur et son mot de passe, cela signifie qu'il existe un cookie pour cette session dans le cache du navigateur.
  4. Code JavaScript sur la page de www.bad-guy.com fait un appel Ajax à my-bank.com .
  5. Pour le navigateur, il s'agit d'un appel HTTP normal, il doit envoyer les cookies my-bank à l'adresse suivante my-bank.com et il les envoie.
  6. La banque traite cette demande car elle ne peut pas distinguer cet appel de l'activité régulière de l'utilisateur.
  7. Le fait que le code JavaScript puisse lire la réponse n'est pas important. Dans le cas d'une attaque, ce n'est peut-être pas nécessaire. Ce qui est vraiment important, c'est que l'utilisateur en face de l'ordinateur n'aura aucune idée que cette interaction a lieu. Il regardera de belles images sur le www.bad-guy.com page.
  8. Le code JavaScript fait plusieurs autres appels à my-bank.com si cela est nécessaire.

L'essentiel est qu'aucune injection ou altération de la page n'est nécessaire.

Une meilleure solution pourrait être d'autoriser l'appel lui-même mais de ne pas envoyer de cookies. Il s'agit d'une solution très simple qui ne nécessite pas de développement approfondi. Dans de nombreux cas, l'appel Ajax va vers un emplacement non protégé et le fait de ne pas envoyer de cookies ne sera pas une limitation.

Le CORS (Cross Origin Resource Sharing) qui est actuellement en discussion, entre autres choses, parle de l'envoi ou non de cookies.

2voto

Andrew Rollings Points 8361

Eh bien, apparemment vous n'êtes pas la seule personne à penser ainsi...

http://www.google.com/search?q=xmlhttp+cross+site

EDIT : Il y a une discussion intéressante liée à la recherche ci-dessus :

http://blogs.msdn.com/ie/archive/2008/06/23/securing-cross-site-xmlhttprequest.aspx

Il semble que des propositions soient en cours pour permettre les requêtes xmlhttp intersites (IE 8, FF3 etc.), même si j'aurais aimé qu'elles soient là quand j'écrivais le code de mes sites :) Et puis il y a le problème de la compatibilité... Il faudra un certain temps avant qu'il ne soit omniprésent.

1voto

Mike Griffith Points 538

C'est un problème car il peut être utilisé à de mauvaises fins, comme vous l'avez mentionné. Il peut également être utilisé avec de bonnes intentions, et c'est pour cette raison que des protocoles inter-domaines sont développés.

Les deux plus grandes préoccupations concernent son utilisation en conjonction avec le cross-site scripting (XSS) et le cross-site request forgery (CSRF). Ces deux menaces sont sérieuses (c'est pourquoi elles figurent dans le top 10 de l'OWASP et dans le SANS 25).

La seule façon de l'utiliser de manière abusive serait d'injecter du Javascript.

Il s'agit de XSS. De trop nombreuses applications sont encore vulnérables, et si les modèles de sécurité des navigateurs n'empêchent pas l'AJAX du domaine X, ils ouvrent leurs utilisateurs à un vecteur d'attaque considérable.

vous pouvez simplement ajouter un élément img, script ou iframe au document pour qu'il demande l'URL du tiers.

Oui, mais ceux-ci enverront un HTTP_REFERRER et (par d'autres moyens) peuvent être bloqués pour empêcher CSRF. Les appels AJAX peuvent usurper les en-têtes plus facilement et permettraient d'autres moyens de contourner les protections CSRF traditionnelles.

1voto

Shawn Points 8120

Je pense qu'une autre chose qui sépare cette attaque d'une attaque XSRF normale est que vous pouvez faire des choses avec les données que vous obtenez en retour aussi bien via javascript.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X