Follow Cyber Kendra on Google News! | WhatsApp | Telegram

Add as a preferred source on Google

Composer Bug Silently Dumped GitHub Tokens Into CI Logs — Patch Now

A quiet format change in GitHub's token structure collided with a four-year-old regex in PHP's package manager, exposing live authentication secrets.

Immediately Update Composer

Millions of PHP developers who rely on Composer for dependency management were silently exposed to a token-leaking vulnerability this week — one that required no misconfiguration, no attacker interaction, and no unusual setup to trigger. Just running a normal composer install inside a GitHub Actions workflow was enough.

The issue, tracked as GHSA-f9f8-rm49-7jv2 with a CVE identifier still pending, was publicly reported on May 12, 2026, by GitHub user kesselb — first as a regular issue, then escalated to a security advisory just hours later. Fixed builds shipped within hours of the security report, on the morning of May 13.

What Actually Happened

GitHub has been quietly rolling out a new format for the auto-generated GITHUB_TOKEN that every Actions workflow receives. The new structure — shaped like ghs_<numeric-id>_<base64url-JWT> — includes a hyphen (-) character that was absent from the old format.

Composer has validated GitHub tokens since 2021 against an allowed character set that never included -. When the new-format token hit that validation in BaseIO::loadConfiguration(), Composer threw an UnexpectedValueException — and critically, the exception message interpolated the full token value verbatim:

// The exception that leaked everything
"Your github oauth token for github.com contains invalid characters: ghs_12345_ABC-xyz..."

Symfony Console then wrote that message to stderr. In any CI environment, stderr is captured and persisted in job logs — logs that are visible to every repository collaborator, and sometimes stored by third-party log shippers, monitoring tools, or support systems.

"Users do not need to opt into any unusual configuration; the leak occurs on the default code path whenever an affected token format is in use."

Three factors conspired to make this worse than a typical error message leak. GitHub Actions' built-in secret masker works by exact substring matching — but when Symfony Console renders the exception, it may wrap text or inject ANSI escape sequences, breaking the masker's pattern detection. The token sailed through unredacted.

Who Was Exposed

Any workflow that configured a GITHUB_TOKEN or GitHub App installation token into Composer's authentication, then ran any Composer command, was affected if GitHub had already migrated that repository to the new token format. Crucially, popular Actions like shivammathur/setup-php do this automatically — no deliberate Composer auth setup required.

Packagist confirmed it is unaffected. Private Packagist also escaped exposure since GitHub had not yet issued the new token format for their GitHub App — and they've since applied the patch and audited their logs.

GitHub has rolled back the new token format rollout, buying the PHP ecosystem time to patch. The immediate urgency to disable GitHub Actions has passed, but the patch should still be applied before GitHub resumes the rollout.

The Fix

Composer 2.9.8 and 2.2.28 address both root causes. The exception message no longer includes the rejected token value — diagnostic output now identifies which credential failed without revealing its contents. Additionally, the validation character set now accepts -, matching GitHub's current structured token format. This second fix also protects against future credentials with similar character sets hitting the same error path.

What You Should Do Right Now

Update Composer immediately with composer.phar self-update. If you use shivammathur/setup-php and did not pin the Composer tool to a specific version, you're likely already protected. If you pinned it, update the pin explicitly.

Run composer.phar self-update immediately to upgrade to Composer 2.9.8 (mainline) or 2.2.28 (LTS). Legacy users should target 1.10.28, though upgrading to 2.x is strongly recommended.

Review recent GitHub Actions job logs for any runs that printed token-shaped strings. Delete log contents where leaked tokens may not yet have expired — particularly for self-hosted runners, where the window can stretch to 24 hours. For any GitHub App installation tokens found in logs, revoke them immediately via the GitHub Apps API regardless of apparent expiry.

This incident is a sharp reminder that secret masking in CI is a last-resort safety net, not a primary control — and that incremental format changes in one tool can quietly break security assumptions in another, with no warning until credentials are already written to persistent logs.

Post a Comment