Manifest V3 capability analysis, lab malicious extension catalog, update-channel hijack simulation, and defender-side tooling. Each extension demonstrates a distinct capability retained by MV3 — cookie theft, form grabbing, traffic redirection, session interception — paired with Sigma detection rules.
Containment: All extensions hard-check LAB_MODE = true and refuse to
exfiltrate to anything other than 127.0.0.1. All Python tools require
EXPLOIT_LAB_ACTIVE=1 and ContainmentGuard. These extensions are never
submitted to the Chrome Web Store.
The Chrome Manifest V3 migration was positioned as a security improvement.
MV3 removed remote code evaluation, replaced persistent background pages with
service workers, and restricted blocking webRequest. Despite these changes,
MV3 extensions retain sufficient capability for full session cookie theft,
credential harvesting, and silent traffic redirection — without any exploit.
The primary threat vector moved up the stack: from in-extension code capability to publisher account compromise and silent update delivery. The Cyberhaven incident of December 2024 demonstrated the operational template: steal a developer's Chrome Web Store OAuth token, publish a malicious update to the existing extension ID, and Chrome's auto-update delivers it to hundreds of thousands of users within hours — silently, without any user action required.
See docs/analysis/manifest-v3-capabilities.md for the full technical analysis.
The Cyberhaven Chrome extension (~400,000 users) was compromised:
- Developer receives spear-phishing email posing as Chrome Web Store policy alert
- Developer authenticates to Google; attacker captures OAuth token for Developer API
- Attacker publishes malicious update
v24.10.4targeting Facebook Business cookies - Chrome auto-update delivers the extension to 400k users
- Malicious version active for ~31 hours before takedown
- No zero-day, no CVE, no exploit — just stolen developer credentials
This repo's update-hijack/ module simulates this pattern in a contained lab.
Key finding: chrome.cookies.getAll({}) with <all_urls> host permissions
bypasses HttpOnly — the cookie attribute that protects session tokens from XSS.
An extension can steal all session cookies without any exploit.
- MV3 manifest with
cookiespermission and service worker background - Background service worker calls
chrome.cookies.getAll({})on alarm schedule - Sends to
127.0.0.1:9999/exfil(LAB_MODE enforced) - Detection: Sigma rules for cookie exfil patterns
Pairs with: tools/rust/cookie-theft/ (Rust tool
for local decryption of stored cookies — different threat model; extension
captures live session cookies including session-only cookies never written
to disk).
Key finding: MV3 removed blocking webRequest but observation remains
fully available. onSendHeaders with extraHeaders exposes the Authorization
header (normally segregated). All session material visible at the HTTP layer
is capturable.
- Hooks
onSendHeadersandonHeadersReceivedfor all URLs - Buffers captured Authorization/Cookie/Set-Cookie header events
- Drains to
127.0.0.1:9999/exfilevery 30 seconds - Detection: Sigma rules for webRequest exfil patterns
Key finding: Content scripts are functionally unchanged between MV2
and MV3. A content script with <all_urls> and all_frames: true runs in
every frame on every page including SSO login iframes, with full DOM access
and form event interception capability.
- Content script hooks
form.submitevents and password fieldinputevents - MutationObserver covers dynamically-generated React/Vue/Angular login forms
- Detection: Sigma rules for form grab exfil patterns
Key finding: declarativeNetRequest was MV3's "safer" replacement for
blocking webRequest, but it includes a redirect action type. Static redirect
rules are reviewed at submission time; dynamic rules added via
updateDynamicRules() are not subject to re-review.
- Static rules target
*.corp-lab.localdomains - Service worker polls simulated C2 at
127.0.0.1:9997/rulesfor new redirects - Phishing page at
127.0.0.1:9998/phishreceives redirected users - Detection: Sigma rules for DNR abuse patterns
End-to-end simulation of the Cyberhaven attack pattern:
benign_ext/— v1.0 Tab Counter (tabs permission only)malicious_update/— v1.1 Tab Counter (adds cookies +<all_urls>silently)mock_webstore/server.py— Flask mock Chrome Web Store update endpoint with admin toggle between benign and malicious modesupdate_client.py— Simulates Chrome update check with permission diffpermission_differ.py— Standalone permission comparison tool (exits non-zero on expansion — suitable for CI/CD pipeline integration)- Detection: Sigma rules for permission expansion events
manifest_analyzer.py— Static manifest risk scorer (0-10 scale, CI/CD integration via --threshold flag)runtime_monitor.py— CDP-based runtime monitoring of extension network activity and console output via Chrome remote debugging port
Chrome with loaded extensions
|
|-- cookie-theft ext --> 127.0.0.1:9999/exfil (lab_attacker_server.py)
|-- session-hijack ext -> 127.0.0.1:9999/exfil
|-- form-grab ext -----> 127.0.0.1:9999/exfil
|-- dnr-redirect ext --> 127.0.0.1:9997/rules (C2 mode)
127.0.0.1:9998/phish (phishing page)
Mock Web Store (update-hijack): 127.0.0.1:9800
CDP Debug Port (eval): 127.0.0.1:9222
EXPLOIT_LAB_ACTIVE=1 python lab_attacker_server.py --port 9999Open chrome://extensions, enable Developer Mode, click "Load unpacked",
and select the desired extension directory from this catalog.
curl http://127.0.0.1:9999/status
curl http://127.0.0.1:9999/events/latest?n=5python eval/manifest_analyzer.py cookie-theft/manifest.json
python eval/manifest_analyzer.py update-hijack/malicious_update/manifest.jsonpython update-hijack/permission_differ.py \
--before update-hijack/benign_ext/manifest.json \
--after update-hijack/malicious_update/manifest.json# Start Chromium with debug port (for runtime_monitor.py)
chromium --remote-debugging-port=9222 \
--user-data-dir=/tmp/lab-chrome-profile \
--no-sandbox \
--disable-web-securityThen:
- Navigate to
chrome://extensions - Toggle "Developer mode" on
- Click "Load unpacked"
- Select the extension subdirectory (e.g.,
cookie-theft/)
Important: Each lab extension will be assigned a local extension ID by Chrome. This ID is not registered with the Chrome Web Store. Do not submit these extensions to the Web Store.
| Topic | Location |
|---|---|
| MV3 capability analysis | docs/analysis/manifest-v3-capabilities.md |
| Defender methodology | docs/methodology/browser-extension-supply-chain.md |
| Cookie theft (Rust) | tools/rust/cookie-theft/ |
| Detection rules | Each extension/detection/ directory |