Cette page a été traduite à partir de l'anglais par la communauté. Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.

View in English Always switch to English

Politique de même origine (Same-origin)

La politique de même origine (same-origin policy) est un mécanisme de sécurité fondamental qui restreint la façon dont un document ou un script chargé par une origine peut interagir avec une ressource provenant d'une autre origine.

Elle permet d'isoler les documents potentiellement malveillants, réduisant ainsi les vecteurs d'attaque possibles. Par exemple, elle empêche un site web malveillant sur Internet d'exécuter du JavaScript dans un navigateur pour lire des données d'un service de messagerie tiers (auquel l'utilisateur·ice est connecté·e) ou d'un intranet d'entreprise (protégé contre l'accès direct par l'attaquant·e car il ne possède pas d'adresse IP publique) et de relayer ces données à l'attaquant·e.

Définition de l'origine

Deux URL ont la même origine si le protocole, le port (s'il est spécifié) et le hôte sont identiques pour les deux. Vous pouvez voir cela référencé comme le « triplet schéma/hôte/port » ou simplement « triplet ». (Un « triplet » est un ensemble d'éléments qui, ensemble, forment un tout — une forme générique pour double/triple/quadruple/quintuple, etc.)

Le tableau suivant donne des exemples de comparaisons d'origines avec l'URL http://store.company.com/dir/page.html :

URL Résultat Motif
http://store.company.com/dir2/other.html Même origine
http://store.company.com/dir/inner/another.html Même origine
https://store.company.com/secure.html Échec Protocoles différents
http://store.company.com:81/dir/etc.html Échec Ports différents
http://news.company.com/dir/other.html Échec Hôtes différents

Origines héritées

Les scripts exécutés depuis des pages ayant une URL about:blank ou une URL javascript: héritent de l'origine du document contenant cette URL, car ces types d'URL ne contiennent pas d'information sur un serveur d'origine.

Par exemple, about:blank est souvent utilisé comme URL pour de nouvelles fenêtres pop-up vides dans lesquelles le script parent écrit du contenu (par exemple via le mécanisme Window.open()). Si cette pop-up contient aussi du JavaScript, ce script héritera de la même origine que le script qui l'a créée.

Les URL data: reçoivent un nouveau contexte de sécurité vide.

Origines de fichiers

Les navigateurs modernes traitent généralement l'origine des fichiers chargés via le schéma file:/// comme des origines opaques. Cela signifie que si un fichier inclut d'autres fichiers du même dossier (par exemple), ils ne sont pas considérés comme provenant de la même origine et peuvent déclencher des erreurs CORS.

Notez que la spécification URL (angl.) indique que l'origine des fichiers dépend de l'implémentation, et certains navigateurs peuvent traiter les fichiers du même répertoire ou sous-répertoire comme ayant la même origine, même si cela présente des implications de sécurité (angl.).

Changer l'origine

Attention : L'approche décrite ici (utilisation du mutateur document.domain) est obsolète car elle affaiblit les protections offertes par la politique de même origine, et complique le modèle d'origine dans les navigateurs, entraînant des problèmes d'interopérabilité et des failles de sécurité.

Une page peut changer sa propre origine, avec certaines limitations. Un script peut définir la valeur de document.domain sur son domaine courant ou un super-domaine de son domaine courant. Si elle est définie sur un super-domaine, ce dernier (le plus court) sera utilisé pour les vérifications de même origine.

Par exemple, supposons qu'un script du document à l'adresse http://store.company.com/dir/other.html exécute ce qui suit :

js
document.domain = "company.com";

Après cela, la page pourra passer le test de même origine avec http://company.com/dir/page.html (à condition que http://company.com/dir/page.html définisse aussi son document.domain à "company.com" pour l'autoriser — voir document.domain pour plus d'informations). Cependant, company.com ne peut pas définir document.domain à othercompany.com, car ce n'est pas un super-domaine de company.com.

Le numéro de port est vérifié séparément par le navigateur. Tout appel à document.domain, y compris document.domain = document.domain, entraîne la réinitialisation du port à null. Il est donc impossible de faire communiquer company.com:8080 avec company.com en ne définissant que document.domain = "company.com" dans le premier. Il faut le définir dans les deux pages pour que leurs ports soient tous deux à null.

Ce mécanisme présente certaines limitations. Par exemple, il lèvera une exception DOMException SecurityError si le document est dans un élément <iframe> sandboxé, et changer l'origine de cette façon n'affecte pas les vérifications d'origine utilisées par de nombreuses API Web (par exemple, localStorage, IndexedDB, BroadcastChannel, SharedWorker). Une liste plus exhaustive des cas d'échec se trouve dans Document.domain > Échecs.

Note : Lorsque vous utilisez document.domain pour permettre à un sous-domaine d'accéder à son domaine parent, vous devez définir document.domain sur la même valeur à la fois dans le domaine parent et dans le sous-domaine. Cela est nécessaire même si cela revient à redéfinir le domaine parent sur sa valeur d'origine. Ne pas le faire peut entraîner des erreurs de permission.

Accès réseau inter-origines

