{"id":"CVE-2026-123372","kind":"vulnerability","aliases":["CVE-2026-123372"],"related":[],"title":"compose-lint: linter echoes .env secrets into logs and scan reports","description":"compose-lint is a Docker Compose security linter that identifies dangerous misconfigurations before deployment. From 0.22.0 until 0.32.0, compose-lint substitutes values from a sibling .env file into image fields and quotes the resolved value in CL-0004 and CL-0019 finding messages and fix text. In a workflow that writes secrets into that file and then lints untrusted pull-request content, an attacker can reference a secret variable so its whole value reaches the job log, JSON output, SARIF artifacts, and Code Scanning alerts. Fork pull requests normally lack secrets, so exploitation requires a secret-bearing workflow such as pull_request_target, same-repository branches, or a retained .env on a self-hosted runner, and the pass or fail result is unchanged. This issue is fixed in version 0.32.0.","summary":"compose-lint, a Docker Compose security linter, copies values from a sibling .env file into finding messages when an image field references them. In a CI workflow that writes secrets to that file and lints untrusted pull-request content, an attacker can make a secret's full value appear in job logs, JSON output, SARIF files and Code Scanning alerts.","severity":"low","cvss":2.3,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["ci","compose-lint","docker-compose","github-actions","package"],"not_affected_if":["fork-prs-only","no-secrets-in-env-file","version-0.32.0-or-later"],"how_to_check":"- Run `compose-lint --version` or check the pinned version in your lockfile or workflow file; affected versions are `0.22.0` through `0.32.0`.\n- Check whether CI writes secrets into a `.env` file next to a Compose file and then runs compose-lint on pull-request content, including `pull_request_target` workflows.\n- Check whether a retained `.env` file is left on a self-hosted runner where compose-lint runs.","fix":"- compose-lint: move to `0.32.0`","status":"open","published_at":"2026-11-09T18:17:26+00:00","first_seen_at":"2026-11-09T18:27:56+00:00","triaged_at":"2026-11-09T18:29:29+00:00","updated_at":"2026-11-09T18:29:29+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-11-09T18:29:29Z","model":"claude-haiku-5-5","output":{"fix":"- compose-lint: move to `0.32.0`","reach":"internet","title":"compose-lint: linter echoes .env secrets into logs and scan reports","impact":"medium","summary":"compose-lint, a Docker Compose security linter, copies values from a sibling .env file into finding messages when an image field references them. In a CI workflow that writes secrets to that file and lints untrusted pull-request content, an attacker can make a secret's full value appear in job logs, JSON output, SARIF files and Code Scanning alerts.","audience":"developers","category":"package","nicknames":[],"who_cares":["compose-lint","github-actions","docker-compose","ci"],"confidence":0.7,"fix_status":"available","needs_auth":"unknown","worst_case":"secret values appear in CI logs and Code Scanning alerts","analyst_note":"","how_to_check":"- Run `compose-lint --version` or check the pinned version in your lockfile or workflow file; affected versions are `0.22.0` through `0.32.0`.\n- Check whether CI writes secrets into a `.env` file next to a Compose file and then runs compose-lint on pull-request content, including `pull_request_target` workflows.\n- Check whether a retained `.env` file is left on a self-hosted runner where compose-lint runs.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["no-secrets-in-env-file","fork-prs-only","version-0.32.0-or-later"],"who_is_affected":"Exposure needs a workflow that writes real secrets into a .env file beside the Compose files and then lints content an outsider can change, such as pull_request_target jobs, same-repository branches, or a retained .env on a self-hosted runner. Fork pull requests usually have no secrets and so are not a path. Teams that run compose-lint only on trusted code with no secrets in the workspace can skip it.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.000813,"input_tokens":4767,"output_tokens":673,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-0004':131C '-0019':134C '-123372':15A,18A '-2026':14A,17A '0.22.0':108C '0.32.0':110C,227C 'action':28B 'alert':91B,179C 'appear':80B 'artifact':175C 'attack':72B,158C 'bear':192C 'branch':202C 'ci':19B,56B 'cl':130C,133C 'code':89B,177C 'compos':2A,21B,25B,31B,35B,93C,98C,112C 'compose-lint':1A,20B,30B,92C,111C 'content':70B,156C 'copi':38B 'cve':13A,16A 'danger':103C 'deploy':106C 'docker':24B,34B,97C 'docker-compos':23B 'echo':5A 'env':6A,43B,119C,206C 'exploit':187C 'fail':217C 'field':51B,123C 'file':44B,63B,87B,120C,148C 'find':46B,135C 'fix':138C,224C 'fork':180C 'full':78B 'github':27B 'github-act':26B 'host':211C 'identifi':102C 'imag':50B,122C 'issu':222C 'job':82B,170C 'json':84B,172C 'lack':184C 'lint':3A,22B,32B,65B,94C,113C,151C 'linter':4A,37B,100C 'log':9A,83B,171C 'make':74B 'messag':47B,136C 'misconfigur':104C 'normal':183C 'output':85B,173C 'packag':29B 'pass':215C 'pull':68B,154C,181C,196C 'pull-request':67B,153C 'quot':125C 'reach':168C 'refer':52B,160C 'report':12A 'repositori':201C 'request':69B,155C,182C,197C 'requir':188C 'resolv':127C 'result':218C 'retain':205C 'runner':212C 'same-repositori':199C 'sarif':86B,174C 'scan':11A,90B,178C 'secret':7A,60B,76B,145C,162C,185C,191C 'secret-bear':190C 'secur':36B,99C 'self':210C 'self-host':209C 'sibl':42B,118C 'substitut':114C 'target':198C 'text':139C 'unchang':220C 'untrust':66B,152C 'valu':39B,79B,115C,128C,167C 'variabl':163C 'version':226C 'whole':166C 'workflow':57B,142C,193C 'write':59B,144C","nicknames":[],"mitigations":[],"who_affected":"Exposure needs a workflow that writes real secrets into a .env file beside the Compose files and then lints content an outsider can change, such as pull_request_target jobs, same-repository branches, or a retained .env on a self-hosted runner. Fork pull requests usually have no secrets and so are not a path. Teams that run compose-lint only on trusted code with no secrets in the workspace can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["ci","composelint","dockercompose","githubactions","low","package"],"campaign_type":null,"search_a":"'-123372':15A,18A '-2026':14A,17A 'compos':2A 'compose-lint':1A 'cve':13A,16A 'echo':5A 'env':6A 'lint':3A 'linter':4A 'log':9A 'report':12A 'scan':11A 'secret':7A","search_b":"'action':28B 'alert':91B 'appear':80B 'attack':72B 'ci':19B,56B 'code':89B 'compos':21B,25B,31B,35B 'compose-lint':20B,30B 'content':70B 'copi':38B 'docker':24B,34B 'docker-compos':23B 'env':43B 'field':51B 'file':44B,63B,87B 'find':46B 'full':78B 'github':27B 'github-act':26B 'imag':50B 'job':82B 'json':84B 'lint':22B,32B,65B 'linter':37B 'log':83B 'make':74B 'messag':47B 'output':85B 'packag':29B 'pull':68B 'pull-request':67B 'refer':52B 'request':69B 'sarif':86B 'scan':90B 'secret':60B,76B 'secur':36B 'sibl':42B 'untrust':66B 'valu':39B,79B 'workflow':57B 'write':59B","search_c":"'-0004':131C '-0019':134C '0.22.0':108C '0.32.0':110C,227C 'alert':179C 'artifact':175C 'attack':158C 'bear':192C 'branch':202C 'cl':130C,133C 'code':177C 'compos':93C,98C,112C 'compose-lint':92C,111C 'content':156C 'danger':103C 'deploy':106C 'docker':97C 'env':119C,206C 'exploit':187C 'fail':217C 'field':123C 'file':120C,148C 'find':135C 'fix':138C,224C 'fork':180C 'host':211C 'identifi':102C 'imag':122C 'issu':222C 'job':170C 'json':172C 'lack':184C 'lint':94C,113C,151C 'linter':100C 'log':171C 'messag':136C 'misconfigur':104C 'normal':183C 'output':173C 'pass':215C 'pull':154C,181C,196C 'pull-request':153C 'quot':125C 'reach':168C 'refer':160C 'repositori':201C 'request':155C,182C,197C 'requir':188C 'resolv':127C 'result':218C 'retain':205C 'runner':212C 'same-repositori':199C 'sarif':174C 'scan':178C 'secret':145C,162C,185C,191C 'secret-bear':190C 'secur':99C 'self':210C 'self-host':209C 'sibl':118C 'substitut':114C 'target':198C 'text':139C 'unchang':220C 'untrust':152C 'valu':115C,128C,167C 'variabl':163C 'version':226C 'whole':166C 'workflow':142C,193C 'write':144C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-09-28T16:12:08+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"security-advisories@github.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-123372","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-123372","severity":null,"published_at":"2026-11-09T18:17:26+00:00","modified_at":"2026-11-09T18:17:26+00:00","first_seen_at":"2026-11-09T18:27:56+00:00","fetched_at":"2026-11-09T18:27:56+00:00","note":null}],"documents":[{"id":108804,"url":"https://github.com/tmatens/compose-lint/commit/977da9724789264c2662afe47f79220e915442c2","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":108802,"url":"https://github.com/tmatens/compose-lint/releases/tag/v0.32.0","title":"Release notes: github.com","kind":"release","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release notes: github.com"},{"id":108806,"url":"https://github.com/tmatens/compose-lint/security/advisories/GHSA-jf3h-8jvx-vcrg","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-09-28T16:12:08+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}