Skip to content

Validate compose project name before using it in docker-compose command lines - #829

Open
carfeii wants to merge 1 commit into
jesseduffield:masterfrom
carfeii:fix/project-name-label-validation
Open

Validate compose project name before using it in docker-compose command lines#829
carfeii wants to merge 1 commit into
jesseduffield:masterfrom
carfeii:fix/project-name-label-validation

Conversation

@carfeii

@carfeii carfeii commented Aug 4, 2026

Copy link
Copy Markdown

Fixes #828.

Summary

The auto-detected local project name, and any explicit Service/Project
ProjectName, can originate from the com.docker.compose.project Docker
label. Unlike a project name declared via docker-compose.yml, a raw
container label has no format restriction: docker run --label accepts
any string, including one containing extra command-line flags. That value
was concatenated unescaped into the docker-compose command prefix used to
build every generated command (restart, stop, logs, etc.), allowing
argument injection from any container on the host whose
com.docker.compose.service label happened to match one of the project's
service names.

Fix

Adds isValidComposeProjectName, matching the character class the Compose
spec itself requires for a project name, and uses it in two places:

  • RefreshContainersAndServices: a container's ProjectName label is
    skipped during auto-detection if it doesn't pass validation, so the
    loop continues to a legitimate match instead of adopting it.
  • NewCommandObject: the -p flag is only appended if the project name
    passes validation, as defense in depth in case an invalid value reaches
    this point through another path.

Testing

  • go build ./... and go test ./... pass with no changes to existing
    test expectations.
  • Manually reproduced the injection against an unpatched checkout (crafted
    a container with a com.docker.compose.project label containing
    --project-directory, matching service name web) and confirmed the
    resolved RestartService command's argv contained the injected flag.
    Repeated the same setup against this branch and confirmed the label is
    now rejected, detection falls through to the legitimate project name,
    and the resolved command's argv is unaffected by the malicious
    container's label.

Happy to add an automated regression test for this in pkg/commands if
you'd like one included, following the existing test style in that
package. I kept this PR to the minimal fix in the meantime.

…nd lines

The auto-detected local project name and any explicit Service/Project
ProjectName can originate from the com.docker.compose.project Docker
label, which (unlike a project name declared via docker-compose.yml) has
no format restriction: a plain `docker run --label` can set it to any
string, including one containing extra command-line flags. That value was
being concatenated unescaped into the docker-compose command prefix used
to build every generated command, allowing argument injection.

Reject label-derived values that don't match the character class Compose
itself requires for a project name before adopting them for auto-detection,
and before using them to build a command line, so a stray or malicious
label on an unrelated container can no longer influence the commands run
against the user's own project. See jesseduffield#828.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docker label value used unescaped to build docker-compose commands (argument injection on shared hosts)

1 participant