# 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

