Skip to content

Security: Pin GitHub Actions to immutable SHA hashes#27135

Open
brendandburns wants to merge 5 commits intoPowerShell:masterfrom
brendandburns:security/pin-github-actions-to-sha
Open

Security: Pin GitHub Actions to immutable SHA hashes#27135
brendandburns wants to merge 5 commits intoPowerShell:masterfrom
brendandburns:security/pin-github-actions-to-sha

Conversation

@brendandburns
Copy link
Copy Markdown
Contributor

Summary

This PR updates all GitHub Actions in our CI/CD workflows to use immutable commit SHA hashes instead of mutable tag references, significantly enhancing our supply chain security posture.

Security Impact

Problem: Mutable Tag Vulnerability

Mutable references like @v6, @latest, or branch names can be force-pushed by attackers who compromise action repositories, allowing them to inject malicious code into our CI/CD pipeline without detection.

Solution: Cryptographically Immutable SHA Hashes

SHA-256 commit hashes are cryptographically immutable and cannot be changed, preventing supply chain attacks.

Real-World Security Incident Reference

This change directly addresses vulnerabilities similar to the LiteLLM security incident where their CI/CD pipeline was compromised through their usage of Trivy with mutable tag references. When the Trivy action repository was compromised, attackers were able to modify what the mutable tags pointed to, injecting malicious code into LiteLLM's build process.

Reference: Trivy Security Advisory GHSA-69fq-xp46-6x23

Changes Made

Updated 38 action references across 9 workflow files:

Action Before After
actions/checkout @v6 @1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
actions/setup-dotnet @v5 @d4c94342e560b34958eacfc5d055d21461ed1c5d # v5.0.0
actions/upload-artifact @v7 @bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
actions/github-script @v8 @ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
PowerShell/compliance/...ready-to-merge.yml @v1.0.0 @c8b3ad5819ad7078f3e375519b4f8c6232d1cbdf # v1.0.0

Files Updated:

  • .github/workflows/analyze-reusable.yml
  • .github/workflows/copilot-setup-steps.yml
  • .github/workflows/labels.yml
  • .github/workflows/linux-ci.yml
  • .github/workflows/macos-ci.yml
  • .github/workflows/verify-markdown-links.yml
  • .github/workflows/windows-ci.yml
  • .github/workflows/windows-packaging-reusable.yml
  • .github/workflows/xunit-tests.yml

Security Benefits

Supply Chain Protection: Prevents tag hijacking and malicious code injection
Immutability: SHA hashes cannot be force-pushed or modified by attackers
Transparency: Version comments maintain readability and audit trail
Compliance: Aligns with GitHub security best practices

Verification

All SHA hashes have been verified against the official repositories and correspond to the intended version tags.

Recommended Follow-up

Consider enabling Dependabot for GitHub Actions to automatically update these SHA-pinned actions to newer versions while maintaining security.

Related


This change prevents supply chain attacks while maintaining full functionality of our CI/CD workflows.

- Update all GitHub Action references from mutable tags to immutable SHA hashes
- Prevents supply chain attacks via tag hijacking and force-pushing
- Addresses security vulnerabilities similar to the LiteLLM incident with Trivy
- Maintains version comments for clarity while ensuring cryptographic immutability
- Affects 38 action references across 9 workflow files

Actions updated:
- actions/checkout@v6 → @1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- actions/setup-dotnet@v5 → @d4c94342e560b34958eacfc5d055d21461ed1c5d # v5.0.0
- actions/upload-artifact@v7 → @bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- actions/github-script@v8 → @ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
- PowerShell/compliance/...@v1.0.0 → @c8b3ad5819ad7078f3e375519b4f8c6232d1cbdf # v1.0.0
@brendandburns brendandburns requested review from a team and jshigetomi as code owners April 1, 2026 21:07
Copilot AI review requested due to automatic review settings April 1, 2026 21:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily hardens CI/CD supply-chain security by pinning GitHub Actions uses: references to immutable commit SHAs, replacing mutable version tags. It also includes an unrelated functional change to Write-Host’s object-to-string processing and corresponding test updates.

