How to fix a missing Permissions-Policy header
Your site is missing a `Permissions-Policy` header. This header limits which browser features (camera, microphone, geolocation, USB, payment, etc.) your pages and any embedded iframes can access. Without it, a compromised third-party script could prompt the user for their camera or GPS. Fix it by explicitly denying features you do not use.
Why it matters
Most apps never use the camera, mic, or geolocation. But every page can request them — and every embedded third-party script can try. A locked-down Permissions-Policy means a malicious analytics or ad tag cannot even ask.
How to check
- 01DevTools → Network → Response Headers: look for `permissions-policy`.
- 02If missing, every feature is allowed by default on same-origin.
Or let SafeToShip check it for you in 60 seconds:
How to fix it
Next.js
Deny the features you do not use. Allow on `self` for ones you do.
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=(), usb=(), payment=(self)'
}Generic
Empty parentheses = deny for everyone. `(self)` = allow only same-origin.
Permissions-Policy: camera=(), microphone=(), geolocation=(), usb=()AI prompt
Copy-paste into your AI tool
Paste this prompt into Cursor, Lovable, Bolt, v0, or Claude Code and it will walk through the fix for your specific codebase.
Add a Permissions-Policy header to my app that denies camera, microphone, geolocation, USB, accelerometer, gyroscope, magnetometer, payment, and autoplay by default. If my app legitimately uses one of these, allow only on `self`. Tell me which ones I need to keep by scanning my code for navigator.mediaDevices, navigator.geolocation, and Payment Request API usage.FAQ
Frequently asked questions
- What does empty `()` mean?
- Empty parentheses mean the feature is denied for all origins, including yours. `(self)` allows only your own origin. `(*)` allows any origin (rarely what you want).
- Is this the same as Feature-Policy?
- Permissions-Policy is the current name; Feature-Policy is the old one. The syntax is slightly different. Browsers accept either, but send Permissions-Policy for future-proofing.
Related fix guides
Fix these too
Missing CSP header
A missing Content-Security-Policy header lets attackers inject scripts into your site. Here is what CSP does, why you need it, and how to add it in Next.js, Vercel, and Supabase apps.
Read moreMissing X-Frame-Options
Without X-Frame-Options or CSP frame-ancestors, attackers can embed your site in an invisible iframe to trick users into clicking things. Here is the fix.
Read moreFree tools
Check this yourself
Platform guides
Building on these platforms?
Next.js security
Next.js is the most popular React framework, but even experienced developers miss security headers and accidentally expose server files in production.
Read moreVercel security
Vercel handles hosting and SSL, but your application code still needs security hardening. Missing CSP headers and exposed environment variables are the top issues.
Read moreScan your site for this and 50+ other issues
Free scan. Results in 60 seconds. No account required.