Security Headers··8 min lezen·EuroraCloud Team

Wat is de Permissions-Policy header en waarom is die belangrijk?

Terug naar Blog

Wat is de Permissions-Policy header en waarom is die belangrijk?

De Permissions-Policy header is een response header waarmee een website bepaalt welke browserfuncties de eigen pagina's, en alle content die daarin is ingesloten, mogen gebruiken. Functies als de camera, microfoon, locatie en betaling kunnen elk worden toegestaan, beperkt tot je eigen origin, of volledig uitgeschakeld. Hem instellen betekent dat zelfs als een script of een ingesloten derde partij een van die functies probeert te bereiken, de browser dat weigert tenzij je beleid het toestaat, wat zowel je privacyblootstelling als je aanvalsoppervlak verkleint.

Waarom bestaat de Permissions-Policy header?

Moderne browsers stellen veel krachtige mogelijkheden beschikbaar aan webpagina's: locatie, camera, microfoon, bewegingssensoren en meer. Elk script dat op je pagina draait, inclusief externe scripts die je hebt ingesloten voor analytics, chat of advertenties, kan de browser in principe vragen die mogelijkheden te gebruiken. Permissions-Policy bestaat zodat je op het niveau van de hele site kunt bepalen welke van die functies zijn toegestaan en voor wie.

Het doel is om het gat te dichten tussen wat een browser kan en wat je site werkelijk nodig heeft. De meeste websites gebruiken nooit de accelerometer of de payment-API, maar zonder beleid blijven die functies bereikbaar voor elke code op de pagina. Volgens de documentatie van MDN wordt de gebruiker, wanneer een beleid een functie blokkeert, niet eens om toestemming gevraagd, en mislukt de poging van een script om die te gebruiken simpelweg, wat precies de afscherming is die je wilt voor functies die je nooit van plan was te gebruiken.

Wat doet de Permissions-Policy header eigenlijk?

De header werkt als een lijst van directives, één per functie, elk met een allowlist die aangeeft welke origins hem mogen gebruiken. De syntax is de functienaam, een isgelijkteken, en de toegestane origins tussen haakjes, met meerdere directives gescheiden door komma's, bijvoorbeeld geolocation=(), camera=(self). Een lege allowlist, geschreven als (), schakelt de functie overal uit; self staat hem alleen op je eigen origin toe; een specifieke origin zoals ("https://example.com") staat die origin toe; en * staat hem overal toe, inclusief ingesloten frames.

Een nuttig detail is dat elke functie een standaard allowlist heeft die geldt wanneer je niets opgeeft, en afhankelijk van de functie is die standaard *, self, of geen. De waarde van het expliciet instellen van de header is dus dat je niet langer op de standaarden per functie leunt, maar een bewuste, uniforme keuze maakt: zet alles uit wat je niet gebruikt, en beperk alles wat je wel gebruikt tot je eigen origin of de specifieke partners die het nodig hebben.

Hoe gedraagt de header zich met ingesloten iframes?

Dit is het deel waar de meeste mensen over struikelen, dus het is de moeite waard om precies te zijn. Een functie is alleen beschikbaar binnen een ingesloten iframe als aan twee voorwaarden tegelijk wordt voldaan: je top-level pagina moet de functie in zijn Permissions-Policy toestaan voor de origin van dat frame, en het iframe zelf mag hem niet hebben uitgeschakeld. Met andere woorden: de bovenliggende pagina stelt de buitengrens in, en niets wat is ingesloten kan zichzelf een functie toekennen die de bovenliggende pagina heeft onthouden.

Er is ook een besturing per iframe die naast de header werkt, het allow-attribuut op het iframe-element, bijvoorbeeld een ingesloten kaart toegevoegd met een frame waarvan het allow-attribuut geolocation toestaat. Het mentale model om vast te houden is dat de header het sitebrede beleid is en het allow-attribuut de uitzondering per insluiting daarbinnen: het frame kan alleen ontvangen wat de header al toestaat, en het attribuut verfijnt of richt dat vervolgens op die specifieke insluiting. Dit is precies waarom een externe widget soms meldt dat een functie is geblokkeerd terwijl de code van de widget correct is, omdat de omliggende pagina die functie nooit voor de origin van de widget heeft toegestaan.

Wat gebeurt er als je hem niet instelt?

Zonder de header valt elke functie terug op zijn eigen standaard allowlist, die voor verschillende functies ruimer is dan een typische site nodig heeft. In de praktijk betekent dat dat mogelijkheden die je nooit gebruikt bereikbaar blijven, en dat ingesloten externe content functies kan aanvragen die je niet zou hebben toegekend als je het gevraagd was.

