Skip to content

Commit d6e38d5

Browse files
committed
Do not detect immutable actions in UnpinnedActionsTag
* these should be handles by the UseOfUnversionedImmutableAction.qll query instead * factor out immutableAction detection for reuse in both queries * octokit should not longer ping in UnpinnedActionsTag
1 parent e8ee798 commit d6e38d5

File tree

4 files changed

+12
-11
lines changed

4 files changed

+12
-11
lines changed

ql/lib/codeql/actions/security/UseOfUnversionedImmutableAction.qll

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ class UnversionedImmutableAction extends UsesStep {
44
string immutable_action;
55

66
UnversionedImmutableAction() {
7-
immutableActionsDataModel(immutable_action) and
8-
this.getCallee() = immutable_action and
7+
isImmutableAction(this, immutable_action) and
98
not isSemVer(this.getVersion())
109
}
1110
}
@@ -23,3 +22,8 @@ predicate isSemVer(string version) {
2322
// or latest which will work
2423
or version = "latest"
2524
}
25+
26+
predicate isImmutableAction(UsesStep actionStep, string actionName) {
27+
immutableActionsDataModel(actionName) and
28+
actionStep.getCallee() = actionName
29+
}

ql/src/Security/CWE-829/UnpinnedActionsTag.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Using a tag for a 3rd party Action that is not pinned to a commit can lead to ex
66

77
## Recommendations
88

9-
Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the action's repository and not a repository fork.
9+
Pinning an action to a full length commit SHA is currently the only way to use a non-immutable action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the action's repository and not a repository fork.
1010

1111
## Examples
1212

ql/src/Security/CWE-829/UnpinnedActionsTag.ql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
2-
* @name Unpinned tag for 3rd party Action in workflow
3-
* @description Using a tag for a 3rd party Action that is not pinned to a commit can lead to executing an untrusted Action through a supply chain attack.
2+
* @name Unpinned tag for a non-immutable Action in workflow
3+
* @description Using a tag for a non-immutable Action that is not pinned to a commit can lead to executing an untrusted Action through a supply chain attack.
44
* @kind problem
55
* @security-severity 5.0
66
* @problem.severity recommendation
@@ -12,6 +12,7 @@
1212
*/
1313

1414
import actions
15+
import codeql.actions.security.UseOfUnversionedImmutableAction
1516

1617
bindingset[version]
1718
private predicate isPinnedCommit(string version) { version.regexpMatch("^[A-Fa-f0-9]{40}$") }
@@ -32,7 +33,8 @@ where
3233
) and
3334
uses.getVersion() = version and
3435
not isTrustedOrg(repo) and
35-
not isPinnedCommit(version)
36+
not isPinnedCommit(version) and
37+
not isImmutableAction(uses, repo)
3638
select uses.getCalleeNode(),
3739
"Unpinned 3rd party Action '" + name + "' step $@ uses '" + repo + "' with ref '" + version +
3840
"', not a pinned commit hash", uses, uses.toString()

