Tous les articles

Verrouiller les fonctionnalités du navigateur avec Permissions-Policy et recevoir des reports

CentralCSP Team ·

Dernière mise à jour:

Une page que vous déployez charge des scripts tiers, des tags publicitaires et des widgets intégrés, et chacun d'eux peut demander au navigateur la caméra, le microphone ou la position de l'utilisateur. Le header de réponse Permissions-Policy vous permet de décider quelles fonctionnalités la page et les iframes qu'elle intègre ont le droit d'utiliser, et de couper celles dont vous n'avez pas besoin. C'est un header de réponse : vous le définissez une fois sur le serveur, et le navigateur l'applique à chaque requête.

Ce que Permissions-Policy contrôle

Les navigateurs exposent une longue liste de fonctionnalités que les scripts peuvent appeler : caméra, microphone, géolocalisation, plein écran, lecture automatique, l'API Payment Request, accéléromètre, USB, entre autres. Chacune est régie par une politique nommée. Permissions-Policy vous permet d'indiquer, fonctionnalité par fonctionnalité, qui a le droit de l'utiliser : la page elle-même, des origines précises, tout le monde, ou personne.

La plupart des fonctionnalités valent self par défaut : votre propre origine peut s'en servir, mais pas les iframes cross-origin que vous intégrez, tant que vous ne leur accordez pas l'accès. Définir le header vous permet de resserrer encore (refuser une fonctionnalité d'emblée) ou d'ouvrir délibérément (autoriser une intégration de confiance). Refuser une fonctionnalité que vous n'utilisez jamais réduit la surface d'attaque : un script tiers compromis ne peut pas demander à l'utilisateur sa position si la page a coupé la géolocalisation.

C'est de l'observabilité et du contrôle côté navigateur, pas un pare-feu. Le navigateur applique la politique ; rien ne proxie ni ne réécrit la requête.

Une réserve sur la compatibilité : en pratique, seul Chromium applique le header. Firefox et Safari implémentent le modèle de l'attribut allow des iframes pour certaines fonctionnalités, mais pas le header de réponse Permissions-Policy. Considérez le header comme une couche d'application et de reporting propre à Chromium, et appuyez-vous sur l'attribut allow pour un contrôle par frame qui vaut sur tous les navigateurs.

La syntaxe du header

Le header est une liste d'entrées feature=allowlist séparées par des virgules. L'allowlist se place entre parenthèses et liste les origines autorisées à utiliser cette fonctionnalité.

Permissions-Policy: camera=(), microphone=(), geolocation=(self)

Cet exemple coupe la caméra et le microphone partout (une allowlist vide () signifie aucune origine du tout), et autorise la géolocalisation uniquement sur votre propre origine.

Les tokens d'allowlist sont :

  • () refuse la fonctionnalité à tout le monde, y compris votre propre page.
  • self autorise votre propre origine uniquement.
  • * autorise toutes les origines, votre page et toute iframe intégrée.
  • "https://example.com" autorise une origine précise (entre guillemets). Listez-en plusieurs entre les parenthèses, séparées par des espaces.
Permissions-Policy: fullscreen=(self "https://embed.example.com"), autoplay=()

Ici le plein écran est autorisé pour votre page et une intégration de confiance, et la lecture automatique est coupée pour tout le monde. Choisissez l'allowlist la plus étroite possible sans casser la page : partez de () ou self et n'ajoutez une origine que lorsqu'une intégration a réellement besoin de la fonctionnalité.

Comment il se rapporte à l'attribut allow des iframes

Le header régit votre page de premier niveau et fixe la limite extérieure de ce que n'importe quelle iframe peut recevoir. L'attribut allow des iframes est l'autre moitié : il délègue une fonctionnalité à une frame intégrée précise, dans les limites de ce que la politique au niveau de la page permet déjà.

<iframe src="https://maps.example.com/" allow="geolocation"></iframe>

Pour que cette iframe obtienne réellement la géolocalisation, deux conditions doivent être réunies : la Permissions-Policy de votre page doit autoriser l'origine de l'iframe (par exemple geolocation=(self "https://maps.example.com")), et l'attribut allow doit déléguer la fonctionnalité à la frame. L'attribut ne peut que restreindre ou transmettre ce que le header autorise déjà ; il ne peut jamais accorder une fonctionnalité que la politique au niveau de la page a refusée. Voyez le header comme le plafond, et l'attribut allow comme la délégation frame par frame en dessous.

Il remplace le Feature-Policy déprécié

Permissions-Policy est le successeur de l'ancien header Feature-Policy. Si vous servez encore Feature-Policy, il est temps de le retirer ; nous l'évoquons avec les autres headers à abandonner dans security headers hérités à abandonner.

Le renommage s'est accompagné d'un changement de syntaxe. L'ancien header utilisait une liste séparée par des espaces avec des mots-clés entre guillemets :

-Feature-Policy: geolocation 'self'; camera 'none'
+Permissions-Policy: geolocation=(self), camera=()

La structure est passée de feature 'value' séparé par des points-virgules à feature=(allowlist) séparé par des virgules, 'self' est devenu self (sans guillemets), et 'none' est devenu une allowlist vide (). Les origines sont toujours entre guillemets, mais les noms de fonctionnalités et les mots-clés ne le sont plus.

Recevoir des reports permissions-policy-violation

Une politique qui refuse une fonctionnalité est plus utile quand vous pouvez voir ce qui a tenté de l'utiliser. Quand un script ou une iframe tente une fonctionnalité que la politique bloque, le navigateur peut émettre un report permissions-policy-violation via la Reporting API, nommant la fonctionnalité bloquée et d'où venait la tentative. Cela transforme un refus silencieux en signal : vous apprenez quel tiers cherche à atteindre la caméra, et si une politique resserrée casserait une intégration légitime.

Pour recevoir ces reports, vous déclarez un endpoint avec le header Reporting-Endpoints, le même câblage que pour n'importe quel autre report de navigateur. Nous le détaillons de bout en bout dans comment mettre en place la Reporting API.

Reporting-Endpoints: default="https://<Endpoint-ID>.report.centralcsp.com"

Pour tester une politique sans bloquer, envoyez-la sur le header Permissions-Policy-Report-Only au lieu de celui qui impose. Il signale chaque tentative d'utilisation sans la refuser. Sélectionnez l'endpoint de reporting avec un paramètre report-to= par directive, pas un token dans l'allowlist de la fonctionnalité.

CentralCSP collecte les reports permissions-policy-violation à côté de vos reports CSP et autres reports de navigateur, pour que vous puissiez surveiller quelles fonctionnalités les tiers cherchent à atteindre et alerter dès que quelque chose de nouveau apparaît, sans avoir à construire de récepteur vous-même. Voyez comment nous agrégeons chaque report de navigateur.

Les rapports Permissions Policy dans la vue potentielle, montrant ce que les iframes ont demandé

Par où commencer

Auditez quelles fonctionnalités puissantes votre page et ses intégrations utilisent réellement, refusez le reste avec une allowlist vide, et câblez le reporting pour découvrir quand quelque chose tente une fonctionnalité que vous avez coupée. Puis observez les reports pendant une semaine avant de verrouiller la politique pour de bon.

Commencez à collecter les reports Permissions-Policy.

Articles liés

Sources