Permissions-Policy: switch off the camera, mic, and location you never use
One Permissions-Policy header denies camera, microphone, and geolocation to your page and everything it embeds
The threat
Our scanner saw your responses come back with no Permissions-Policy. That header is how a page declares which powerful browser features (camera, microphone, geolocation, and others) it and its embedded content are allowed to use. With it absent, the browser falls back to a permissive default and leaves those doors unlocked.
That matters because of what your pages pull in. The third-party scripts and iframes most sites embed (ad tags, chat widgets, embedded maps or videos) can prompt your visitors for camera, mic, or location access, and the permission dialog shows up under your domainβs name, not theirs. Most sites never need any of these features at all. Declaring them off means a compromised, swapped, or simply overreaching embed cannot ask for them in your name.
The exact fix
Deny the features you do not use. An empty value, feature=(), switches a feature off for everyone, including your own origin. On Netlify, add it in netlify.toml:
# netlify.toml
[[headers]]
for = "/*"
[headers.values]
Permissions-Policy = "camera=(), microphone=(), geolocation=()"
Or the Netlify _headers form:
/*
Permissions-Policy: camera=(), microphone=(), geolocation=()
On nginx:
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
On Apache:
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
The syntax controls who is allowed:
camera=(): empty parentheses, off for everyone.geolocation=(self): allowed only on your own origin. Use this if your site genuinely needs the feature (a store locator, say) rather than switching it off.microphone=(self "https://widget.example.com"): your origin plus one named partner.
Naming note: this is the current
Permissions-Policyheader. Its predecessor wasFeature-Policy, which used a different syntax. You do not need the old one for todayβs browsers.
Verify it
curl -sI https://yourdomain.com | grep -i permissions-policy
A correct result is a single line: permissions-policy: camera=(), microphone=(), geolocation=().
Proof
apecyber.com sends this header on every response as part of the hardened header set behind its A / 100 grade on Netlify. The ApeCyber scanner flags the missing header passively on every scan, from the outside, touching nothing. Adding it is a clean β4 off the posture score, and it takes about three minutes.