yams/tools/opengrep/rules/audit/yams-github-actions-audit.yml

267 lines
8.6 KiB
YAML

rules:
- id: yams.github-actions.cross-workflow-artifact-download
languages: [yaml]
severity: WARNING
message: >-
Uses a third-party artifact download action across workflows. This may allow artifact
poisoning from untrusted sources. Prefer the official actions/download-artifact@v4 with
an explicit run-id, github-token, and validation of the source run (conclusion, branch,
event). Reject pull_request-triggered runs as artifact sources.
metadata:
category: security
confidence: high
precision: high
yams_triage: artifact-integrity
references:
- https://github.com/dawidd6/action-download-artifact
pattern-regex: 'uses:\s*dawidd6/action-download-artifact@'
paths:
include:
- /.github/workflows/**/*.yml
- /.github/workflows/**/*.yaml
- /tools/opengrep/tests/**/*.yml
- /tools/opengrep/tests/**/*.yaml
- tools/opengrep/tests/**/*.yml
- tools/opengrep/tests/**/*.yaml
exclude:
- /third_party/**
- /build/**
- /build*/**
- id: yams.github-actions.mutable-action-ref
languages: [yaml]
severity: WARNING
message: >-
GitHub Action referenced at a mutable ref (@main or @master). Pinning to a specific
version tag (e.g. @v4) prevents supply-chain drift; pinning to a full commit SHA
prevents tag-move attacks. Use @v4 or @<sha> instead.
metadata:
category: security
confidence: high
precision: medium
yams_triage: supply-chain
pattern-regex: 'uses:\s*[^\n@ ]+@(main|master)\b'
paths:
include:
- /.github/workflows/**/*.yml
- /.github/workflows/**/*.yaml
- /tools/opengrep/tests/**/*.yml
- /tools/opengrep/tests/**/*.yaml
- tools/opengrep/tests/**/*.yml
- tools/opengrep/tests/**/*.yaml
exclude:
- /third_party/**
- /build/**
- /build*/**
- id: yams.github-actions.curl-pipe-shell
languages: [yaml]
severity: WARNING
message: >-
Piped curl-to-shell pattern found in a workflow step. This executes untrusted network
content directly. Prefer verifying a checksum against a known-good manifest or using a
pinned tool/action instead.
metadata:
category: security
confidence: high
precision: high
yams_triage: supply-chain
cwe: "CWE-494"
pattern-regex: 'curl\s+.*\s*\|\s*(?:sudo\s+)?(?:ba)?sh\b'
paths:
include:
- /.github/workflows/**/*.yml
- /.github/workflows/**/*.yaml
- /tools/opengrep/tests/**/*.yml
- /tools/opengrep/tests/**/*.yaml
- tools/opengrep/tests/**/*.yml
- tools/opengrep/tests/**/*.yaml
exclude:
- /third_party/**
- /build/**
- /build*/**
- id: yams.github-actions.privileged-manual-workflow-no-environment
languages: [yaml]
severity: WARNING
message: >-
Workflow triggered by workflow_dispatch with elevated permissions (contents: write,
id-token: write) but without an environment protection rule. This allows any committer
to trigger privileged actions without review. Gate the job behind an environment with
required reviewers or a deployment protection rule.
metadata:
category: security
confidence: medium
precision: medium
yams_triage: access-control
patterns:
- pattern-inside: |
...
on:
...
workflow_dispatch:
...
permissions:
contents: write
...
- pattern-inside: |
jobs:
...
- pattern: |
runs-on: ...
paths:
include:
- /.github/workflows/**/*.yml
- /.github/workflows/**/*.yaml
- /tools/opengrep/tests/**/*.yml
- /tools/opengrep/tests/**/*.yaml
- tools/opengrep/tests/**/*.yml
- tools/opengrep/tests/**/*.yaml
exclude:
- /third_party/**
- /build/**
- /build*/**
- id: yams.github-actions.gh-release-download-raw
languages: [yaml]
severity: INFO
message: >-
Downloads release assets via gh release download with --pattern. Ensure the release
is from a trusted, verified tag. Consider using gh attestation verify or a checksum
manifest produced during the build job to validate asset integrity before use.
metadata:
category: security
confidence: low
precision: medium
yams_triage: artifact-integrity
pattern-regex: 'gh\s+release\s+download\s+.*--pattern'
paths:
include:
- /.github/workflows/**/*.yml
- /.github/workflows/**/*.yaml
- /tools/opengrep/tests/**/*.yml
- /tools/opengrep/tests/**/*.yaml
- tools/opengrep/tests/**/*.yml
- tools/opengrep/tests/**/*.yaml
exclude:
- /third_party/**
- /build/**
- /build*/**
- id: yams.github-actions.pull-request-target-checkout
languages: [yaml]
severity: ERROR
message: >-
pull_request_target event with actions/checkout that does not pin ref to the base
branch. The default checkout checks out the untrusted PR head, giving script injection
access to repository secrets. Always pass ref: ${{ github.event.pull_request.base.sha }}
or ref: ${{ github.base_ref }} when using pull_request_target.
metadata:
category: security
confidence: high
precision: medium
yams_triage: access-control
cwe: "CWE-913"
patterns:
- pattern-inside: |
on:
...
pull_request_target:
...
...
- pattern: |
uses: actions/checkout@...
- pattern-not: |
uses: actions/checkout@...
...
ref: ${{ github.event.pull_request.base.sha }}
- pattern-not: |
uses: actions/checkout@...
...
ref: ${{ github.base_ref }}
paths:
include:
- /.github/workflows/**/*.yml
- /.github/workflows/**/*.yaml
- /tools/opengrep/tests/**/*.yml
- /tools/opengrep/tests/**/*.yaml
- tools/opengrep/tests/**/*.yml
- tools/opengrep/tests/**/*.yaml
exclude:
- /third_party/**
- /build/**
- /build*/**
- id: yams.github-actions.workflow-dispatch-untrusted-input
languages: [yaml]
severity: WARNING
message: >-
workflow_dispatch input is used raw in a shell run step (e.g. ${{ inputs.X }}).
Without sanitization, this is an injection vector. Prefer setting the input to an
intermediate environment variable and validate it against a known set of values before
use in shell commands. Check for input validation (case/if guard) nearby.
metadata:
category: security
confidence: low
precision: low
yams_triage: injection
cwe: "CWE-20"
pattern-regex: '\$\{\{\s*inputs\.'
paths:
include:
- /.github/workflows/**/*.yml
- /.github/workflows/**/*.yaml
- /tools/opengrep/tests/**/*.yml
- /tools/opengrep/tests/**/*.yaml
- tools/opengrep/tests/**/*.yml
- tools/opengrep/tests/**/*.yaml
exclude:
- /third_party/**
- /build/**
- /build*/**
- id: yams.github-actions.artifact-download-without-source-validation
languages: [yaml]
severity: WARNING
message: >-
Downloads artifacts from a workflow_dispatch-controlled run_id input without visible
source validation. An attacker with write access can supply an arbitrary run_id pointing
to poisoned artifacts. Validate the run before downloading (check conclusion=success,
reject pull_request-triggered runs, verify the workflow name/event).
metadata:
category: security
confidence: high
precision: medium
yams_triage: artifact-integrity
cwe: "CWE-345"
patterns:
- pattern-inside: |
on:
...
workflow_dispatch:
...
inputs:
...
run_id:
...
...
- pattern: |
uses: actions/download-artifact@...
...
run-id: ${{ ...
- pattern-not: |
uses: actions/download-artifact@...
...
run-id: ${{ steps.resolve...
paths:
include:
- /.github/workflows/**/*.yml
- /.github/workflows/**/*.yaml
- /tools/opengrep/tests/**/*.yml
- /tools/opengrep/tests/**/*.yaml
- tools/opengrep/tests/**/*.yml
- tools/opengrep/tests/**/*.yaml
exclude:
- /third_party/**
- /build/**
- /build*/**