web-extension-reverse
Reverse engineer browser extensions (Chrome/Edge MV2/MV3, Firefox) for an authorized review: unpack .crx/.xpi, assess the permission surface, trace background/service-worker and content-script logic,
SKILL.mdskills/web/web-extension-reverse/SKILL.md
GitHubBrowser extension reverse engineering
When it applies
The target is a browser extension — a .crx/.xpi package or an unpacked extension directory —
not ordinary page JavaScript (for that, load reverse-eng-js). Typical jobs: audit an in-scope
extension's client-side signing/encryption/proxy logic, hunt for over-privileged permissions in a
review, or investigate a malicious or supply-chain-poisoned extension. Target must be confirmed in
scope.txt (tradecraft-scope-roe); for malicious samples work in an isolated VM and see
defense-malware-triage.
Why it works
An extension is just a zip with a manifest.json that declares its entire trust surface —
permissions, host permissions, entry scripts. Reading the manifest first tells you exactly which
scripts can touch which origins, and every browser-API capability (webRequest, cookies,
nativeMessaging) is reachable by grepping for chrome.* / browser.* calls from those entry
points. The dynamic half is free: Chrome runs unpacked extensions natively and DevTools attaches
straight to the background service worker.
Method
- Unpack.
.xpiis a plain zip..crxhas a CRX3 header before the zip data — most unzip tools tolerate it; if not, strip the header or pull the already-unpacked copy from the browser profile (.../Extensions/<id>/<version>/). - Read the manifest first:
jq '{permissions, host_permissions, background, content_scripts, web_accessible_resources, externally_connectable, content_security_policy}' manifest.json. Record MV2 (background.scripts,webRequestBlocking) vs MV3 (background.service_worker,declarativeNetRequest) — it changes where the logic lives. - Score the permission surface. Red flags:
<all_urls>(read/write any site),webRequest/webRequestBlocking(MITM-grade request rewriting),debugger,cookies,nativeMessaging(escapes the browser to a host binary — follow it withreverse-eng-binary-triage), andexternally_connectable(lets web pages drive the extension — a remote attack surface). - Trace the logic. Start at the service worker / background entry, then the content scripts —
note each script's
matches,run_at, and whether it runs in the isolated world. Grep forchrome.storage/ IndexedDB to find stored keys and tokens, and forruntime.onMessage/sendMessage/postMessageto map who can drive what. For obfuscated or webpack-packed code, anchor on thechrome.*API calls and run thereverse-eng-jsrecovery flow; for the fast attack-side path seeweb-client-side-signing-bypass. - Go dynamic. Load the unpacked directory at
chrome://extensions(Developer mode), watch for load errors, then open DevTools on the service worker link. Trigger events and observe network traffic and message passing; Burp/CDP covers the deeper hooks. For known-bad hunting, run YARA rules for malicious-extension families over the unpacked tree.
Gotchas
- MV3 service workers suspend when idle — breakpoints go cold. Keep the worker's DevTools window open and trigger the event you're tracing; don't expect it to be alive on its own.
- MV3
declarativeNetRequestis declarative — the blocking/redirect logic lives in the JSON ruleset, not JS. Read the rules file; there is no function to hook. - Content scripts run in an isolated world — page JS can't see their variables, and they can't
see the page's. Cross-talk happens over the DOM or
postMessage; audit both directions. - Secrets live in the installed profile, not the package —
chrome.storage.localpersists in the profile's LevelDB; check there during a live-host review. .crxfrom the Web Store is signed and version-locked — for reproducible analysis record the extension ID + version, and diff updates before concluding.
Verify success
You can state, with evidence: the full permission surface and entry scripts, the data flow (what the extension reads, where it sends it, where keys/tokens live), and who can message it (other extensions, web pages, native hosts) — each claim cited to a manifest field or code location.
References
Chrome MV3 migration docs; chrome://extensions developer mode; OWASP CISQ extension guidance.
Portions adapted from reverse-skill by zhaoxuya520, MIT License.