Merge Develop into Release#3830
Conversation
Fix languages mixed
…#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>
Fix more
… 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
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.event.pull_request.head.ref }} |
There was a problem hiding this comment.
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.
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.event.pull_request.head.sha || github.ref }} |
There was a problem hiding this comment.
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.
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.head_ref }} |
There was a problem hiding this comment.
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 found 12
Using variable interpolation |
Created automatically with the Argo bot using the Argo workflow template in workflows/release-rule-changes/release-workflow-template.yaml