compose-lint: Text
Affects compose-lintSource GCVE Database
Not known to be exploited · CVSS 5.3 Medium : upgrade to 0.32.0 when convenient.
Data as of 10 Nov 2026, 19:05 UTC
Thin evidence
One scorer or none| CNA (GitHub_M) | CVSS 4.0 | 5.3 |
|---|
- Patch
- Available – fixed in 0.32.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:L/VA:N/SC:N/SI:L/SA:NExploitation evidence
Disclosed: evidence found.
CVE published 10 Nov 2026
Detectable: no evidence on record.
No public nuclei template indexed
Weaponized: no evidence on record.
No public exploit code indexed in Metasploit or Exploit-DB
Exploited in the wildExploited: no evidence on record.
Not in CISA KEV and no source reports exploitation
Observed by OffSeq MirageSeen by Mirage: no evidence on record.
No attack traffic recorded by OffSeq Mirage sensors
A missing step is not evidence of safety. Sources: cve.org (opens in a new tab), the Metasploit, Exploit-DB and nuclei-templates index as of 10 Nov 2026.
What to do
Upgrade compose-lint to 0.32.0.
Affected software
| Product | Affected | Fixed in |
|---|---|---|
| PyPIcompose-lint | Affected
| Fixed in
|
Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.
Description
### Impact 0.31.0 fixed GHSA-6f4g-xm8v-pgv6, where text from a Compose file became GitHub Actions workflow commands in compose-lint's output. The fix escapes the command openers in everything compose-lint prints, and the 0.31.0 changelog says the report "escapes both openers (also covering Azure Pipelines)". Five paths were left open: - **Unicode whitespace before a line-leading `::`.** The runner strips all Unicode whitespace from the start of a line before it looks for a command. compose-lint only accounted for spaces and tabs, so a no-break space or another Unicode space ahead of `::` is not escaped. It can come from a Compose value, or from a file name: the text report's file heading and per-file summary, and the `fix` summary on stderr, start with the path as given, so a directory named with a leading no-break space followed by `::` puts a command at the start of a line. This reaches those lines, the text report's fix guidance, the `fix` dry-run diff, and continuation lines of stderr diagnostics. - **JSON and SARIF printed to stdout.** `--format json` and `--format sarif` output never passed through the sanitizer, so `##[` inside a service name or other value reaches the log intact when the output isn't redirected to a file. - **Command-line errors.** When a repository path reaches compose-lint's arguments without a `--` before it, the argument parser prints it raw in its error message. That includes a carriage return, which the runner treats as a line break, so a command can also start a new line there. - **Azure Pipelines.** `##vso[` logging commands were not escaped on any path, despite the changelog's Azure claim. - **An error message in the GitHub Action (0.30.0 and 0.31.0).** When `sarif-file:` names a file in a subdirectory that can't be created, the Action prints the directory's resolved path in an error message, outside the window in which it turns command processing off. A pull request can commit a symlink on that path to a directory whose name contains a newline followed by a command. The documented setup, `sarif-file: results.sarif` at the repository root, is not affected. A pull request can therefore create annotations, fold or hide parts of the job log, or issue other commands the runner accepts, when CI runs compose-lint over it, before anyone reviews it. The pass/fail result is not changed. Affected setups are those that print compose-lint's output to a CI log without the GitHub Action: the `compose-lint` package run directly in a workflow, the pre-commit hook run in CI, and the Docker image. The pre-commit hook is affected in its default configuration: it passes each changed file's path to compose-lint, and a path whose directory name starts with Unicode whitespace and `::` reaches the report's file heading. The JSON/SARIF and command-line paths also need output left on stdout, or `args:` without the documented trailing `--`, which is why they alone would score lower. The GitHub Action turns command processing off around each compose-lint run, so of these paths only its own error message affects it, and only when `sarif-file:` points into a subdirectory. That setup is outside the documented one, which is why that path alone would also score lower. Found during an internal pre-1.0 security review. **Docker image.** `composelint/compose-lint` tag 0.31.0, the matching minor tag, and `latest` are affected. Releases before 0.31.0 are covered by GHSA-6f4g-xm8v-pgv6, except the Action's error message, which also affects Action 0.30.0. ### Patches Fixed in 0.32.0. The line-start escaping covers every character the runner strips before `::`, so it holds for quoted values and file names alike. JSON and SARIF on stdout escape `##[` inside strings as `\u005b`, which decodes to the same data. argparse's own messages go through the same sanitizer. `##vso[` is escaped everywhere. In the Action, the SARIF-directory error names the `sarif-file:` input as written. ### Workarounds - Upgrade to 0.32.0 or later. - On GitHub Actions, use the `tmatens/compose-lint` Action, or bracket the compose-lint step with `::stop-commands::<random token>` and `::<token>::`, as the Action does. - In the Action, keep `sarif-file` at the workspace root, for example `sarif-file: results.sarif`. - Write `--format json` and `--format sarif` output to a file rather than the log. - End the pre-commit hook's `args:` with `--`. This closes the command-line path only; it does not stop a file name at the start of a report line, so in CI also bracket the pre-commit step with `::stop-commands::` as above. - On Azure Pipelines, don't print compose-lint's output from runs over untrusted pull requests to the job log. ### Reproduction On compose-lint 0.31.0 on a GitHub-hosted runner (runner 2.337.0), each of the following creates an annotation: - a Compose file with `image: "nginx\n\u00a0::notice::X"`, linted with the text report; - a directory named `\u00a0::notice::X` (a no-break space, then `::notice::X`) holding a `comp
References
- github.com/tmatens/compose-lint/security/advisories/GHSA-r7j4-crjv-h467 (opens in a new tab)
- github.com/tmatens/compose-lint/pull/945 (opens in a new tab)
- github.com/tmatens/compose-lint/commit/542e63126f795564a65c63887ea0dc558a500688 (opens in a new tab)
- github.com/tmatens/compose-lint (opens in a new tab)
- github.com/tmatens/compose-lint/releases/tag/v0.32.0 (opens in a new tab)