GHSA-whr6-fgpq-fpv9: compose-lint: A committed symlink makes compose-lint quote a file from outside the project into its output

Published Nov 9, 2026
·
Updated

Impact

Like Docker Compose, compose-lint follows symlinks when it reads a project's files. Unlike Compose, compose-lint up to 0.24.0 could then put the contents of a file from outside the project into its output, where the author of a pull request can read it.

A pull request can commit a symlink, under a name compose-lint reads, pointing at a file on the CI runner:

- The Compose file itself (0.2.0–0.24.0). A compose.yml that is a symlink, whether the pre-commit hook passes its name or the Action or a bare run finds it. - compose.override.yml (0.22.0–0.24.0), which compose-lint merges automatically. - A COMPOSEFILE entry (0.22.0–0.24.0) in a .env beside the Compose file.

When the target is not valid YAML, the parse error quotes the line it failed on. Docker Compose, given the same file, reports only a line number. That line reaches standard error (the job log), JSON errors[], and the SARIF toolExecutionNotifications, which the Action uploads to Code Scanning.

A fourth route: from 0.23.0, a symlinked envfile: target makes CL-0020 and CL-0021 report the credential-like key names in a file outside the project. Values are not printed.

What can be read is one line of a file chosen by path, at the point where the YAML parser fails, which the attacker cannot choose; or key names. A symlink to /proc/self/environ gave neither in testing. The pass/fail result is not affected. On a public repository the job log is visible to the pull request's author.

Found during an internal pre-1.0 security review.

GitHub Action. Action tags v0.18.0 through v0.24.0 install their own compose-lint version and are affected. Earlier tags install the newest release unless version: is set; they were affected while that was 0.24.0 or earlier.

Docker image. composelint/compose-lint tags 0.3.3 through 0.24.0, and the matching minor tags, are affected. Inside the container a symlink resolves within the container, so what can be read is the container's own files and anything mounted into it. Fixed from 0.25.0.

Patches

Fixed in 0.25.0. Parse errors no longer quote the source line; the error and its line and column are kept. envfile: targets and COMPOSEFILE entries that resolve outside the project are also refused, with the existing outside-the-project note. Symlinks that stay inside the project still work.

From 0.25.0 through 0.31.0, a committed symlink to a target that is itself a Compose file could still be read, and its values could reach findings. 0.32.0 stops following a discovered, named or override Compose file whose link leaves the checkout.

A related gap for the sibling .env file is covered by GHSA-6wcv-rj3c-mhv3, and one for a symlinked .compose-lint.yml by GHSA-88f4-frh5-gmcr.

Workarounds

- Upgrade to 0.25.0 or later. - On older versions, don't run compose-lint on untrusted pull requests on a machine whose files outside the checkout hold credentials. --no-env closes the COMPOSEFILE and envfile: routes, but not the others.

Reproduction

project/compose.yml -> /path/outside/project/credentials (symlink)

compose-lint --format sarif compose.yml on 0.24.0 exits 2, and the SARIF notification quotes a line of the linked file. On 0.25.0 the error gives only the line and column.

Other sources

compose-lint is a Docker Compose security linter that identifies dangerous misconfigurations before deployment. From 0.2.0 until 0.25.0, compose-lint follows a project-controlled symbolic link used as the Compose file outside the project. The same issue affects compose.override.yml and a COMPOSEFILE entry from 0.22.0, and an envfile target from 0.23.0. If an external Compose-related target fails YAML parsing, the error quotes an attacker-uncontrolled line into standard error, JSON errors, and SARIF notifications, while an external envfile can expose credential-like key names through CL-0020 and CL-0021 findings. The attacker selects the target path but not the exact parser-failure line, values from envfile are not printed, and the pass or fail result is unchanged. This issue is fixed in version 0.25.0.

— OSV

Affected Software

5 affected componentsFixes available
compose-lint>=0.2.0<0.25.0
actions/tmatens/compose-lint>=0.2.0<=0.24.0
0.25.0
pip/compose-lint>=0.2.0<=0.24.0
0.25.0
pip/compose-lint>=0.2.0<0.25.0
0.25.0
actions/tmatens/compose-lint>=0.2.0<0.25.0
0.25.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade actions/tmatens/compose-lint to a version that resolves this vulnerability.

    Fixed in 0.25.0
  2. Upgrade

    Upgrade pip/compose-lint to a version that resolves this vulnerability.

    Fixed in 0.25.0
  3. Upgrade

    Upgrade composelint/compose-lint to a version that resolves this vulnerability.

    Fixed in 0.32.0
  4. Configuration

    Run compose-lint with --no-env to close the COMPOSE_FILE and env_file: routes; this does not close the other symlink routes.

    compose-lint --no-env = enabled
  5. Compensating control

    On older versions, do not run compose-lint on untrusted pull requests on a machine whose files outside the checkout contain credentials.

Event History

Nov 9, 2026
CVE Published
via OSV·05:46 PM
Data Sourced
via OSV·05:46 PM
DescriptionSeverityWeakness
Nov 10, 2026
Advisory Published
via GitHub·03:57 PM
Data Sourced
via GitHub·03:57 PM
DescriptionWeaknessAffected Software
Data Sourced
via OSV·03:57 PM
Affected Software

Frequently Asked Questions

1

Who is exposed to this issue?

Projects are exposed when they contain a symbolic link that compose-lint uses as the Compose file, compose.override.yml, a COMPOSE_FILE entry, or an env_file target, and that link resolves outside the project. The affected feature scope depends on version: the primary Compose file is affected from 0.2.0, compose.override.yml and COMPOSE_FILE from 0.22.0, and env_file from 0.23.0.

2

What must happen for information to be disclosed?

For Compose-related files outside the project, the selected target must fail YAML parsing; compose-lint may then include an attacker-uncontrolled line in stderr, JSON errors, and SARIF notifications. For an external env_file, CL-0020 and CL-0021 findings can reveal credential-like key names, but env_file values are not printed.

3

Does exploitation change the lint result or require control over the leaked content?

No. The pass-or-fail result is unchanged, and the attacker can select the target path but cannot select the exact line quoted by a YAML parser failure.

4

What is the remediation?

Upgrade compose-lint to version 0.25.0, which fixes the issue. If upgrading is not immediately possible, avoid project-controlled symlinks for Compose-related files and env_file targets that resolve outside the project.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203