Skip to content

Actions: Add four experimental queries#21624

Open
JamieMagee wants to merge 5 commits intogithub:mainfrom
JamieMagee:jamie/zizmor-inspired-actions-queries
Open

Actions: Add four experimental queries#21624
JamieMagee wants to merge 5 commits intogithub:mainfrom
JamieMagee:jamie/zizmor-inspired-actions-queries

Conversation

@JamieMagee
Copy link
Copy Markdown

Four new experimental queries that catch GitHub Actions issues Zizmor flags but CodeQL currently misses. All are structural pattern-matching (@kind problem), no dataflow.

actions/secrets-inherit (CWE-200): secrets: inherit on reusable workflow calls forwards every org and repo secret to the callee. Almost nobody actually needs that; the fix is listing the specific secrets the workflow uses.

actions/hardcoded-container-credentials (CWE-798): Literal passwords in container.credentials.password or services.*.credentials.password. Checks that the value isn't a ${{ }} expression.

actions/unsound-contains (CWE-183): contains('refs/heads/main refs/heads/develop', github.ref) looks like a membership check but is actually a substring match. A branch named mai would pass. The fix is contains(fromJSON('["refs/heads/main", "refs/heads/develop"]'), github.ref).

actions/spoofable-actor-check (CWE-290): github.actor == 'dependabot[bot]' as a security gate on pull_request_target. github.actor is the last actor to touch the context, not the one who opened the PR, so an attacker can spoof it. The existing ActorIfCheck in ControlChecks.qll already excludes [bot] patterns from being treated as security guards, which confirms the framework considers these checks insufficient.

Each query has an .md help file and test fixtures with both positive and negative cases.

@JamieMagee JamieMagee requested a review from a team as a code owner March 31, 2026 22:42
Copilot AI review requested due to automatic review settings March 31, 2026 22:42
@github-actions github-actions bot added documentation Actions Analysis of GitHub Actions labels Mar 31, 2026
@@ -0,0 +1 @@
experimental/Security/CWE-183/UnsoundContains.ql
@@ -0,0 +1 @@
experimental/Security/CWE-200/SecretsInherit.ql
@@ -0,0 +1 @@
experimental/Security/CWE-290/SpoofableActorCheck.ql
@@ -0,0 +1 @@
experimental/Security/CWE-798/HardcodedContainerCredentials.ql
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds four new experimental GitHub Actions security queries (structural @kind problem) to catch common workflow misconfigurations that can lead to secret exposure or bypassable security controls.

Changes:

  • Added 4 experimental Actions security queries: actions/secrets-inherit, actions/hardcoded-container-credentials, actions/unsound-contains, and actions/spoofable-actor-check.
  • Added per-query help (.md) documentation.
  • Added query-tests with positive/negative workflow fixtures and .expected results.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
