A high-severity vulnerability in Composer, the PHP dependency manager, has been actively exposing GitHub Actions tokens in CI/CD pipeline logs, prompting Packagist to issue an emergency update advisory for the entire PHP ecosystem.
Security advisory GHSA-f9f8-rm49-7jv2, rated CVSS 7.5 (High), affects Composer versions before 2.9.8, 2.2.28 LTS, and 1.10.28, and is directly tied to GitHub’s recent rollout of a new token format for GitHub App installation tokens.
The root cause of this disclosure is a mismatch between Composer’s authentication validation logic and GitHub’s updated token format. On April 24, 2026, GitHub announced that newly minted GitHub App installation tokens, including the auto-injected GITHUB_TOKEN used in Actions workflows would migrate to a longer, variable-length format: ghs_APPID_JWT.
The new format includes a hyphen character and produces tokens approximately 520 characters long, far exceeding the old fixed 40-character limit ghs_[A-Za-z0-9]{36} pattern.
Composer Vulnerability
Composer’s internal validation regex did not allow hyphens, so when a workflow presented one of these new-format tokens as GitHub OAuth credentials, Composer rejected it and critically printed the full token value to stderr as part of the error message.
Since GitHub Actions captures stderr output in job logs, the token was immediately persisted in plain text, where anyone with repository access could read it. The trigger path required no unusual configuration.
Any workflow that runs a Composer command after a widely used setup action such as shivammathur/setup-php automatically registers GITHUB_TOKEN into Composer’s global auth.json.
This means millions of PHP projects running standard CI pipelines were silently at risk the moment GitHub began its staged rollout on April 27.
Not all exposure windows are created equal, and understanding the severity depends on which runner type and token type your workflow uses.
GitHub-hosted runners carry the lowest risk. The GITHUB_TOKEN issued per job expires when the job finishes or after a maximum of 6 hours. In most real-world cases, the failed Composer command immediately terminates the job, expiring the leaked token almost instantly.
Self-hosted runners face a significantly wider exposure window. A leaked GITHUB_TOKEN on a self-hosted runner may remain valid for up to 24 hours after issuance.
Teams using self-hosted runners should treat this as a critical incident, immediately audit all recent Actions logs from the past 48 hours, and cross-reference all token activity in GitHub’s audit log against the potential leak window.
GitHub App installation tokens present the most serious risk profile. These tokens carry a default TTL of 1 hour, but their permissions can be considerably broader than the workflow’s own permissions: declaration.
A leaked GitHub App installation token could grant an attacker write access to repositories, package registries, or other resources the App was granted during installation potentially far exceeding what the workflow itself was authorized to do.
Packagist moved swiftly after the vulnerability was confirmed. The Packagist.org public registry itself is not affected, since it does not use a GitHub App and does not run Composer against GitHub App installation tokens.
Private Packagist has already applied the Composer fix and conducted a full audit of its package update logs, confirming no tokens were exposed in its environment.
On May 13, 2026, at 2:30 PM UTC, Packagist co-founder Nils Adermann posted an update confirming that GitHub has rolled back the new token format change. This temporarily reduces the risk of new leaks from this specific rollout, since older-format tokens don’t trigger the vulnerable Composer validation path.
However, Packagist was unambiguous: the rollback is not a fix. GitHub intends to reattempt the rollout in the coming weeks, and the PHP ecosystem must be fully patched before then.
Remediation
Teams running Composer in GitHub Actions should act immediately, regardless of whether they believe they were affected.
- Update Composer to version 2.9.8, 2.2.28 LTS, or 1.10.28 (legacy) by running
composer self-updateorcomposer.phar self-update - Audit recent Actions logs for failed Composer runs that may have printed token values to stderr, covering the window from April 27 onward
- Delete the affected log entries where token exposure has been confirmed. GitHub allows individual line deletion from the Actions UI
- Review token scopes for any GitHub App installation tokens used in CI; rotate credentials if unexpected API activity is observed
- Avoid pinning Composer to older versions in your CI setup actions; if you explicitly pin
shivammathur/setup-phpto a pre-patch Composer version, update that pin immediately - Treat tokens as opaque strings in the future and remove any hardcoded regex patterns for
ghs_tokens from your codebase or tooling
The patched versions fix the vulnerability in two ways: they remove the rejected token value from Composer’s error output entirely, and they relax the validation character set to accept the new hyphenated ghs_APPID_JWT token format, Socket reported.
FAQ
Q1: Which versions of Composer fix the GitHub token disclosure vulnerability?
Composer 2.9.8, 2.2.28 LTS, and 1.10.28 all include the fix for GHSA-f9f8-rm49-7jv2.
Q2: Does this vulnerability compromise Packagist.org?
No, the public Packagist.org registry is unaffected because it does not use a GitHub App or run Composer against GitHub App installation tokens.
Q3: How long could a leaked GitHub token remain valid after exposure?
On GitHub-hosted runners, up to 6 hours; on self-hosted runners, up to 24 hours; GitHub App installation tokens expire in 1 hour by default but may carry broader permissions.
Q4: Does GitHub rolling back the token format change mean teams don’t need to update Composer?
No, GitHub plans to retry the rollout in the coming weeks, so all PHP teams must update Composer before that happens to prevent future token leaks.
Site: thecybrdef.com
For more insights and updates, follow us on Google News, Twitter, and LinkedIn.