GHSA-F42P-WJW5-97QH

Vulnerability from github – Published: 2026-11-09 21:56 – Updated: 2026-11-09 21:56
VLAI
Summary
zizmor: Debug logging prints available GitHub credentials in cleartext
Details

Summary

zizmor 1.27.0 exposes GitHub access tokens in cleartext when debug-level logging is enabled. Tokens supplied via environment variables (GH_TOKEN, GITHUB_TOKEN, ZIZMOR_GITHUB_TOKEN), or the corresponding command-line options (--gh-token, --github-token, --zizmor-github-token) are included in the debug representation of the parsed application configuration and written to stderr.

The affected logging is enabled by a single -v/--verbose or an applicable RUST_LOG directive.

Details

The issue was introduced in commit 919bea46, merged through PR #2180. Version 1.26.1 and earlier are unaffected. Version 1.27.0 is the first and only affected release.

zizmor accepts GitHub credentials to perform authenticated GitHub API requests for the purposes of retrieving remote GitHub repositories and performing online audits that may require resolving information such as action references, commits, or repository metadata. A GitHub credential is used to avoid unauthenticated API limits and, when applicable, provide access to private repositories.

PR #2180 was intended to improve the experience around zizmor’s implicit offline mode. It also moved the CLI types into a dedicated module and added a debug log of the fully parsed App value:

tracing::debug!("app: {app:?}");

This diagnostic is useful for understanding the effective CLI state, including whether offline operation was explicit or inferred. However, the same commit added derived Debug implementations to App, NetworkArgs, and GitHubToken(String). Before the debug event is emitted, the compatibility token aliases are merged into app.network.gh_token.

The resulting stderr contains the token verbatim. Explicit --offline clears the token before the debug event, but normal online operation and --no-online-audits retain it.

PoC

Using zizmor at v1.27.0:

GH_TOKEN=gho_ZIZMOR_MRE zizmor --verbose example.yml

will emit

DEBUG zizmor: app: App { input: InputArgs { inputs: ["example.yml"], collect: [Default], strict_collection: false }, audit: AuditArgs { fix: None, pedantic: false, persona: Regular, min_severity: None, min_confidence: None, no_ignores: false }, output: OutputArgs { verbose: Verbosity { verbose: 1, quiet: 0, phantom: PhantomData<clap_verbosity_flag::InfoLevel> }, format: Plain, no_progress: false, color: None, render_links: Auto, show_audit_urls: Auto, no_exit_codes: false, naches: false }, network: NetworkArgs { offline: false, gh_token: Some(GitHubToken("gho_ZIZMOR_MRE")), github_token: None, zizmor_github_token: None, gh_hostname: Standard("github.com"), no_online_audits: false, cache_dir: "/Users/shaan/.cache/zizmor" }, args: GlobalArgs { lsp: LspArgs { lsp: false, stdio: false }, config: None, no_config: false, completions: None, thanks: false, help: (), version: () } }

Impact

In practice, the impact of this vulnerability should be mediated by GitHub's own layered defenses, including secret redaction in Actions logs and automatic credential revocation in issue/PR/etc. comments. However, zizmor itself should never log sensitive materials, and so the behavior is still considered vulnerable even if compensating controls exist in downstream systems.

An affected user must enable debug logging while supplying a GitHub credential, and the resulting stderr must be available to another party. Plausible disclosure channels include a public bug report, CI log or artifact, or terminal capture. A potential attacker only needs permission to read the disclosed logs.

The resulting impact depends on the token's scopes, repository access, and lifetime. A minimally scoped token may only expose public read-only data, while a broader OAuth token or personal access token may permit private-repository or modification of repositories, packages, workflows, or organization resources. The default informational logging level is unaffected. Exploitation requires debug logging and subsequent log exposure, which limits likelihood.

