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 is pinned to a mutable version tag instead of an immutable commit SHA, allowing attackers to inject malicious code if they compromise the repository.

More details about this

The GitHub Action shivammathur/setup-php is pinned to a version tag (2.37.1) instead of a full commit SHA. This creates a security risk because tags can be re-pushed or overwritten by an attacker who gains access to the repository.

Here's how an attacker could exploit this:

  1. The attacker gains write access to the shivammathur/setup-php repository (through credential theft, social engineering, or compromised CI/CD access)
  2. They inject malicious code into the action (for example, adding a reverse shell or credential stealer into the PHP setup script)
  3. They force-push the 2.37.1 tag to point to their malicious commit instead of the original one
  4. The next time your workflow runs, GitHub Actions fetches the tag 2.37.1 and downloads the attacker's malicious version
  5. The malicious code executes in your CI/CD pipeline with access to your repository secrets (like GITHUB_TOKEN) and can steal credentials, inject backdoors into your code, or compromise your build artifacts

Using a full commit SHA (e.g., uses: shivammathur/setup-php@a1e9c3c1d7e8b9f7e8c5d4a2b1c9d8e7f6a5b4c3) makes the reference immutable—even if someone re-pushes the tag, your workflow will continue using the exact commit you specified.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
uses: shivammathur/setup-php@2.37.1
# TODO: Replace the placeholder below with the verified full 40-character commit SHA that the 2.37.1 tag points to in shivammathur/setup-php.
# Example format:
# uses: shivammathur/setup-php@0123456789abcdef0123456789abcdef01234567
uses: shivammathur/setup-php@REPLACE_WITH_VERIFIED_40_CHAR_COMMIT_SHA
View step-by-step instructions
  1. Replace shivammathur/setup-php@2.37.1 with a full 40-character commit SHA for the exact action release you want to keep using.
  2. Update each uses: entry for this action in the workflow, for example change uses: shivammathur/setup-php@2.37.1 to uses: shivammathur/setup-php@<full-40-char-commit-sha>.
  3. Get the SHA from the shivammathur/setup-php repository by finding the commit that the 2.37.1 tag points to, and copy the full commit hash instead of the version tag. This makes the workflow use an immutable action revision.
  4. Keep the rest of the step unchanged, including with: and id: values, so only the action reference changes.

Alternatively, if you want to upgrade while fixing this, pin to the full commit SHA for a newer trusted release instead of the SHA behind 2.37.1.

💬 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 a mutable version tag (@2.37.1) that can be repointed to malicious code, allowing supply-chain attacks. Pin to a full commit SHA instead.

More details about this

The Setup PHP Action step references the shivammathur/setup-php action using a mutable version tag (@2.37.1) instead of a pinned commit SHA.

Attack scenario:

  1. An attacker compromises the shivammathur/setup-php repository or the maintainer's account.
  2. The attacker re-tags the 2.37.1 release to point to a malicious commit that injects code (e.g., stealing secrets from the environment, exfiltrating source code, or modifying build artifacts).
  3. Your workflow runs and pulls the compromised action code. The action receives access to ${{ secrets.GITHUB_TOKEN }} and environment variables with sensitive data.
  4. The malicious code executes during the Setup PHP step before any of your legitimate build steps run, giving it full access to your CI/CD environment.
  5. The attacker can steal credentials, modify your compiled output, or inject backdoors into your dependencies.

Even though 2.37.1 looks specific, the tag can be silently moved to a different commit at any time. This is how the trivy-action and kics-github-action compromises occurred in real attacks.

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' ]
dependencies:
- "lowest"
- "highest"
steps:
- name: Checkout smtpapi-php
uses: actions/checkout@v2
- name: Setup PHP Action
# NOTE: Replace the SHA below with the exact 40-character commit for shivammathur/setup-php v2.37.1 from the upstream release/tag page.
uses: shivammathur/setup-php@<FULL_40_CHARACTER_COMMIT_SHA_FOR_V2_37_1> # v2.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 smtpapi-php
uses: actions/checkout@v2
- name: Setup PHP
# NOTE: Use the same exact pinned commit SHA as above for shivammathur/setup-php v2.37.1.
uses: shivammathur/setup-php@<FULL_40_CHARACTER_COMMIT_SHA_FOR_V2_37_1> # v2.37.1
with:
php-version: '8.1'
id: php
View step-by-step instructions
  1. Replace the mutable action reference with a full 40-character commit SHA for shivammathur/setup-php instead of the version tag @2.37.1.
  2. Keep the human-readable version as a comment after the SHA, for example: uses: shivammathur/setup-php@<full-40-char-commit-sha> # v2.37.1
  3. Get the correct commit SHA from the v2.37.1 release page or tag in the action's repository, then use that exact SHA in the workflow. Pinning to a commit SHA prevents the tag from being moved to different code later.
  4. Update the other shivammathur/setup-php@2.37.1 step in this workflow the same way so both job steps use the same pinned commit.
