Skip to content

Merge Develop into Release#3830

Open
r2c-argo[bot] wants to merge 18 commits into
releasefrom
merge-develop-to-release
Open

Merge Develop into Release#3830
r2c-argo[bot] wants to merge 18 commits into
releasefrom
merge-develop-to-release

Conversation

@r2c-argo
Copy link
Copy Markdown
Contributor

@r2c-argo r2c-argo Bot commented Apr 28, 2026

Created automatically with the Argo bot using the Argo workflow template in workflows/release-rule-changes/release-workflow-template.yaml

LewisArdern and others added 18 commits March 27, 2026 08:04
…#3783)

* Add GHA supply chain security rules (mutable-action-tag, pwn-request)

github-actions-mutable-action-tag (WARNING / CWE-1104):
- Detects non-SHA-pinned uses: references via pattern-regex with negative
  lookahead for 40-char hex SHA. Catches all mutable refs including tagged
  versions, branches, and 'latest'. Validated against 853 peer-vendor repos
  (6,147 findings, 0 SHA-pinned false positives).
- Motivated by TeamPCP campaign where trivy-action@0.29.0 and
  kics-github-action@master were repointed to malicious commits.

gha-pwn-request-fork-checkout (ERROR / CWE-829):
- Detects pull_request_target + fork-controlled checkout ref combination
  (the "Pwn Request" attack pattern). Uses pattern-inside for trigger
  detection + metavariable-regex for fork ref forms.
- Confirmed TPs: sigstore/community (CRITICAL, PULUMI_ACCESS_TOKEN),
  jfrog/jfrog-cli (HIGH), SonarSource/official-images (HIGH).

Both ported from semgrep/semgrep-rules-jsonnet PRs #10484 and #10485
per reviewer feedback that community rules belong in this repository.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Merge gha-pwn-request-fork-checkout into pull-request-target-code-checkout

Absorbs the new rule's improvements into the existing rule rather than
shipping a duplicate rule for the same vulnerability class:

- Severity: WARNING → ERROR; subcategory: audit → vuln
- Confidence/likelihood/impact: LOW/LOW/MEDIUM → HIGH/MEDIUM/HIGH
- CWE-913 → CWE-829 (Inclusion of Functionality from Untrusted Control Sphere)
- OWASP A01 (Broken Access Control) → A08 (Software and Data Integrity Failures)
- Drop actions/checkout requirement — any step with ref: is in scope
- Replace broad github.event.pull_request metavariable-pattern with precise
  metavariable-regex targeting head.sha, head.ref, github.head_ref, refs/pull/
- Extend regex to also cover refs/pull/ merge refs (existing test coverage)
- Absorb new test cases: github.head_ref, head.ref, sha||github.ref

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Restore original message text in pull-request-target-code-checkout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Restore original pattern structure; improve ref matching with metavariable-regex

Keeps the original actions/checkout + jobs/steps scaffolding. Replaces the
broad generic-language metavariable-pattern on $EXPR with a metavariable-regex
that precisely targets the dangerous fork-head refs:
  github.event.pull_request.head.sha, github.event.pull_request.head.ref,
  github.head_ref, refs/pull/ merge refs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix ruleid comment placement in TP-4/5/6 test cases

Semgrep reports matches at the `uses:` line, not the `ref:` line inside
`with:`. Move ruleid comments to precede `- uses:` to match TP-1/2/3 style.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Use metavariable-pattern + nested metavar-regex for precise ref matching

Replaces the previous approaches with the correct technique: keep the original
pattern structure (actions/checkout + jobs/steps scaffold), but improve the
metavariable-pattern on $EXPR to use pattern-either with a nested
metavariable-regex rather than a broad literal prefix match.

The generic-mode patterns match as substrings against the captured $EXPR value
(e.g. "${{ github.event.pull_request.head.sha }}"), so no ${{ }} wrapper is
needed in the sub-patterns:
  - github.event.pull_request.head.$PR_REF + regex ^(sha|ref)$ catches the
    two specific dangerous head fields while excluding .number, .body, etc.
  - github.head_ref ... catches the shorthand form

