I was the reporter on this one. If you have Github Actions in your organization, disable them immediately if you're unsure which version of composer your Github Actions run.
Could you elaborate on this bit on why Github's secret masking doesn't work here:
> 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.
What does this log rendering look like such that the token from that code snippet becomes interleaved enough to not be a substring match?
I'm not familiar with composer/Symfony but I would expect something like:
I don't have an exact count, but during my analysis, I found that ~40 of the top 100 starred repos in the PHP ecosystem were impacted. Primarily by jobs that run `on: schedule` or by a maintainer with an `on: push`
GHA have always been a PITA for any serious DevOps; it's quite clear they were designed to integrate in 7 lines of code and then tell everyone who complains that they're doing it wrong.
I may be silly but why would you ever want to validate the structure of an opaque authentication key?
Couldn't you just hit an harmless endpoint (e.g. /rate_limit) to see if it returns 401 or not?
This is also a good reminder to scan CI logs, not just source code.
Shameless plug: I work on Kingfisher, an Apache 2.0 OSS secret scanner and validator written in Rust, that can also map blast radius and revoke many creds:
It can scan repos, history, and artifacts and validate many findings against provider APIs, as well as revoke many exposed tokens directly from the CLI. Also generates a blast-radius/access-map view so you can see what a leaked credential could reach.
Install:
brew install kingfisher
# or
uv tool install kingfisher-bin
11 comments
[ 0.21 ms ] story [ 19.0 ms ] thread> 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.
What does this log rendering look like such that the token from that code snippet becomes interleaved enough to not be a substring match?
I'm not familiar with composer/Symfony but I would expect something like:
How many other actions/libraries do you think are vulnerable?
This does not surprise me.
Shameless plug: I work on Kingfisher, an Apache 2.0 OSS secret scanner and validator written in Rust, that can also map blast radius and revoke many creds:
<https://github.com/mongodb/kingfisher>
It can scan repos, history, and artifacts and validate many findings against provider APIs, as well as revoke many exposed tokens directly from the CLI. Also generates a blast-radius/access-map view so you can see what a leaked credential could reach.
Install:
Scan a local path: Or scan a GitHub/GitLab repo directly: