crx-manifest-parser¶
What does a Chrome extension actually have permission to do? The answer
lives in its manifest.json — the permissions, host_permissions, and
content_scripts fields that define which browser APIs and which websites an
extension can touch. Parse that file into a typed struct and you can audit,
compare, and flag extensions mechanically instead of eyeballing JSON.
crx-manifest-parser is a pure-Rust, zero-dependency crate that decodes a
Chrome / Chromium Manifest V3 manifest.json string into a strongly-typed
Manifest struct exposing exactly the fields a security
scanner cares about: name, version, description, manifest_version,
permissions, optional_permissions, host_permissions, and
content_scripts. It carries its own minimal JSON value parser, so a manifest
can be decoded in any sandboxed or #[no_std]-adjacent context without
dragging in serde or serde_json. It is #![forbid(unsafe_code)].
This is the manifest-decode layer behind the zovo.one Chrome-extension privacy & security scanner.
Why these fields¶
| field | what it grants | risk |
|---|---|---|
permissions |
named API tokens (activeTab, storage, tabs, ...) |
capability |
optional_permissions |
same, requested later at runtime | deferred |
host_permissions |
match-patterns granting site access (https://*/*) |
data access |
content_scripts |
scripts + match list injected into pages (cross-origin) | injection |
content_scripts is the biggest cross-origin exposure surface: it runs your
code inside other people's pages. host_permissions decides which pages. A
typed struct makes "does this extension read every site I visit?" a one-liner.
Install¶
Quick start¶
use crx_manifest_parser::Manifest;
let json = r#"{
"manifest_version": 3,
"name": "My Extension",
"version": "1.4.2",
"permissions": ["activeTab", "storage"],
"host_permissions": ["https://*.example.com/*"],
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"js": ["content.js"]
}
]
}"#;
let manifest = Manifest::from_json(json).expect("valid manifest");
assert_eq!(manifest.name.as_deref(), Some("My Extension"));
assert_eq!(manifest.version.as_deref(), Some("1.4.2"));
assert_eq!(manifest.manifest_version, Some(3));
assert_eq!(manifest.permissions, ["activeTab", "storage"]);
assert_eq!(manifest.host_permissions, ["https://*.example.com/*"]);
assert_eq!(manifest.content_scripts.len(), 1);
See it live
The crate gives you the parsed manifest. For a full extension security report — every permission explained, every host flagged, every content script surfaced — paste the extension into the zovo.one scanner.
Features¶
- Pure Rust, no deps — no
serde, noserde_json; a self-contained JSON value parser is included. #![forbid(unsafe_code)]— nounsafeanywhere, ever.- Typed
Manifest— strongly-typed fields, not a bag ofserde_json::Value. - MV3 fields —
permissions,optional_permissions,host_permissions,content_scripts, plus identity fields. - Helpful errors —
ParseErrorcarries a byte offset + reason, easy to point at the offending token. #[no_std]-friendly core —alloc-based JSON model; works in sandboxed contexts.- MIT licensed — embed anywhere.
Links¶
- Source crate:
crx-manifest-parser - Interactive tool: zovo.one