Safari does not recognize the Permissions-Policy header name — it only supports the older Feature-Policy header. Sites that configure Permissions-Policy without a matching Feature-Policy leave Safari users with no API restrictions at all: camera, microphone, geolocation, and payment APIs remain unrestricted for embedded content. CWE-693 applies when a protection mechanism is deployed in a way that bypasses it for a significant user segment. OWASP A05 flags browser-specific security header gaps as misconfiguration — partial cross-browser coverage is operationally equivalent to no coverage for affected users.
Low because Safari's market share is significant (especially on mobile), and omitting `Feature-Policy` leaves that entire segment without any API permissions restrictions despite `Permissions-Policy` being configured.
Set both Permissions-Policy (Chromium/Firefox) and Feature-Policy (Safari) with matching restrictions. The syntax differs: Feature-Policy uses 'none' instead of () and semicolons instead of commas.
headers: [
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()'
},
{
key: 'Feature-Policy',
value: "camera 'none'; microphone 'none'; geolocation 'none'"
}
]
Skip this step only if you have confirmed your deployment target is Chromium-only (Chrome extension, Electron app, kiosk). For public web apps, both headers are required.
ID: security-headers-ii.permissions-depth.feature-policy-compat
Severity: low
What to look for: Check for both Permissions-Policy (modern) and Feature-Policy (legacy) headers. Safari does not support the newer Permissions-Policy name. Both headers should be present with matching restrictions for cross-browser coverage.
Pass criteria: Both Permissions-Policy and Feature-Policy headers are present with matching restrictions — at least 3 APIs restricted in each. Count the number of restricted APIs in each header and verify they match.
Fail criteria: Only Permissions-Policy is set without a corresponding Feature-Policy header, or vice versa.
Skip (N/A) when: No Permissions-Policy header configured. Also skip if the project explicitly targets Chromium-only (e.g., Chrome extension, Electron app).
Detail on fail: "Permissions-Policy header set but no legacy Feature-Policy — Safari users have no API restrictions" or "Feature-Policy present but missing modern Permissions-Policy header"
Remediation: Set both headers for cross-browser compatibility. The syntax differs slightly:
headers: [
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()'
},
{
key: 'Feature-Policy',
value: "camera 'none'; microphone 'none'; geolocation 'none'"
}
]
Feature-Policy uses 'none' instead of () and semicolons instead of commas. This is a low-priority compatibility improvement.