Trusted:
- End-user devices (sender/receiver)
- TLS/HTTPS transport layer
- Operating system crypto libraries
Untrusted:
- Relay server operator (honest-but-curious model)
- Network infrastructure (assume monitoring)
- Third-party observers
User Responsibility:
- Endpoint security (malware prevention)
- Password strength (if using password protection)
- QR code privacy (prevent shoulder surfing)
Algorithm: AES-256-GCM
Key Derivation: HKDF-SHA256
Token Generation: Cryptographically secure random (256-bit)
Encryption Flow:
-
Key Generation (Client-side)
- Master key: 32 random bytes (256-bit)
- Never transmitted to server
- Sent in URL fragment only (client-to-client)
-
Key Derivation (HKDF)
Master Key (32 bytes) ├─ HKDF-SHA256 → File Encryption Key (32 bytes) ├─ HKDF-SHA256 → Metadata Encryption Key (32 bytes) ├─ HKDF-SHA256 → File Nonce Prefix (4 bytes) └─ HKDF-SHA256 → Metadata Nonce Prefix (4 bytes) -
Nonce Construction
- Nonce = Prefix (4 bytes) + Counter (8 bytes) = 12 bytes
- Unique per chunk (counter increments)
- Prevents nonce reuse
-
Chunk Encryption
- File split into 64KB chunks
- Each encrypted independently with unique nonce
- GCM provides authentication (AEAD)
-
Metadata Encryption
- Filename, size, checksum encrypted separately
- Server never sees plaintext metadata
Security Properties:
- Confidentiality: AES-256 encryption
- Integrity: GCM authentication tags
- Forward Secrecy: Per-session keys
- Server Blindness: Server sees only ciphertext
Purpose: Additional security layer for sensitive transfers
Algorithm: Argon2id (memory-hard, side-channel resistant)
Flow:
-
Sender Side:
- User provides password via
--passwordflag - Argon2id derives password key (32 bytes)
- Master key encrypted with password key (AES-256-GCM)
- Encrypted master key transmitted to receiver
- Password never transmitted
- User provides password via
-
Receiver Side:
- Prompts for password
- Derives same password key using Argon2id
- Decrypts master key
- Proceeds with normal E2E decryption
Argon2id Parameters:
- Time cost: 3 iterations
- Memory: 64MB
- Parallelism: 4 threads
- Salt: 16 random bytes (unique per transfer)
Security Properties:
- Brute-force Resistant: Memory-hard function
- Side-channel Resistant: Data-independent execution
- Zero-knowledge: Server never sees password
Threats:
- Weak Passwords: User responsibility
- Password Reuse: No enforcement mechanism
Strength: 256-bit cryptographically secure random
Encoding: Base64url (URL-safe)
Lifetime: 5 minutes default (configurable)
Usage: Single-use (invalidated after transfer)
Generation:
token := make([]byte, 32) // 256 bits
rand.Read(token) // crypto/rand
encoded := base64.URLEncoding.EncodeToString(token)Properties:
- Unpredictable: Cryptographic RNG
- High Entropy: 2^256 possible values
- Single-use: Prevents replay attacks
- Time-limited: Auto-expiry prevents stale sessions
- Creation: Client requests session → server generates token
- Active: Both parties connect via WebSocket
- Transfer: Encrypted data streams through server
- Completion: Session destroyed immediately
- Expiry: Automatic cleanup after TTL (5 min default)
Cleanup:
- Background task runs every 30 seconds
- Removes expired sessions
- Frees memory
- Prevents session exhaustion attacks
Minimum: TLS 1.2
Recommended: TLS 1.3
Cipher Suites: Modern, forward-secret ciphers only
Production Deployment:
- Reverse proxy handles TLS termination (nginx/Traefik/Caddy)
- Automatic certificate renewal (Let's Encrypt)
- HSTS headers recommended
- Server behind reverse proxy (HTTP → HTTPS upgrade)
Development:
--insecureflag allows HTTP (testing only)- Warning displayed to user
- Never use in production
Implementation: Token bucket algorithm
Default: 10 requests/second per IP, burst 20
Scope: Per-IP enforcement via X-Forwarded-For header
Protected Endpoints:
POST /api/sessions(session creation)GET /download/:token(download page)GET /upload/:token(upload page)
Prevents:
- Brute-force token guessing
- Session exhaustion attacks
- Resource exhaustion
Mechanism: Origin header validation + CSRF tokens
Implementation:
- Server validates
Originheader on state-changing requests - CSRF tokens embedded in forms
- Double-submit cookie pattern
- SameSite cookie attribute
Protected Endpoints:
POST /api/sessions- File upload endpoint
Filename Sanitization:
// Remove path traversal attempts
filename = filepath.Base(filename)
// Remove null bytes
filename = strings.ReplaceAll(filename, "\x00", "")
// Limit length
if len(filename) > 255 {
filename = filename[:255]
}
// Block dangerous patterns
if strings.Contains(filename, "..") {
return error
}Prevents:
- Path traversal attacks
- Directory escape
- Null byte injection
Default: 200MB
Server-configurable: XFER_MAX_SIZE environment variable
Enforcement: Both client and server sides
Prevents:
- Memory exhaustion
- Disk space attacks
- DoS via large files
Checksum Verification:
- SHA-256 hash calculated client-side
- Transmitted with encrypted metadata
- Automatically verified on receive
- Mismatch triggers error
Prevents:
- File corruption
- Tampering (within E2E scope)
- Incomplete transfers
Mechanism: file_end -> file_committed -> file_received_ack -> file_acknowledged
Flow:
- Uploader sends
file_endwith expected relayed bytes/chunks for that file - Relay validates observed relayed totals before emitting
file_committed - Receiver finalizes checksum and sends
file_received_ack - Relay confirms back to uploader with
file_acknowledged
Prevents:
- Random completion races on large transfers
- Premature close signaling before final chunk drain
- False-positive success when receiver has not finalized file integrity
Mechanism: Browser uploader enters a locked state after transfer start.
Flow:
Add more files,Clear all, file picker, and drag-drop mutations are blocked while upload is active- File list can be edited again only if transfer fails and uploader returns to retry state
Prevents:
- Mid-transfer client-side file list mutation that can desync user intent from transmitted stream
- Confusing partial-selection state transitions during active encrypted relay
Mechanism: Release workflow runs vulnerability scanning on Dockerfile base images.
Policy:
- Scanner: Trivy
- Scope: base images used by Dockerfile build/runtime stages
- Threshold: fail release on HIGH or CRITICAL findings
Prevents:
- Publishing release images with known severe base-image vulnerabilities
- Regressions where
latestand version tags carry avoidable CVE exposure
Mechanism: Browser download page queues all incoming WebSocket messages and processes them sequentially.
Problem Solved:
- WebSocket onmessage handlers in JavaScript are non-blocking for async functions
- Multiple chunks arriving rapidly would each start async decryption in parallel
- The "complete" or "close" event could fire before all decryptions finished
- This caused false "Transfer incomplete" errors on large files (e.g., 69MB of 70MB)
Flow:
- All incoming messages (binary chunks, metadata, complete, close) are queued
- A single processor works through the queue sequentially
- File completion only triggers after all queued chunks are processed
- Error/finalize states only set after queue is empty
Prevents:
- Race conditions between async chunk decryption and connection close
- False incomplete transfer errors on fast transfers
- Lost data when processing lags behind network receive speed
Mechanism: Browser sends download_ack only after all files are finalized locally; relay waits for it before session close.
Flow:
- Relay forwards all encrypted data and
completeto browser receiver - Browser decrypts/finalizes and then emits
download_ack - Relay waits up to 45 seconds for ack before marking session complete
- Missing/invalid/timeout ack marks session failed (strict mode)
Prevents:
- Premature WebSocket close before browser-side finalization under real network latency
- False-positive transfer success when browser has not fully processed payload
- Silent truncation at tail-end of large downloads
Mechanism: Sender success is gated on relay terminal status, and binary frame writes use a longer deadline than control frames.
Flow:
- CLI sender streams encrypted chunks and sends
complete - CLI sender then waits for relay terminal status (
completeorfailed) - Relay returns
completeonly after browserdownload_ack; otherwise returnsfailedwith reason - Sender binary writes tolerate slow receiver backpressure better via extended binary write deadline
Prevents:
- False sender-side success when receiver has not actually finalized transfer
- Spurious sender disconnects on large transfers when downstream drain is temporarily slow
- Ambiguous abnormal-closure outcomes without an explicit terminal state
| Vulnerability | Mitigation | Status |
|---|---|---|
| Man-in-the-Middle | TLS + E2E encryption | Protected |
| Server Data Access | Mandatory E2E encryption | Protected |
| Session Hijacking | 256-bit tokens, single-use | Protected |
| Replay Attacks | Nonces, session expiry | Protected |
| Brute Force | Rate limiting, strong tokens | Protected |
| Path Traversal | Filename sanitization | Protected |
| CSRF | Origin validation, tokens | Protected |
| File Tampering | SHA-256 checksums | Protected |
| DoS (File Size) | 200MB limit | Protected |
| DoS (Rate) | Token bucket limiting | Protected |
| Threat | Risk Level | Mitigation |
|---|---|---|
| Endpoint Compromise | High | User responsibility, no technical fix |
| Weak Passwords | Medium | User education, no enforcement |
| Shoulder Surfing | Medium | QR hide/reveal feature |
| Server DoS | Medium | Reverse proxy rate limiting |
| Browser password support | Low | CLI-only password protection until browser KDF added |
| Quantum Attacks | Low | AES-256 is quantum-resistant (Grover's) |
- User Authentication - By design, sessionless
- Long-term Storage - Files never stored, temporary relay only
- Transfer History Sync - Local only, privacy-first
- Virus Scanning - Optional hook available, not built-in
Server Never Sees:
- File contents (encrypted)
- Filenames (encrypted metadata)
- Crypto keys (URL fragment, client-only)
- Passwords (used locally only)
Server Sees:
- Session tokens (necessary for routing)
- File sizes (encrypted payload size)
- IP addresses (necessary for networking)
- Timestamps (session management)
If Enabled:
- Session creation/completion events
- Security events (rate limit hits, invalid tokens)
- No file contents or metadata
- Privacy-preserving (no PII beyond IP)
Use Case: Compliance, abuse detection
- No Hardcoded Secrets - All config via env/file
- Secure Defaults - Encryption mandatory, secure timeouts
- Input Validation - All user input sanitized
- Error Handling - No sensitive data in errors
- Dependency Management - Minimal deps, reviewed
- Standard Libraries - Go crypto/* packages
- No Custom Crypto - Proven algorithms only
- Secure RNG - crypto/rand, never math/rand
- Key Management - Ephemeral keys, proper derivation
- Unit Tests - Core crypto and protocol
- Integration Tests - Full transfer flows
- Security Tests - CSRF, rate limiting, path traversal
- Fuzzing - Input validation (planned)
Rate Limit Exceeded:
- Log event
- Return HTTP 429
- Temporary IP block (if repeated)
Invalid Token:
- Log event
- Return HTTP 404 (prevent enumeration)
- No sensitive information leaked
Session Expired:
- Clean up resources
- Return clear error to client
- User retries with new session
Process:
- Report to security@thecodefreak.in
- Acknowledge within 24 hours
- Fix critical issues within 7 days
- Coordinated disclosure after fix
Scope:
- Server vulnerabilities
- Protocol weaknesses
- Crypto implementation flaws
- DoS vectors
- Data Minimization - Only necessary data processed
- Purpose Limitation - Data used only for transfer
- Storage Limitation - No permanent storage
- User Control - Opt-out of history
- Right to Deletion -
xfer history clear
Note: Self-hosted deployment gives full data control
- OWASP Top 10 - Addressed common vulnerabilities
- CWE/SANS Top 25 - Mitigated critical weaknesses
- NIST Guidelines - Follows crypto recommendations
Recommended:
- Run as non-root user
- Minimal container image (distroless)
- Read-only filesystem where possible
- No shell in production container
- Resource limits (memory, CPU)
- Network segmentation
Monitoring:
- Health check endpoint
- Metrics export (Prometheus compatible)
- Log aggregation (JSON structured logs)
- Alert on unusual patterns
No Data to Backup:
- Stateless design
- No persistent storage
- Sessions in-memory only
- Configuration via environment
Disaster Recovery:
- Redeploy server
- No data loss (nothing stored)
- Users retry failed transfers
- Mandatory E2E encryption
- Optional password protection
- 256-bit session tokens
- Rate limiting
- CSRF protection
- Checksum verification
- Input sanitization
- Security audit (third-party)
- Penetration testing
- Bug bounty program
- Security.txt file
- CVE monitoring automation
- Multi-factor authentication (for future account features)
- Hardware security key support
- Transfer expiry (auto-delete after download)
- IP allowlist/blocklist
Xfer prioritizes security through:
- Mandatory encryption - No plaintext option
- Zero-knowledge server - Cannot access file contents
- Defense in depth - Multiple layers of protection
- Privacy by design - Minimal data collection
- Secure defaults - Safe out-of-the-box configuration
Trust Model: "Don't trust the server, don't trust the network, trust the crypto."