Aller au contenu principal

3. Principles of the Same-Origin Policy (Principes de la politique de même origine)

3. Principles of the Same-Origin Policy (Principes de la politique de même origine)

De nombreux agents utilisateurs entreprennent des actions au nom de parties distantes. Par exemple, les agents utilisateurs HTTP suivent les redirections, qui sont des instructions provenant de serveurs distants, et les agents utilisateurs HTML exposent de riches interfaces Document Object Model (DOM) aux scripts récupérés depuis des serveurs distants.

Sans modèle de sécurité, les agents utilisateurs pourraient entreprendre des actions préjudiciables à l'utilisateur ou à d'autres parties. Au fil du temps, de nombreuses technologies liées au Web ont convergé vers un modèle de sécurité commun, connu familièrement sous le nom de "politique de même origine" (same-origin policy). Bien que ce modèle de sécurité ait évolué de manière largement organique, la politique de même origine peut être comprise en termes de quelques concepts clés. Cette section présente ces concepts et fournit des conseils sur la façon d'utiliser ces concepts en toute sécurité.

3.1 Trust (Confiance)

La politique de même origine spécifie la confiance par URI. Par exemple, les documents HTML désignent quel script exécuter avec un URI:

<script src="https://example.com/library.js"></script>

Lorsqu'un agent utilisateur traite cet élément, l'agent utilisateur récupérera le script à l'URI désigné et exécutera le script avec les privilèges du document. De cette manière, le document accorde tous les privilèges qu'il possède à la ressource désignée par l'URI. Essentiellement, le document déclare qu'il fait confiance à l'intégrité des informations récupérées depuis cet URI.

En plus d'importer des bibliothèques depuis des URI, les agents utilisateurs envoient également des informations à des parties distantes désignées par URI. Par exemple, considérez l'élément de formulaire HTML:

<form method="POST" action="https://example.com/login">
... <input type="password"> ...
</form>

Lorsque l'utilisateur entre son mot de passe et soumet le formulaire, l'agent utilisateur envoie le mot de passe au point de terminaison réseau désigné par l'URI. De cette manière, le document exporte ses données secrètes vers cet URI, déclarant essentiellement qu'il fait confiance à la confidentialité des informations envoyées à cet URI.

3.1.1 Pitfalls (Pièges)

Lors de la conception de nouveaux protocoles utilisant la politique de même origine, assurez-vous que les distinctions de confiance importantes sont visibles dans les URI. Par exemple, si les ressources protégées par Transport Layer Security (TLS) et non-TLS utilisent toutes deux le schéma URI "http" (comme dans [RFC2817]), un document ne pourrait pas spécifier qu'il souhaite récupérer un script uniquement via TLS. En utilisant le schéma URI "https", les documents peuvent indiquer qu'ils souhaitent interagir avec des ressources protégées contre les attaquants réseau actifs.

3.2 Origin (Origine)

En principe, les agents utilisateurs pourraient traiter chaque URI comme un domaine de protection séparé et exiger un consentement explicite pour que le contenu récupéré depuis un URI interagisse avec un autre URI. Malheureusement, cette conception est lourde pour les développeurs car les applications Web se composent souvent d'un certain nombre de ressources agissant de concert.