actions/ql/src/experimental/Security/CWE-200/SecretsInherit.ql New query flagging secrets: inherit on reusable workflow calls.
actions/ql/src/experimental/Security/CWE-200/SecretsInherit.md Help text for actions/secrets-inherit.
actions/ql/test/query-tests/Security/CWE-200/SecretsInherit.qlref Test registration for SecretsInherit.
actions/ql/test/query-tests/Security/CWE-200/SecretsInherit.expected Expected results for SecretsInherit tests.
actions/ql/test/query-tests/Security/CWE-200/.github/workflows/secrets-inherit.yml Positive/negative workflow fixtures for SecretsInherit.
actions/ql/src/experimental/Security/CWE-798/HardcodedContainerCredentials.ql New query flagging hardcoded container/service credential passwords.
actions/ql/src/experimental/Security/CWE-798/HardcodedContainerCredentials.md Help text for actions/hardcoded-container-credentials.
actions/ql/test/query-tests/Security/CWE-798/HardcodedContainerCredentials.qlref Test registration for HardcodedContainerCredentials.
actions/ql/test/query-tests/Security/CWE-798/HardcodedContainerCredentials.expected Expected results for HardcodedContainerCredentials tests.
actions/ql/test/query-tests/Security/CWE-798/.github/workflows/hardcoded-credentials.yml Positive/negative workflow fixtures for hardcoded container/service credentials.
actions/ql/src/experimental/Security/CWE-183/UnsoundContains.ql New query flagging substring-based contains() membership checks using string literals.
actions/ql/src/experimental/Security/CWE-183/UnsoundContains.md Help text for actions/unsound-contains.
actions/ql/test/query-tests/Security/CWE-183/UnsoundContains.qlref Test registration for UnsoundContains.
actions/ql/test/query-tests/Security/CWE-183/UnsoundContains.expected Expected results for UnsoundContains tests.
actions/ql/test/query-tests/Security/CWE-183/.github/workflows/unsound-contains.yml Positive/negative workflow fixtures for unsound contains() usage.
actions/ql/src/experimental/Security/CWE-290/SpoofableActorCheck.ql New query flagging bot-name checks against spoofable actor contexts on externally triggerable events.
actions/ql/src/experimental/Security/CWE-290/SpoofableActorCheck.md Help text for actions/spoofable-actor-check.
actions/ql/test/query-tests/Security/CWE-290/SpoofableActorCheck.qlref Test registration for SpoofableActorCheck.
actions/ql/test/query-tests/Security/CWE-290/SpoofableActorCheck.expected Expected results for SpoofableActorCheck tests.
actions/ql/test/query-tests/Security/CWE-290/.github/workflows/bot-conditions.yml Positive/negative workflow fixtures for spoofable actor checks.
Comments suppressed due to low confidence (1)

actions/ql/src/experimental/Security/CWE-183/UnsoundContains.md:37

  • This second fromJSON() example also escapes the JSON quotes (it includes backslashes before the quotes). Please remove the backslashes so the JSON is written with normal double-quotes for copy/paste correctness.
```yaml
steps:
  - run: terraform apply
    if: contains(fromJSON('["refs/heads/main", "refs/heads/develop"]'), github.ref)
</details>

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.

New experimental security queries for GitHub Actions:

- actions/secrets-inherit (CWE-200): Flags \`secrets: inherit\` on
  reusable workflow calls. This passes all org/repo secrets to the
  callee, violating least privilege.
- actions/hardcoded-container-credentials (CWE-798): Flags hardcoded
  passwords in \`container.credentials\` and \`services.*.credentials\`.
- actions/unsound-contains (CWE-183): Flags \`contains()\` with a
  string-literal first argument. This does substring matching, not
  array membership, so \`contains('refs/heads/main', github.ref)\`
  also matches a branch named \`mai\`.
- actions/spoofable-actor-check (CWE-290): Flags \`github.actor\`
  or \`github.triggering_actor\` compared to a \`[bot]\` name on
  externally triggerable events. \`github.actor\` refers to the last
  actor on the context, not the triggering actor, so an attacker can
  spoof it.

Includes .md help files and tests for each query.
@JamieMagee JamieMagee force-pushed the jamie/zizmor-inspired-actions-queries branch from 68bdbbe to b6388da Compare April 1, 2026 17:36
@JamieMagee JamieMagee requested a review from Copilot April 1, 2026 17:37
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.

@intrigus-lgtm
Copy link
Copy Markdown
Contributor

secrets: inherit on reusable workflow calls forwards every org and repo secret to the callee. Almost nobody actually needs that; the fix is listing the specific secrets the workflow uses. [emphasis mine]

Is this actually true? If so, do you have a source for that? As far as I'm aware, only secrets to which the caller workflow already has access are getting inherited.

Fun fact, the GitHub blog explicitly lists secrets: inherit as an improvement: https://github.blog/changelog/2022-05-03-github-actions-simplify-using-secrets-with-reusable-workflows/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Actions Analysis of GitHub Actions documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants