10 KiB
Security Audit Report
Date: 2025-10-31 Application: Media Downloader v6.3.3 Auditor: Claude Code Severity Levels: 🔴 Critical | 🟠 High | 🟡 Medium | 🟢 Low
Executive Summary
A comprehensive security audit was conducted on the Media Downloader application. 6 critical vulnerabilities were identified that require immediate attention. The application has good foundations (bcrypt, JWT, rate limiting) but lacks proper authentication enforcement and network security.
Risk Level: 🔴 CRITICAL
Critical Vulnerabilities (Immediate Action Required)
🔴 1. NO FIREWALL ENABLED
Severity: CRITICAL Impact: All services exposed to network
Finding:
$ sudo ufw status
Status: inactive
Exposed Services:
- Port 8000: FastAPI backend (0.0.0.0 - all interfaces)
- Port 5173: Vite dev server (0.0.0.0 - all interfaces)
- Port 3456: Node service (0.0.0.0 - all interfaces)
- Port 80: Nginx
Risk:
- Anyone on your network (192.168.1.0/24) can access these services
- If port-forwarded, services are exposed to the entire internet
- No protection against port scans or automated attacks
Fix (URGENT - 15 minutes):
# Enable firewall
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH (if remote)
sudo ufw allow 22/tcp
# Allow only nginx (reverse proxy)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Block direct access to backend ports
# (nginx should proxy to localhost:8000)
# Enable firewall
sudo ufw enable
🔴 2. 95% OF API ENDPOINTS ARE UNAUTHENTICATED
Severity: CRITICAL Impact: Anyone can access/modify your data
Finding:
- Total endpoints: 43
- Authenticated: 2 (4.6%)
- Public (no auth): 41 (95.4%)
Unauthenticated Endpoints Include:
/api/downloads- View ALL downloads/api/downloads/{id}- DELETE downloads/api/platforms/{platform}/trigger- Trigger downloads/api/scheduler/current-activity/stop- Stop downloads/api/scheduler/tasks/{task_id}/skip- Modify schedule/api/config- View/modify configuration/api/media/*- Access all media files
Risk:
- Anyone on your network can:
- View all your downloads
- Delete your files
- Trigger new downloads
- Stop running downloads
- Modify configuration
- Access your media library
Fix (HIGH PRIORITY - 2 hours):
Add Depends(get_current_user) to all sensitive endpoints:
# BEFORE (VULNERABLE)
@app.delete("/api/downloads/{download_id}")
async def delete_download(download_id: int):
# AFTER (SECURE)
@app.delete("/api/downloads/{download_id}")
async def delete_download(
download_id: int,
current_user: Dict = Depends(get_current_user) # ADD THIS
):
🔴 3. DATABASES ARE WORLD-READABLE
Severity: CRITICAL Impact: Sensitive data exposure
Finding:
-rw-r--r-- root root /opt/media-downloader/database/auth.db
-rw-r--r-- root root /opt/media-downloader/database/media_downloader.db
Risk:
- Any user on the system can read:
- Password hashes (auth.db)
- User sessions and tokens
- Download history
- All metadata
Fix (5 minutes):
# Restrict database permissions
sudo chmod 600 /opt/media-downloader/database/*.db
sudo chown root:root /opt/media-downloader/database/*.db
# Verify
ls -la /opt/media-downloader/database/*.db
# Should show: -rw------- root root
🔴 4. DEVELOPMENT SERVERS RUNNING IN PRODUCTION
Severity: HIGH Impact: Performance, stability, security
Finding:
- Vite dev server on port 5173 (should be built static files)
- Development mode has verbose errors, source maps, hot reload
- Not optimized for production
Risk:
- Exposes source code and stack traces
- Poor performance
- Memory leaks
- Not designed for production load
Fix (30 minutes):
# Build production frontend
cd /opt/media-downloader/web/frontend
npm run build
# Serve via nginx, not Vite dev server
# Update nginx config to serve dist/ folder
# Stop Vite dev server
sudo systemctl stop vite-dev-server # (if running as service)
🔴 5. NO RATE LIMITING ON API
Severity: HIGH Impact: Denial of Service, brute force attacks
Finding:
- No rate limiting middleware on FastAPI
- Login endpoint has application-level rate limiting (good)
- But other endpoints have no protection
Risk:
- API can be flooded with requests
- Download all your files via API spam
- Trigger hundreds of downloads simultaneously
- DDoS the service
Fix (2 hours): Install slowapi:
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
# Apply to routes
@app.get("/api/downloads")
@limiter.limit("10/minute") # 10 requests per minute
async def get_downloads(...):
🟠 6. MIXED COOKIE FILE PERMISSIONS
Severity: MEDIUM Impact: Session hijacking potential
Finding:
-rw-r--r-- 1 root root 1140 fastdl_cookies.json # World-readable
-rw------- 1 root root 902 forum_cookies.json # Secure
-rw-rw-r-- 1 root root 4084 toolzu_cookies.json # Group-writable
Risk:
- Other users/processes can steal cookies
- Session hijacking across platforms
Fix (2 minutes):
sudo chmod 600 /opt/media-downloader/cookies/*.json
sudo chown root:root /opt/media-downloader/cookies/*.json
Additional Security Concerns
🟡 7. CORS Configuration (Development Only)
Current:
allow_origins=["http://localhost:5173", "http://localhost:3000"]
Issue: If accessed via IP or domain name, CORS will block. Need production config.
Fix:
# Production
allow_origins=["https://yourdomain.com"]
# Or if same-origin (nginx proxy)
# No CORS needed
🟡 8. JWT Secret Key
Current:
SECRET_KEY = os.environ.get("JWT_SECRET_KEY", secrets.token_urlsafe(32))
Issue:
- Falls back to random key on each restart
- Invalidates all sessions on restart
- Not persisted
Fix:
# Generate and save secret
echo "JWT_SECRET_KEY=$(openssl rand -hex 32)" | sudo tee -a /etc/environment
# Restart services to pick up env var
sudo systemctl restart media-downloader-api
🟡 9. No HTTPS/TLS
Finding: Services run on HTTP only
Risk:
- Passwords transmitted in clear text
- Session tokens visible on network
- Man-in-the-middle attacks
Fix: Use Let's Encrypt with Certbot:
sudo certbot --nginx -d yourdomain.com
🟢 10. Log Files Growing Unbounded
Finding:
- service.log: 15MB
- web-api.log: 2.3MB
- No rotation configured
Risk: Disk space exhaustion
Fix: Already recommended in previous report (logrotate)
What's Secure (Good Practices Found)
✅ Password Hashing: Using bcrypt (industry standard) ✅ JWT Implementation: Using jose library correctly ✅ Login Rate Limiting: 5 attempts, 15 min lockout ✅ SQL Injection: No f-string queries, using parameterized queries ✅ Session Management: Proper session table with expiration ✅ CORS (Dev): Restricted to localhost during development
Recommended Action Plan
Phase 1: IMMEDIATE (Do NOW - 1 hour total)
Priority 1: Enable Firewall (15 min)
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
sudo ufw status
Priority 2: Fix Database Permissions (5 min)
sudo chmod 600 /opt/media-downloader/database/*.db
sudo chmod 600 /opt/media-downloader/cookies/*.json
Priority 3: Set JWT Secret (5 min)
openssl rand -hex 32 | sudo tee /opt/media-downloader/.jwt_secret
echo "JWT_SECRET_KEY=$(cat /opt/media-downloader/.jwt_secret)" | sudo tee -a /etc/environment
sudo chmod 600 /opt/media-downloader/.jwt_secret
sudo systemctl restart media-downloader-api
Phase 2: URGENT (Do Today - 2-3 hours)
Priority 4: Add Authentication to API Endpoints (2 hours)
Create a comprehensive list of endpoints that need auth:
- All DELETE operations
- All POST operations (except /api/auth/login)
- All configuration endpoints
- All download/media access endpoints
Priority 5: Add Rate Limiting (1 hour)
Install and configure slowapi on all endpoints.
Phase 3: IMPORTANT (Do This Week)
Priority 6: Production Frontend Build
- Stop Vite dev server
- Configure nginx to serve static build
- Remove development dependencies
Priority 7: HTTPS Setup
- Obtain SSL certificate
- Configure nginx for HTTPS
- Redirect HTTP to HTTPS
Priority 8: Network Segmentation
- Consider running services on localhost only
- Use nginx as reverse proxy
- Only expose nginx to network
Security Best Practices for Future
- Always require authentication - Default deny, explicitly allow
- Principle of least privilege - Restrict file permissions
- Defense in depth - Firewall + authentication + rate limiting
- Regular security audits - Review code and config quarterly
- Keep dependencies updated - Run
npm auditandpip audit - Monitor logs - Watch for suspicious activity
- Backup encryption keys - Store JWT secret securely
Testing Your Security
After implementing fixes, verify:
# 1. Firewall is active
sudo ufw status
# 2. Services not directly accessible
curl http://192.168.1.6:8000/api/downloads
# Should fail or require auth
# 3. File permissions correct
ls -la /opt/media-downloader/database/
# Should show -rw------- (600)
# 4. API requires auth
curl -H "Content-Type: application/json" \
http://localhost/api/downloads
# Should return 401 Unauthorized
Questions?
Review this document and implement Phase 1 (IMMEDIATE) fixes right away. The firewall and file permissions take less than 30 minutes total but dramatically improve security.
Current Risk Level: 🔴 CRITICAL After Phase 1: 🟠 HIGH After Phase 2: 🟡 MEDIUM After Phase 3: 🟢 LOW