Removes the refs/pull/ test case — that pattern uses .number (not a head ref)
and was never covered by the new rule being merged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Use $...PR_REF ellipsis capture with nested metavariable-pattern

$...PR_REF captures the full multi-token expression between ${{ and }},
avoiding the single-token limitation of $PR_REF. metavariable-regex does
not support $...VAR, so a nested metavariable-pattern with pattern-either
is used instead to match the three dangerous fork-head ref forms:
  - github.event.pull_request.head.sha
  - github.event.pull_request.head.ref
  - github.head_ref

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Simplify metavariable-pattern using pattern-inside ${{ ... }}

Uses pattern-inside to scope matches to within ${{ }} expressions,
then pattern-either to match the specific dangerous fork-head refs.
No metavar capture needed — cleaner than the nested metavariable-pattern approach.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Retain original github.event.pull_request ... pattern alongside new refs

Adds github.event.pull_request ... back to the pattern-either so the
original broad coverage (including refs/pull/.../merge via .number) is
preserved alongside the explicit head.sha, head.ref, and head_ref patterns.
Restores the refs/pull/ spelling test case accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Remove patterns subsumed by github.event.pull_request ...

head.sha and head.ref are already matched by the broader prefix pattern.
Test cases for both remain (TP-1/2/5 cover head.sha, TP-6 covers head.ref).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Rewrite github-actions-mutable-action-tag to use proper YAML patterns

Quality issues fixed:
- pattern-regex (raw text scan) -> pattern-inside + pattern + metavariable-pattern,
  matching the approach used by third-party-action-not-pinned-to-commit-sha and
  pull-request-target-code-checkout; comment exclusion handled by YAML parser
- Add pattern-inside: "{steps: ...}" scope (consistent with comparable rule)
- CWE-1104 (Unmaintained Component) -> CWE-1357 + CWE-353 (Integrity Check);
  CWE-353 is exact for "not verifying integrity of what you execute"
