Live encrypted chat with zero JavaScript. https://x.securityops.co
  • HTML 75.7%
  • Python 23.1%
  • Dockerfile 1.2%
Find a file
2026-03-11 01:14:51 -03:00
screenshots The best chat. Ever. 2026-03-11 01:14:51 -03:00
.env The best chat. Ever. 2026-03-11 01:14:51 -03:00
base.html The best chat. Ever. 2026-03-11 01:14:51 -03:00
chat.html The best chat. Ever. 2026-03-11 01:14:51 -03:00
crypto.html The best chat. Ever. 2026-03-11 01:14:51 -03:00
docker-compose.yml The best chat. Ever. 2026-03-11 01:14:51 -03:00
Dockerfile The best chat. Ever. 2026-03-11 01:14:51 -03:00
LICENSE The best chat. Ever. 2026-03-11 01:14:51 -03:00
login.html The best chat. Ever. 2026-03-11 01:14:51 -03:00
main.py The best chat. Ever. 2026-03-11 01:14:51 -03:00
README.md The best chat. Ever. 2026-03-11 01:14:51 -03:00
rooms.html The best chat. Ever. 2026-03-11 01:14:51 -03:00

🔒 SecChat

Live encrypted chat with zero JavaScript.

FRONTEND

Crypto stack

STACK

Layer Algorithm Why
Messages ChaCha20-Poly1305 TLS 1.3, Signal, WireGuard — AEAD, timing-attack resistant
Key exchange X25519 ECDH + HKDF-SHA256 Curve25519, used in Signal Protocol
Passwords Argon2id (64MB, t=3) PHC winner, GPU/ASIC resistant
Sessions HttpOnly + SameSite=Strict No JS access, CSRF-safe
Live updates <meta http-equiv="refresh"> Zero JS — page polls every 5s

CHAT

Deploy

# 1. Clone / copy project
# Edit .env — generate secret:
python3 -c "import secrets; print('SERVER_SECRET=' + secrets.token_hex(32))" > .env

# 2. Run
docker compose up -d --build

# App running at: http://yourip:8100

Nginx Proxy Manager (NPM) config

Point your domain to port 8100.

Add to Advanced:

# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'none'; connect-src 'none';" always;

# Rate limit (protect login endpoint)
limit_req_zone $binary_remote_addr zone=secchat:10m rate=20r/m;
limit_req zone=secchat burst=10 nodelay;

Architecture

Browser (pure HTML forms)
    │  POST /chat/{room}/send
    │  GET  /chat/{room}  ← meta refresh every 5s
    ▼
FastAPI (Python 3.11)
    ├── Argon2id: password verify
    ├── X25519 ECDH: room key derivation
    ├── ChaCha20-Poly1305: encrypt/decrypt each message
    └── SSE: /chat/{room}/stream (optional, for JS clients)

Notes

  • In-memory storage - restart clears all messages and users.
    For persistence: add SQLite with aiosqlite (swap rooms dict for DB calls).
  • secure=True on session cookie requires HTTPS - set this in main.py when behind NPM.
  • SSE endpoint /chat/{room}/stream is available for future JS-optional progressive enhancement.