Au lieu de cela, les agents utilisateurs regroupent les URI en domaines de protection appelés "origines" (origins). En gros, deux URI font partie de la même origine (c'est-à-dire représentent le même principal) s'ils ont le même schéma, hôte et port. (Voir la section 4 pour plus de détails.)

Q: Pourquoi ne pas utiliser simplement l'hôte?

R: L'inclusion du schéma dans le tuple d'origine est essentielle pour la sécurité. Si les agents utilisateurs n'incluaient pas le schéma, il n'y aurait aucune isolation entre http://example.com et https://example.com car les deux ont le même hôte. Cependant, sans cette isolation, un attaquant réseau actif pourrait corrompre le contenu récupéré depuis http://example.com et faire en sorte que ce contenu instruise l'agent utilisateur de compromettre la confidentialité et l'intégrité du contenu récupéré depuis https://example.com, contournant les protections offertes par TLS [RFC5246].

Q: Pourquoi utiliser le nom d'hôte entièrement qualifié plutôt que simplement le domaine de "premier niveau"?

R: Bien que le DNS dispose d'une délégation hiérarchique, les relations de confiance entre les noms d'hôte varient selon le déploiement. Par exemple, dans de nombreuses institutions éducatives, les étudiants peuvent héberger du contenu à https://example.edu/~student/, mais cela ne signifie pas qu'un document rédigé par un étudiant devrait faire partie de la même origine (c'est-à-dire habiter le même domaine de protection) qu'une application Web de gestion des notes hébergée à https://grades.example.edu/.

Le déploiement example.edu illustre que le regroupement des ressources par origine ne s'aligne pas toujours parfaitement avec chaque scénario de déploiement. Dans ce déploiement, le site Web de chaque étudiant habite la même origine, ce qui peut ne pas être souhaitable. Dans un certain sens, la granularité de l'origine est un artefact historique de l'évolution du modèle de sécurité.

3.2.1 Examples (Exemples)

Toutes les ressources suivantes ont la même origine:

http://example.com/
http://example.com:80/
http://example.com/path/file

Chacun des URI a les mêmes composants de schéma, d'hôte et de port.

Chacune des ressources suivantes a une origine différente des autres:

http://example.com/
http://example.com:8080/
http://www.example.com/
https://example.com:80/
https://example.com/
http://example.org/
http://ietf.org/

Dans chaque cas, au moins un des composants de schéma, d'hôte et de port différera des autres dans la liste.

3.3 Authority (Autorité)

Bien que les agents utilisateurs regroupent les URI en origines, toutes les ressources d'une origine ne portent pas la même autorité (au sens sécurité du terme "autorité", et non au sens [RFC3986]). Par exemple, une image est un contenu passif et, par conséquent, ne porte aucune autorité, ce qui signifie que l'image n'a pas accès aux objets et ressources disponibles pour son origine. En revanche, un document HTML porte l'autorité complète de son origine, et les scripts dans (ou importés dans) le document peuvent accéder à chaque ressource de son origine.

Les agents utilisateurs déterminent le niveau d'autorité à accorder à une ressource en examinant son type de média. Par exemple, les ressources avec un type de média image/png sont traitées comme des images, et les ressources avec un type de média text/html sont traitées comme des documents HTML.

Lors de l'hébergement de contenu non fiable (tel que du contenu généré par les utilisateurs), les applications Web peuvent limiter l'autorité de ce contenu en restreignant son type de média. Par exemple, servir du contenu généré par l'utilisateur en tant que image/png est moins risqué que de le servir en tant que text/html. Bien sûr, de nombreuses applications Web incorporent du contenu non fiable dans leurs documents HTML. Si cela n'est pas fait avec soin, ces applications risquent de divulguer l'autorité de leur origine au contenu non fiable, une vulnérabilité communément appelée cross-site scripting.

3.3.1 Pitfalls (Pièges)

Lors de la conception de nouvelles parties de la plateforme Web, veillez à ne pas accorder d'autorité aux ressources indépendamment du type de média. De nombreuses applications Web servent du contenu non fiable avec des types de média restreints. Une nouvelle fonctionnalité de la plateforme Web qui accorde l'autorité à ces éléments de contenu risque d'introduire des vulnérabilités dans les applications existantes. Privilégiez plutôt l'octroi d'autorité aux types de média qui possèdent déjà l'autorité complète de l'origine ou aux nouveaux types de média conçus spécifiquement pour porter la nouvelle autorité.

Afin de rester compatible avec les serveurs qui fournissent des types de média incorrects, certains agents utilisateurs emploient le "reniflage de contenu" (content sniffing) et traitent le contenu comme s'il avait un type de média différent de celui fourni par le serveur. Si cela n'est pas fait avec soin, le reniflage de contenu peut entraîner des vulnérabilités de sécurité car les agents utilisateurs pourraient accorder aux types de média à faible autorité, tels que les images, les privilèges des types de média à haute autorité, tels que les documents HTML [SNIFF].

3.4 Policy (Politique)

De manière générale, les agents utilisateurs isolent les différentes origines et permettent une communication contrôlée entre les origines. Les détails de la façon dont les agents utilisateurs fournissent l'isolation et la communication varient en fonction de plusieurs facteurs.

3.4.1 Object Access (Accès aux objets)

La plupart des objets (également appelés interfaces de programmation d'applications ou API) exposés par l'agent utilisateur ne sont disponibles que pour la même origine. Plus précisément, le contenu récupéré depuis un URI peut accéder aux objets associés au contenu récupéré depuis un autre URI si, et seulement si, les deux URI appartiennent à la même origine, par exemple, ont le même schéma, hôte et port.

Il existe quelques exceptions à cette règle générale. Par exemple, certaines parties de l'interface Location de HTML sont disponibles entre les origines (par exemple, pour permettre la navigation dans d'autres contextes de navigation). Comme autre exemple, l'interface postMessage de HTML est visible entre les origines explicitement pour faciliter la communication inter-origines. Exposer des objets à des origines étrangères est dangereux et ne devrait être fait qu'avec beaucoup de prudence car cela expose ces objets à des attaquants potentiels.

3.4.2 Network Access (Accès réseau)

L'accès aux ressources réseau varie selon que les ressources sont dans la même origine que le contenu tentant d'y accéder.

En général, la lecture d'informations provenant d'une autre origine est interdite. Cependant, une origine est autorisée à utiliser certains types de ressources récupérées depuis d'autres origines. Par exemple, une origine est autorisée à exécuter des scripts, à rendre des images et à appliquer des feuilles de style depuis n'importe quelle origine. De même, une origine peut afficher du contenu provenant d'une autre origine, tel qu'un document HTML dans un cadre HTML. Les ressources réseau peuvent également choisir de permettre à d'autres origines de lire leurs informations, par exemple en utilisant le partage de ressources inter-origines (Cross-Origin Resource Sharing, CORS) [CORS]. Dans ces cas, l'accès est généralement accordé par origine.

L'envoi d'informations vers une autre origine est autorisé. Cependant, l'envoi d'informations sur le réseau dans des formats arbitraires est dangereux. Pour cette raison, les agents utilisateurs limitent les documents à l'envoi d'informations en utilisant des protocoles particuliers, tels que dans une requête HTTP sans en-têtes personnalisés. L'élargissement de l'ensemble des protocoles autorisés, par exemple en ajoutant le support des WebSockets, doit être fait avec soin pour éviter d'introduire des vulnérabilités [RFC6455].

3.4.3 Pitfalls (Pièges)

Chaque fois que les agents utilisateurs permettent à une origine d'interagir avec des ressources d'une autre origine, ils invitent des problèmes de sécurité. Par exemple, la capacité d'afficher des images provenant d'une autre origine divulgue leur hauteur et leur largeur. De même, la capacité d'envoyer des requêtes réseau vers une autre origine donne lieu à des vulnérabilités de falsification de requête inter-sites (cross-site request forgery, CSRF) [CSRF]. Cependant, les implémenteurs d'agents utilisateurs équilibrent souvent ces risques avec les avantages de permettre l'interaction inter-origines. Par exemple, un agent utilisateur HTML qui bloquerait les requêtes réseau inter-origines empêcherait ses utilisateurs de suivre des hyperliens, une fonctionnalité centrale du Web.

Lors de l'ajout de nouvelles fonctionnalités à la plateforme Web, il peut être tentant d'accorder un privilège à une ressource mais de refuser ce privilège à une autre ressource dans la même origine. Cependant, refuser des privilèges de cette manière est inefficace car la ressource sans le privilège peut généralement obtenir le privilège de toute façon car les agents utilisateurs n'isolent pas les ressources au sein d'une origine. Au lieu de cela, les privilèges doivent être accordés ou refusés aux origines dans leur ensemble (plutôt que de discriminer entre les ressources individuelles au sein d'une origine) [BOFGO].

3.5 Conclusion

La politique de même origine utilise les URI pour désigner les relations de confiance. Les URI sont regroupés en origines, qui représentent des domaines de protection. Certaines ressources dans une origine (par exemple, le contenu actif) se voient accorder l'autorité complète de l'origine, tandis que d'autres ressources dans l'origine (par exemple, le contenu passif) ne se voient pas accorder l'autorité de l'origine. Le contenu qui porte l'autorité de son origine se voit accorder l'accès aux objets et aux ressources réseau au sein de sa propre origine. Ce contenu se voit également accorder un accès limité aux objets et aux ressources réseau d'autres origines, mais ces privilèges inter-origines doivent être conçus avec soin pour éviter les vulnérabilités de sécurité.