Dit is meestal geen urgent gat, en juist daarom blijft het onaangepakt, maar het is wel een reëel gat. Het weegt het zwaarst waar je code insluit die je niet zelf hebt geschreven: een analytics-tag, een chatwidget, een marketingpixel. Het beperken van functies die je niet gebruikt verkleint wat al die ingesloten code kan proberen, en het is precies het soort ontbrekende header dat securityscanners en audits inmiddels op vrijwel elke site aanmerken die hem niet heeft ingesteld.

Hoe implementeer je de Permissions-Policy header?

Je stelt Permissions-Policy in als één HTTP response header. Een verstandig startbeleid is om de functies uit te schakelen waarvan je weet dat je ze niet gebruikt en de rest tot je eigen origin te beperken, bijvoorbeeld Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), en dan alleen individuele directives te versoepelen waar een echte behoefte bestaat. Hij kan worden toegepast op de webserver, in de applicatielaag, of aan de rand in een CDN of securitylaag voor de site.

Het helpt om dit tegen een echte site te bekijken in plaats van in abstracte termen. Neem een kliniekwebsite die een ingesloten kaart toont zodat patiënten de praktijk kunnen vinden, en een online boekingstool draait die een betaalstap opent, maar verder geen browserfuncties gebruikt. Een beleid dat op die site is afgestemd zou alles uitschakelen wat hij nooit aanraakt en alleen toestaan wat die twee functies nodig hebben: geolocation beperkt tot de origin van de kaartprovider, payment beperkt tot de boekings- of betaalprovider, en camera, microfoon en de diverse sensorfuncties allemaal uitgezet met een lege allowlist. Het resultaat is een pagina waar de kaart en de checkout precies werken als voorheen, terwijl elke andere mogelijkheid simpelweg niet beschikbaar is voor welk script dan ook, of dat script nu van jou is of van een ingesloten derde partij. Het principe is algemeen toepasbaar: benoem wat de site echt gebruikt, sta die toe aan de specifieke origins die ze leveren, en sluit de rest af.

Test voordat je hem vastzet. De header heeft een report-only tegenhanger, Permissions-Policy-Report-Only, die de Reporting API van de browser gebruikt om je te vertellen wat een beleid zou blokkeren zonder het daadwerkelijk af te dwingen. Die eerst draaien is de veilige manier om te ontdekken of een echte functie, een kaart die geolocation nodig heeft, een boekingstool die een betaalflow opent, een ingesloten video, door je beleid zou worden gevangen, zodat je die bewust toestaat in plaats van hem per ongeluk te breken.

Wat verandert er op je site zodra hij aanstaat?

Voor de meeste sites niets zichtbaars. Gewone pagina's die geen beperkte functies gebruiken gedragen zich precies als voorheen, en bezoekers merken niets, omdat het beleid alleen ingrijpt wanneer een stuk code een functie probeert te bereiken die je niet hebt toegestaan.

De plek om te controleren is elke functie waar je eigen site echt op leunt, en alles wat je ingesloten derde partijen nodig hebben. Een winkelzoeker die geolocation gebruikt, een videobelfunctie die camera en microfoon gebruikt, of een checkout die de payment-API gebruikt, moeten allemaal hun directives zo hebben ingesteld dat de juiste origins worden toegestaan, en dat is precies waarom testen in report-only ertoe doet voordat je afdwingt. Krijg dat één keer goed en de header houdt daarna stilletjes de lijn vast, staat toe wat je bedoelde en weigert al het andere.

Wat moet je nu doen?

Begin met controleren of je site überhaupt een Permissions-Policy header verstuurt, want zonder een header valt elke functie simpelweg terug op zijn standaard. Als hij ontbreekt, is het risicoarme pad om hem toe te voegen in report-only modus, de functies op te sommen die je daadwerkelijk gebruikt, te bevestigen dat niets waar je op leunt wordt geblokkeerd, en dan een beleid af te dwingen dat al het andere uitschakelt.

Wil je dit correct laten controleren en instellen over je hele site in plaats van stukje bij beetje, dan kan EuroraCloud je huidige security headers bekijken en je laten zien wat ons platform oplost. Bekijk wat EuroraCloud oplost

Conclusie: wat moet je onthouden over de Permissions-Policy header?

Permissions-Policy is een stille, praktische header: hij laat je de browserfuncties uitschakelen die je site nooit gebruikt en de functies die hij wel gebruikt beperken tot alleen de origins die ze nodig hebben, zodat noch je eigen scripts noch ingesloten derde partijen mogelijkheden kunnen bereiken die je nooit van plan was bloot te stellen. De veilige manier om hem in te voeren is testen in report-only modus, bevestigen dat je echte functies nog werken, en dan een beleid afdwingen dat de rest uitschakelt. De nuttigste stap is controleren of je site de header vandaag verstuurt, want zolang dat niet zo is, staat elke functie op zijn standaard.