- Remove wrong reference to pwn-requests paper (unrelated topic)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
… rule (#3797)

ServerSocket(0) used to detect available ports (→ localPort → close())
is a common benign pattern that does not transmit cleartext data.
Add pattern-not-inside clauses scoped to functions returning Int.

Closes SRC-12442

Made-with: Cursor
Detects use of `secrets: inherit` in reusable workflow calls, which
passes all repository secrets to the called workflow. This violates
least privilege — callers should explicitly pass only needed secrets.
If `head_ref` is deemed untrustworthy, we should include the other properties that reference a branch name. We should also include workflow names, which can be attacker controlled when used with `pull_request_target`.

Source: https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#github-context
…es (#3685)

Co-authored-by: Vasilii Ermilov <inkz@xakep.ru>
feat: ocaml rule for unsafe mutex use
* update gha rules

* update gha rules
The pre-commit check-yaml hook previously maintained an explicit
allowlist of test files permitted to use multi-document YAML (---
separators). This required updating the config every time a new
multi-document test file was added.

Generalize the pattern to allow all *.test.ya?ml files to use
multi-document YAML. These files are semgrep rule test files where
multiple documents is a natural way to express separate test cases.
The files are still validated for well-formedness via the
--allow-multiple-documents hook.

Made-with: Cursor
* Add in rules for package managers for cooldown (and a few other rules for pnpm)

* Revert .gitignore

* Update Dependabot configuration message for cooldown

Clarified the message regarding the cooldown period for Dependabot updates.

* Update bun-missing-minimum-release-age.yaml warning

Consolidate warning message for missing minimum release age.

* Update pnpm-block-exotic-sub-dependencies message

Clarify the message for the pnpm-block-exotic-sub-dependencies rule.

* Add warning for missing minimum release age in pnpm config

Added a warning about missing minimum release age in pnpm configuration.

* Revise pnpm trust policy message

Updated trust policy message to include guidance on setting 'trustPolicy: no-downgrade' for security.

* Update renovate config to include minimum release age

Document the minimum release age for package updates.

* Simplify dependency cooldown message in YAML

Updated message to simplify instructions for setting a dependency cooldown in uv.

* Remove example for npmMinimalAgeGate

Removed example for npmMinimalAgeGate in the YAML configuration.

* Add in .npmrc rule

* Simplify branch one, teach it to not pick up blank lines, minor pedantic linting.
…ail loudly (#3829)

`scripts/historical-semgrep-version` has been failing on every PR since
April 15 with a confusing empty error:

    Could not determine historical version, tried:
    Process completed with exit code 1.

Two issues conspired to produce this silent failure:

1. The script called `gh api /repos/returntocorp/semgrep/releases`. The
   repo was renamed to `semgrep/semgrep` and, while a personal token
   transparently follows the rename, the workflow's scoped GITHUB_TOKEN
   does not, so the API call returns an empty/error response in CI.
2. The pipeline `gh api ... | jq ... | tail | head | tr` ran without
   `pipefail`, so the failed call produced an empty `versions` string
   without surfacing any error and the subsequent for-loop just
   no-op'd into the failure print.

This change:

- Uses the canonical `/repos/semgrep/semgrep/releases` path.
- Adds `set -euo pipefail` and an explicit check on the `gh api`
  exit status, echoing the response on failure so future breakage is
  diagnosable from CI logs.
- Echoes the candidate versions before iterating, and uses
  `if docker pull ...` instead of checking `$?` after the fact.

The Docker image is still pulled from `returntocorp/semgrep`, which
continues to be published alongside `semgrep/semgrep`.

Made-with: Cursor
Comment on lines +104 to +106
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
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 a blocking 🔴 issue in your code:
This GitHub Actions workflow file uses pull_request_target and checks out code from the incoming pull request. When using pull_request_target, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., npm build and make) or dependency installation scripts (e.g., python setup.py install). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations.

Why this might be safe to ignore:

This finding is in a test fixture file for Semgrep rule validation. The path structure and context (with comments like 'ruleid: pull-request-target-code-checkout' and 'TP-6: github.event.pull_request.head.ref') indicate this is intentional test code designed to verify the rule detects vulnerable patterns, not actual production workflow code.

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 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 pull-request-target-code-checkout.

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

Comment on lines +94 to +96
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}
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 a blocking 🔴 issue in your code:
This GitHub Actions workflow file uses pull_request_target and checks out code from the incoming pull request. When using pull_request_target, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., npm build and make) or dependency installation scripts (e.g., python setup.py install). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations.

Why this might be safe to ignore:

This finding is in a test file containing Semgrep rule examples and test fixtures. The comment '# ruleid: pull-request-target-code-checkout' and the path pattern indicate this is intentional vulnerable code used to validate that Semgrep correctly detects the security issue, not actual production GitHub Actions workflow code.

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 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 pull-request-target-code-checkout.

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

Comment on lines +84 to +86
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
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 a blocking 🔴 issue in your code:
This GitHub Actions workflow file uses pull_request_target and checks out code from the incoming pull request. When using pull_request_target, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., npm build and make) or dependency installation scripts (e.g., python setup.py install). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations.

Why this might be safe to ignore:

This finding is in a test fixture file containing intentional rule examples, as indicated by the path structure and context showing multiple test cases (TP-4, TP-5, etc.) with comments like 'ruleid: pull-request-target-code-checkout'. The vulnerable code patterns are deliberately included to verify that Semgrep correctly detects them, not to be fixed.

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 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 pull-request-target-code-checkout.

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

@semgrep-zcs-prod-semgrep
Copy link
Copy Markdown

Semgrep found 12 run-shell-injection findings:

Using variable interpolation ${{...}} with github context data in a run: step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. github context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with env: to store the data and use the environment variable in the run: script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".

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.

10 participants