# Additional browser APIs restricted

- **Pattern:** `ab-002446` (`security-headers-ii.permissions-depth.unused-apis-restricted`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002446
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002446)

## Why it matters

Beyond camera, microphone, and geolocation, browser APIs like `payment`, `usb`, `display-capture`, `accelerometer`, `gyroscope`, and `magnetometer` give embedded scripts access to hardware interfaces, screen capture, and payment flows. A compromised analytics script with access to `display-capture` can screenshot users' screens; `usb` access enables attacks against physical devices; `payment` access can initiate payment dialogs. CWE-693 applies to each unblocked API. OWASP A05 identifies unnecessary API surface as a security misconfiguration — the principle of least privilege applies to browser API grants just as it does to database permissions.

## Severity rationale

Medium because these APIs are less commonly exploited than camera/mic/geo but represent real hardware and payment attack surfaces that are trivial to restrict with a single header value extension.

## Remediation

Extend your `Permissions-Policy` header to restrict all APIs your application does not use. The full recommended restrictive policy:

```js
headers: [{
  key: 'Permissions-Policy',
  value: [
    'camera=()',
    'microphone=()',
    'geolocation=()',
    'payment=()',
    'usb=()',
    'accelerometer=()',
    'gyroscope=()',
    'magnetometer=()',
    'display-capture=()'
  ].join(', ')
}]
```

Only remove an API from the restriction list if your application actively calls it. Check your codebase with `grep -r 'navigator\.' src/` to inventory which browser APIs you actually use.

## Detection

- **ID:** `unused-apis-restricted`
- **Severity:** `medium`
- **What to look for:** Parse the `Permissions-Policy` header value. Check whether these 6 additional browser APIs are restricted: `payment`, `usb`, `accelerometer`, `gyroscope`, `magnetometer`, `display-capture`. Count how many are set to `()`.
- **Pass criteria:** At least 4 of 6 additional APIs are set to `()`. Count the restricted APIs and report: "X of 6 additional APIs restricted."
- **Fail criteria:** Fewer than 4 of the 6 additional APIs are restricted.
- **Skip (N/A) when:** No `Permissions-Policy` header configured.
- **Detail on fail:** `"X of 6 additional APIs restricted — missing: payment, usb, display-capture"` or `"Permissions-Policy restricts only camera/mic/geo but not additional APIs like payment, usb, accelerometer"`
- **Remediation:** Restrict browser APIs your app does not use. This prevents embedded content and compromised scripts from accessing these capabilities:

  ```js
  headers: [{
    key: 'Permissions-Policy',
    value: 'camera=(), microphone=(), geolocation=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=(), display-capture=()'
  }]
  ```

  Only leave unrestricted the APIs your application actively uses.

## External references

- cwe CWE-693
- owasp A05

Taxons: access-control

HTML version: https://auditbuffet.com/patterns/ab-002446
