-
Notifications
You must be signed in to change notification settings - Fork 11
Description
Is your feature request related to a problem? Please describe.
When a CI job uses services: [docker:dind] (Docker-in-Docker), it creates a Docker daemon inside the CI container. On shared runners running in privileged mode, this enables:
- Container escape: Access to the host's Docker daemon and kernel namespaces
- Lateral movement: Listing/inspecting containers from other projects running on the same runner
- Volume access: Reading volumes mounted by other CI jobs (potentially containing secrets)
- Network reconnaissance: Probing the runner's internal network
This is a well-known attack vector documented in GitLab CI security best practices.
Describe the solution you'd like
Add a new control pipelineMustNotUseDockerInDocker that:
- Detects
docker:dind(and variants likedocker:*-dind,docker:latest) inservices:blocks - Optionally detects insecure configurations:
DOCKER_TLS_CERTDIR: ""orDOCKER_HOST: tcp://docker:2375(unencrypted) - Reports each affected job with a warning
Configuration in .plumber.yaml
controls:
pipelineMustNotUseDockerInDocker:
enabled: true
# Suggest alternatives in the output
suggestAlternatives: true # e.g., kaniko, buildah
# Also flag insecure Docker daemon configuration
detectInsecureDaemon: true # DOCKER_TLS_CERTDIR="" or tcp://docker:2375Implementation Hints
These are just ideas. Feel free to change the implementation.
- Data source: The
PipelineImagecollector already parses images from CI jobs, includingservices:. ThePipelineOrigincollector provides the merged CI config with per-job variables. - New control file: Create
control/controlGitlabPipelineDockerInDocker.go. - Logic:
- Iterate over all jobs from the merged CI config
- For each job, check
services:for images matchingdocker:dindordocker:*-dind - Optionally check job variables for
DOCKER_TLS_CERTDIR: ""orDOCKER_HOSTpointing totcp://...:2375(non-TLS)
- Compliance: 0% if any job uses
docker:dind, 100% otherwise. - Output: Include the job name, the dind image reference, and (if
suggestAlternativesis enabled) a recommendation to use kaniko or buildah instead.
Files Touched
control/controlGitlabPipelineDockerInDocker.go(new control)control/types.go(add result field toAnalysisResult)control/task.go(wire the new control inRunAnalysis())configuration/plumberconfig.go(add config struct and getter).plumber.yaml(add default config section)cmd/analyze.go(add output formatting)
Why It's Valuable
Docker-in-Docker is one of the most common and dangerous patterns in CI/CD pipelines, especially on shared runners. While it's sometimes necessary, teams should be aware of the risk and consider alternatives like kaniko or buildah. This control raises visibility on the attack surface without necessarily blocking the build — compliance teams can decide whether to enforce or just warn.