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: .env bind-mount changed from :ro to writable — container compromise escalates to credential overwrite
Severity: Medium Category: Security Platform: All (Linux, macOS, Windows/WSL2) Confidence: Confirmed
Description
Commit c7ffea39 (feat(settings): add secure environment editor) changed the .env bind-mount in docker-compose.base.yml from read-only (:ro) to writable for the dashboard-api container. This was done to support the new PUT /api/settings/env endpoint.
The endpoint itself is correctly protected by verify_api_key. The security regression is at the container isolation layer: the dashboard-api container now has write access to .env at the filesystem level, independent of API authentication.
Affected File(s)
dream-server/docker-compose.base.yml line ~179
dream-server/extensions/services/dashboard-api/main.py — PUT /api/settings/env, POST /api/settings/env/apply
Root Cause
# Before (c7ffea39 parent):
- ./.env:/dream-server/.env:ro# After (c7ffea39):
- ./.env:/dream-server/.env
The writable mount was required to support the new in-dashboard .env editor.
Evidence
The PUT /api/settings/env endpoint calls _write_text_atomic(env_path, raw_text) which writes the merged env values directly to .env. The backup flow shutil.copy2(env_path, backup_path) also runs within the container.
_prepare_env_save validates that only schema-backed keys and existing local overrides can be changed — a sound application-level control. However, with a writable bind-mount, any code execution within the container bypasses this validation.
Platform Analysis
Linux (systemd): Any process running as the dashboard-api container user can write to .env on the host filesystem. Host agent is 0.0.0.0 on Linux (issue Host agent binds to 0.0.0.0 — Docker control API exposed to LAN #283), so planting a known DREAM_AGENT_KEY also grants host-agent access.
macOS (Docker Desktop): Same via the Docker Desktop VM filesystem layer.
Windows/WSL2: Same via the WSL2 VHD bind-mount path.
Reproduction
Exploit any code-execution vulnerability in the dashboard-api container (e.g., SSRF chain, compromised Python dependency, future FastAPI CVE).
From the compromised container, write a crafted .env with a known DREAM_AGENT_KEY value.
Call the host agent (port 7710 on Linux, reachable from the container) with the planted key.
Host agent grants Docker container lifecycle control and hook script execution.
Impact
Before: container RCE → read secrets from .env (credential theft)
After: container RCE → read and write secrets → reset DREAM_AGENT_KEY, reset DASHBOARD_API_KEY, modify cloud API keys (OPENAI_API_KEY, ANTHROPIC_API_KEY), set up persistent access
This escalates container compromise from credential theft to full-stack credential overwrite.
Suggested Approach
Route .env writes through the host agent, which already writes .env for model activation in _do_model_activate. Add a /v1/env/update endpoint on the host agent with schema-validated key-value updates, and revert the dashboard-api mount to :ro. This preserves the original isolation boundary while supporting the settings editor feature.
Filed by automated security auditor after full-sweep of changes merged 2026-04-06 → 2026-04-11 on upstream/main @ c0600ca.
Bug Report: .env bind-mount changed from :ro to writable — container compromise escalates to credential overwrite
Severity: Medium
Category: Security
Platform: All (Linux, macOS, Windows/WSL2)
Confidence: Confirmed
Description
Commit
c7ffea39(feat(settings): add secure environment editor) changed the.envbind-mount indocker-compose.base.ymlfrom read-only (:ro) to writable for thedashboard-apicontainer. This was done to support the newPUT /api/settings/envendpoint.The endpoint itself is correctly protected by
verify_api_key. The security regression is at the container isolation layer: the dashboard-api container now has write access to.envat the filesystem level, independent of API authentication.Affected File(s)
dream-server/docker-compose.base.ymlline ~179dream-server/extensions/services/dashboard-api/main.py—PUT /api/settings/env,POST /api/settings/env/applyRoot Cause
The writable mount was required to support the new in-dashboard
.enveditor.Evidence
The
PUT /api/settings/envendpoint calls_write_text_atomic(env_path, raw_text)which writes the merged env values directly to.env. The backup flowshutil.copy2(env_path, backup_path)also runs within the container._prepare_env_savevalidates that only schema-backed keys and existing local overrides can be changed — a sound application-level control. However, with a writable bind-mount, any code execution within the container bypasses this validation.Platform Analysis
.envon the host filesystem. Host agent is0.0.0.0on Linux (issue Host agent binds to 0.0.0.0 — Docker control API exposed to LAN #283), so planting a knownDREAM_AGENT_KEYalso grants host-agent access.Reproduction
.envwith a knownDREAM_AGENT_KEYvalue.Impact
Before: container RCE → read secrets from
.env(credential theft)After: container RCE → read and write secrets → reset
DREAM_AGENT_KEY, resetDASHBOARD_API_KEY, modify cloud API keys (OPENAI_API_KEY,ANTHROPIC_API_KEY), set up persistent accessThis escalates container compromise from credential theft to full-stack credential overwrite.
Suggested Approach
Route
.envwrites through the host agent, which already writes.envfor model activation in_do_model_activate. Add a/v1/env/updateendpoint on the host agent with schema-validated key-value updates, and revert the dashboard-api mount to:ro. This preserves the original isolation boundary while supporting the settings editor feature.Filed by automated security auditor after full-sweep of changes merged 2026-04-06 → 2026-04-11 on upstream/main @ c0600ca.