Skip to content

security: .env bind-mount changed from :ro to writable — container compromise enables full-stack credential overwrite #317

@yasinBursali

Description

@yasinBursali

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.pyPUT /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

  1. Exploit any code-execution vulnerability in the dashboard-api container (e.g., SSRF chain, compromised Python dependency, future FastAPI CVE).
  2. From the compromised container, write a crafted .env with a known DREAM_AGENT_KEY value.
  3. Call the host agent (port 7710 on Linux, reachable from the container) with the planted key.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions