Security review for production deployment on a shared AI server. All findings fixed and covered by regression tests.
Critical
Unauthenticated arbitrary file read: the SPA catch-all joined the raw URL path onto the dist dir without containment — GET /%2e%2e/.../etc/passwd leaked any file readable by the root server. Now realpath-contained, fail-closed 404.
High
Daemon socket: serve_start no longer accepts caller-chosen host/port (socket is world-connectable; callers could rebind the root server to 0.0.0.0). Daemon always binds the configured address; CLI warns on mismatch.
Medium
Removed per-request max_delta_khz API override — the server-enforced safety cap is authoritative. CLI direct paths (write, profile apply, verify) honor the configured cap; --max-delta still overrides for explicit root use.
Snapshot restore confined to the snapshot dir (realpath, blocks symlink escapes).
New trusted_proxies config: X-Forwarded-For honored only for listed peers (rightmost untrusted hop), so the login lockout works behind a reverse proxy; spoofed headers ignored.
New allow_api_shutdown config (default true) to disable POST /api/shutdown on shared systems.
TLS (opt-in, like auth)
ssl_certfile/ssl_keyfile config + CLI flags (serve start, service install/configure, --no-ssl). When active: HTTPS UI/API, wss:// WebSockets, Secure session cookie, CLI auto-https. Cert/key validated up front.
Tests & docs
tests/test_security.py: standalone regression tests (no new deps) — 26/26 passing.
Behavior changes: API clients sending max_delta_khz are silently ignored; snapshot restore --file is confined to the snapshot dir on the root CLI path too.
Security review for production deployment on a shared AI server. All findings fixed and covered by regression tests.
**Critical**
- Unauthenticated arbitrary file read: the SPA catch-all joined the raw URL path onto the dist dir without containment — `GET /%2e%2e/.../etc/passwd` leaked any file readable by the root server. Now realpath-contained, fail-closed 404.
**High**
- Daemon socket: `serve_start` no longer accepts caller-chosen host/port (socket is world-connectable; callers could rebind the root server to 0.0.0.0). Daemon always binds the configured address; CLI warns on mismatch.
**Medium**
- Removed per-request `max_delta_khz` API override — the server-enforced safety cap is authoritative. CLI direct paths (write, profile apply, verify) honor the configured cap; `--max-delta` still overrides for explicit root use.
- Snapshot restore confined to the snapshot dir (realpath, blocks symlink escapes).
- New `trusted_proxies` config: `X-Forwarded-For` honored only for listed peers (rightmost untrusted hop), so the login lockout works behind a reverse proxy; spoofed headers ignored.
- New `allow_api_shutdown` config (default true) to disable `POST /api/shutdown` on shared systems.
**TLS (opt-in, like auth)**
- `ssl_certfile`/`ssl_keyfile` config + CLI flags (`serve start`, `service install/configure`, `--no-ssl`). When active: HTTPS UI/API, `wss://` WebSockets, `Secure` session cookie, CLI auto-https. Cert/key validated up front.
**Tests & docs**
- `tests/test_security.py`: standalone regression tests (no new deps) — 26/26 passing.
- README + Usage-Guide: TLS section, new config keys, updated security notes.
Behavior changes: API clients sending `max_delta_khz` are silently ignored; `snapshot restore --file` is confined to the snapshot dir on the root CLI path too.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Security review for production deployment on a shared AI server. All findings fixed and covered by regression tests.
Critical
GET /%2e%2e/.../etc/passwdleaked any file readable by the root server. Now realpath-contained, fail-closed 404.High
serve_startno longer accepts caller-chosen host/port (socket is world-connectable; callers could rebind the root server to 0.0.0.0). Daemon always binds the configured address; CLI warns on mismatch.Medium
max_delta_khzAPI override — the server-enforced safety cap is authoritative. CLI direct paths (write, profile apply, verify) honor the configured cap;--max-deltastill overrides for explicit root use.trusted_proxiesconfig:X-Forwarded-Forhonored only for listed peers (rightmost untrusted hop), so the login lockout works behind a reverse proxy; spoofed headers ignored.allow_api_shutdownconfig (default true) to disablePOST /api/shutdownon shared systems.TLS (opt-in, like auth)
ssl_certfile/ssl_keyfileconfig + CLI flags (serve start,service install/configure,--no-ssl). When active: HTTPS UI/API,wss://WebSockets,Securesession cookie, CLI auto-https. Cert/key validated up front.Tests & docs
tests/test_security.py: standalone regression tests (no new deps) — 26/26 passing.Behavior changes: API clients sending
max_delta_khzare silently ignored;snapshot restore --fileis confined to the snapshot dir on the root CLI path too.✅ No issues found — changes look consistent with the stated intent. Ready to be merged.