Changes:

  • Pin third-party GitHub Actions (e.g., actions/checkout, actions/setup-dotnet, actions/upload-artifact, actions/github-script, github/codeql-action, and PowerShell/compliance) to immutable commit SHAs across workflows.
  • Update Write-Host runtime behavior to treat IDictionary as a scalar (not an IEnumerable to be unrolled) and add a new test case validating the behavior.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteConsoleCmdlet.cs Updates Write-Host object processing to special-case IDictionary.
test/powershell/Modules/Microsoft.PowerShell.Utility/Write-Host.Tests.ps1 Adds a test case for IDictionary (Hashtable) output behavior.
.github/workflows/analyze-reusable.yml Pins actions/setup-dotnet (and already has SHA pins for checkout/codeql).
.github/workflows/copilot-setup-steps.yml Pins actions/checkout to an immutable SHA.
.github/workflows/labels.yml Pins actions/checkout and actions/github-script to immutable SHAs.
.github/workflows/linux-ci.yml Pins actions/checkout and PowerShell/compliance workflow reference to immutable SHAs.
.github/workflows/macos-ci.yml Pins actions/checkout, actions/setup-dotnet, actions/upload-artifact, and PowerShell/compliance to immutable SHAs.
.github/workflows/verify-markdown-links.yml Pins actions/checkout to an immutable SHA.
.github/workflows/windows-ci.yml Pins actions/checkout and PowerShell/compliance workflow reference to immutable SHAs.
.github/workflows/windows-packaging-reusable.yml Pins actions/checkout, actions/setup-dotnet, and actions/upload-artifact to immutable SHAs.
.github/workflows/xunit-tests.yml Pins actions/checkout, actions/setup-dotnet, and actions/upload-artifact to immutable SHAs.

Comment on lines +55 to +68
switch (o)
{
// strings are IEnumerable, so we special case them
if (s.Length > 0)
{
return s;
}
}
else if (o is XmlNode xmlNode)
{
return xmlNode.Name;
}
else if (o is IEnumerable enumerable)
{
// unroll enumerables, including arrays.

bool printSeparator = false;
StringBuilder result = new();

foreach (object element in enumerable)
{
if (printSeparator && Separator != null)
case string s:
// strings are IEnumerable, so we special case them
if (s.Length > 0)
{
result.Append(Separator.ToString());
return s;
}
break;
case XmlNode xmlNode:
return xmlNode.Name;
case IDictionary dictionary:
return dictionary.ToString();
case IEnumerable enumerable:
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description/title focus on pinning GitHub Actions to immutable SHAs, but this hunk also changes Write-Host runtime behavior (adds an IDictionary special-case in ProcessObject). This functional change should either be moved to a separate PR (preferred) or the PR description updated to include the Write-Host behavior change and its rationale/compat considerations.

Copilot uses AI. Check for mistakes.
@kilasuit
Copy link
Copy Markdown
Collaborator

kilasuit commented Apr 2, 2026

Whilst reviewing this & I can't speak for the team, I'd be more inclined to split out the changes around Write-Host to it's own PR, if they are still needed, to keep this PR just to the SHA Hash changes.

It's also worth readers coming to this PR to also have a read of The Comforting Lie Of SHA Pinning which follows on from the linked hack & suggests there are still security concerns even with using SHA hashes for GitHub Actions that need to be considered which can be summed up by this quote from that article

If I leave the action owner unchanged and only swap the SHA, the original exploit still works…

Dependabot is configured on this repo & by looks of the last few PR's it has raised it is preferring use of SHA Commits - just seems that the actions being changed in this PR had been missed in moving across to using SHA commits over version tags.

@TravisEz13 TravisEz13 self-requested a review April 7, 2026 19:47
@TravisEz13
Copy link
Copy Markdown
Member

I agree that they should be separate. I've created a PR with the action pins and I'll see if I can merge.

@TravisEz13
Copy link
Copy Markdown
Member

@brendandburns Can you update the title and description of your PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants