CentralCSP
Headers de sécurité

Cross-Origin-Resource-Policy

CORP permet à une ressource de déclarer qui peut la charger, une protection contre les fuites cross-origin et le hotlinking. Valeurs et lien avec COEP.

Dernière mise à jour:

Tout ce que votre serveur publie est intégrable par défaut. N'importe quelle page du web peut pointer une balise <img>, <script> ou <video> vers vos URL, et le navigateur récupère la ressource directement dans le processus de cette page. Cross-Origin-Resource-Policy (CORP) est un header de réponse qu'une ressource envoie pour indiquer qui peut la charger : uniquement sa propre origine, uniquement son propre site, ou tout le monde.

C'est l'inverse du partage des ressources entre origines (CORS) : CORS permet à un serveur d'autoriser d'autres origines à lire ses réponses, tandis que CORP permet à une ressource de refuser d'être intégrée par elles.

Le réglage le plus strict réserve une ressource à l'origine qui l'a servie :

Cross-Origin-Resource-Policy: same-origin

Valeurs et ce que fait chacune

ValeurStatutDescription
same-origin✅ BonSeules les requêtes provenant exactement de la même origine (schéma, hôte et port) reçoivent la ressource. Le choix deny par défaut pour les ressources privées.
same-site✅ BonLes requêtes provenant du même domaine enregistrable passent, sous-domaines compris, avec une règle de schéma : une page HTTP ne peut pas charger une ressource HTTPS par ce biais.
cross-origin✅ BonN'importe quelle origine peut charger la ressource. Réservé aux ressources vraiment publiques ; il existe surtout pour que les pages sous COEP require-corp puissent encore les charger.

Un header absent se comporte comme cross-origin : la ressource reste chargeable par tout le monde. Il en va de même pour une valeur que le navigateur ne sait pas analyser. Tout ce qui n'est pas l'un de ces trois mots-clés est traité comme si aucun header n'avait été envoyé, si bien qu'une faute de frappe désactive silencieusement la protection.

CORP n'empêche pas la requête. Le navigateur l'envoie, votre serveur répond, et ce n'est qu'ensuite que le navigateur vérifie le header puis, en cas de non-correspondance, retient le corps et fait échouer le chargement avec une erreur réseau. La ressource n'entre jamais dans le processus de la page qui l'intègre, mais la requête a tout de même atteint votre serveur.

La vérification ne s'applique qu'aux requêtes no-cors, le mode par défaut pour <img>, <script src>, <audio>, <video> et les feuilles de style chargées sans attribut crossorigin. Une requête faite en mode CORS échappe à la vérification CORP, parce que CORS exige déjà une autorisation explicite du serveur. Les requêtes provenant de l'origine même de la ressource passent toujours, quelle que soit la valeur. Et CORP ne bloque pas à lui seul les navigations de premier niveau ni les intégrations <iframe> simples ; les réponses d'iframe ne sont vérifiées par CORP que lorsque le document intégrant applique COEP require-corp.

Contre quoi cela protège

  • Les canaux auxiliaires de classe Spectre. CORP a été relancé en 2018, à partir de l'ancienne proposition From-Origin, en réponse à Spectre et Meltdown. Ces attaques permettaient à une page malveillante de lire toute donnée partageant son processus, y compris les ressources cross-origin qu'elle avait intégrées. CORP maintient d'emblée votre ressource hors du processus de l'attaquant, donc il n'y a rien à lire.
  • L'inclusion de script cross-site (XSSI). Un script marqué same-origin ou same-site ne peut pas être tiré par la balise <script> d'un autre site, ce qui ferme les attaques qui incluent vos scripts pour lire les données qu'ils transportent.
  • Le hotlinking. Les navigateurs qui le prennent en charge refusent d'afficher vos images et médias sur d'autres sites. Notez la limite : les clients non navigateurs ignorent le header, il s'agit donc d'un contrôle d'intégration, pas d'une protection de bande passante.

Les navigateurs imposent déjà un socle par défaut ici. Opaque Response Blocking (ORB) bloque les lectures no-cors des réponses clairement de type données (HTML, JSON, XML, PDF, archives) sans aucun header requis, mais il laisse délibérément passer JavaScript, CSS, images et médias pour que les sites existants continuent de fonctionner. L'explainer ORB encourage fortement à protéger ces types de ressources laissés passer avec Cross-Origin-Resource-Policy dès qu'ils contiennent quoi que ce soit de sensible. Considérez ORB comme la valeur par défaut et CORP comme le contrôle explicite de ce qu'il laisse passer.

Le lien avec COEP

Cross-Origin-Embedder-Policy (COEP) est l'autre moitié de la paire, et sa propre page la traite en entier. Un document qui applique Cross-Origin-Embedder-Policy: require-corp ne charge que les sous-ressources cross-origin qui y consentent, et il traite un header CORP absent ou mal formé comme same-origin. C'est ce renversement du comportement par défaut qui bloque les ressources tierces non étiquetées, et c'est pourquoi tout hôte qui sert des ressources vraiment publiques (un CDN, un widget, un service de polices) doit envoyer Cross-Origin-Resource-Policy: cross-origin pour rester intégrable dans des contextes isolés.

