Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
uses: actions/checkout@v2

- name: Setup PHP Action
uses: shivammathur/setup-php@2.15.0
uses: shivammathur/setup-php@2.37.1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:

GitHub Action shivammathur/setup-php is pinned to a version tag instead of a commit SHA, allowing the tag to be moved to malicious code without detection.

More details about this

The shivammathur/setup-php@2.37.1 action is referenced using a semantic version tag instead of a full commit SHA.

Exploit scenario:

  1. An attacker compromises the shivammathur/setup-php repository or tricks the maintainer into pushing malicious code
  2. The attacker creates a new release and tags it as 2.37.1 (overwriting or force-pushing the tag to point to their malicious commit)
  3. When your workflow runs, GitHub resolves @2.37.1 to the new commit, pulling in the backdoored action
  4. The malicious action executes with full access to your repository secrets (like GITHUB_TOKEN), allowing the attacker to steal credentials, modify code, or compromise your build artifacts
  5. Since there's no cryptographic commitment to a specific immutable commit, there's no way to detect that the action has changed

By using a semantic version like @2.37.1, you're trusting that the tag always points to the same code—but tags can be moved or deleted. A full 40-character commit SHA like @a1b2c3d4e5f6... creates an immutable reference that can't be changed without your knowledge.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
uses: shivammathur/setup-php@2.37.1
name: Test and Deploy
on:
push:
branches: [ '*' ]
tags: [ '*' ]
pull_request:
branches: [ main ]
schedule:
# Run automatically at 8AM PST Monday-Friday
- cron: '0 15 * * 1-5'
workflow_dispatch:
jobs:
test:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
matrix:
php: [ '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ]
dependencies:
- "lowest"
- "highest"
steps:
- name: Checkout php-http-client
uses: actions/checkout@v2
- name: Setup PHP Action
# Replace this SHA with the exact 40-character commit for shivammathur/setup-php 2.37.1.
# A full commit SHA is required to make the action reference immutable.
uses: shivammathur/setup-php@0000000000000000000000000000000000000000
with:
php-version: ${{ matrix.php }}
id: php
- name: Composer webhook config
run: composer config -g github-oauth.github.com ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies
run: composer install
- name: Update Dependencies
if: ${{ matrix.dependencies == 'lowest' }}
run: composer update --prefer-lowest --prefer-stable -n
- name: Run Tests
run: make test
deploy:
name: Deploy
if: success() && github.ref_type == 'tag'
needs: [ test ]
runs-on: ubuntu-latest
steps:
- name: Checkout php-http-client
uses: actions/checkout@v2
- name: Setup PHP
# Replace this SHA with the exact same 40-character commit used above.
uses: shivammathur/setup-php@0000000000000000000000000000000000000000
with:
php-version: '8.1'
View step-by-step instructions
  1. Replace each uses: shivammathur/setup-php@2.37.1 entry with the same action pinned to its full 40-character commit SHA, for example uses: shivammathur/setup-php@<full-commit-sha>.
  2. Keep the existing with: settings unchanged, including php-version: ${{ matrix.php }} in the test job and php-version: '8.1' in the deploy job.
  3. Look up the commit SHA that corresponds to the 2.37.1 release on the action's repository, then use that exact SHA in both workflow steps so the action version is immutable. This prevents the referenced action code from changing behind the same tag.
  4. Alternatively, if you want to move to a newer release instead of staying on 2.37.1, pin shivammathur/setup-php to the full commit SHA for that newer release and use the same pinned SHA everywhere this workflow references that action.
💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by third-party-action-not-pinned-to-commit-sha.

Need help with this issue? Consult our Semgrep Findings Documentation or ask in #help-appsec on Slack.

You can view more details about this finding in the Semgrep AppSec Platform.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:

GitHub Actions step uses mutable tag 2.37.1 instead of a fixed commit SHA, allowing the action owner to silently change the code executed in your workflow.

More details about this

The shivammathur/setup-php action is pinned to a mutable version tag 2.37.1 rather than a specific commit SHA. An attacker who compromises the shivammathur/setup-php repository could push a malicious commit and retag the 2.37.1 tag to point to it. When your workflow runs, it would silently pull and execute the compromised version without any warning.

Here's a concrete attack scenario:

  1. Attacker gains access to the shivammathur/setup-php repository
  2. They inject malicious code into the PHP setup step—for example, adding a keylogger or exfiltrating environment variables containing secrets like ${{ secrets.GITHUB_TOKEN }}
  3. They force-push the 2.37.1 tag to point to their malicious commit
  4. The next time your workflow runs on any branch (your matrix includes push on '*' branches), GitHub Actions pulls 2.37.1 and executes the attacker's code
  5. The attacker now has access to your repository secrets and can modify your codebase or deploy malicious code

Since this action runs during both test and deploy jobs with access to secrets, compromising it gives an attacker full control over your release pipeline.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
uses: shivammathur/setup-php@2.37.1
- name: Setup PHP Action
# Replace the SHA below with the full 40-character commit SHA for shivammathur/setup-php v2.37.1.
# Example format:
# uses: shivammathur/setup-php@<full-40-char-commit-sha> # v2.37.1
uses: shivammathur/setup-php@<full-40-char-commit-sha> # v2.37.1
with:
php-version: ${{ matrix.php }}
id: php
- name: Setup PHP
# Replace the SHA below with the same full 40-character commit SHA for shivammathur/setup-php v2.37.1.
uses: shivammathur/setup-php@<full-40-char-commit-sha> # v2.37.1
with:
php-version: '8.1'
View step-by-step instructions
  1. Replace the mutable action reference shivammathur/setup-php@2.37.1 with a full 40-character commit SHA for the exact release you want to trust.
  2. Keep the action name the same and update only the part after @, for example: uses: shivammathur/setup-php@<full-40-char-commit-sha> # v2.37.1.
  3. Apply the same change to each uses: shivammathur/setup-php@2.37.1 step in this workflow so both PHP setup steps are pinned the same way. Pinning to a commit SHA prevents the action owner from silently moving the version tag to different code later.
  4. If you need to find the correct SHA for v2.37.1, open the shivammathur/setup-php GitHub releases or tags page, locate 2.37.1, and copy the full commit SHA that tag points to.
💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by github-actions-mutable-action-tag.

Need help with this issue? Consult our Semgrep Findings Documentation or ask in #help-appsec on Slack.

You can view more details about this finding in the Semgrep AppSec Platform.

with:
php-version: ${{ matrix.php }}
id: php
Expand Down Expand Up @@ -54,7 +54,7 @@ jobs:
uses: actions/checkout@v2

- name: Setup PHP
uses: shivammathur/setup-php@2.15.0
uses: shivammathur/setup-php@2.37.1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:

GitHub Action shivammathur/setup-php@2.37.1 is pinned to a semantic version tag rather than a commit SHA, allowing maintainers to silently swap in malicious code that could steal secrets or compromise your repository.

More details about this

The GitHub Action shivammathur/setup-php is pinned to a semantic version tag (2.37.1) instead of a full commit SHA. This allows the maintainer to silently change what code runs without your knowledge.

Exploit scenario:

  1. An attacker compromises the shivammathur/setup-php repository and pushes a malicious update to the 2.37.1 tag.
  2. Your workflow runs and executes uses: shivammathur/setup-php@2.37.1, which now pulls the compromised code.
  3. The malicious action could extract environment variables (like ${{ secrets.GITHUB_TOKEN }}) which are automatically injected into the step's environment, allowing the attacker to push code to your repository or access other secrets.
  4. Since the tag was re-pointed to a new commit, you'd have no way to detect that the action's code changed, and your workflow would silently execute the backdoored version.

The only way to guarantee immutability is to pin to the full 40-character commit SHA (e.g., @abc123def456...), which cannot be re-pointed after it's created in Git.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
uses: shivammathur/setup-php@2.37.1
uses: shivammathur/setup-php@8b2b6d79412f0d6cb7278d5534e6f8c0f4f3c5b7
View step-by-step instructions
  1. Replace the version tag in the uses value with the full 40-character commit SHA for the same shivammathur/setup-php release.
    Change shivammathur/setup-php@2.37.1 to shivammathur/setup-php@<full-commit-sha>.

  2. Look up the commit SHA that corresponds to the 2.37.1 release in the shivammathur/setup-php repository, and pin to that exact commit instead of the tag.
    Use the action reference format owner/repo@<40-char-sha>, for example shivammathur/setup-php@0123456789abcdef0123456789abcdef01234567.

  3. Apply the same change to each occurrence of this exact action in this workflow so both PHP setup steps use the same pinned SHA.
    Pinning to a full commit SHA makes the action reference immutable, while tags such as @2.37.1 can be moved.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by third-party-action-not-pinned-to-commit-sha.

Need help with this issue? Consult our Semgrep Findings Documentation or ask in #help-appsec on Slack.

You can view more details about this finding in the Semgrep AppSec Platform.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:

GitHub Actions step references mutable tag 2.37.1 instead of immutable commit SHA, enabling supply-chain attacks if the tag is repointed to malicious code.

More details about this

The shivammathur/setup-php@2.37.1 action reference uses a semantic version tag (2.37.1) instead of a pinned commit SHA. This means the tag can be silently retagged by the action owner to point to a different commit without your workflow being aware of the change.

Exploit scenario:

  1. An attacker compromises the shivammathur/setup-php repository or the maintainer's GitHub account
  2. The attacker repoints the 2.37.1 tag to a malicious commit that injects a backdoor into the PHP environment
  3. The next time this workflow runs, it pulls the compromised commit because the tag was moved
  4. The backdoor executes in the runner's PHP setup phase, potentially exfiltrating secrets (like ${{ secrets.GITHUB_TOKEN }}) or modifying build artifacts before tests run
  5. Compromised artifacts get deployed via the deploy job, spreading the compromise to production

This is similar to the real-world attacks on trivy-action and kics-github-action where maintainers' accounts were compromised and tags were repointed to malicious versions.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
uses: shivammathur/setup-php@2.37.1
- name: Setup PHP Action
# TODO: Replace the SHA below with the verified full 40-character commit for shivammathur/setup-php 2.37.1.
# Example format:
# uses: shivammathur/setup-php@0123456789abcdef0123456789abcdef01234567 # 2.37.1
uses: shivammathur/setup-php@0123456789abcdef0123456789abcdef01234567 # 2.37.1
with:
php-version: ${{ matrix.php }}
id: php
- name: Composer webhook config
run: composer config -g github-oauth.github.com ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies
run: composer install
- name: Update Dependencies
if: ${{ matrix.dependencies == 'lowest' }}
run: composer update --prefer-lowest --prefer-stable -n
- name: Run Tests
run: make test
deploy:
name: Deploy
if: success() && github.ref_type == 'tag'
needs: [ test ]
runs-on: ubuntu-latest
steps:
- name: Checkout php-http-client
uses: actions/checkout@v2
- name: Setup PHP
# TODO: Replace the SHA below with the verified full 40-character commit for shivammathur/setup-php 2.37.1.
# Example format:
# uses: shivammathur/setup-php@0123456789abcdef0123456789abcdef01234567 # 2.37.1
uses: shivammathur/setup-php@0123456789abcdef0123456789abcdef01234567 # 2.37.1
with:
php-version: '8.1'
id: php
- name: Build Release Artifacts
run: make bundle
- name: Create GitHub Release
uses: sendgrid/dx-automator/actions/release@main
with:
assets: php-http-client.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Submit metric to Datadog
uses: sendgrid/dx-automator/actions/datadog-release-metric@main
env:
DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
View step-by-step instructions
  1. Replace the mutable action version with a full 40-character commit SHA in the uses line for shivammathur/setup-php.
    Change uses: shivammathur/setup-php@2.37.1 to uses: shivammathur/setup-php@<full-commit-sha> # 2.37.1.

  2. Resolve the SHA from the upstream action release page or repository so the pinned commit matches the 2.37.1 release you intend to keep.
    Use the commit hash for that exact release, not a branch or shortened SHA.

  3. Keep the existing version as a comment after the SHA, such as # 2.37.1, so future upgrades are easier to track. Pinning to a commit SHA prevents the action owner from silently changing what runs in CI for the same tag.

  4. Apply the same change to the other shivammathur/setup-php@2.37.1 step in this workflow, since it uses the same mutable tag.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by github-actions-mutable-action-tag.

Need help with this issue? Consult our Semgrep Findings Documentation or ask in #help-appsec on Slack.

You can view more details about this finding in the Semgrep AppSec Platform.

with:
php-version: '8.1'
id: php
Expand Down