Skip to content

Option to hide container environment variables (Config.Env) from inspect responses #189

Description

@fabiocatalao

Problem

Monitoring tools that watch container state need CONTAINERS=1, because they read that state from the container inspect endpoint. For example, Uptime Kuma's Docker monitor calls GET /containers/{name}/json (monitor.js).

The same response also contains Config.Env, which is where most Compose stacks put database passwords and API tokens. So a client that only needs to know whether a container is running can read the secrets of every container on the host, and so can anyone who compromises that client. I ran into this during a security review of my own setup.

This is related to #182 and to the discussion in #15. The deny rules in #183 / #186 can't cover it, though: these tools need the endpoint itself, and only part of the response is the problem.

Proposal

Add an opt-in HIDE_CONTAINER_ENV=1 (default 0). When it's set together with CONTAINERS=1, container inspect responses come back with "Env": [].

HAProxy ≥2.5 doesn't allow rewriting response bodies in HTTP mode. Instead, inspect requests would go to a small Lua HTTP service (http-request use-service) that fetches the response from SOCKET_PATH, empties Env, and answers the client. The HAProxy base image already includes Lua, so there are no new dependencies.

  • It fails closed. use-service is a final rule, so a socket error or a malformed response returns 502, never the unfiltered body.
  • The JSON scanning tracks strings, so env values containing ], " or \ can't end the array early.
  • The query string is forwarded, so ?size=1 keeps working. Responses are streamed, so tune.bufsize doesn't need to change.
  • It's off by default, because tools that recreate containers from their inspect output (e.g. Watchtower) need the environment.

It only covers container inspect. SERVICES, TASKS and IMAGES can still expose environment variables, and the README change would say so.

Status

An earlier version of this has been running in my fork since May. I've reworked it into what's described above and have a branch with tests ready. The tests cover unchanged default behaviour, filtered docker inspect, unusual path spellings and ?size=1.

Before opening a PR, I'd like to check:

  1. Is this something you'd accept?
  2. Are you happy with the name and default (HIDE_CONTAINER_ENV, off)?
  3. Should I base it on [IMP] Modernize project #185 (which moves haproxy.cfg to system_files/) and [IMP] Harden sensitive endpoints and methods #186, or open it against master now?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions