security: the EIP-6963 provider UUID is persisted and reused, so any site can read a stable per-install tracking identifier #398

Open
opened 2026-09-21 20:37:56 +02:00 by clawbot · 1 comment
Collaborator

Severity: privacy.

Where. src/content/index.js:26-46 reads, creates and persists eip6963Uuid
in extension storage and posts it as AUTISTMASK_PROVIDER_UUID;
src/content/inpage.js:207-240 overwrites the per-load random UUID with that
persisted value and announces it in eip6963:announceProvider.

What is wrong. EIP-6963 expects a fresh UUIDv4 per announcement, to
distinguish providers within one page. AutistMask instead generates one UUID at
first run, stores it, and announces the same value to every page on every load,
across origins and browser restarts. Any web page — connected or not — can read
it and use it as a stable cross-site, cross-session identifier for the install.
This contradicts the README's "No analytics, telemetry, or tracking".

Why it matters. A supercookie any site can read correlates the user across
unrelated sites and fingerprints the wallet's presence.

Reproduction. On two unrelated sites run
window.addEventListener("eip6963:announceProvider", (e) => console.log(e.detail.info.uuid)); window.dispatchEvent(new Event("eip6963:requestProvider"))
— the same UUID appears on both, and is unchanged after a browser restart.

Acceptable. Announce a fresh crypto.randomUUID() generated per page load
(inpage.js already creates one as a fallback); remove the eip6963Uuid storage
key and the AUTISTMASK_PROVIDER_UUID message.

Definition of done.

  • inpage.js announces a UUID generated fresh on each page load; nothing
    persists it.
  • The eip6963Uuid storage key and the AUTISTMASK_PROVIDER_UUID
    content-script message are removed.
  • The announced UUID differs across page loads and across sites (a test
    asserts two loads differ).
  • No behaviour depends on the UUID being stable.

Model: fable-5-1 (review); opus-4-8 (filing)

Severity: privacy. **Where.** `src/content/index.js:26-46` reads, creates and persists `eip6963Uuid` in extension storage and posts it as `AUTISTMASK_PROVIDER_UUID`; `src/content/inpage.js:207-240` overwrites the per-load random UUID with that persisted value and announces it in `eip6963:announceProvider`. **What is wrong.** EIP-6963 expects a fresh UUIDv4 per announcement, to distinguish providers within one page. AutistMask instead generates one UUID at first run, stores it, and announces the same value to every page on every load, across origins and browser restarts. Any web page — connected or not — can read it and use it as a stable cross-site, cross-session identifier for the install. This contradicts the README's "No analytics, telemetry, or tracking". **Why it matters.** A supercookie any site can read correlates the user across unrelated sites and fingerprints the wallet's presence. **Reproduction.** On two unrelated sites run `window.addEventListener("eip6963:announceProvider", (e) => console.log(e.detail.info.uuid)); window.dispatchEvent(new Event("eip6963:requestProvider"))` — the same UUID appears on both, and is unchanged after a browser restart. **Acceptable.** Announce a fresh `crypto.randomUUID()` generated per page load (inpage.js already creates one as a fallback); remove the `eip6963Uuid` storage key and the `AUTISTMASK_PROVIDER_UUID` message. **Definition of done.** - [ ] inpage.js announces a UUID generated fresh on each page load; nothing persists it. - [ ] The `eip6963Uuid` storage key and the `AUTISTMASK_PROVIDER_UUID` content-script message are removed. - [ ] The announced UUID differs across page loads and across sites (a test asserts two loads differ). - [ ] No behaviour depends on the UUID being stable. Model: fable-5-1 (review); opus-4-8 (filing)
clawbot added this to the 1.0.0 milestone 2026-09-21 20:37:56 +02:00
Author
Collaborator

Fixed in #412 (base next).

src/content/inpage.js now announces a per-load crypto.randomUUID() and persists nothing. The eip6963Uuid storage key and the AUTISTMASK_PROVIDER_UUID content-script message are removed.

Judgement call: eip6963Uuid was a standalone top-level storage entry, never a field of the versioned autistmask profile, so src/shared/stateSchema.js and the persisted-field harness needed no change and no existing profile is affected. A stale value left by an older install is read by no code after this change and is not reachable by web pages.

No README sentence describes the provider UUID, so none was changed. A new jest test asserts two loads announce different UUIDv4s.

Model: opus-4-8

Fixed in https://git.eeqj.de/sneak/AutistMask/pulls/412 (base `next`). `src/content/inpage.js` now announces a per-load `crypto.randomUUID()` and persists nothing. The `eip6963Uuid` storage key and the `AUTISTMASK_PROVIDER_UUID` content-script message are removed. Judgement call: `eip6963Uuid` was a standalone top-level storage entry, never a field of the versioned `autistmask` profile, so `src/shared/stateSchema.js` and the persisted-field harness needed no change and no existing profile is affected. A stale value left by an older install is read by no code after this change and is not reachable by web pages. No README sentence describes the provider UUID, so none was changed. A new jest test asserts two loads announce different UUIDv4s. Model: opus-4-8
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#398