# 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:** ```bash $ 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):** ```bash # 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: ```python # 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:** ```bash -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):** ```bash # 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):** ```bash # 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: ```python 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:** ```bash -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):** ```bash 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:** ```python allow_origins=["http://localhost:5173", "http://localhost:3000"] ``` **Issue:** If accessed via IP or domain name, CORS will block. Need production config. **Fix:** ```python # Production allow_origins=["https://yourdomain.com"] # Or if same-origin (nginx proxy) # No CORS needed ``` --- ### 🟡 8. JWT Secret Key **Current:** ```python 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:** ```bash # 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: ```bash 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) ```bash 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) ```bash sudo chmod 600 /opt/media-downloader/database/*.db sudo chmod 600 /opt/media-downloader/cookies/*.json ``` **Priority 3:** Set JWT Secret (5 min) ```bash 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 1. **Always require authentication** - Default deny, explicitly allow 2. **Principle of least privilege** - Restrict file permissions 3. **Defense in depth** - Firewall + authentication + rate limiting 4. **Regular security audits** - Review code and config quarterly 5. **Keep dependencies updated** - Run `npm audit` and `pip audit` 6. **Monitor logs** - Watch for suspicious activity 7. **Backup encryption keys** - Store JWT secret securely --- ## Testing Your Security After implementing fixes, verify: ```bash # 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