MV3 Detection Markers
⚠️ Educational Use Only — Use at Your Own Risk
This project provides benign Chrome MV3 extensions ("detection markers") for validating browser-extension security scanners. It is the EICAR-equivalent pattern for browser-extension detection.
- Educational and defensive-testing purpose only. Do not use for any unlawful activity.
- No working credential-theft logic. Markers exercise suspicious manifest patterns and API call shapes. They do not read or transmit real keystrokes, password values, cookie values, or clipboard contents.
- Only load on systems and in browser profiles you own or have written authorization to test. Do not deploy against third parties.
- You assume all risk. The authors and contributors accept no liability for misuse, data loss, or any consequence of running this software. See
LICENSE.If you cannot agree to the above, do not use this project.
Benign Chrome MV3 extensions that trigger specific suspicious-behavior signatures. Used as test cases for enterprise extension scanners.
No real user data is captured or exfiltrated. Each marker exercises one detection category and logs a literal marker string (and optionally POSTs to a local test endpoint).
Test endpoint setup (optional)
Markers 02 and 03 POST to http://127.0.0.1:8080/marker. To capture those POSTs, run any local logger before loading:
# Quick netcat logger (echoes raw request)
while true; do nc -l -p 8080 -q 1; done
# Or a small Python catcher
python3 -c "
from http.server import BaseHTTPRequestHandler, HTTPServer
class H(BaseHTTPRequestHandler):
def do_POST(self):
n = int(self.headers.get('content-length', 0))
print(self.rfile.read(n).decode(errors='replace'))
self.send_response(204); self.end_headers()
HTTPServer(('127.0.0.1', 8080), H).serve_forever()
"
If you skip this, the fetch calls silently fail and markers still log to the extension's service-worker / content-script console.
Load procedure
- Open
chrome://extensions(Chrome MV3) orbrave://extensions(Brave). - Toggle Developer mode (top right).
- Load unpacked → pick one marker folder.
- Note the generated extension ID.
- Run your scanner against:
- the folder (static analysis), and
- the loaded extension ID (dynamic / runtime analysis).
- Record verdict per marker.
For marker 09 (manifest-delta), load v1-narrow first, run scanner, then remove and load v2-wide. Scanner should flag the permission expansion as a delta-based signal.
Marker matrix
| # | Folder | Detection signal | Real-world example |
|---|---|---|---|
| 01 | 01-form-hook |
Content script attaches keydown listener to input[type=password] on <all_urls> |
Credential keylogger pattern |
| 02 | 02-cookie-read |
Service worker calls chrome.cookies.getAll({}) on install |
Session theft pattern (Cyberhaven cluster) |
| 03 | 03-beacon-c2 |
chrome.alarms periodic POST to external host |
C2 beaconing |
| 04 | 04-dnr-redirect |
declarativeNetRequest static redirect rule |
MV3-only attack vector (replaces MV2 webRequest blocking) |
| 05 | 05-broad-perms |
<all_urls> host perm + cookies + scripting + webRequest + tabs combo |
Manifest-only signal — pure static test |
| 06 | 06-programmatic-inject |
chrome.scripting.executeScript on every tab complete event |
Stealth content-script injection without content_scripts declaration |
| 07 | 07-clipboard-read |
navigator.clipboard.readText() on Ctrl+V |
Clipboard-stealer pattern |
| 08 | 08-tab-capture |
chrome.tabs.captureVisibleTab on action click |
Screen-grabber pattern |
| 09 | 09-manifest-delta |
v1 narrow scope → v2 widens to <all_urls> + cookies + scripting |
Update-poisoning pattern (Cyberhaven technique) |
What these markers do NOT do
- Do not read keystroke values, password contents, cookie values, or clipboard text.
- Do not transmit any data to non-local destinations.
- Do not persist anything to disk or
chrome.storage. - Do not modify form behavior, page DOM, or user actions.
Safe to load in a disposable Brave/Chrome dev profile. A clean VM is still recommended so any false-positive enterprise EDR action doesn't disrupt your daily browser.
Per-category recall scoring
For each marker, record:
| Marker | Scanner verdict | Detection rule fired | Notes |
|---|---|---|---|
| 01 | flagged / clean | ||
| 02 | |||
| ... |
Anything in the clean column → a gap. Cross-reference to the prior detection-category report (research-260516-0713-malicious-chrome-extension-samples-for-detection-testing.md, §2) to map the miss to a missing rule type.
Removing markers
Each is its own extension — remove via chrome://extensions → trash icon. No system changes, no registry keys, no leftover files.
Unresolved
- Manifest delta
keyfield. For scanners that require both versions to share an extension ID (i.e., compare by ID), you must inject a stablekeyfield into bothmanifest.jsonfiles. Generate one withchromepacking the v1 folder once and copying the resulting public key. Skipped here because most static scanners diff by name/folder; flag this if your scanner needs ID-stability. - MV2 counterparts for any of the above markers can be added when you're ready — say the word and I'll generate them alongside.