A security review of the transport and verification layers. Every item is a fix
to how untrusted peer input is handled; no features changed.
- SAS verification could be bypassed. `verification_both_confirmed` is an
unauthenticated frame on a channel that is not yet trusted, but it was taken as
proof that both sides had compared their codes — so a peer who completed the
signalling exchange could send it right after the data channel opened and drive
the other side to a "verified" session while the user never looked at the code.
It is now only an acknowledgement: refused unless this side already confirmed
locally, and _setVerifiedStatus() independently rejects any SAS-based
transition without a local confirmation. Holding ECDH-derived keys was never
proof of identity — a MITM has those too.
- Unauthenticated frames could be injected into the chat. A bare
{type:"message"} frame, a raw non-JSON frame and a binary frame were each
decoded and rendered, bypassing decryption, the HMAC check and the verification
gate; the injected text was indistinguishable from a genuine message. Chat
content now reaches the UI only through the authenticated enhanced_message
path.
- A peer could supply the verification code. `sas_code` announcements were
adopted verbatim when no local SAS had been derived yet. They may now only
corroborate the locally derived code.
- Anti-replay never ran. The sequence-number and AAD validators were defined on
SecureKeyStorage instead of the connection manager, so every call site failed
with a TypeError and the sliding replay window was dead code. Moved onto the
manager, wired into the live chat path, and a missing or non-numeric sequence
number now fails closed instead of sailing through the range checks.
- File transfers are gated on verification in both directions. Control frames are
written straight to the data channel by the transfer system; sending was
already gated, receiving now is too.
- Tighter CSP: connect-src and img-src no longer allow arbitrary https: hosts
(nothing in the app talks to a third party), plus base-uri 'none'.
- The SAS is no longer written to logs, and is compared in constant time on every
path. Fixed SecureMasterKeyManager.isUnlocked() testing a field renamed long
ago, so it never actually gated anything.
- Fixed the header showing "Secure undefined%": getRealSecurityLevel() became
reachable for the first time by the move above and returned only per-feature
booleans, while the header renders `level` and `score` directly. It now runs
the same verified scoring as every other consumer.
Adds regression tests for the verification gate, inbound frame authentication and
the security-level shape.
9.4 KiB
SecureBit.chat
End-to-end encrypted, peer-to-peer chat that runs entirely in your browser.
No accounts. No servers storing your messages. No installation required.
Features · How it works · Security · Quick start · Documentation
SecureBit.chat is a browser-based, peer-to-peer messenger built on WebRTC and the Web Crypto API. Two people establish a direct, end-to-end encrypted channel and verify each other in person — there is no registration, no central server relaying or storing messages, and no metadata account to leak. Everything cryptographic happens locally in the two browsers.
It is designed for people who need a small, auditable, zero-infrastructure way to talk privately: journalists and sources, security researchers, or anyone who simply wants a conversation that leaves nothing behind.
Screenshots
| Open a secure channel | Encrypted conversation |
|---|---|
![]() |
![]() |
Features
** Encryption & verification**
- ECDH P-384 key agreement with derived per-session keys, AES-256-GCM payloads, and DTLS-protected transport.
- Interactive Short Authentication String (SAS) verification — you confirm a code out-of-band before the session is trusted, defeating man-in-the-middle attacks.
- Replay protection, message integrity (HMAC), and a live security report you can open at any time during a call.
** Privacy by design**
- Direct peer-to-peer connection — messages never touch a SecureBit server.
- No accounts, no phone numbers, no message history on disk.
- Optional relay-only mode routes traffic through your own TURN server so your IP is never exposed to the peer.
- Local key metadata is stored encrypted in IndexedDB; disconnecting cleans up session state.
** Encrypted calls**
- 1:1 voice and video calls over the same verified peer-to-peer connection — media rides the SAS-verified DTLS-SRTP transport, so calls inherit the session's end-to-end encryption and never traverse a SecureBit server.
- Adaptive audio: Opus with in-band FEC, DTX and RED redundancy for intelligible speech under 15–20% packet loss; audio is prioritised and never throttled by the network controller.
- Adaptive video: VP9/AV1 single-encoding SVC (H.264/VP8 fallback) that degrades by spatial/temporal layer, with a runtime controller that trims video bitrate on loss/RTT and recovers as the link clears.
- Live connection-quality indicator (Excellent → Good → Fair → Weak) shown in the call UI, plus in-call mute and video-upgrade controls.
** Messaging**
- Encrypted voice messages — record in the browser and send over the same end-to-end encrypted transfer channel as files. Audio is captured as PCM/WAV, integrity-protected by a signed hash, and played back inline on the recipient's device without ever touching disk.
- Code blocks with syntax highlighting and an auto-clearing copy button.
- View-once and disappearing messages with countdown timers.
- Unsend (delete for everyone) over the authenticated control channel.
- WhatsApp-style delivery status (sending → sent → delivered) with offline store-and-forward.
Multiple conversations
- Run several independent chats at the same time. Every conversation gets its own encrypted session, keys and verification, so two chats can never mix.
- A side panel lists your open chats with unread badges. Switching is instant, and starting a new chat leaves the others connected.
- Set your availability (Available, Away, Busy or Invisible) and connected peers can see it. You can also give each chat a private label that is stored only on your device and is never sent to the other side.
** File transfer**
- Consent-gated, end-to-end encrypted transfers with resumable, per-chunk progress.
- Strict file-type allowlist; executable and scriptable formats are rejected.
** Progressive Web App**
- Installable on desktop and mobile, works offline, and ships update notifications.
How it works
SecureBit never sees your conversation. A session is built directly between the two browsers:
Peer A Peer B
│ 1. create encrypted offer │
│ ────────────────────────────► │ (shared out-of-band: QR / link / paste)
│ │
│ 2. return encrypted answer │
│ ◄──────────────────────────── │
│ │
│ 3. compare SAS code aloud │
│ ✓ both confirm → verified │
│ │
│ ═══ end-to-end encrypted ════ │
- Peer A creates an offer (sharable as a QR code, link, or text).
- Peer B opens it and returns an answer the same way.
- Both sides see a SAS code and compare it over a trusted channel (in person, a call you recognize, etc.).
- Only after both peers confirm the matching code does the chat unlock. Three failed attempts terminate the session.
Security model
| Layer | Mechanism |
|---|---|
| Key agreement | ECDH (P-384), per-session derived keys |
| Transport | WebRTC data channel over DTLS |
| Message encryption | AES-256-GCM, end-to-end |
| Authentication | Interactive SAS bound to both peers' DTLS fingerprints |
| Integrity | HMAC + replay protection |
| Sanitization | DOMPurify text-only rendering boundary |
| Local storage | Encrypted key metadata in IndexedDB |
A session is not treated as verified until both peers complete the SAS flow. This is the step that protects you against a man-in-the-middle: the code must be compared through a channel an attacker cannot impersonate.
Warning
SecureBit.chat is privacy software, not a guarantee. View-once and disappearing messages are cooperative (not screenshot-proof), and a TURN relay can observe both peers' IPs and traffic timing — though never message contents. See
SECURITY_DISCLAIMER.md.
Quick start
Run locally
npm install
npm run build
npm run serve
Open the printed local URL in two browser windows or profiles, then:
- Create an offer in the first window.
- Transfer it to the second and create an answer.
- Return the answer to the first window.
- Compare the SAS code out-of-band and enter it on both sides.
- Start chatting once both peers are verified.
Install as an app
SecureBit is a PWA — open it in a supported browser and choose Install (or Add to Home Screen on mobile) to run it as a standalone, offline-capable app.
Configuration
TURN / privacy mode
Direct WebRTC connections can reveal IP addresses to the peer. SecureBit supports a relay-only privacy mode:
- Default keeps standard WebRTC behavior with public STUN.
- Relay-only sets
iceTransportPolicy: "relay"and requires a configured TURN server. - STUN alone does not hide IP addresses; public TURN credentials are never bundled.
Configure your own STUN/TURN servers under Advanced network settings, or at deployment time. See doc/CONFIGURATION.md.
File transfer policy
Incoming transfers require explicit consent. Metadata is validated and dangerous names rejected before the prompt appears. Accepted: common raster images, PDF, plain text, and ZIP. Executable/scriptable formats (.exe, .bat, .sh, .js, .msi, .dmg, .jar, .ps1, .vbs, .html, .svg, …) are blocked, and MIME type must agree with the file extension.
Development
Requirements: Node.js 18+ and npm.
npm install
npm test # run the test suite
npm audit # check dependencies
npm run build # build CSS + JS bundles and refresh meta.json
npm run dev # build and serve locally
Project structure
src/network/ WebRTC connection and session lifecycle
src/transfer/ secure file-transfer implementation
src/crypto/ cryptographic utilities
src/components/ React UI components
src/styles/ component styles
doc/ technical documentation
dist/ built bundles served in production
Documentation
SECURITY.md— security policy & reportingdoc/CONFIGURATION.md— deployment & ICE configurationdoc/CRYPTOGRAPHY.md— cryptographic designdoc/SECURITY-ARCHITECTURE.md— architecture overviewdoc/API.md— internal APIsCHANGELOG.md— full release history
Contributing & responsible use
Issues and pull requests are welcome. SecureBit.chat is intended for lawful, ethical communication only — please read RESPONSIBLE_USE.md before using or contributing.
License
Released under the MIT License.

