HTTP / WebSocket gateway for Fabric peers and browser clients.
Outstanding queue: docs/OUTSTANDING.md.
Fabric networks are intended for deployment where peers, relays, hubs, and operators may be hostile. Design and review against:
- Untrusted TCP / WebSocket / WebRTC neighbors (forgery, replay, amplification, pin hijack)
- Phishing of identity flows (
fabric://login, device-link) toward attacker-controlled hubs - Public observability of unsigned or plaintext application traffic unless an explicit seal is used
- No reliance on an “honest majority” of random internet peers for key custody
This package fails closed on missing auth secrets, enforces Hub origin allowlists for site-login / device-link completion, and treats shared HTTP bind as an explicit operator choice.
Basics coverage: tests/adversarialEnvironment.basics.test.js. Broader auth / WS hardening: tests/security.auth.server.js.
functions/fabricHubAllowlist.js — default network hubs + loopback; extras via FABRIC_HUB_ALLOWLIST. Unknown origins must not receive signed login/link completions.
- WebSocket
GenericMessageAMP-verify — unauthenticated frames are already dropped before localcalldispatch andhandleFabricMessagepeer broadcast (types/server.js). Remaining: prefer named outer types /JSONCallfor new Hub UI paths; optionally verify AMP signatures before any remaining peer relay of signed carriers; do not treat unsigned JSON carriers as equivalent to author-signed AMP. Hub tracking: MESSAGE_TRANSPORT.md. Shared-host WS: Hub callsapplySharedModeWebsocketGate(functions/httpSharedMode.js) so shared HTTP bind (HTTP_SHARED_MODE/0.0.0.0) auto-enableswebsocket.requireClientToken(fail-closed even whenFABRIC_WS_CLIENT_TOKENis unset — handshakes reject until a token is configured). Explicitwebsocket.requireClientToken: falsestill wins. - Site-login / device-link poll secret (PR #69 High) — Hub self-sign is opt-in (
allowHubSelfSign === true; Hub desktop enables it) and loopback-only. Site-login and LiveRelay shareclientMayPollDesktopSessionfor pending polls. Off-loopback signedGET /sessions/:id(Hub + LiveRelay Bearer redeem) and DELETE/device-links/:idrequire the create-responsepollSecretviaX-Fabric-Poll-Secret(never onfabric:/// QR / query strings). Device-link GET pending/accepted/linked stays Origin-gated so the responder can complete with onlysessionId. Keep Hub origin allowlists fail-closed; never treatX-Forwarded-*as proof of loopback. Cleartext production hub defaults— default allowlist is HTTPS-only for network hubs; cleartexthttp://hub.fabric.pub/relay.goon.vc/goon.vcrequireFABRIC_HUB_ALLOWLIST/opts.extra. Loopbackhttp://remains allowed.- Device-link attestation binding — offer replay of
(nonce, initiatorId, origin)after link (and while pending) is rejected; create path andofferReplayKeycanonicalize origin vianormalizeHubOrigin. Remaining: bind randomsessionIdintobuildDeviceLinkMessage(and coordinated Passport / desktop / SCL signers) so captured link signatures cannot recreate alinkedsession under a new id. SLIP-0044 regen—scripts/slip-0044.jsfetches a pinned commit (a8f4330…) and validates row count / field shapes before rewritingsettings/slip-44.json.Docs polish (PR #69)—docs/MESSAGE_SPEC.mddocumentsJSONCallResultsuccess/error + hash correlation; MD040 language tags land on flow fences inMESSAGE_PROTOCOL_REPORT.md/AUDIT.md.— lockfile tip@fabric/corepin hygieneff7c05c52c38c39e552c6f4a4bc62442425bdd0e(refreshed viaFabricLabs/fabric#feature/rsi). Coordinate Hub / apps on the same SHA for releases;report:installremovespackage-lock.jsonthennpm i --allow-git=all(nested git SHA prepare). Bump the tip withnpm install FabricLabs/fabric#feature/rsi --allow-git=allwhen core moves.402 document offer digests—contentHashHex/blobHashHexaccept exact 64-hex only (no trim/truncation);blobIndexaccepts non-negative safe integers only (no stringNumber()coercion);blobIndex-only offers still emitdocumentOffer; invalid fields are omitted.Peer host self-check DNS— IPv6 bracketed addresses parse correctly; ports must be decimal 1..65535 (parseFabricPeerPort); DNS cache keys includeownHosts. Own-host checks usedns.promises.lookup(cached; cache miss is not treated as self). Optionalpubkey@host:portuserinfo is stripped so gossip pins share the same host ashost:port.RFC6902 sidechain JSON bridge— multi-op sequences are preserved inpatchesCanonical(functions/messageBodyJsonBridge.js;tests/messageBodyJsonBridge.test.js). Catalog still seeds from the first/registryop.- Fabric coin types (downstream) — core pin includes 7777 / 7778; Hub/app helpers that still hardcode
7778for mainnet still need alignment. - Site-login delegation token — fail-closed when
expectedsupplies only one ofsessionId/origin; expired-session GET requires opaque Bearer registry key +timingSafeEqualbind to pathsessionId, orAuthorization: Bearermatching path when the path is the token; unauthenticatedGET /sessions/:delegationTokenis 404. LiveRelay omits Bearer whenissueBeareris absent (no orphan random token). Remaining: Hub dual-key legacy cleanup if any path still stores undersessionId. - Device-link client —
createDeviceLinkOffer/ fetch / signature helpers require an explicit browserorigin(nohubBasefallback).
npm testbefore merging HTTP/auth changes.- Never commit seeds, admin tokens, or production
stores/. - Prefer loopback HTTP unless shared mode is intentional.
Canonical monitored contact: security@fabric.pub (also in README.md / AUDIT.md).
GitHub Security Advisories are an alternate private channel. Do not open a public
issue with exploit details. Expect an initial response within a few business days.