morphit/docs/METADATA-LEAK-CATALOG.md

161 lines
9.7 KiB
Markdown

# Morphit metadata-leak catalog
**Published openly so you can see exactly what Morphit does and does not reveal.**
Privacy is a spectrum. This document tells you the truth about every surface
of Morphit — what it leaks, what it doesn't, and how far we've gone to make
Monero and the other privacy coins as private and untraceable as the design
allows. It is honest, not reassuring-by-omission. Everything claimed here is
enforced by code and pinned by CI tests that fail the build if a change ever
weakens it.
One-line summary: **Morphit logs no IP, no analytics, no cookies, no email, no
phone, no KYC; your keys and chat plaintext never leave your device; and your
actual coin settlement never touches the chain Morphit coordinates on.** What
remains visible is the minimum a *public-orderbook, public-chain* marketplace
must expose — and we've stripped that to the bone.
---
## 1. What does NOT leak — and why
| Surface | Why it's safe |
|---|---|
| **Your identity** | No email, phone, SMS, KYC, or real name — ever. Accounts are pseudonymous Blurt keys. There is no central account database to subpoena or breach. |
| **Your trade settlement** | When you trade any coin, the coins move **peer-to-peer on that coin's own chain**, directly between the two wallets. That transfer is never broadcast to, stored on, or visible from the Blurt blockchain Morphit uses to coordinate. |
| **Your chat content** | Chat is end-to-end encrypted (X25519 + ChaCha20-Poly1305-IETF, fresh sender-ephemeral key per message; ADR-0015). Bodies are unreadable even to the indexer operator. Sender-side forward secrecy: a later posting-key leak does not expose past messages you sent. |
| **Your keys** | Private keys never leave your browser. The project could not decrypt your chats if a regulator demanded it. The operator's hot key is encrypted at rest (scrypt N=2^17 + AES-GCM). |
| **Your IP address** | Never logged, written to disk, transmitted, or retained anywhere. The relay uses the client IP only as an in-memory rate-limit bucket that is discarded when the window passes (`apps/relay/src/middleware/ip.ts`). |
| **Your behavior** | No Google Analytics, no Hotjar, no Facebook Pixel, no cookies, no third-party telemetry. Fonts and assets are self-hosted (no Google Fonts, no CDNs). The `order_views` table stores aggregate counts only — never per-viewer rows. |
| **Monero/privacy-coin view keys** | The XMR treasury **view key does not exist on any Morphit indexer** — it was removed entirely (no chain field, no API, no logs, no env var). Fee verification uses Monero's own selective-disclosure `tx_proof` instead (see section 3). |
**Federation is the meta-protection:** because anyone can run an indexer
(`morphit-ops init`, roughly 23 prompts), you can be the only party that sees your own
SSE traffic and point at your own Blurt RPC — removing the entire
server-stored and network-observable surface for your own users.
---
## 2. What DOES leak — and why
Everything below follows from one unavoidable fact: a **federated public
orderbook** has to be readable by every indexer, and "readable by every
indexer" means "readable by anyone." A centralized exchange hides these things
from the public — but only by collecting your ID, address, bank details, IPs,
and full history for itself. We chose the opposite trade.
### On-chain (anyone reading the Blurt blockchain)
- **The order you posted.** An order is an *advertisement*, so its side
(buy/sell), asset, amount range, payment methods, and optional region are
public — that is how a counterparty finds you. *What we stripped:* the order
permlink is now an opaque random token (`order-...`), **not**
`sell-xmr-usd-...`, so the asset name no longer appears in the permlink, order
URLs, RSS feeds, or block explorers; the expiry timestamp is floored to the
day so it can't fingerprint your exact posting moment; and **no IP, timezone,
language, or browser fingerprint is ever attached** — what you typed in the
form is all that goes on chain.
- **Chat envelopes.** Sender, recipient, block-time, and ciphertext length are
visible for each message — but the content is encrypted and unreadable
(ADR-0015). Ciphertext length is the minimum AEAD chunking allows.
- **Block-time correlation.** Two accounts posting within seconds of each other
can be probabilistically linked. Inherent to any public timestamped log.
- *Take it further:* a fresh Blurt account per trade (free for new users) + Tor
breaks cross-order and timing correlation.
### Network-observable (your ISP, or a server you connect to)
Bodies are TLS-encrypted; only connection metadata is visible (who, when, how
long, how much). The four hops are: the indexer SSE streams, the federation
health-probe between indexers, the Blurt RPC endpoints, and the CoinGecko
price API (a generic CORS `Origin` only — no personal data; price data is
display-only and not used for fee math). *Take it further:* run your own
indexer and RPC, or connect over Tor / I2P / Lokinet (all first-class
transports, not bolt-ons), and this category disappears.
### Server-stored (the indexer operator running your instance)
Which account pairs have paid a stranger-fee to chat; operator-written block
reasons (sanitized at intake and render); aggregate view counts. Federation
lets you choose who the operator is — including yourself.
### Client-stored & browser fingerprint (your own device)
localStorage order drafts (wiped on explicit lock), IndexedDB static-asset
cache (never user data), notification-permission state, and the standard
web-platform fingerprint surfaces (audio context, etc.) common to every
website and gated behind explicit opt-in where the browser allows.
---
## 3. Privacy coins — how far we've gone
Morphit treats **Monero (XMR), Zcash (ZEC), Pirate Chain (ARRR), Dash (DASH),
and Decred (DCR)** as first-class privacy assets and applies every on-chain
protection to all of them. The goal is simple: give the privacy-coin
communities nothing to criticize about trading on Morphit or about our use of
a public coordination chain.
**Protections that apply to every privacy coin automatically:**
- **Settlement is off-chain and peer-to-peer.** The actual coins never touch
Blurt — only the public advertisement and the encrypted chat do.
- **Opaque order permlinks.** "xmr"/"zec"/"arrr" never appears in the
permlink, URL, RSS feed, or explorer — only an `order-...` token.
- **Day-floored expiry + zero silent metadata.** No submit-moment timestamp,
IP, timezone, language, or fingerprint on the order op.
- **Amount jitter, on by default.** Every shared receive amount gets a tiny
random tail down to the coin's smallest unit (piconero for XMR;
satoshi-scale for ZEC/ARRR/DASH/DCR), so the on-chain amount can't be matched
to your posted order. (`jitterAmountForAsset` covers all 16 assets.)
- **Shielded-address-aware validation.** ZEC (`zs1` Sapling, `u1` Unified),
ARRR (`zs1` shielded-only), Monero (stealth/subaddress) are all validated by
shape without ever requiring or storing a viewing key.
**ZEC, ARRR, DASH, DCR are trade-only — their TxID never appears on Blurt at
all.** You can't pay Morphit's listing fee with them (the `fee_method` enum is
frozen at `blurt | btc | xmr`), and settlement is peer-to-peer, so there is no
point at which their transaction IDs are written to the public chain. For these
four, the on-chain story is *cleaner than Monero's*.
**Monero's single, optional, opt-out-able cross-chain touch.** XMR is one of
three assets (with BLURT and BTC) you *may* use to pay the ~$0.25 listing fee.
If you do, that fee payment's TxID is recorded in your order on Blurt so any
operator can verify it — **using Monero's native `tx_proof` selective
disclosure** (`get_tx_proof`), which proves "this txid paid this address this
amount" and nothing else. **No view key is involved, transmitted, or logged**
(the proof string is per-payment, single-use, and excluded from logs; the
explorer API's confusingly-named `viewkey=` parameter carries this proof, not a
key — see OPERATIONS section 12 / section 40.2). This is the *only* place an XMR
TxID touches Blurt, and it's a fee to a public address, never your trade. **Want
zero Monero-to-Blurt linkage? Pay the listing fee in BLURT** — it's the default
and half the price.
**Additional opt-in privacy tech we surface per coin** (on the `/privacy/{asset}`
pages): PayJoin/CoinJoin for BTC, CashFusion for BCH, MWEB for LTC, PrivateSend
for DASH, CoinShuffle++ for DCR, shielded pools for ZEC/ARRR.
---
## How Morphit compares
| Source | What they collect about you |
|---|---|
| Centralized exchange | Gov ID, address, bank info, login IPs, full trade history, withdrawal destinations, support-chat plaintext, device fingerprints |
| "DEX" with KYC | All of the above + the marketing word "decentralized" |
| Bisq desktop | Tor IP if Tor isn't running; full local trade DB; Tor bandwidth signature |
| Haveno desktop | Same as Bisq + Monero RPC traffic |
| **Morphit** | The public orderbook entries you posted; public chat envelopes (ciphertexts unreadable); aggregate view counts; localStorage drafts on your own device until you lock. **Zero IP logging, zero KYC, zero analytics.** |
---
## Provenance & change policy
This catalog began as the Audit 2026-05 metadata-leak enumeration and is
refreshed every audit cycle. It grows on disclosure, not on time — if you find
a leak surface it doesn't cover, open an issue at
`git.agorise.net/agorise/morphit`. The sealings applied so far include: opaque
order permlinks and day-floored expiry (cp175); chat/orderbook SSE buffer caps;
CoinGecko + federation-probe body caps; CSP `connect-src` allowlist at runtime
and build time; chat-route and backup-keys `noindex`; and the removal of the
XMR fee view key in favor of `tx_proof` verification.