fix: pin 0 actions to commit SHA, extract 10 expressions to env vars#49825
fix: pin 0 actions to commit SHA, extract 10 expressions to env vars#49825dagecko wants to merge 2 commits intospring-projects:mainfrom
Conversation
|
@dagecko Unfortunately, none of the links to vigilantdefense.com are working at the time of writing due to a TLS stack error so apologies if this is already explained elsewhere. My understanding of the exploit is that it requires a workflow to run with attacker controlled content, typically through the |
|
Hey @wilkinsona, appreciate the thorough review. You're right that these workflows trigger on push and workflow_dispatch, not pull_request, so there's no external attacker path here. The attack surface is an insider or compromised contributor account. That's a narrower risk, but it's the exact scenario that played out with tj-actions/changed-files. That compromise started with a compromised maintainer account, and the expression injection patterns in the CI pipeline were what enabled the attacker to execute arbitrary code in the release context once they had access. For spring-boot specifically, the expression extraction is a defense-in-depth measure. If a contributor account is ever compromised, having expressions already extracted to env vars means the attacker can't leverage crafted ref names or tag names to inject commands through the CI pipeline. It closes a path that would otherwise be available. I understand if you consider the risk acceptable given your branch protections and access controls. Happy to close if this doesn't fit your threat model. On the links, they're up on our end. You may have hit a TLS issue with a proxy or firewall. Here they are again: |
|
Thanks for the clarification, @dagecko.
I haven't been able to find any documentation that states that using env vars would help in this case. To the contrary, all that I have found is this CodeQL documentation that describes the risks of creating environment variables from user-controlled sources. Your proposed changes include setting an environment variable from the ref name: If the goal is to protect against a compromised maintainer account where they could push something with a crafted ref name, my reading of the CodeQL documentation is that the proposed change does not fix it and would be flagged as a severity 9 (critical) problem should it be used in a context where it's possible for the input to be user-controlled. |
|
Happy to, thanks for getting back on it.
|
Per review feedback from @wilkinsona — unquoted env vars are still vulnerable to shell injection. Adding double quotes around all env var references in command arguments.
|
@wilkinsona Sorry for my brief response earlier, it was a late night and I skimmed your comment before reading it completely. I just read through the CodeQL doc you linked. You're right. The env var extraction without proper quoting doesn't fully address it. Got me some schooling on that one. I've pushed a follow-up commit that adds double quotes around the env var references. I also went back and checked the secrets extractions in distribute.yml, they are already properly quoted inside the curl strings, so I didn't change them. Hope you have a great day.
|
Re-submission of #49808. Had a problem with my fork and had to delete it, which closed the original PR. Apologies for the noise.
Summary
This PR pins all GitHub Actions to immutable commit SHAs instead of mutable version tags and extracts expressions from
run:blocks intoenv:mappings.Changes by file
A note on internal action pinning
This PR pins all actions including org-owned ones. Best practice is to pin everything — the tj-actions/changed-files attack was an internally maintained action that was compromised, and every repo referencing it by tag silently executed attacker code. That said, it's your codebase. If you'd prefer to leave org-owned actions unpinned, let us know and we'll adjust the PR.
How to verify
Review the diff — each change is mechanical and preserves workflow behavior:
action@v3becomesaction@abc123 # v3— original version preserved as comment${{ expr }}inrun:moves toenv:block, referenced as$ENV_VARin the scriptI put up some research on this on Twitter and a research site if you want more context. I wrote a scanner called Runner Guard and open sourced it here.
If you have any questions, reach out. I'll be monitoring comms.
- Chris Nyhuis (dagecko)