crx-manifest-parser 0.1.0

Parse Chrome / Manifest V3 extension manifest.json fields (name, version, permissions, content_scripts, host_permissions) into a typed struct. Zero-dependency, no serde. Powers the zovo.one extension security scanner.
Documentation
  • Coverage
  • 84.62%
    22 out of 26 items documented1 out of 1 items with examples
  • Size
  • Source code size: 39.07 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 647.71 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 4s Average build duration of successful builds.
  • all releases: 4s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • theluckystrike

crx-manifest-parser

crates.io docs

Parse a Chrome / Chromium Manifest V3 manifest.json string into a strongly-typed Manifest struct exposing the fields an extension security scanner actually cares about:

  • name, version, description, manifest_version
  • permissions and optional_permissions (named API tokens)
  • host_permissions (match-patterns granting site access)
  • content_scripts (the script + match list — the biggest cross-origin exposure surface)

Pure Rust, zero dependencies (no serde, no serde_json), #![forbid(unsafe_code)]. Ships its own minimal, fully-tested JSON value parser so a manifest can be decoded without dragging a JSON library into the build graph.

This is the manifest-decode layer behind the zovo.one Chrome-extension privacy & security scanner, which audits the permissions requested by any installed extension and flags the ones that can read your data across every site.

Why parse the manifest

The manifest.json is the single source of truth for what an extension is allowed to do. Two extensions that both "just change your new tab page" can declare wildly different access: one asks for storage, the other for <all_urls> + cookies + content scripts on every site. The manifest is the first thing a privacy review opens — this crate turns it into a typed value you can branch on, render, or feed to a permission auditor (see the companion permission-auditor crate).

Install

[dependencies]
crx-manifest-parser = "0.1"

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.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);
assert!(manifest.is_mv3());

// The full set of grant tokens, ready for a permission auditor.
assert_eq!(manifest.all_grants(), ["activeTab", "storage", "https://*.example.com/*"]);

API surface

Item Description
Manifest Typed struct over the security-relevant fields.
ContentScript One content_scripts entry (matches, js, css, ...).
Manifest::from_json(s) Parse a manifest string into a Manifest.
Manifest::from_json_value(&v) Build from an already-parsed Json value.
Manifest::all_grants() permissions + host_permissions concatenated.
Manifest::content_match_patterns() Deduped site match-patterns across all content scripts.
Manifest::is_mv3() / is_mv2() Manifest-version predicates.
Json, ParseError The bundled JSON value model + parse error.

Design choices

  • Zero dependencies. No serde, no serde_json. The crate carries a small recursive-descent JSON parser so it works in any sandboxed or constrained build context.
  • Missing fields are tolerated. Manifests routinely omit keys; a missing permissions array is an empty Vec, not an error. A parse error only fires for malformed JSON or a field with the wrong JSON type (e.g. permissions given as a string).
  • No unsafe. #![forbid(unsafe_code)] — there is no unsafe anywhere in the crate.
  • UTF-8 and escape fidelity. Strings are decoded with full \uXXXX / surrogate-pair / \b \f \n \r \t handling, and raw control characters are rejected (per RFC 8259) so a manifest can't smuggle unescaped control bytes.

License

MIT.

Links