ql/test/query-tests/Security/CWE-829/UnpinnedActionsTag.expected

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,7 @@
1010
| .github/workflows/issue_comment_3rd_party_action.yml:14:15:14:52 | xt0rted/pull-request-comment-branch@v2 | Unpinned 3rd party Action 'PR head from 3rd party action' step $@ uses 'xt0rted/pull-request-comment-branch' with ref 'v2', not a pinned commit hash | .github/workflows/issue_comment_3rd_party_action.yml:12:9:16:6 | Uses Step: comment-branch | Uses Step: comment-branch |
1111
| .github/workflows/issue_comment_3rd_party_action.yml:27:15:27:52 | xt0rted/pull-request-comment-branch@v2 | Unpinned 3rd party Action 'PR head from 3rd party action' step $@ uses 'xt0rted/pull-request-comment-branch' with ref 'v2', not a pinned commit hash | .github/workflows/issue_comment_3rd_party_action.yml:25:9:30:6 | Uses Step: comment-branch | Uses Step: comment-branch |
1212
| .github/workflows/issue_comment_3rd_party_action.yml:41:15:41:42 | eficode/resolve-pr-refs@main | Unpinned 3rd party Action 'PR head from 3rd party action' step $@ uses 'eficode/resolve-pr-refs' with ref 'main', not a pinned commit hash | .github/workflows/issue_comment_3rd_party_action.yml:39:9:45:6 | Uses Step: refs | Uses Step: refs |
13-
| .github/workflows/issue_comment_octokit2.yml:13:15:13:41 | octokit/request-action@v2.x | Unpinned 3rd party Action 'Octokit (heuristics)' step $@ uses 'octokit/request-action' with ref 'v2.x', not a pinned commit hash | .github/workflows/issue_comment_octokit2.yml:12:9:19:6 | Uses Step: fetch_issue | Uses Step: fetch_issue |
14-
| .github/workflows/issue_comment_octokit2.yml:20:15:20:43 | octokit/request-action@v2.x.x | Unpinned 3rd party Action 'Octokit (heuristics)' step $@ uses 'octokit/request-action' with ref 'v2.x.x', not a pinned commit hash | .github/workflows/issue_comment_octokit2.yml:19:9:26:6 | Uses Step: fetch_pr | Uses Step: fetch_pr |
1513
| .github/workflows/issue_comment_octokit2.yml:34:15:34:42 | some-action/some-repo@latest | Unpinned 3rd party Action 'Octokit (heuristics)' step $@ uses 'some-action/some-repo' with ref 'latest', not a pinned commit hash | .github/workflows/issue_comment_octokit2.yml:33:9:37:6 | Uses Step | Uses Step |
16-
| .github/workflows/issue_comment_octokit.yml:13:15:13:41 | octokit/request-action@v2.x | Unpinned 3rd party Action 'Octokit (heuristics)' step $@ uses 'octokit/request-action' with ref 'v2.x', not a pinned commit hash | .github/workflows/issue_comment_octokit.yml:12:9:19:6 | Uses Step: fetch_issue | Uses Step: fetch_issue |
17-
| .github/workflows/issue_comment_octokit.yml:20:15:20:41 | octokit/request-action@v2.x | Unpinned 3rd party Action 'Octokit (heuristics)' step $@ uses 'octokit/request-action' with ref 'v2.x', not a pinned commit hash | .github/workflows/issue_comment_octokit.yml:19:9:26:6 | Uses Step: fetch_pr | Uses Step: fetch_pr |
18-
| .github/workflows/issue_comment_octokit.yml:104:15:104:43 | octokit/request-action@v2.0.2 | Unpinned 3rd party Action 'Octokit (heuristics)' step $@ uses 'octokit/request-action' with ref 'v2.0.2', not a pinned commit hash | .github/workflows/issue_comment_octokit.yml:103:9:109:6 | Uses Step: request | Uses Step: request |
1914
| .github/workflows/label_trusted_checkout1.yml:20:13:20:36 | completely/fakeaction@v2 | Unpinned 3rd party Action 'label_trusted_checkout1.yml' step $@ uses 'completely/fakeaction' with ref 'v2', not a pinned commit hash | .github/workflows/label_trusted_checkout1.yml:20:7:24:4 | Uses Step | Uses Step |
2015
| .github/workflows/label_trusted_checkout1.yml:24:13:24:37 | fakerepo/comment-on-pr@v1 | Unpinned 3rd party Action 'label_trusted_checkout1.yml' step $@ uses 'fakerepo/comment-on-pr' with ref 'v1', not a pinned commit hash | .github/workflows/label_trusted_checkout1.yml:24:7:27:21 | Uses Step | Uses Step |
2116
| .github/workflows/label_trusted_checkout2.yml:21:13:21:36 | completely/fakeaction@v2 | Unpinned 3rd party Action 'label_trusted_checkout2.yml' step $@ uses 'completely/fakeaction' with ref 'v2', not a pinned commit hash | .github/workflows/label_trusted_checkout2.yml:21:7:25:4 | Uses Step | Uses Step |

0 commit comments

Comments
 (0)