7.8 KiB
Security Audit Command
Perform a comprehensive security audit of the FromChat application codebase.
Project Context
FromChat is a 100% open source secure messaging application with:
- React/TypeScript frontend
- Python FastAPI backend
- End-to-end encryption for DMs and calls
- Caddy reverse proxy with security headers
- WebSocket support for real-time features
- Electron support for desktop app
Important Design Decisions (NOT Vulnerabilities)
When auditing, remember these are intentional design choices:
-
Public messages endpoint - Open forum accessible without authentication (by design)
- The public chat is meant to be an open forum
- Private DMs are properly E2E encrypted and require authentication
-
Public user list - All users visible in DMs tab (by design)
- Users can see all registered accounts
- This is intentional for a community-based chat app
-
XSS protection - Multi-layer defense already implemented:
- React auto-escaping
- DOMPurify for sanitization
- Caddy CSP headers
- Do NOT flag localStorage key storage as critical (already well-protected)
-
File upload security - Docker isolation in place:
- Server runs in Docker without executable flags
- Files cannot execute on server
- PIL re-encodes images
- Do NOT flag Content-Type validation as critical
-
CSRF protection - Not needed:
- No cookies used
- JWT tokens in Authorization headers only
- CSRF attacks don't apply to this auth model
-
Beta domain CSP - 'unsafe-inline' is required:
- Beta domain (beta.fromchat.ru) points to development machine
- Vite dev server requires 'unsafe-inline' to function
- Production domain has strict CSP
-
Security logging - Already implemented:
- All events are logged including security-related activity
- Do NOT flag as missing
-
100% Open Source - This is a security strength:
- Full transparency
- Community review capability
- No hidden backdoors
Android App
EXCLUDE from all audits - Android app is not production-ready and out of scope.
Infrastructure (Caddy)
The application runs behind Caddy reverse proxy with comprehensive security controls:
Caddyfile Configuration
fromchat.ru {
reverse_proxy 172.18.0.1:8301 host.docker.internal:8301 172.17.0.1:8301 {
lb_policy first
}
# Security headers
header {
X-XSS-Protection "1; mode=block" # Prevent XSS attacks
X-Content-Type-Options "nosniff" # Prevent MIME type sniffing
X-Frame-Options "DENY" # Prevent clickjacking
Referrer-Policy "strict-origin-when-cross-origin"
Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https: blob:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none';"
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Permissions-Policy "geolocation=(), microphone=(self), camera=(self)"
}
rate_limit {
zone global {
key {remote_ip}
window 1m
burst 20
events 500
}
}
handle_errors {
@errors {
expression {err.status_code} >= 400
}
handle @errors {
rewrite * /{err.status_code}
reverse_proxy https://http.cat {
header_up Host {upstream_hostport}
replace_status {err.status_code}
}
}
}
}
beta.fromchat.ru {
reverse_proxy 95.165.0.162:8301
# Security headers
header {
X-XSS-Protection "1; mode=block" # Prevent XSS attacks
X-Content-Type-Options "nosniff" # Prevent MIME type sniffing
X-Frame-Options "DENY" # Prevent clickjacking
Referrer-Policy "strict-origin-when-cross-origin"
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https: blob:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none';"
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Permissions-Policy "geolocation=(), microphone=(self), camera=(self)"
}
rate_limit {
zone global {
key {remote_ip}
window 1m
burst 20
events 1000
}
}
handle_errors {
@errors {
expression {err.status_code} >= 400
}
handle @errors {
rewrite * /{err.status_code}
reverse_proxy https://http.cat {
header_up Host {upstream_hostport}
replace_status {err.status_code}
}
}
}
}
Key Infrastructure Protections
- ✅ HTTPS enforcement - Automatic SSL/TLS with Caddy
- ✅ HSTS - Strict-Transport-Security with preload
- ✅ CSP - Content Security Policy (strict on production, 'unsafe-inline' for scripts on beta for Vite)
- ✅ Rate limiting - 500 events/min (production), 1000 events/min (beta)
- ✅ X-Frame-Options: DENY - Prevents clickjacking
- ✅ X-Content-Type-Options: nosniff - Prevents MIME sniffing
- ✅ X-XSS-Protection: 1; mode=block - XSS protection
- ✅ Permissions-Policy - Restricts geolocation, allows camera/mic for calls
Important: These protections are already in place at the infrastructure level. Don't flag missing security headers or rate limiting in the application code.
Audit Process
- Read the Caddyfile first to understand infrastructure protections
- Check backend code for authentication, authorization, input validation
- Review frontend code for XSS protections, crypto implementation
- Verify E2E encryption implementation (NaCl for DMs, AES-GCM for calls)
- Test CORS configuration in backend/app.py
- Review password policies in backend/validation.py
- Check file upload handling in backend/routes/messaging.py and profile.py
Rating Guidelines
- Infrastructure (Caddy): Should be 9/10 or higher (excellent security headers)
- Cryptography: Should be 8-9/10 (uses industry-standard libraries)
- Frontend Security: Should be 7-8/10 (multi-layer XSS protection)
- Backend API: Focus on CORS, password policies, rate limiting
Output Format
Provide a clean, concise report with:
- Executive Summary - Overall rating and production readiness
- Security Status - Critical issues (if any) and recommendations
- Security Strengths - What's done well
- Component Ratings - Table format for quick reference
- Design Decisions - Clarify what's intentional vs vulnerable
- Threat Analysis - Current realistic threats only
- Recommendations - Prioritized with time estimates
- Conclusion - Clear production readiness statement
Keep it under 500 lines - focus on actionable findings, not verbose explanations.
Common False Positives to Avoid
❌ DO NOT FLAG THESE AS ISSUES:
- Public messages endpoint (intentional)
- Username enumeration (users list is public by design)
- Keys in localStorage (XSS is well-protected)
- Content-Type validation (Docker isolation prevents execution)
- CSRF protection (not applicable - no cookies)
- Beta CSP 'unsafe-inline' (required for Vite)
- Security logging (already implemented)
- Android app security (out of scope)
Key Security Features to Verify
✅ MUST CHECK:
- CORS configuration in backend/app.py
- Password validation in backend/validation.py
- JWT token generation and validation
- E2E encryption implementation (NaCl, AES-GCM)
- File upload sanitization
- Authorization checks on sensitive endpoints
- Rate limiting configuration
- Security headers in Caddyfile
Example Good Finding Format
### Password Policy (HIGH PRIORITY - Non-blocking)
**Current:** 5 character minimum
**Recommended:** 12+ characters with complexity requirements
**Risk:** Brute force attacks (mitigated by rate limiting)
**Estimated Fix:** 4-6 hours
**Code Location:** backend/validation.py:11-16
Notes from Developer
- Application is production-ready after CORS fix
- Focus on practical, actionable improvements
- Don't overthink things that are already well-protected
- Open source is a feature, not a concern
- Community can audit the code themselves