ARIA 39701c12ff 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.
2026-09-10 16:19:21 +02:00

NVCurve Logo

NVCurve

Linux NVIDIA GPU V/F Curve Editor & OC Tool


NVCurve brings MSI Afterburner-style per-point voltage-frequency curve control to Linux via undocumented NvAPI functions. A React web UI for interactive editing and monitoring; a Python CLI for scripting and headless use.

Warning

Experimental software. Undocumented NvAPI functions may change between driver releases. Write operations alter GPU operational parameters. Always run nvcurve setup before applying changes.

Important

Blackwell GPU memory — This is a specialized fork with extended memory offset support (up to +3000 MHz) for Blackwell GPUs (RTX 50-series).
Fan Controls — There is an additional "Fans" tab to setup a customized fan curve, controlling all fans or individual fans.
Dashboard — The default tab is an Dashboard with additional information (PCIe link speed, VBIOS information, Max Core Clock, Throttle Reason and much much more.)
Authentification — For production deplyoment, I added authentification with bcrypt hashing to allow only one or multiple people to have access.
Installing the pre-built PyPI package will NOT include these features. You must build from source.

Dashboard Curve Editor
Performance Fans

Prerequisites

  • Linux with NVIDIA proprietary drivers
  • Python 3.12+
  • Node.js 18+ and npm (for building the React frontend)
  • uv — Python package manager
  • Root/sudo access (required for GPU hardware interactions)

Installation from Source

git clone <this-repo-url>.git
cd nvcurve

# Build the React frontend
cd frontend
npm install
npm run build
cd ..

# Install the Python package (includes bundled frontend)
uv tool install .

After installation, verify hardware compatibility:

nvcurve setup

Getting Started

nvcurve          # Launch web UI at http://localhost:8042
nvcurve read     # Quick curve read from CLI

Authentication (Multi-User)

The server runs open by default. On a shared machine (e.g. an AI server), add users to require a login — the web UI then shows a sign-in screen and every API/WebSocket call is protected. Passwords are stored as bcrypt hashes; sessions last 24 hours.

sudo nvcurve user add alice      # add a user (prompts for password)
nvcurve user list                # list users
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 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.

# 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:

Install with web server auto-start

nvcurve service install --auto-serve --host 0.0.0.0 --port 8042

Install daemon only (start web server on demand)

nvcurve service install

Manage

nvcurve service start|stop|restart|status
nvcurve service uninstall

Reconfigure

nvcurve service configure --auto-serve      # Enable web server auto-start
nvcurve service configure --no-auto-serve   # Disable web server auto-start
nvcurve service configure --host 0.0.0.0 --port 8042

Manual systemd Unit

If you prefer managing the unit file directly, here is the template installed by nvcurve service install:

[Unit]
Description=NVCurve NVIDIA GPU V/F Curve Daemon
After=nvidia-persistenced.service
Wants=nvidia-persistenced.service

[Service]
Type=simple
ExecStart=/usr/bin/python3 -m nvcurve daemon
Restart=on-failure
RestartSec=5
Environment=PYTHONDONTWRITEBYTECODE=1

[Install]
WantedBy=multi-user.target

Place at /etc/systemd/system/nvcurve.service, then:

sudo systemctl daemon-reload
sudo systemctl enable --now nvcurve

Persistent Configuration

The daemon reads settings from /etc/nvcurve/config.json:

{
  "host": "127.0.0.1",
  "port": 8042,
  "auto_serve": false,
  "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"
  }
}
Setting Description
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). 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.

Documentation

Upgrading

cd nvcurve
git pull
cd frontend && npm run build && cd ..
uv tool install .

If running as a systemd service:

nvcurve service restart

Changelog

See CHANGELOG.md.

S
Description
Linux NVIDIA GPU V/F Curve Editor
Readme MIT
1.7 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 65.9%
TypeScript 33.2%
Shell 0.4%
CSS 0.2%
Makefile 0.1%
Other 0.1%