docs: BUG-25 security hardening + Phase 9.5 notes

This commit is contained in:
Mathieu Moran
2026-08-15 18:29:35 -04:00
parent 24250e06df
commit 7a9be9d63f
2 changed files with 47 additions and 0 deletions
+21
View File
@@ -411,6 +411,27 @@ confirmed matching row counts on the server via direct psql query, live upload s
Exposed externally at `https://yaris.ceaf.dev` via the user's Cloudflare Tunnel (public hostname
added in the Cloudflare dashboard, pointing at `192.168.10.10:8098`).
### Phase 9.5: Remote-portal security hardening — ✅ DONE (2026-08-15)
Security review of the internet-exposed `https://yaris.ceaf.dev` portal (BUG-25) surfaced three
issues, all fixed in `24250e0`:
1. **Path traversal → arbitrary file write** in `POST /api/v1/dashcam/upload/chunk`: the `sha256`
form field was joined into the chunk staging path with no validation, so a crafted digest
(`../../...`) could escape `DASHCAM_STORAGE_DIR` and write files anywhere inside the container
as root (device-auth required, but the device key lives on the Pi). `sha256` is now validated
as a strict 64-char hex digest on the single-shot, chunk-status, and chunk-upload endpoints.
2. **No login rate limiting** — added an in-memory failed-attempt limiter (8 failures / 15 min
per `CF-Connecting-IP` + per-username, returns 429). Single gunicorn worker makes process-local
state sufficient.
3. **Session cookies** — now `HttpOnly` + `SameSite=Lax` + `Secure` (Secure can be disabled via
`COOKIE_SECURE=0` for plain-HTTP LAN login; documented in `server/.env.example`).
**Remaining exposure (not code):** the Pi's own web app (192.168.50.220:5000) is unauthenticated
and binds all interfaces. It is *not* reachable through the Cloudflare Tunnel, but a compromised
server container could reach it if the 192.168.10.x (Unraid) and 192.168.50.x (home) subnets route
to each other — isolate those VLANs and/or enable Cloudflare Bot Fight Mode + the free 1
rate-limiting rule on `/login`.
### Phase 10: Dashcam upload memory/size fixes — ✅ DONE, verified on real hardware
Two real-hardware-only bugs surfaced once actual ~300MB+ video files (not small test fixtures) hit
the upload path for the first time: