Skip to content

Security hardening: TLS, HMAC auth, rate limiting, privacy fixes#6

Open
leetcrypt wants to merge 5 commits into
diorwave:mainfrom
leetcrypt:security-hardening
Open

Security hardening: TLS, HMAC auth, rate limiting, privacy fixes#6
leetcrypt wants to merge 5 commits into
diorwave:mainfrom
leetcrypt:security-hardening

Conversation

@leetcrypt
Copy link
Copy Markdown

@leetcrypt leetcrypt commented May 26, 2026

Summary

Security hardening + encrypted file transfer for cmd-chat. All changes maintain the SRP + Fernet architecture. Zero new dependencies.

Security Fixes

  • TLS by default — auto-generated self-signed certs at ~/.cmd-chat/certs/
  • Session key removed from wire — no longer returned in /srp/verify response
  • HMAC WebSocket authws_token verified with hmac.compare_digest()
  • Admin-only /clear — requires Bearer token (printed at server start)
  • Password hidden — env var or interactive getpass instead of CLI arg
  • IPs removeduser_ip deleted from Message model
  • Rate limiting — 10 req/min/IP on SRP endpoints
  • Message cap — 1000 max (prevents RAM DoS)
  • Access log off — disabled HTTP request logging
  • Username sanitization — prevents rich markup injection
  • Dead code removed — 4 unused functions from helpers.py
  • requirements.txt — fixed broken UTF-16 encoding

Encrypted File Transfer

New commands: /send <filepath>, /accept, /reject

  • Files chunked (64KB), encrypted with room Fernet key, relayed via WebSocket
  • SHA-256 integrity verification on receipt
  • Server never sees file content (E2E encrypted)
  • 50MB max, saved to ./downloads/ with collision-safe naming
  • Zero server changes — server remains a dumb encrypted relay

Lab Environment

lab/setup-lab.sh — one-command tmux lab with server + 2 chat clients.


Setup

git clone https://github.com/diorwave/cmd-chat.git
cd cmd-chat
pip install -r requirements.txt

Hosting

# Password prompted securely
python3 cmd_chat.py serve 0.0.0.0 3000

# Or use helper script (shows IPs + friend instructions)
./lab/host-chat.sh

Connecting

python3 cmd_chat.py connect SERVER_IP 3000 yourname --insecure

--insecure skips cert verification for self-signed certs.

Securing the Connection

Tailscale (recommended): Both install Tailscale. Use Tailscale IP (tailscale ip -4). Encrypted WireGuard tunnel, zero port forwarding, works across NATs.

python3 cmd_chat.py connect 100.x.x.x 3000 theirname --insecure

LAN: Use local IP. No port forwarding. Both devices must be on same network.

python3 cmd_chat.py connect 192.168.1.x 3000 theirname --insecure

Public internet: Requires router port forwarding (TCP 3000). Use real TLS certs via --cert/--key if exposing to internet.

Sharing the Password

Share out-of-band (never through the chat):

  1. In person — tell them verbally
  2. Signal — disappearing message (30s)
  3. One-time link — onetimesecret.com (self-destructs after one view)
  4. Split — half via Telegram, half via SMS

CLI Flags

Flag Server Client Purpose
--password, -p yes yes Room password (prompts if omitted)
--cert yes Custom TLS certificate path
--key yes Custom TLS private key path
--no-tls yes yes Disable TLS (dev/LAN only)
--insecure, -k yes Skip TLS cert verification

Chat Commands

Command Action
/send <filepath> Propose file transfer
/accept Accept pending file offer
/reject Decline pending file offer
q Disconnect

Test Plan

  • 79 existing tests pass
  • TLS auto-cert generation
  • SRP auth over HTTPS/WSS
  • Message encryption between 2 users
  • /clear requires admin Bearer token
  • Rate limiter returns 429 after threshold
  • File transfer: send → accept → SHA-256 verified
  • File transfer: send → reject → sender notified
  • Lab script runs end-to-end

leetcrypt and others added 5 commits May 25, 2026 20:30
…rate limiting, IP leak prevention

CRITICAL fixes:
- Auto-generated self-signed TLS certs (HTTPS/WSS by default)
- Removed session_key from /srp/verify response (was sent in plaintext)
- Replaced with HMAC-SHA256 ws_token for WebSocket authentication

HIGH fixes:
- WebSocket auth now validates ws_token via hmac.compare_digest()
- /clear endpoint requires Bearer admin_token (printed at server start)
- Password no longer required as CLI arg — supports env var + getpass prompt
- Removed user_ip from Message model (no longer broadcast to clients)

MEDIUM fixes:
- Rate limiter on /srp/init and /srp/verify (10 req/min/IP)
- MessageStore capped at 1000 messages (prevents RAM DoS)
- access_log disabled (was leaking request metadata)

LOW fixes:
- Username sanitization against rich markup injection
- Dead code removed from helpers.py

All 79 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ncoding

- lab/setup-lab.sh: automated tmux setup with server + 2 chat clients
  Supports --no-tls, --password, --port, --user1/--user2, --teardown
  Auto-installs missing pip dependencies, verifies port availability,
  waits for server health before connecting clients
- lab/README.md: usage docs and keyboard shortcuts
- requirements.txt: fixed UTF-16 encoding to UTF-8, cleaned pinned versions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tions

Detects all available IPs (Tailscale, LAN, public), prints connect
command for friends to copy, prompts for password securely via getpass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New commands: /send <filepath>, /accept, /reject

Protocol:
- Sender proposes file (name, size, SHA-256 hash)
- Recipient sees offer and chooses /accept or /reject
- On accept: file chunked (64KB), encrypted with room key, sent over WebSocket
- On receive: chunks reassembled, SHA-256 verified, saved to ./downloads/
- Server never sees file content (E2E encrypted, same as messages)

Limits: 50MB max file size. Files saved with collision-safe naming.
No server changes — server remains a dumb encrypted relay.

All 79 existing tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… guide

Clear, concise documentation covering installation, hosting, connection
security (Tailscale/LAN/public), password sharing, file transfer protocol,
CLI reference, helper scripts, and architecture overview.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant