Skip to content

Latest commit

 

History

History
66 lines (52 loc) · 2.97 KB

File metadata and controls

66 lines (52 loc) · 2.97 KB

Changelog

0.1.0 — unreleased

First working build. Not yet submitted to the Chrome Web Store; see PUBLISHING.md for what is still outstanding.

Detection

  • Value getter interception. HTMLInputElement, HTMLTextAreaElement and HTMLSelectElement value getters are wrapped in the MAIN world at document_start, before any page script runs.
  • Stack-trace attribution. Each read is attributed by walking the whole call stack, not the topmost frame. Frameworks that wrap the value accessor — React's _valueTracker — otherwise absorb the blame, and with React bundled first-party that turns into a dropped detection rather than a mislabelled one.
  • FormData interception. new FormData(form) serialises every field inside the browser without touching the value getter. It is the idiomatic way to read a form and the shape submit-time harvesting takes, and it was completely invisible until now.
  • Page scan. Existing and late-injected scripts are matched against the vendor list, catching pixels that arrive via a tag container or after a consent banner is dismissed.
  • Tamper detection. Prototype replacement is detected and re-wrapped; element-level shadowing is caught by reading a field and checking whether our getter ran. An unrepairable bypass is reported rather than hidden.

Three warning tiers

Deliberately distinct, because conflating them is how a privacy tool becomes noise:

  • Present — a known form-reading vendor is loaded. Never claims a read.
  • Reads your fields — we watched a script read a field that was empty at the time. Nothing taken, but proof it will be.
  • Data read — a script read a field with content in it.

A field upgrades from tier two to tier three when a read catches content, and never downgrades.

Interface

  • In-page panel with a labelled edge launcher, and the browser side panel on Chrome 114+. The in-page one is primary: Brave and some other Chromium browsers do not expose chrome.sidePanel.
  • Built to be read at a glance — one large number, three colour bands, category glyphs, mono field pills, prose collapsed behind a disclosure.
  • Field marking recolours the field's existing border, walking up to the nearest bordered ancestor when the input itself has none. Falls back to an outline. Re-asserted via a MutationObserver, because an inline style does not survive a re-render.

Privacy

  • Field contents never leave sensor.js. The value is read for a length check and nothing else.
  • No network requests, no server, no account, nothing persisted.
  • tools/check-invariant.js enforces the mechanical parts statically and the build refuses to package on failure.

Verification

157 automated checks across five suites, every one negative-tested. Eleven browser fixtures covering the injection race, React attribution, performance, the overlay, the page scan, tamper resistance, iframes, client-side routing, strict CSP, FormData harvesting, and outline durability.