AJAX cross-domain Restrictions de sécurité liées au domaine

Same Origin Policy

Deux documents ne provenant pas du même domaine ne peuvent pas accéder aux contenus respectifs :

  • Pas d’accès au DOM, aux cookies, aux URLs, …
  • Pas d’accès entre fenêtres et entre frames.

Cependant

  • Les scripts inclus avec <script> ont plein accès (conséquence : SOP ne peut pas bloquer le JavaScript injecté) ;
  • Autres balises violant la SOP (et pour cause) : <img>, <link>, <embed>, <object>, <iframe>, <bgsound>, <audio>, <video>, …
  • window.name viole la SOP (pas très utilisé) ;
  • window.postMessage : violation contrôlée de la SOP.

Lire : http://code.google.com/p/browsersec/wiki/Part2.

SOP : Exemple

Restrictions sur AJAX

  • Un script peut envoyer une XMLHttpRequest vers toute adresse ;
  • il ne peut lire que les réponses provenant du même domaine.

Problème : comment interroger des APIs de sites tiers (Google maps, Yahoo finance, etc.) ?

AJAX Cross-domain

Problème : comment interroger des API tierces ?

Solution classique : Proxies

Écrire un programme côté serveur qui transmet la requête au service web.

www.example.com AJAX Client query.yahooapis.com AJAX

…Pas très satisfaisant

Cross-Origin Resource Sharing

CORS : standardise en 2014 par le W3C :

  1. Le XMLHttpRequest fait une requête GET cross-domain ;
  2. Le navigateur ajoute une entête HTTP Origin ;
GET /api/query.php?car=peugeot HTTP/1.1
Host: api.webservice.com
...
Origin: www.example.com
  1. Le serveur répond avec Acces-Control-Allow-Origin:
HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: *
HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: www.example.com
  1. Le navigateur transmet la réponse à XMLHttpRequest uniquement si l’origine est autorisée.

Requêtes preflighted

Politique adaptée pour requêtes avec effets non-réversibles : POST, PUT, DELETE, …

  1. XMLHttpRequest fait une requête POST cross-domain ;
  2. Le navigateur change le type de la requête en OPTIONS ;
OPTIONS /api/query.php?car=peugeot HTTP/1.1
Host: api.webservice.com
Origin: www.example.com
Access-Control-Request-Method: POST
  1. Le serveur répond avec Acces-Control-Allow-Origin :
HTTP/1.1 200 OK
Access-Control-Allow-Origin: www.example.com
Access-Control-Allow-Methods: POST, GET, OPTIONS 
  1. Si la requête est autorisée, le navigateur envoie la requête POST ;
POST /api/query.php?car=peugeot HTTP/1.1
Host: api.webservice.com
Origin: www.example.com
  1. La réponse est transmise à XMLHttpRequest.

CORS et sécurité

CORS est une protection opt-out :

  • Si www.mybank.com n’a pas activé CORS, il est protégé par défaut ;
  • www.hacker.com ne peut pas utiliser des requêtes AJAX pour mener une attaque CSRF ;
  • Cohérent avec la SOP des frames et des fenêtres.

Mais rien n’empêche à www.hacker.com d’activer CORS. Dans ce cas, www.mybank.com peut télécharger du contenu de www.hacker.com via AJAX :

  • Nécessite une faille XSS pour que le téléchargement se fasse sans l’accord de www.mybank.com ;
  • Pas plus dangereux que l’injection de balises <script>, <iframe>, <img>, …
www.mybank.com Client www.hacker.com XSS

Exemple d’utilisation : contourner un filtrage bloquant l’injection de balises <script>.

Lectures

Google browser security guide (M. Zalewski)

Same Origin Policy

Fork me on GitHub