You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug Report: host-agent still binds 0.0.0.0 on fresh install — closure of #283 was premature, secure default never applied
Severity: High Category: Security / Network Exposure / Insecure Default Platform: Linux (and Linux-equivalent paths on macOS / Windows-WSL2 via Docker Desktop) Confidence: Confirmed
Followup of: #283 (Host agent binds to 0.0.0.0 — Docker control API exposed to LAN), CLOSED.
The original bug is still present at runtime on a fresh install — the bind line in bin/dream-host-agent.py is unchanged, the daemon emits a runtime warning admitting it, and the installer never sets the safer default that would silence the warning.
Description
#283 was filed for the fact that bin/dream-host-agent.py binds the agent HTTP server to 0.0.0.0, exposing the Docker control API and hook execution endpoints to the entire LAN. The issue was closed — presumably accepting the wide bind as required to keep the host-agent reachable from inside Docker containers (#283's body and Light-Heart-Labs/DreamServer#752 both note this trade-off). The compromise that was apparently agreed: keep the wide bind, emit a startup WARNING, and let users opt into DREAM_AGENT_BIND=127.0.0.1 via .env.
The closure is premature because the safer default isn't applied by the installer and the host-agent itself emits a warning admitting it on every boot. Users who don't read journal logs (which is most users) get LAN-exposed without ever knowing.
Affected File(s)
dream-server/bin/dream-host-agent.py — line that binds ("0.0.0.0", port) (still hardcoded; the env var DREAM_AGENT_BIND is checked by the daemon but only if set, and the installer doesn't set it).
dream-server/.env.example — should document DREAM_AGENT_BIND and set it to 127.0.0.1 by default.
dream-server/installers/phases/06-directories.sh (or wherever .env is generated from .env.example during install) — should explicitly write DREAM_AGENT_BIND=127.0.0.1 unless the install profile genuinely requires container-side reachability.
Root Cause
The 0.0.0.0 bind was deliberately chosen to fix Light-Heart-Labs/DreamServer#752 (host agent unreachable from Docker containers when bound to 127.0.0.1). The trade-off agreed at close time was: keep the wide bind, but emit a warning and offer an opt-in via DREAM_AGENT_BIND=127.0.0.1 in .env. The opt-in part never landed in the installer flow — fresh installs leave DREAM_AGENT_BIND unset, the daemon falls through to the default 0.0.0.0, and the warning fires forever.
Evidence
Fresh install of the integration branch (open PR stack Light-Heart-Labs#893–909 merged onto Light-Heart-Labs/DreamServer@c0600ca) on WSL2 / Ubuntu 24.04. bash install.sh --all --non-interactive --no-comfyui reaches phase 13 cleanly. Then:
$ systemctl --user restart dream-host-agent.service # see #334 — installer doesn't restart it
$ journalctl --user -u dream-host-agent.service -n 5 --no-pager
Apr 12 00:11:41 ... python3[353285]: Dream Host Agent v1.0.0 listening on 0.0.0.0:7710
Apr 12 00:11:41 ... python3[353285]: WARNING: Agent is listening on all interfaces. Set DREAM_AGENT_BIND=127.0.0.1 in .env to restrict.
Apr 12 00:11:41 ... python3[353285]: Install dir: /home/rosenrot/dream-server | GPU: nvidia | Tier: 1
The host-agent itself logs the warning on every startup. So the daemon knows the default is unsafe.
Listening on all interfaces, port 7710. Confirmed via ss.
$ grep DREAM_AGENT_BIND ~/dream-server/.env
# (no match — installer didn't set it)
$ grep DREAM_AGENT_BIND ~/dream-server/.env.example
# (no match — also not documented in the example file)
The installer didn't set DREAM_AGENT_BIND in .env. .env.example doesn't even document the variable, so a user trying to find the right key to set wouldn't see it in the canonical reference. The only way to discover the safer default is to read the journal warning and grep the host-agent source.
Platform Analysis
Linux: Affected — port 7710 exposed to LAN. Most desktop Linux distros have no restrictive firewall by default. This is the Tier 1 default install path; verified end-to-end on WSL2 today.
Windows/WSL2: Partially affected — WSL2 NAT usually shields ports from the wider LAN, but the Docker Desktop config can expose them. Verified the bind is 0.0.0.0:7710 inside the WSL2 instance; whether the Windows host blocks LAN-side reach is environment-specific.
Reproduction
bash install.sh --all --non-interactive on a fresh system. Reach phase 13.
The original symptom #283 describes is intact. The "fix" is a startup warning that nobody reads.
Impact
Security boundary that Host agent binds to 0.0.0.0 — Docker control API exposed to LAN #283 originally identified is still broken. An attacker on the LAN who obtains the API key (shoulder surfing .env, separate vulnerability, or SSRF chain) can start/stop containers, execute extension setup hook scripts, and read container logs.
Defense-in-depth gap: even if the API key is rotated frequently and the auth check is correct, there's no second layer (network ACL, OS firewall rule auto-installed) to mitigate.
The class of bug #283 was filed about — exposing Docker control API to the LAN — is unchanged on a fresh install of the integration branch.
Suggested Approach
Minimum:
Default .env to DREAM_AGENT_BIND=127.0.0.1 during install. Have the installer write it explicitly into the generated .env.
Document DREAM_AGENT_BIND in .env.example with a comment explaining the trade-off (127.0.0.1 for safety, 0.0.0.0 if a containerized service needs to reach the host-agent across the Docker bridge).
Stop emitting the WARNING when the bind is 127.0.0.1. Promote the warning to ERROR level when the bind is 0.0.0.0, so the next time someone reads journal they see it as a real problem rather than a routine info line.
Better:
4. Bind to 127.0.0.1and the Docker bridge gateway IP (e.g. 172.17.0.1), or use a Unix socket bind-mounted into containers that need reach. This is what #283's body originally suggested. It maintains container reachability without LAN exposure. Requires a small refactor of ThreadedHTTPServer to bind multiple sockets (or to the bridge IP only), but it's the cleanest answer.
Ask the user at install time:
5. Prompt during --non-interactive setup whether the install is single-user-local (default → 127.0.0.1) or multi-container-with-host-agent-access (→ bridge IP or 0.0.0.0 with explicit warning). Don't make 0.0.0.0 the silent default.
Cross-references
Host agent binds to 0.0.0.0 — Docker control API exposed to LAN #283 (closed) — original issue. The bind line and the LAN exposure are unchanged from when this was filed; the closure was based on the assumption that the warning + opt-in env var would be enough, but the opt-in side never landed in the installer.
Light-Heart-Labs/DreamServer#752 (closed) — context for why the bind was moved off 127.0.0.1 in the first place. Necessary background, not in dispute.
Filed during full-stack integration test of open PR stack Light-Heart-Labs#893–909 on Light-Heart-Labs/DreamServer@c0600ca3. Environment: WSL2 / Ubuntu 24.04 / NVIDIA RTX 3070 Laptop / Tier 1.
Bug Report: host-agent still binds 0.0.0.0 on fresh install — closure of #283 was premature, secure default never applied
Severity: High
Category: Security / Network Exposure / Insecure Default
Platform: Linux (and Linux-equivalent paths on macOS / Windows-WSL2 via Docker Desktop)
Confidence: Confirmed
Description
#283 was filed for the fact that
bin/dream-host-agent.pybinds the agent HTTP server to0.0.0.0, exposing the Docker control API and hook execution endpoints to the entire LAN. The issue was closed — presumably accepting the wide bind as required to keep the host-agent reachable from inside Docker containers (#283's body andLight-Heart-Labs/DreamServer#752both note this trade-off). The compromise that was apparently agreed: keep the wide bind, emit a startup WARNING, and let users opt intoDREAM_AGENT_BIND=127.0.0.1via.env.The closure is premature because the safer default isn't applied by the installer and the host-agent itself emits a warning admitting it on every boot. Users who don't read journal logs (which is most users) get LAN-exposed without ever knowing.
Affected File(s)
dream-server/bin/dream-host-agent.py— line that binds("0.0.0.0", port)(still hardcoded; the env varDREAM_AGENT_BINDis checked by the daemon but only if set, and the installer doesn't set it).dream-server/.env.example— should documentDREAM_AGENT_BINDand set it to127.0.0.1by default.dream-server/installers/phases/06-directories.sh(or wherever.envis generated from.env.exampleduring install) — should explicitly writeDREAM_AGENT_BIND=127.0.0.1unless the install profile genuinely requires container-side reachability.Root Cause
The
0.0.0.0bind was deliberately chosen to fixLight-Heart-Labs/DreamServer#752(host agent unreachable from Docker containers when bound to127.0.0.1). The trade-off agreed at close time was: keep the wide bind, but emit a warning and offer an opt-in viaDREAM_AGENT_BIND=127.0.0.1in.env. The opt-in part never landed in the installer flow — fresh installs leaveDREAM_AGENT_BINDunset, the daemon falls through to the default0.0.0.0, and the warning fires forever.Evidence
Fresh install of the integration branch (open PR stack Light-Heart-Labs#893–909 merged onto
Light-Heart-Labs/DreamServer@c0600ca) on WSL2 / Ubuntu 24.04.bash install.sh --all --non-interactive --no-comfyuireaches phase 13 cleanly. Then:The host-agent itself logs the warning on every startup. So the daemon knows the default is unsafe.
Listening on all interfaces, port 7710. Confirmed via
ss.The installer didn't set
DREAM_AGENT_BINDin.env..env.exampledoesn't even document the variable, so a user trying to find the right key to set wouldn't see it in the canonical reference. The only way to discover the safer default is to read the journal warning and grep the host-agent source.Platform Analysis
0.0.0.0:7710inside the WSL2 instance; whether the Windows host blocks LAN-side reach is environment-specific.Reproduction
bash install.sh --all --non-interactiveon a fresh system. Reach phase 13.systemctl --user restart dream-host-agent.service(per bug: installer doesn't restart dream-host-agent.service after rewriting bin/dream-host-agent.py — leaves zombie reading deleted inode #334, the installer doesn't restart it after rewriting the binary).journalctl --user -u dream-host-agent.service -n 5 --no-pager— observe the WARNING about all-interfaces bind.ss -tlnp | grep 7710— observe0.0.0.0:7710.grep DREAM_AGENT_BIND ~/dream-server/.env— empty.grep DREAM_AGENT_BIND ~/dream-server/.env.example— empty.The original symptom #283 describes is intact. The "fix" is a startup warning that nobody reads.
Impact
.env, separate vulnerability, or SSRF chain) can start/stop containers, execute extension setup hook scripts, and read container logs./healthendpoint is also still unauthenticated (per Host agent binds to 0.0.0.0 — Docker control API exposed to LAN #283's original analysis), so version fingerprinting works LAN-wide.The class of bug #283 was filed about — exposing Docker control API to the LAN — is unchanged on a fresh install of the integration branch.
Suggested Approach
Minimum:
.envtoDREAM_AGENT_BIND=127.0.0.1during install. Have the installer write it explicitly into the generated.env.DREAM_AGENT_BINDin.env.examplewith a comment explaining the trade-off (127.0.0.1for safety,0.0.0.0if a containerized service needs to reach the host-agent across the Docker bridge).127.0.0.1. Promote the warning to ERROR level when the bind is0.0.0.0, so the next time someone reads journal they see it as a real problem rather than a routine info line.Better:
4. Bind to
127.0.0.1and the Docker bridge gateway IP (e.g.172.17.0.1), or use a Unix socket bind-mounted into containers that need reach. This is what #283's body originally suggested. It maintains container reachability without LAN exposure. Requires a small refactor ofThreadedHTTPServerto bind multiple sockets (or to the bridge IP only), but it's the cleanest answer.Ask the user at install time:
5. Prompt during
--non-interactivesetup whether the install is single-user-local (default → 127.0.0.1) or multi-container-with-host-agent-access (→ bridge IP or 0.0.0.0 with explicit warning). Don't make0.0.0.0the silent default.Cross-references
Light-Heart-Labs/DreamServer#752(closed) — context for why the bind was moved off127.0.0.1in the first place. Necessary background, not in dispute.dream-host-agent.serviceafter rewriting the binary, so an upgrade leaves the OLD daemon running with whatever bind it had at start. Compounds this issue: a user who manually flippedDREAM_AGENT_BIND=127.0.0.1after a previous install will see their setting ignored until they restart the service themselves..envwrites. PR fix(security): route .env writes through host agent, restore :ro mount Light-Heart-Labs/DreamServer#908 fixed that one cleanly; this issue is the parallel security fix that didn't.Filed during full-stack integration test of open PR stack Light-Heart-Labs#893–909 on
Light-Heart-Labs/DreamServer@c0600ca3. Environment: WSL2 / Ubuntu 24.04 / NVIDIA RTX 3070 Laptop / Tier 1.