NavSentinel is a local-first Chrome MV3 extension that hardens two abuse-heavy browser surfaces:
- deceptive navigation flows such as hidden overlays, popunders, retargeted clicks, delayed redirects, and synthetic popup attempts
- risky credential submissions such as HTTP password posts, lookalike domains, untrusted domains, and suspicious cross-site form actions
The current main branch ships the merged suite baseline. That means the extension now includes the navigation firewall, the credential guard, a popup, a full options page, trusted-domain management, and a bounded local event log.
- Scores clicks with a Click Deception Score (CDS) before allowing navigation side effects.
- Patches
window.open,location.assign,location.replace, and form submission in the main world to catch script-driven navigation. - Relays isolated-world and main-world control messages through the extension runtime instead of page-visible
window.postMessagetraffic. - Intercepts password-form submission and computes local credential risk before allowing the submit.
- Stores only local settings, allowlists, trusted domains, and a bounded event log in
chrome.storage.local. - Provides a popup for the current tab and an options page for persistent configuration, import/export, and log review.
Off: no intervention; useful only for debugging or side-by-side comparisons.Smart: recommended default. Blocks clearly deceptive interactions while allowing ordinary navigation and most legitimate_blanklinks.Strict: lowers the block threshold and is better for adversarial testing in the Gym.
Off: disables password submit prompting and paste warnings.Smart: recommended default. Prompts on untrusted domains and medium/high risk submits.Strict: prompts more aggressively and is the better mode when testing phishing-style scenarios.
- Trusted domains are for password-submit decisions. Add domains you genuinely trust to receive credentials.
- The navigation allowlist is per-site and per-destination host. It is for flows you intentionally permit after a navigation block or prompt.
- Do not treat them as the same control. A site can be safe to open in a new tab without being a trusted destination for password submission.
- Start in
smartnavigation mode andsmartcredential mode. - Use the popup on a live page to inspect the current registrable domain, trust state, and recent events.
- Use the options page to tune thresholds, inspect the allowlist, and export/import settings.
- Use the Gym to validate changes before trusting behavior on the open web.
- Switch to
strictwhile developing new heuristics or new Gym levels.
extension/: MV3 source, manifest, assets, and build outputgym/: deterministic HTML fixtures for navigation and credential scenariostests/: Vitest unit tests and Playwright E2E testsdocs/: architecture, threat model, testing, release, and usage docsscripts/: release and verification scripts
npm install
npm run buildLoad extension/dist in chrome://extensions with Developer Mode enabled.
Useful commands:
npm run watch
npm run test
npm run test:e2e
npm run demo:showcase
npm run demo:showcase:record
npm run typecheck
npm run verify:versions
npm run package:ext
npm run gym:serveThe popup is the fastest control surface for the current tab. It lets you:
- see the active registrable domain
- see whether that domain is trusted for credential submits
- trust or untrust the current domain
- switch nav mode and credential mode
- inspect the latest event entries
- jump into the full options page
The options page is the durable operator view. It lets you:
- configure navigation mode, debug overlay, and the experimental DNR backstop
- configure credential prompts, paste warnings, medium-risk threshold, and lookalike sensitivity
- tune the event log ring-buffer size
- inspect and clear the navigation allowlist
- manage the trusted-domain list
- export and import the full local configuration bundle
The Gym gives you deterministic fixtures for common attack and edge-case patterns:
- Levels 1-9: overlay, retargeting, popunder, programmatic click, and legitimacy edge cases
- Level 10: delayed redirects and form submits
- Level 11: risky password-submit prompt coverage
- Level 12: slow same-tab navigation legitimacy coverage
Start it with:
npm run gym:serveThen open gym/index.html through the local server.
npm run test: unit tests for local heuristics and shared logicnpm run test:e2e: Playwright suite scoped totests/e2e/**/*.spec.tsnpm run demo:showcase: guided headed demo using the stablecorevariantnpm run demo:showcase:record: same core variant with video capture by default, plus optional trace capture via--tracenpm run demo:showcase:operator: popup/options heavy walkthrough using the real popup surfacenpm run demo:showcase:recovery: redirect/recovery-prompt focused guided variantnpm run typecheck: strict type verification
For custom demo runs:
node scripts/run_demo.mjs core --fast- shorter waits for editing and dry runs
node scripts/run_demo.mjs core --record --trace- record mode plus an explicit Playwright trace artifact
The Playwright config intentionally limits discovery to E2E specs so Vitest files are not loaded by the Playwright runner.
- No remote telemetry
- No remote reputation lookups
- No password-value storage
- No clipboard-content capture
- Local-only settings and logs
See:
docs/README.mdPRIVACY.mdSECURITY.md
Start with docs/README.md. The most useful follow-on docs are:
docs/Project_Overview.mddocs/Architecture_and_Data_Flow.mddocs/Intent_Model_and_Scoring.mddocs/Testing_and_Gym.mddocs/Real_World_Adversarial_Program.mddocs/RELEASING.md
Historical merge-era context lives under:
docs/archive/README.md