La politique de même origine contrôle les interactions entre deux origines différentes, par exemple lorsque vous utilisez fetch() ou un élément HTML <img>. Ces interactions sont généralement classées en trois catégories :

  • Les écritures inter-origines (cross-origin en anglais) sont généralement autorisées. Exemples : liens, redirections, envois de formulaires. Certaines requêtes HTTP nécessitent une requête préliminaire.
  • L'embarquement inter-origines est généralement autorisé (voir les exemples ci-dessous).
  • Les lectures inter-origines sont généralement interdites, mais l'accès en lecture est souvent contourné via l'embarquement. Par exemple, il est possible de lire les dimensions d'une image embarquée, les actions d'un script embarqué, ou la disponibilité d'une ressource embarquée (angl.).

Voici quelques exemples de ressources pouvant être embarquées inter-origines :

  • Le JavaScript avec <script src="…"></script>. Les détails d'erreur de syntaxe ne sont disponibles que pour les scripts de même origine.
  • Le CSS appliqué avec <link rel="stylesheet" href="…">. En raison de la souplesse de la syntaxe CSS, une feuille de style inter-origines nécessite un en-tête Content-Type correct. Les navigateurs bloquent le chargement d'une feuille de style si le type MIME est incorrect et que la ressource ne commence pas par une construction CSS valide.
  • Les images affichées par <img>.
  • Les médias lus par <video> et <audio>.
  • Les ressources externes embarquées avec <object> et <embed>.
  • Les polices appliquées avec @font-face. Certains navigateurs autorisent les polices inter-origines, d'autres exigent la même origine.
  • Tout ce qui est embarqué par <iframe>. Les sites peuvent utiliser l'en-tête X-Frame-Options pour empêcher l'embarquement inter-origines.

Autoriser l'accès inter-origines

Utilisez CORS pour autoriser l'accès inter-origines. CORS fait partie de HTTP et permet aux serveurs de définir d'autres hôtes à partir desquels un navigateur peut charger du contenu.

Comment bloquer l'accès inter-origines

  • Pour interdire les écritures cross-origin writes, contrôlez dans la requête un token qui ne peut être déviné, connu sous le nom de Cross-Site Request Forgery (CSRF) (angl.) token, et interdisez la lecture cross-origin des pages qui connaissent ce token.
  • Pour interdire la lecture cross-origin d'une ressource, assurez-vous qu'elle ne peut pas être embarquée.
  • Pour interdire l'embarquement (embed) d'une ressource cross-origin, assurez vous qu'elle ne peut pas être interprétée comme une des ressources embarquable vues précédemment. Dans la plupart des cas, les navigateurs ne respectent pas le Content-Type. Par exemple, pour une balise <script> pointant un document HTML, le navigateur va tenter d'interpréter le code HTML comme du JavaScript. Si votre ressource n'est pas un point d'entrée de votre site, vous pouvez également utiliser un jeton CSRF.

Accès aux API de scripts inter-origines

Les API JavaScript comme iframe.contentWindow, window.parent, window.open et window.opener permettent aux documents de se référencer directement entre eux. Lorsque deux documents n'ont pas la même origine, ces références ne donnent qu'un accès très limité aux objets Window et Location, comme décrit dans les deux sections suivantes.

Pour communiquer entre documents de différentes origines, utilisez window.postMessage.

Spécification : HTML Living Standard § Objets inter-origines (angl.).

Window

L'accès inter-origines (cross-origin en anglais) aux propriétés suivantes de Window est autorisé :

Méthodes
window.blur
window.close
window.focus
window.postMessage
Attributs Accès
window.closed Lecture seule
window.frames Lecture seule
window.length Lecture seule
window.location Lecture/écriture
window.opener Lecture seule
window.parent Lecture seule
window.self Lecture seule
window.top Lecture seule
window.window Lecture seule

Certains navigateurs autorisent l'accès à plus de propriétés que celles listées ci-dessus.

Location

L'accès inter-origines aux propriétés suivantes de Location est autorisé :

Méthodes
location.replace
Attributs Accès
location.href Écriture seule

Certains navigateurs autorisent l'accès à plus de propriétés que celles listées ci-dessus.

Accès au stockage de données inter-origines

L'accès aux données stockées dans le navigateur, comme le Web Storage et IndexedDB, est séparé par origine. Chaque origine dispose de son propre espace de stockage, et le JavaScript d'une origine ne peut ni lire ni écrire dans le stockage appartenant à une autre origine.

Cookies utilise une définition différente de l'origine. Une page peut définir un cookie pour son propre domaine ou pour tout domaine parent, tant que ce domaine parent n'est pas un suffixe public. Firefox et Chrome utilisent la liste des suffixes publics (angl.) pour déterminer si un domaine est un suffixe public. Lors de la définition d'un cookie, vous pouvez limiter sa disponibilité à l'aide des attributs Domain, Path, Secure et HttpOnly. Lors de la lecture d'un cookie, il n'est pas possible de savoir d'où il a été défini. Même si vous n'utilisez que des connexions https sécurisées, tout cookie visible peut avoir été défini via une connexion non sécurisée.

Voir aussi