Notably, because zizmor’s bug-report template asks users to rerun commands with --verbose and paste the complete logs, this can result in credentials being copied into public issues or other support channels.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "zizmor"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.27.0"
            },
            {
              "fixed": "1.28.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "1.27.0"
      ]
    }
  ],
  "aliases": [
    "CVE-2026-102289"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-532"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-11-09T21:56:25Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\n\nzizmor 1.27.0 exposes GitHub access tokens in cleartext when debug-level logging is enabled. Tokens supplied via environment variables (`GH_TOKEN`, `GITHUB_TOKEN`, `ZIZMOR_GITHUB_TOKEN`), or the corresponding command-line options (`--gh-token`, `--github-token`, `--zizmor-github-token`) are included in the debug representation of the parsed application configuration and written to stderr.\n\nThe affected logging is enabled by a single `-v`/`--verbose` or an applicable `RUST_LOG` directive. \n\n### Details\n\nThe issue was introduced in commit [919bea46](https://github.com/zizmorcore/zizmor/commit/919bea4635bae204d5186e5743cb263c70b518b4), merged through [PR #2180](https://github.com/zizmorcore/zizmor/pull/2180). Version `1.26.1` and earlier are unaffected. Version `1.27.0` is the first and only affected release.\n\nzizmor accepts GitHub credentials to perform authenticated GitHub API requests for the purposes of retrieving remote GitHub repositories and performing online audits that may require resolving information such as action references, commits, or repository metadata. A GitHub credential is used to avoid unauthenticated API limits and, when applicable, provide access to private repositories.\n\nPR #2180 was intended to improve the experience around zizmor\u2019s implicit offline mode. It also moved the CLI types into a dedicated module and added a debug log of the fully parsed `App` value:\n\n```rust\ntracing::debug!(\"app: {app:?}\");\n```\n\n This diagnostic is useful for understanding the effective CLI state, including whether offline operation was explicit or inferred. However, the same commit added derived `Debug` implementations to `App`, `NetworkArgs`, and `GitHubToken(String)`.\nBefore the debug event is emitted, the compatibility token aliases are merged into `app.network.gh_token`.\n\nThe resulting stderr contains the token verbatim. Explicit `--offline` clears the token before the debug event, but normal online operation and `--no-online-audits` retain it.\n\n### PoC\n\nUsing `zizmor` at `v1.27.0`:\n\n`GH_TOKEN=gho_ZIZMOR_MRE zizmor --verbose example.yml`\n\nwill emit\n\n```text\nDEBUG zizmor: app: App { input: InputArgs { inputs: [\"example.yml\"], collect: [Default], strict_collection: false }, audit: AuditArgs { fix: None, pedantic: false, persona: Regular, min_severity: None, min_confidence: None, no_ignores: false }, output: OutputArgs { verbose: Verbosity { verbose: 1, quiet: 0, phantom: PhantomData\u003cclap_verbosity_flag::InfoLevel\u003e }, format: Plain, no_progress: false, color: None, render_links: Auto, show_audit_urls: Auto, no_exit_codes: false, naches: false }, network: NetworkArgs { offline: false, gh_token: Some(GitHubToken(\"gho_ZIZMOR_MRE\")), github_token: None, zizmor_github_token: None, gh_hostname: Standard(\"github.com\"), no_online_audits: false, cache_dir: \"/Users/shaan/.cache/zizmor\" }, args: GlobalArgs { lsp: LspArgs { lsp: false, stdio: false }, config: None, no_config: false, completions: None, thanks: false, help: (), version: () } }\n```\n\n### Impact\n\nIn practice, the impact of this vulnerability should be mediated by GitHub\u0027s own layered defenses, including secret redaction in Actions logs and automatic credential revocation in issue/PR/etc. comments. However, zizmor itself should never log sensitive materials, and so the behavior is still considered vulnerable even if compensating controls exist in downstream systems.\n\nAn affected user must enable debug logging while supplying a GitHub credential, and the resulting stderr must be available to another party. Plausible disclosure channels include a public bug report, CI log or artifact, or terminal capture. A potential attacker only needs permission to read the disclosed logs.\n\nThe resulting impact depends on the token\u0027s scopes, repository access, and lifetime. A minimally scoped token may only expose public read-only data, while a broader OAuth token or personal access token may permit private-repository or modification of repositories, packages, workflows, or organization resources. The default informational logging level is unaffected. Exploitation requires debug logging and subsequent log exposure, which limits likelihood.\n\nNotably, because `zizmor`\u2019s bug-report template asks users to rerun commands with `--verbose` and paste the complete logs, this can result in credentials being copied into public issues or other support channels.",
  "id": "GHSA-f42p-wjw5-97qh",
  "modified": "2026-11-09T21:56:25Z",
  "published": "2026-11-09T21:56:25Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/zizmorcore/zizmor/security/advisories/GHSA-f42p-wjw5-97qh"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zizmorcore/zizmor/pull/2213"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zizmorcore/zizmor/pull/2215"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zizmorcore/zizmor/commit/0731e01706af273be860d3d221e4d122e6741b6f"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zizmorcore/zizmor/commit/724d0e86f4c073c3dc64507fb6c39bc20e46a48f"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/zizmorcore/zizmor"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zizmorcore/zizmor/releases/tag/v1.28.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:A/VC:H/VI:N/VA:N/SC:H/SI:H/SA:H",
      "type": "CVSS_V4"
    }
  ],
  "summary": "zizmor: Debug logging prints available GitHub credentials in cleartext"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
How durations are calculated

Following the VTEM framework (Black Hat USA 2015), time to patch starts when the vendor or a coordinator was informed, total time to patch at discovery, and disclosure to patch at public disclosure; vendor response time runs from the report to its acknowledgement. Time to exploit and time unpatched start at the earliest discovery or report, falling back to public disclosure. Unpatched time ends at the first recorded patch, or the calculation time when no patch is recorded. Exploitation to patch shows the interval between those two events; a published proof of concept is a public exploit, not exploitation.

Each result shows its source dates. A negative interval means the end event came first; when date-only inputs leave the order open, the result says so. Date-only inputs are approximate. The earliest evidence wins: KEV report dates and sightings are labelled as such. Records describing another vulnerability are listed but never calculated from, and a PoC alone does not establish exploitation. Missing patch evidence does not prove that no patch exists. Filters below change the event list only.

Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.