Restrict ttyd :7681 to NPM and rotate the shared credential #1

Closed
opened 2026-10-07 20:04:25 -04:00 by jared · 1 comment
Owner

Source: engineering review, 2026-10-07.

The static Basic credential is the only thing guarding a root shell, and it leaks:

  • ttyd listens on 0.0.0.0:7681 and CT 126's nft input policy is accept.
  • The credential is on ttyd's command line (libexec/devdesk-serve --credential), so ps shows it to any local user. A review agent's ps copied it into Claude transcripts on 2026-10-07.
  • /token hands it to every browser, and NPM sends it in plaintext over the LAN. It has never been rotated.

Anyone on the LAN who obtains it gets root without Authelia or 2FA.

Fix:

  • nft rule on CT 126 allowing tcp/7681 only from 10.10.10.27 (NPM) and loopback; make DEPLOY.md's "optional hardening" mandatory, or ship it.
  • Rotate: rm /etc/devdesk/secret.env && dpkg-reconfigure devdesk, update the NPM host 58 Advanced Authorization line, then systemctl restart devdesk.
  • Optionally bind ttyd to the CT's LAN IP only.
_Source: engineering review, 2026-10-07._ The static Basic credential is the only thing guarding a root shell, and it leaks: - ttyd listens on `0.0.0.0:7681` and CT 126's nft input policy is `accept`. - The credential is on ttyd's command line (`libexec/devdesk-serve` `--credential`), so `ps` shows it to any local user. A review agent's `ps` copied it into Claude transcripts on 2026-10-07. - `/token` hands it to every browser, and NPM sends it in plaintext over the LAN. It has never been rotated. Anyone on the LAN who obtains it gets root without Authelia or 2FA. **Fix:** - [ ] nft rule on CT 126 allowing tcp/7681 only from 10.10.10.27 (NPM) and loopback; make DEPLOY.md's "optional hardening" mandatory, or ship it. - [ ] Rotate: `rm /etc/devdesk/secret.env && dpkg-reconfigure devdesk`, update the NPM host 58 Advanced `Authorization` line, then `systemctl restart devdesk`. - [ ] Optionally bind ttyd to the CT's LAN IP only.
jared added this to the v0.5.0 hardening + header/phone milestone 2026-10-07 20:04:25 -04:00
jared added the securitypriority:high labels 2026-10-07 20:04:25 -04:00
Author
Owner

Fixed 2026-10-07.

Firewall:

  • CT 126 nftables (table inet devdesk) now allows tcp/7681 only from NPM (10.10.10.27) and loopback, and resets everything else. Tracked in pve-infra 93a3c1e (containers/126-codingenvironment/etc/nftables.conf); deploy.sh validates it with nft -c before installing.
  • Verified: loopback → 401, NPM (CT 139) → 401, another LAN host (large1) → connection refused. Other ports unchanged.

Credential rotation:

  • New secret generated by postinst; NPM host 58's Advanced Authorization line updated through the API; ttyd restarted.
  • Verified: new credential → 200, old credential → 401, NPM's generated conf carries the new value.

Still open: the credential is still on ttyd's command line (visible to local users in ps); ttyd 1.7.7 only takes it via -c. With the firewall in place it's only usable from the NPM host. If local exposure matters, look at hidepid on /proc, or put a reverse proxy on loopback in front of ttyd.

**Fixed 2026-10-07.** **Firewall:** - CT 126 nftables (table `inet devdesk`) now allows tcp/7681 only from NPM (10.10.10.27) and loopback, and resets everything else. Tracked in pve-infra `93a3c1e` (`containers/126-codingenvironment/etc/nftables.conf`); `deploy.sh` validates it with `nft -c` before installing. - Verified: loopback → 401, NPM (CT 139) → 401, another LAN host (large1) → connection refused. Other ports unchanged. **Credential rotation:** - New secret generated by postinst; NPM host 58's Advanced `Authorization` line updated through the API; ttyd restarted. - Verified: new credential → 200, old credential → 401, NPM's generated conf carries the new value. **Still open:** the credential is still on ttyd's command line (visible to local users in `ps`); ttyd 1.7.7 only takes it via `-c`. With the firewall in place it's only usable from the NPM host. If local exposure matters, look at `hidepid` on /proc, or put a reverse proxy on loopback in front of ttyd.
jared closed this issue 2026-10-07 20:08:22 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/devdesk#1