Fix librarySecurity

Security

Switch off browser features your site does not use

Your site does not declare which browser features it needs, so features like the camera, the microphone, and location stay available to any script on the page.

Why it matters

Those features are available to scripts by default. A policy that switches off the ones you never use means that if something unwanted does get onto a page, it cannot quietly reach them. Declaring the policy also clears this check.

How you would notice it

  • A security scan reported a missing Permissions-Policy header.
  • A privacy review asked which browser capabilities the site can reach.
  • An embedded widget asked for camera, microphone, or location access unexpectedly.

What to do

We wrote this policy for our own site, then took an entry back out of it before we published. Here is why, twice.

Stage 1Steps 1–1 · includes the code for this stage

  1. Use the current header name, Permissions-Policy. The older name Feature-Policy is ignored by browsers, and this check does not read it either.

    If you copied a snippet that says Feature-Policy, it was written before 2020. Rename it and use current feature names, because the check only reads a modern name written as a feature=allowlist pair, such as camera=(). A header full of typos or pre-2020 names fails even though the header is present. One recognized pair is enough to clear the check, so keep the list short and spelled correctly.

Our production dispatch

The feature we deliberately left on

A deny list copied from a tutorial was written for a documentation site, not for a site that sells something. Our own audit page has a button that copies a code snippet to the visitor's clipboard. Clipboard write access appears in most of the lists that get handed around, and switching it off breaks that button for everyone, silently, with no error message anywhere. We left it enabled and pinned that decision in our build check so nobody completes the list later. Before you paste a list, walk your own funnel: checkout, forms, video, maps, and anything with a copy button.

Source: Clipboard API acquisition funnel interaction audit

Code for this stage
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

Stage 2Steps 2–5 · includes the code for this stage

  1. Start with only the features a typical site does not need, and delete any line for a feature you do use.

    An empty pair of brackets such as camera=() means switched off for everyone, including your own pages. It is a block, not a polite request.

  2. Take out any line for a feature your site relies on. These three cause the most breakage.

    fullscreen breaks video players, payment breaks checkout, and geolocation breaks a store locator or a delivery estimate. If any of those matter to you, leave that line out.

  3. Do not paste a long list from a tutorial. A longer policy is not a better one, and each extra line is another chance to break a feature you forgot about.
  4. Add the header the same way as your other security headers, so it applies to the whole site.
Our production dispatch

And the feature behind the main call to action

The same lists usually switch off autoplay. Our main call to action plays a short muted video, and muted video is normally exempt from autoplay rules, so switching the feature off should be harmless. We left it out anyway, because the cost of being wrong is the primary conversion path and the benefit is zero points. When an entry protects nothing you need and risks something you sell, leave it off.

Source: HTML5 muted video inline playback verification on QuestIntro

Code for this stage
# nginx
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;

How to check it worked

Confirm it worked

Load your site and click through the parts that use interactive features, such as any video, map, or checkout step, and confirm they still work. Then request the address with a header check and confirm permissions-policy appears with your chosen values in the response the browser actually receives, not just in your configuration file. If the recommendation survives that, compare each feature name against the current standard list: the check needs at least one recognized name written as a feature=allowlist pair, so a list made only of typos or pre-2020 names counts for nothing even though the header is being sent. Re-run the Siege Test and confirm the recommendation is gone.

Want this handled for you?

Bring your report to The Council and we will scope the repairs, the rebuild, or the full stronghold.