Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GMACH

Local cookie-store counter-intelligence. Parses browser cookie databases, reconstructs what the ad-tech ecosystem can infer about you, and flags concrete threats - all fully offline, on your machine.

Named after the Building from Stanisław Lem's Memoirs Found in a Bathtub: an environment of total surveillance where every artifact may be a message and every message may be a cipher. The tool is named after the adversary it maps.

python gmach.py            # scan Chrome / Edge / Brave / Firefox profiles
                           # -> gmach_report.json + gmach_purge.json
open dashboard.html        # drag & drop the report (or serve both via http.server)

No report yet? The dashboard ships with a synthetic-data preview mode.

What it shows

  • Exposure profile - interest sectors inferred from cookie domains (explicitly labeled as inference, not fact)
  • Activity rhythm - 7×24 heatmap from last_access timestamps: the same behavioral pattern every tracker on your list can reconstruct server-side
  • Sync bursts / tracking seed events - clusters of tracker cookies created within a 10-second window: one page visit seeding a wave of tracking, pointing at seeder sites
  • Cross-browser correlation - trackers present in ≥2 browsers, i.e. domains for which browser separation provides no isolation
  • Trend & diff - append-only run history (gmach_history.jsonl), sparklines across runs, new/removed domains with new trackers highlighted
  • Findings engine - severity-ranked, each finding tagged with provenance: measured / heuristic / inference
  • Purge list - actionable gmach_purge.json (stale + ad-tech candidates); the tool never writes to live browser databases

Findings (v1.4)

id severity trigger
auth-no-secure high session/auth-named cookie without Secure
persistent-id-cookies high entropy >3.5 bit/char, len ≥16, lifetime >30d (Firefox only)
tracking-seed-events medium/high ≥3 tracker domains created within 10s
samesite-none-insecure medium SameSite=None without Secure
lifetime-gt-400d medium beyond the Chrome lifetime cap
adtech-footprint medium/high ad-tech domain density
fingerprinting-adjacent medium device-intelligence / anti-bot domains
new-tracker-domains medium tracker domains absent in the previous run
cross-browser-tracking medium same tracker in ≥2 browsers
stale-cookies low unused >180d, still valid
identity-graph info cross-service login ecosystems
session-hijack-surface high/medium auth/session cookies stealable via XSS/network
jwt-identity-exposure medium JWTs carrying decoded identity claims
pii-in-cookies high email/phone/uuid/ip found inside cookie values

Confidential layer (v1.4)

By default the tool reads only metadata. The confidential layer goes deeper into what cookies actually carry - while keeping raw secrets out of any shareable artifact:

  • JWT decode - header + payload of your own tokens (no signature verification): issuer, subject, email, scope, expiry. Shows what services store about you and whom they trust. PII masked.
  • Token classifier - session / auth / jwt / oauth_bearer / csrf / opaque_id.
  • In-value PII scan - emails, phones, UUIDs, embedded IPs. Masked in the report.
  • Theft-impact score (0-100) - per cookie: what an attacker gains if it leaks, weighted by missing HttpOnly (XSS-stealable), missing Secure (network-interceptable), weak SameSite, lifetime.
  • Session-hijack surface - auth/session cookies ranked by theft impact.
  • Re-identification index - relative signal (inference) of how uniquely identifiable you are across the tracker set + PII/JWT presence.

Privacy architecture - deliberate, and the point:

  • The main gmach_report.json never contains raw values. Confidential data is derived and masked (prefix + length, redacted claims).
  • Firefox values are plaintext, so the confidential layer runs by default (masked output only).
  • --decrypt (opt-in) decrypts Chromium values using the current user's own OS credentials - self-scoped, the same operation the browser performs; App-Bound-Encrypted stores return no key and are skipped.
  • --reveal (opt-in) is the only way raw values leave memory: they go to a separate gmach_confidential.json, chmod 600, warning-stamped, gitignored. Treat it like a password file: analyze, then delete. A file of live session tokens is a liability, not a feature - the tool is built so you have to ask for it explicitly.

Design decisions (deliberate)

  • Chromium decryption is opt-in, not default (--decrypt). Default analysis runs on metadata. When enabled, it uses the current user's own OS key material and is self-scoped by the OS crypto.
  • Raw values never enter the main report or history. They leave memory only with --reveal, into a separate gitignored 0600 file. The shareable report is always value-free.
  • Snapshot-copy before read - locked SQLite files from a running browser are handled safely; source stores are opened read-only, never modified.
  • Provenance on every claim. Tracker classification and naive eTLD+1 are explicitly labeled heuristics; the method in use is stamped in report meta and the dashboard footer.
  • Fully offline dashboard. Zero CDN, zero external fonts, zero network calls beyond an optional local report fetch. Works air-gapped.

Optional dependencies

  • pip install publicsuffix2 - upgrades eTLD+1 grouping from the built-in naive heuristic (fallback is automatic and labeled)
  • python gmach.py --tracker-list services.json - swap the built-in tracker snapshot for a Disconnect-format list

Methodology caveats

  • last_access is overwritten by browsers: the rhythm heatmap is a snapshot of last touches, not full visit history.
  • Diff compares domain sets between runs. Changing scan scope (different --path, added browser) reflects scope change, not behavior - keep scope constant for a meaningful trend. Natural usage pattern: a weekly scheduled task.
  • Third-party status is proxied by domain classification, not by request-context measurement.
  • No entropy-based ID detection for Chromium (values encrypted by design choice above); metadata analysis remains complete.
  • Built-in tracker list is a curated snapshot, not exhaustive - hence the Disconnect hook.
  • Findings and dashboard UI are currently in Polish; i18n is on the backlog.

License

MIT

Packages

Contributors

Languages