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
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.
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.
Source: engineering review, 2026-10-07.
The static Basic credential is the only thing guarding a root shell, and it leaks:
0.0.0.0:7681and CT 126's nft input policy isaccept.libexec/devdesk-serve--credential), sopsshows it to any local user. A review agent'spscopied it into Claude transcripts on 2026-10-07./tokenhands 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:
rm /etc/devdesk/secret.env && dpkg-reconfigure devdesk, update the NPM host 58 AdvancedAuthorizationline, thensystemctl restart devdesk.Fixed 2026-10-07.
Firewall:
inet devdesk) now allows tcp/7681 only from NPM (10.10.10.27) and loopback, and resets everything else. Tracked in pve-infra93a3c1e(containers/126-codingenvironment/etc/nftables.conf);deploy.shvalidates it withnft -cbefore installing.Credential rotation:
Authorizationline updated through the API; ttyd restarted.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 athidepidon /proc, or put a reverse proxy on loopback in front of ttyd.