Un piège fait trébucher bien des déploiements : ajouter Access-Control-Allow-Origin à une réponse no-cors ne satisfait pas require-corp. Soit l'élément intégrant fait une vraie requête CORS (un attribut crossorigin), soit la ressource envoie CORP. La valeur credentialless de COEP est l'alternative qui charge les ressources cross-origin sans CORP en retirant les identifiants de la requête.

Risques sans le header

N'importe quel site peut tirer vos ressources dans son propre processus. Une page dont vous n'avez jamais entendu parler peut intégrer les avatars, graphiques ou documents que votre serveur renvoie aux utilisateurs connectés, puis utiliser un canal auxiliaire d'exécution spéculative pour les lire. Elle peut inclure vos scripts avec une balise <script> et observer ce qu'ils exposent (XSSI). Et elle peut faire du hotlinking sur vos images et médias, servant votre contenu dans ses propres pages. ORB ne bloque que les cas clairement de type données ; tout le reste repose sur le comportement par défaut cross-origin tant que vous n'envoyez pas le header.

Risques et pièges à l'usage

  • same-origin casse les configurations multi-sous-domaines. Les ressources servies depuis cdn.example.com et consommées par www.example.com sont cross-origin l'une par rapport à l'autre, donc same-origin les bloque. Utilisez same-site quand des sous-domaines partagent des ressources.
  • Le cas particulier HTTPS de same-site. Le schéma du demandeur compte : une page HTTP ne peut pas charger une ressource HTTPS marquée same-site, même sur le même domaine enregistrable. C'est le comportement spécifié et implémenté, même si certaines documentations l'omettent dans leur prose.
  • Sur-marquer des ressources publiques casse les consommateurs. Poser same-origin ou same-site sur des ressources que d'autres sites sont censés charger casse tout consommateur tiers, y compris toute page qui applique COEP require-corp. Ces ressources ont besoin de cross-origin.
  • Sans risque à déployer partout. Les navigateurs sans prise en charge de CORP ignorent le header, donc le déployer ne présente aucun risque de compatibilité.
  • Il se marie bien avec l'isolation côté serveur. CORP est appliqué par le navigateur après l'arrivée de la réponse. Rejeter les requêtes indésirables sur le serveur avec Fetch Metadata (par exemple, en refusant Sec-Fetch-Site: cross-site) le complète.

Comment le mettre en place

  1. Classez ce que vous servez en trois catégories : les ressources privées utilisées par une seule origine, les ressources partagées entre vos sous-domaines, et les ressources publiques destinées à d'autres sites.
  2. Réglez le header par catégorie : same-origin sur les ressources privées, same-site sur les ressources partagées entre sous-domaines, cross-origin uniquement sur les publiques.
  3. Si l'une de vos pages doit activer COEP require-corp, chargez-la avec les nouveaux headers en place et vérifiez que chaque sous-ressource arrive toujours ; une ressource que vous avez sur-marquée à l'étape 2 échouera là en premier.
  4. Vérifiez le header déployé, et le reste de vos headers de réponse, avec le scanner de headers de sécurité.

Recommandation

Envoyez Cross-Origin-Resource-Policy: same-site comme valeur par défaut pour vos propres ressources :

Cross-Origin-Resource-Policy: same-site

La cheat sheet OWASP sur les headers HTTP recommande same-site, limitant le chargement des ressources à votre site et à ses sous-domaines. Traitez-le comme le plafond, pas le plancher : préférez same-origin partout où les sous-domaines n'ont pas besoin de la ressource, et n'assouplissez vers cross-origin que sur les ressources que d'autres sites sont censés charger, y compris celles isolées par COEP.

Prise en charge par les navigateurs

Pris en charge par les versions actuelles de Chrome, Edge, Firefox et Safari. Les navigateurs sans prise en charge ignorent le header, donc il n'y a aucun inconvénient à l'envoyer partout.

FAQ

Quelle est la différence entre CORP et CORS ?

Ce sont des inverses. CORS fonctionne en opt-in : une ressource l'utilise pour autoriser d'autres origines à lire son contenu. CORP fonctionne en opt-out : une ressource l'utilise pour déclarer qui peut l'intégrer en cross-origin. CORP ne régit que les requêtes no-cors, le mode par défaut des images, scripts et médias, tandis que les requêtes en mode CORS échappent entièrement à la vérification CORP.

Quelle est la différence entre CORP et COEP ?

CORP est posé par la ressource et dit qui peut la charger. COEP est posé par la page intégrante et dit qu'elle ne chargera que des ressources qui y consentent. Un header CORP absent est traité comme same-origin sous COEP require-corp, ce qui bloque les ressources tierces non étiquetées. Voir CORP vs COEP pour la comparaison complète.

CORP bloque-t-il le hotlinking ?

Dans les navigateurs, oui. Un chargement no-cors cross-origin d'une ressource marquée same-origin ou same-site échoue avec une erreur réseau, donc un autre site ne peut pas intégrer votre image ou votre script. Les clients non navigateurs ignorent cependant le header, donc traitez CORP comme un contrôle d'intégration face aux navigateurs, pas comme une protection de bande passante ou contre le vol.

Voir aussi

Sources

On this page