CVE-2026-45793: Composer/composer Github Actions Issued GITHUB_TOKEN Disclosure Vulnerability

HIGH
Advisory Identifier: GHSA-f9f8-rm49-7jv2
CVSS 7.5
CWE-200
Published
Advisory Summary

CVE-2026-45793 is a HIGH (CVSS 7.5) github actions issued github_token disclosure vulnerability (CWE-200: Exposure of Sensitive Information to an Unauthorized Actor) affecting Composer/composer libraries in the Packagist ecosystem. The issue involves github actions issued github_token disclosure in github actions logs. Remediation is available by upgrading affected packages to version 1.10.28, 2.9.8, 2.2.28.

CVE-2026-45793 at a Glance

CVE Identifier CVE-2026-45793
GHSA Identifier GHSA-f9f8-rm49-7jv2
Severity HIGH
CVSS v3.1 Base Score 7.5
CWE Classification CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
Affected Product Composer/composer
Package Ecosystem Packagist
Published Date
Last Updated

Security Impact

CVSS: 7.5

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity None (I:N)
Availability None (A:N)

How to Fix CVE-2026-45793

To remediate this vulnerability, upgrade all affected Composer/composer dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

composer/composer fixed: 1.10.28
Upgrade composer/composer to 1.10.28
composer/composer fixed: 2.9.8
Upgrade composer/composer to 2.9.8
composer/composer fixed: 2.2.28
Upgrade composer/composer to 2.2.28
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for composer/composer

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-45793, inspect your project dependencies for Composer/composer:

inspect dependencies for composer/composer

Analyze the terminal output to locate any version of Composer/composer in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.10.28), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-200: Exposure of Sensitive Information to an Unauthorized Actor, where the product exposes sensitive information to an actor that is not explicitly authorized to have access to that information. In Composer/composer, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary Composer leaks the full contents of tokens configured as GitHub OAuth tokens if they do not match Composer's expected format for such tokens to stderr. GitHub has introduced a new format for GitHub Actions GITHUB_TOKEN values. These tokens are validated in the same way by Composer on GitHub Actions. The new format including a `-` (hyphen) fails Composer's validation and leads to disclosure of the GITHUB_TOKEN in logs. Many widely-used Actions (e.g. `shivammathur/setup-php`) auto-register `GITHUB_TOKEN` into composer's global `auth.json`, so the leak triggers without any unusual user configuration. GitHub Actions tokens expire when the associated job finishes, and they are scoped to the respective repository only. So in most regular cases the Composer validation, which errors while leaking the token, also immediately ends the job, expiring the token immediately. Tokens expire at the very latest after 6 hours on GitHub-hosted runners. If you use self-hosted runner, expiration is at most 24 hours after creation. The new token format is being rolled out gradually, so not all repositories are affected yet, but will be soon. Classic `ghp_` PATs are not affected by the regex bug per se, but the same leak primitive applies to any future credential that fails validation for any reason. ### Details When a GitHub token fails regular expression validation of the character set, the rejected token is interpolated verbatim into the `UnexpectedValueException` message thrown by `Composer\IO\BaseIO::loadConfiguration()`, which Symfony Console then prints. Validation reliably fails for any token containing a `-` (hyphen), which includes the modern `ghs_<id>_<base64url-JWT>` GitHub App installation token format, the same format used by GitHub Actions' built-in `GITHUB_TOKEN` and by `actions/create-github-app-token`. Severity: medium. Pre-conditions are common in real-world CI. Practical blast radius is bounded by the leaked credential's scope and TTL (short for a workflow `GITHUB_TOKEN`, longer for App-minted tokens or user-issued credentials that happen to contain `-`). Vulnerable code, `src/Composer/IO/BaseIO.php` (line 139 on `main`, line 143 on 2.8.x), inside `loadConfiguration()`: ```php // allowed chars for GH tokens are from https://github.blog/changelog/2021-03-04-authentication-token-format-updates/ // plus dots which were at some point used for GH app integration tokens if (!Preg::isMatch('{^[.A-Za-z0-9_]+$}', $token)) { throw new \UnexpectedValueException( 'Your github oauth token for '.$domain.' contains invalid characters: "'.$token.'"' ); } ``` Three issues combine to produce the leak: 1. **The rejected token is interpolated into the exception message.** The exception bubbles up to Symfony Console's default error renderer, which writes it to stderr. Any environment that captures stderr (CI logs, log shippers, monitoring, support transcripts) now has the raw token. 2. **The validation regex `^[.A-Za-z0-9_]+$` does not permit `-`.** GitHub's current `ghs_<numeric-id>_<base64url-JWT>` structured installation tokens routinely contain `-`, because base64url (RFC 4648 §5) uses `-` and `_` as URL-safe replacements for `+` and `/`. The regex was chosen in 2021 on the understanding that GitHub tokens use only `[A-Za-z0-9_]` plus `.`. 3. **Detection / mitigation in upstream platforms is unreliable.** GitHub Actions' built-in secret masker matches registered values as exact substrings. When the exception message is rendered by Symfony Console it may wrap, embed in `In BaseIO.php line N:` framing, or interleave with ANSI control sequences. So the masker does not redact, and the plaintext token reaches the log.