💬 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 All @@ -53,7 +53,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:

The setup-php action is pinned to a version tag instead of a commit SHA, allowing tag manipulation attacks if the upstream repository is compromised.

More details about this

The setup-php action is pinned to a version tag (2.37.1) rather than a full-length commit SHA. Version tags can be moved or deleted by the action maintainer, potentially allowing a malicious actor to force your workflow to run a backdoored version of the action if they compromise the repository.

Exploit scenario:

  1. An attacker gains access to the shivammathur/setup-php repository and modifies the code to inject a backdoor (e.g., stealing secrets or credentials).
  2. The attacker then moves the 2.37.1 tag to point to a malicious commit with their backdoor code.
  3. The next time your workflow runs, it checks out uses: shivammathur/setup-php@2.37.1, which now resolves to the attacker's compromised code instead of the original.
  4. The backdoor executes during your build step—for example, exfiltrating ${{ secrets.GITHUB_TOKEN }} that's available in the workflow environment, allowing the attacker to push malicious code to your repository.

Pinning to an immutable commit SHA (like @abc123def456...) ensures that even if the tag is moved, your workflow always runs the exact code you verified.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
uses: shivammathur/setup-php@2.37.1
- name: Setup PHP Action
# Replace the placeholder below with the verified full 40-character commit SHA for shivammathur/setup-php release 2.37.1 from the action's GitHub tag/release page.
uses: shivammathur/setup-php@<full-40-character-commit-sha-for-2.37.1>
with:
php-version: ${{ matrix.php }}
id: php
- name: Setup PHP
# Replace the placeholder below with the verified full 40-character commit SHA for shivammathur/setup-php release 2.37.1 from the action's GitHub tag/release page.
uses: shivammathur/setup-php@<full-40-character-commit-sha-for-2.37.1>
with:
php-version: '8.1'
id: php
View step-by-step instructions
  1. Replace the third-party action reference shivammathur/setup-php@2.37.1 with a full 40-character commit SHA that corresponds to the 2.37.1 release, for example shivammathur/setup-php@<full-commit-sha>.
  2. Keep the same action name and inputs, and only change the value after @. This makes the workflow use an immutable action revision instead of a mutable tag.
  3. Get the correct SHA from the action's GitHub release or tag page for version 2.37.1, and pin both occurrences shown here:
    • uses: shivammathur/setup-php@<full-commit-sha> in the test job
    • uses: shivammathur/setup-php@<full-commit-sha> in the deploy job
  4. Avoid short SHAs or version tags such as @v2, @main, or @2.37.1, because they can be moved to a different commit later.
💬 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 a mutable semantic version tag (2.37.1) instead of a pinned commit SHA, allowing the action owner to silently inject malicious code into your workflow.

More details about this

The workflow uses shivammathur/setup-php@2.37.1, which pins to a semantic version tag instead of a specific commit SHA. An attacker who controls the shivammathur/setup-php repository could force-push the 2.37.1 tag to point to malicious code without warning.

Exploit scenario:

  1. An attacker gains control of the shivammathur/setup-php repository (or the maintainer's account gets compromised)
  2. They force-push the 2.37.1 tag to a new commit containing a backdoor that exfiltrates ${{ secrets.GITHUB_TOKEN }}
  3. Your workflow runs and fetches the updated tag, executing the malicious action
  4. The attacker uses the stolen token to push code to your repository or access other secrets
  5. This could be repeated across thousands of projects using this action, as happened with the trivy-action and kics-github-action compromises

The version tag 2.37.1 is mutable—it can be repointed by the repository owner at any time, making it unsafe for supply-chain security.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
uses: shivammathur/setup-php@2.37.1
# TODO: Replace the placeholder below with the verified 40-character commit SHA for shivammathur/setup-php tag 2.37.1 from the action's release/tag page.
uses: shivammathur/setup-php@<FULL_40_CHARACTER_COMMIT_SHA> # 2.37.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 same release, for example shivammathur/setup-php@<full-commit-sha> # 2.37.1.
  2. Keep the version as a YAML comment after the SHA so the pinned release is still easy to identify, such as uses: shivammathur/setup-php@<full-commit-sha> # 2.37.1.
  3. Get the correct SHA from the action's release or tag page before updating the workflow. Pinning to a commit SHA prevents the tag from being silently moved to different code later.
💬 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