Problem
Two exposure paths for the password-auth SSH server (claude:claude):
- Bridge mode:
-p "${ssh_port}:${ssh_port}" (dclaude:1878) binds 0.0.0.0 by Docker default — once dclaude ssh server starts sshd, anyone on the local network can log in
- Host mode: sshd listens directly on the host network stack, same LAN exposure
The container user is in the docker group with the host Docker socket mounted, so an SSH login is effectively host-level control (can start privileged containers, mount host paths). SECURITY.md's "local development only" note undersells this: coffee-shop / office LAN is enough.
Fix
- Bridge mode: bind loopback only —
-p "127.0.0.1:${ssh_port}:${ssh_port}". All documented use cases (JetBrains Gateway, VS Code Remote, sftp) connect to localhost, so nothing breaks
- Host mode: pass an sshd
ListenAddress 127.0.0.1 (e.g. /usr/sbin/sshd -p $port -o ListenAddress=127.0.0.1 in cmd_ssh_server)
- Longer term: generate a per-container random password or use key auth, since the hardcoded credential is guessable by anyone who reads the repo
Found during a full-project code review.
Problem
Two exposure paths for the password-auth SSH server (
claude:claude):-p "${ssh_port}:${ssh_port}"(dclaude:1878) binds 0.0.0.0 by Docker default — oncedclaude ssh serverstarts sshd, anyone on the local network can log inThe container user is in the
dockergroup with the host Docker socket mounted, so an SSH login is effectively host-level control (can start privileged containers, mount host paths). SECURITY.md's "local development only" note undersells this: coffee-shop / office LAN is enough.Fix
-p "127.0.0.1:${ssh_port}:${ssh_port}". All documented use cases (JetBrains Gateway, VS Code Remote, sftp) connect tolocalhost, so nothing breaksListenAddress 127.0.0.1(e.g./usr/sbin/sshd -p $port -o ListenAddress=127.0.0.1incmd_ssh_server)Found during a full-project code review.