# Heavy permissions are optional

- **Pattern:** `ab-001322` (`extension-permissions-security.permission-scope-validation.optional-permissions`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001322
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001322)

## Why it matters

Requesting every permission upfront means users see the full warning list before they have any reason to trust the extension, which reduces install rates and raises legitimate privacy concerns. CWE-250 applies: permissions that only support optional features run with unnecessary privilege during all other extension operations. Chrome's `optional_permissions` API lets you defer scary permission requests — `bookmarks`, `downloads`, `history` — until the user opts into the specific feature that needs them, which dramatically increases trust-to-request ratio and keeps your surface area small when those features are unused.

## Severity rationale

Low because the attack surface created by upfront optional permissions is real but modest — it exposes feature-specific APIs to the background context rather than blocking core functionality.

## Remediation

Move non-core permissions to `optional_permissions` in `manifest.json` and request them at runtime when the user enables the relevant feature.

```javascript
// src/features/export.js
chrome.permissions.request({ permissions: ['downloads'] }, (granted) => {
  if (granted) { startExport(); }
});
```

Declare the set in manifest so Chrome knows they are valid optional targets, but do not grant them at install time.

## Detection

- **ID:** `optional-permissions`
- **Severity:** `low`
- **What to look for:** List all entries in `permissions` and `optional_permissions` in `manifest.json`. Count how many secondary-feature permissions are placed in `optional_permissions` vs requested upfront. Check if permissions that are not critical for the core functionality are placed in `optional_permissions` or `optional_host_permissions`.
- **Pass criteria:** At least 1 non-core permission (like `bookmarks`, `downloads`, specific broad hosts) is placed in `optional_permissions` for secondary features, or all permissions are core to the single-purpose extension. Report the count of optional vs upfront permissions.
- **Fail criteria:** All permissions are requested upfront in `permissions`, even those used for rarely accessed features.
- **Skip (N/A) when:** The extension is single-purpose and all permissions are core.
- **Detail on fail:** `"Permissions 'downloads' and 'bookmarks' are requested upfront but appear to be for optional features."`
- **Remediation:** Use `chrome.permissions.request()` to ask for permissions only when the user enables the specific feature.

  ```javascript
  // src/features/export.js
  chrome.permissions.request({ permissions: ['downloads'] }, (granted) => {
    if (granted) { /* proceed */ }
  });
  ```

## External references

- cwe CWE-250
- external chrome-optional-permissions — https://developer.chrome.com/docs/extensions/reference/api/permissions

Taxons: access-control

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