v0.6.1 — Security release
Security release. Upgrading is recommended for all deployments.
Several endpoints were missing authorization checks, several request fields that reach shell commands on managed hosts were unvalidated, and several defaults were permissive. This release fixes all of them.
No API or database schema changes — but some deployments need configuration changes. See Action required below.
A GitHub Security Advisory with full detail will follow shortly.
Authorization
Endpoints that were reachable by any authenticated user — including a viewer — now require an appropriate role:
GET /servers/:id/auto-update— executes a shell script on the managed host over SSHPOST /ssh-keys/test-server/:id— an online SSH credential testGET /ssh-keys— host key listingGET /servers/:id/alert-channels— notification configuration- All six SSL mutations (
scan, per-domain scan, create, update, delete, restore)
Global vault unlock and lock now require admin-level vault permissions. They were gated on the server-update permission, which an editor holds, despite being documented as admin-only. Persisting the vault passphrase to .env requires a separate permission and is now recorded in the audit log.
Input validation
Request fields interpolated into shell commands are now strictly validated and shell-escaped:
- ATOP time windows are pinned to
HH:MM[:SS], enforced in the shared schema and re-checked at the point of interpolation - OS user shells, home directories and group names are validated and escaped
- Sudoers command entries are allowlisted to absolute command paths with plain arguments
- Sudoers rules are written from a base64 payload via
mktempandinstall(1)instead of anechoredirect, removing both shell expansion and a predictable-filename race
Two related bugs fixed along the way: install -o root -g root replaces mv + chmod, which previously left sudoers.d files owned by the SSH user — files sudo silently ignores. And a custom sudo grant with an empty command list used to fall back to ALL, silently granting unrestricted passwordless root; it is now rejected.
Defaults
TRUSTED_ORIGINSfalls back toWEB_ORIGINinstead of*. The wildcard remains available as an explicit opt-in and logs a warning at boot.- The
Securecookie flag is set wheneverBETTER_AUTH_URLorWEB_ORIGINis https, rather than being inferred fromBETTER_AUTH_URLalone. - Self-registration is disabled unless
ALLOW_SELF_SIGNUP=true. - The "persist passphrase to .env" checkbox defaults to off. The write is now atomic, mode
0600, and anchored to the exact variable so it no longer rewrites commented-out or similarly-named lines.
Audit coverage
Added entries for fifteen mutations that were previously unrecorded: SSH key add/remove, SSH connectivity tests, API key issue/revoke, access-request deletion, remote auto-update changes, storage recalculation, all SSL mutations, and all four inventory export endpoints.
Documentation accuracy
The credential vault was described as zero-knowledge with client-side WebCrypto encryption in fourteen places across the README, user guide, security policy and product portal. No client-side cryptography exists. The vault is server-side envelope encryption (PBKDF2 → KEK → DEK, AES-256-GCM): the passphrase is sent to the server on unlock, and opting in to auto-unlock writes it to .env. All affected copy now describes the actual design.
Run RackMap behind TLS.
Also corrected: SSH_ENABLED was documented as an RCE kill-switch. It gates only the browser terminal — metrics, discovery, log viewing, ATOP and OS user management still execute commands over SSH when it is false. And SSH_HOST_POLICY is declared but never read; it is now marked as not implemented. Real host-key verification is next.
Action required on upgrade
TRUSTED_ORIGINSno longer defaults to*. If you reach RackMap at a hostname or IP that differs fromWEB_ORIGIN, sign-in will be rejected. Set it explicitly:TRUSTED_ORIGINS=https://rackmap.example.com,http://10.0.0.5:8080TRUSTED_ORIGINS=*restores the old behaviour and logs a warning.ALLOW_SELF_SIGNUPdefaults tofalse. The registration form and the checkout sign-up step are hidden. Set it totrueto restore self-registration.- Custom sudo permissions with an empty command list are rejected. Supply explicit absolute command paths, or choose the full-access option deliberately.
Upgrading
git pull
docker compose up -d --buildVerification
pnpm build, pnpm -r typecheck and pnpm test all pass. Test count goes from 35 to 150: the new suites assert that an unauthenticated caller and a viewer are both rejected on every newly guarded route, and that hostile values are rejected on every field that reaches a shell.
Still open
- Host-key verification is not implemented —
hostVerifiercurrently accepts any key. Planned for the next release. - 27 Dependabot alerts (8 high) remain on the default branch.
Full changelog: https://github.com/deziss/rackmap/blob/v0.6.1/CHANGELOG.md