permission-auditor
Audit a list of Chrome / Manifest V3 extension permissions against a curated risk database and produce a structured per-extension report:
- a risk level (
Low/Medium/High/Critical) for each permission, plus a short plain-English description of what it grants, - recognition for host-access patterns (
<all_urls>, scheme wildcards, scoped match-patterns) and broad-vs-scoped classification, - an overall verdict for the whole extension, with the count of each
severity and escalation to
Criticalfor the canonical spyware capability set (arbitrary host access + code injection / cookie access).
Pure Rust, zero dependencies, #![forbid(unsafe_code)], fully tested.
This is the audit engine behind the zovo.one
Chrome-extension privacy & security scanner. It is a more comprehensive
companion to ext-permission-risk:
it covers the full MV3 permission surface, adds a Critical tier for the truly
dangerous combinations, and returns a structured report rather than a single
lookup.
Why audit permissions
The permission list in an extension's manifest.json is the single best
signal for whether it is safe to install. Two extensions that both "just
change your new tab page" can request wildly different access: one asks for
storage, the other for <all_urls> + cookies + scripting. The latter
can read every password you type, on every site, forever. This crate turns
that signal into a labelled, countable, explainable report — the input a
scanner UI renders to a user before they install.
Install
[]
= "0.1"
Quick start
use ;
// A canonical surveillance-set manifest.
let report = audit;
// activeTab + storage are Low; tabs is Medium; <all_urls> is Critical;
// scripting + cookies are High. The broad-host + code combo escalates to Critical.
assert_eq!;
assert!;
assert_eq!;
println!;
// "CRITICAL overall (1 critical, 2 high, 1 medium, 2 low)"
// The "what should I worry about" view.
let worry = report.findings_at_or_above;
assert!;
A benign manifest stays Low:
use ;
let r = audit;
assert_eq!;
API surface
| Item | Description |
|---|---|
audit(permissions) |
Audit an iterable of permission tokens into an AuditReport. |
audit_with_manifest_version(permissions, mv) |
Same, recording the manifest version on the report. |
AuditReport |
{ findings, overall, critical_count, high_count, medium_count, low_count, manifest_version }. |
AuditReport::summary() |
One-line CRITICAL overall (1 critical, 2 high, ...) string. |
AuditReport::findings_at_or_above(level) |
Findings at or above a severity, for a "what to worry about" view. |
Finding |
{ token, level, description, kind } — one audited permission. |
FindingKind |
Known (in DB) / HostPattern (synthesised) / Unknown. |
RiskLevel |
Low / Medium / High / Critical, ordered and comparable. |
find_permission(token) |
Direct database lookup; None if unknown. |
RISK_DATABASE |
The static &[PermissionEntry] constant (60+ MV3 tokens). |
classify_host_pattern(token) |
Structural scope of a host pattern: All / Scheme / Scoped / Unknown. |
is_host_access_pattern(token) |
Heuristic: does this look like a host match-pattern? |
How classification works
For each token, in order:
- Named database hit — the entry's level + description are used directly.
- Host match-pattern — its [
HostScope] is classified: blanket (<all_urls>,*://*/*) and scheme-wide (https://*/*,file:///*) patterns areCritical; a scoped per-site pattern (*://*.example.com/*) isMedium. - Unknown token — surfaced as a Low
Unknownfinding with a "review manually" note. Unknown tokens are never silently escalated.
The overall report level is the highest finding's level, with one escalation
rule: an extension requesting any blanket host access together with
scripting, debugger, cookies, or webRequest is the canonical
spyware capability set and is escalated to Critical regardless of how the
individual tokens classified.
Design choices
- Unknown ≠ Critical. A token not in the database is surfaced as unclassified (Low, "review manually"), never silently escalated. False alarms erode trust; the scanner tells you what it knows.
- Four tiers, not three. A separate
Criticaltier keeps the truly dangerous grants (every site, native process, total tab control) distinct from merely "high" ones (history, bookmarks), so a UI can render them differently. - Combination awareness.
<all_urls>alone is bad;<all_urls>+scripting+cookiesis the full surveillance tool. The auditor recognises the combination and escalates accordingly. - Comprehensive MV3 coverage. 60+ named tokens — every permission in the Chrome Extensions reference plus the host-access pattern tokens.
- Zero dependencies, no
unsafe.#![forbid(unsafe_code)]; nothing added to the build graph.
License
MIT.
Links
- zovo.one — the Chrome-extension privacy & security scanner powered by this engine: https://zovo.one/
- Source (zovo monorepo): https://github.com/theluckystrike/zovo
- Full API docs: https://docs.rs/permission-auditor