security: harden web server, daemon socket, and write paths
Security review findings, fixed and verified: Critical - Fix unauthenticated arbitrary file read: the SPA catch-all route joined the raw URL path onto the dist dir without containment, so encoded '..' segments (/%2e%2e/etc/passwd) leaked any file readable by the root server. Resolve with realpath and reject paths outside the dist dir (fail-closed 404). High - Daemon socket: serve_start no longer accepts caller-chosen host/port. The socket is world-connectable (unprivileged CLI users), so callers could previously rebind the root web server to 0.0.0.0. The daemon now always binds the operator-configured address and reports it in the response; the CLI warns on mismatch. Medium - Remove the per-request max_delta_khz override from the API: the server-enforced safety cap is now authoritative. CLI direct paths (write, profile apply, verify) honor the configured cap; --max-delta still overrides for explicit root use. - Snapshot restore: confine filepath to the snapshot directory (realpath containment; blocks symlink escapes). - Login lockout: honor X-Forwarded-For only for peers listed in the new trusted_proxies config (rightmost untrusted hop), so the per-IP lockout works behind a reverse proxy. Spoofed headers from untrusted peers are ignored. - /api/shutdown: new allow_api_shutdown config (default true); shared systems can disable the API shutdown path. TLS (opt-in, like auth) - New ssl_certfile/ssl_keyfile config + CLI flags (serve start, service install/configure, --no-ssl to disable). When active: HTTPS for UI/API, wss:// for WebSockets, Secure session cookie, CLI auto-switches to https://. Cert/key paths are validated up front with a clear error instead of a silent uvicorn crash. Tests & docs - tests/test_security.py: standalone regression tests (no new deps) covering SPA containment, snapshot containment, cap removal, client-IP derivation, proxy normalization, TLS scheme detection, and daemon host/port hardening. - README + Usage-Guide: TLS section, new config keys, updated security notes.
This commit is contained in:
1 parent
8956fc9d7b
commit
39701c12ff
9 files changed
+648
-55
No files matched your search
@@ -78,6 +78,20 @@ sudo nvcurve user remove alice # remove a user
|
||||
|
||||
Adding the first user enables authentication immediately; removing the last user disables it. See the [Usage Guide](docs/Usage-Guide.md#authentication-multi-user) for details.
|
||||
|
||||
## TLS (HTTPS)
|
||||
|
||||
The server speaks **plain HTTP by default**. For network access (e.g. behind a reverse proxy or on a LAN), you can enable TLS so the web UI, API, and WebSocket all run over HTTPS — the session cookie is then marked `Secure`.
|
||||
|
||||
```bash
|
||||
# One-off (this server run only)
|
||||
nvcurve serve start --ssl-certfile /path/to/cert.pem --ssl-keyfile /path/to/key.pem
|
||||
|
||||
# Persistent (stored in /etc/nvcurve/config.json; used by the daemon too)
|
||||
sudo nvcurve service configure --ssl-certfile /path/to/cert.pem --ssl-keyfile /path/to/key.pem
|
||||
```
|
||||
|
||||
With TLS enabled the UI is at `https://<host>:8042` and the CLI switches to `https://` automatically. A self-signed certificate works for local use (the browser will warn); for multi-user setups use a certificate your browser trusts (e.g. via your internal CA or a reverse proxy).
|
||||
|
||||
## Systemd Service
|
||||
|
||||
Install the daemon for automatic profile loading on boot and optional web server auto-start:
|
||||
@@ -149,6 +163,10 @@ The daemon reads settings from `/etc/nvcurve/config.json`:
|
||||
"max_delta_khz": 3000000,
|
||||
"auto_snapshot": true,
|
||||
"max_snapshots": 20,
|
||||
"ssl_certfile": null,
|
||||
"ssl_keyfile": null,
|
||||
"trusted_proxies": [],
|
||||
"allow_api_shutdown": true,
|
||||
"auto_load_profiles": {
|
||||
"idx:0": "my_profile"
|
||||
}
|
||||
@@ -160,9 +178,12 @@ The daemon reads settings from `/etc/nvcurve/config.json`:
|
||||
| `host` | Web server bind address (`0.0.0.0` for network access) |
|
||||
| `port` | Web server port (default `8042`) |
|
||||
| `auto_serve` | Auto-start web server on boot |
|
||||
| `max_delta_khz` | Safety cap for frequency offsets (default 3000 MHz) |
|
||||
| `max_delta_khz` | Safety cap for frequency offsets (default 3000 MHz). Enforced server-side; API clients cannot raise it per request |
|
||||
| `auto_snapshot` | Save snapshot before every write |
|
||||
| `max_snapshots` | Max snapshots to keep (`0` = unlimited) |
|
||||
| `ssl_certfile` / `ssl_keyfile` | TLS certificate/key — enables HTTPS when both are set (default: off) |
|
||||
| `trusted_proxies` | Proxy IPs whose `X-Forwarded-For` is trusted for the login lockout (e.g. `["127.0.0.1"]` for a local reverse proxy) |
|
||||
| `allow_api_shutdown` | Allow authenticated users to stop the server via `POST /api/shutdown` (set `false` on shared systems; use systemd instead) |
|
||||
| `auto_load_profiles` | Per-GPU profile to apply on boot (`{gpu_key: profile_name}`) |
|
||||
|
||||
The GPU key can be a UUID, `pci:XXXX`, or `idx:N` fallback. Find your GPU key with `nvcurve gpus`.
|
||||
|
||||
Reference in new issue
Block a user