CVE-2026-45793 Affected Composer/composer Versions

3 component(s)
Fixed Versions:
1.10.282.9.82.2.28
Product / Package Ecosystem Affected Versions Fixed Version
composer/composer
Packagist
≥ 1.0
< 1.10.28
1.10.28
composer/composer
Packagist
≥ 2.3.0
< 2.9.8
2.9.8
composer/composer
Packagist
≥ 2.0.0
< 2.2.28
2.2.28

References

Frequently Asked Questions

What is CVE-2026-45793?
CVE-2026-45793 is a security vulnerability in Composer/composer involving Github Actions issued GITHUB_TOKEN disclosure in GitHub Actions logs under CWE-200: Exposure of Sensitive Information to an Unauthorized Actor.
Which Composer/composer versions are affected?
Affected versions include releases prior to 1.10.28, 2.9.8, 2.2.28 across affected packages: composer/composer.
What version fixes CVE-2026-45793?
Upgrading to 1.10.28, 2.9.8, 2.2.28 (or the latest patched release for your respective branch) resolves the vulnerability.
Is composer/composer affected?
Yes, composer/composer is affected in releases prior to 1.10.28, 2.9.8, 2.2.28. Upgrade your dependency to 1.10.28, 2.9.8, 2.2.28 or later.
What is the CVSS score of CVE-2026-45793?
CVE-2026-45793 has a CVSS v3.1 base score of 7.5 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N.
What CWE is associated with CVE-2026-45793?
CVE-2026-45793 is classified under CWE-200: Exposure of Sensitive Information to an Unauthorized Actor (The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.).
How can I check Packagist dependencies for CVE-2026-45793?
Run the dependency tree command: 'inspect dependencies for composer/composer'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-f9f8-rm49-7jv2",
  "modified" : "2026-07-20T19:12:15Z",
  "published" : "2026-05-19T16:17:58Z",
  "aliases" : [ "CVE-2026-45793" ],
  "summary" : "Github Actions issued GITHUB_TOKEN disclosure in GitHub Actions logs",
  "details" : "### Summary\n\nComposer leaks the full contents of tokens configured as GitHub OAuth tokens if they do not match Composer's expected format for such tokens to stderr. GitHub has introduced a new format for GitHub Actions GITHUB_TOKEN values. These tokens are validated in the same way by Composer on GitHub Actions. The new format including a `-` (hyphen) fails Composer's validation and leads to disclosure of the GITHUB_TOKEN in logs.\n\nMany widely-used Actions (e.g. `shivammathur/setup-php`) auto-register `GITHUB_TOKEN` into composer's global `auth.json`, so the leak triggers without any unusual user configuration.\n\nGitHub Actions tokens expire when the associated job finishes, and they are scoped to the respective repository only. So in most regular cases the Composer validation, which errors while leaking the token, also immediately ends the job, expiring the token immediately. Tokens expire at the very latest after 6 hours on GitHub-hosted runners. If you use self-hosted runner, expiration is at most 24 hours after creation. The new token format is being rolled out gradually, so not all repositories are affected yet, but will be soon.\n\nClassic `ghp_` PATs are not affected by the regex bug per se, but the same leak primitive applies to any future credential that fails validation for any reason.\n\n### Details\n\nWhen a GitHub token fails regular expression validation of the character set, the rejected token is interpolated verbatim into the `UnexpectedValueException` message thrown by `Composer\\IO\\BaseIO::loadConfiguration()`, which Symfony Console then prints. Validation reliably fails for any token containing a `-` (hyphen), which includes the modern `ghs_<id>_<base64url-JWT>` GitHub App installation token format, the same format used by GitHub Actions' built-in `GITHUB_TOKEN` and by `actions/create-github-app-token`. \n\nSeverity: medium. Pre-conditions are common in real-world CI. Practical blast radius is bounded by the leaked credential's scope and TTL (short for a workflow `GITHUB_TOKEN`, longer for App-minted tokens or user-issued credentials that happen to contain `-`).\n\nVulnerable code, `src/Composer/IO/BaseIO.php` (line 139 on `main`, line 143 on 2.8.x), inside `loadConfiguration()`:\n\n```php\n// allowed chars for GH tokens are from https://github.blog/changelog/2021-03-04-authentication-token-format-updates/\n// plus dots which were at some point used for GH app integration tokens\nif (!Preg::isMatch('{^[.A-Za-z0-9_]+$}', $token)) {\n    throw new \\UnexpectedValueException(\n        'Your github oauth token for '.$domain.' contains invalid characters: \"'.$token.'\"'\n    );\n}\n```\n\nThree issues combine to produce the leak:\n\n1. **The rejected token is interpolated into the exception message.** The exception bubbles up to Symfony Console's default error renderer, which writes it to stderr. Any environment that captures stderr (CI logs, log shippers, monitoring, support transcripts) now has the raw token.\n\n2. **The validation regex `^[.A-Za-z0-9_]+$` does not permit `-`.** GitHub's current `ghs_<numeric-id>_<base64url-JWT>` structured installation tokens routinely contain `-`, because base64url (RFC 4648 §5) uses `-` and `_` as URL-safe replacements for `+` and `/`. The regex was chosen in 2021 on the understanding that GitHub tokens use only `[A-Za-z0-9_]` plus `.`.\n\n3. **Detection / mitigation in upstream platforms is unreliable.** GitHub Actions' built-in secret masker matches registered values as exact substrings. When the exception message is rendered by Symfony Console it may wrap, embed in `In BaseIO.php line N:` framing, or interleave with ANSI control sequences. So the masker does not redact, and the plaintext token reaches the log.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "composer/composer"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.3.0"
      }, {
        "fixed" : "2.9.8"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "composer/composer"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.0.0"
      }, {
        "fixed" : "2.2.28"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "composer/composer"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "1.0"
      }, {
        "fixed" : "1.10.28"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/composer/composer/security/advisories/GHSA-f9f8-rm49-7jv2"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-45793"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/composer/composer/pull/12853"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/composer/composer/pull/12855"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/composer/composer/commit/3f5e7f9fbfa541137d6d1d5643ec3b718e9d5039"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/composer/composer/commit/65e6390c49f1a11cd8b660d81822086db51fe2d1"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/composer/composer/commit/e66c8fdb7ff5409bd2f358c5f194038e49e93714"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/FriendsOfPHP/security-advisories/blob/master/composer/composer/CVE-2026-45793.yaml"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/composer/composer"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/composer/composer/releases/tag/1.10.28"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/composer/composer/releases/tag/2.2.28"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/composer/composer/releases/tag/2.9.8"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-200" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-05-19T16:17:58Z",
    "nvd_published_at" : "2026-07-15T17:16:48Z"
  }
}