Skip to content

Commit a1fe250

Browse files
authored
Merge pull request #1 from hvitved/nodeselector-actions-lockfile-aware-pinning
Code review suggestions
2 parents e733ac6 + 61a5127 commit a1fe250

2 files changed

Lines changed: 25 additions & 28 deletions

File tree

actions/ql/lib/codeql/actions/Lock.qll

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,21 @@
22
* Provides classes for working with GitHub Actions lockfiles.
33
*/
44

5+
private import actions
56
private import codeql.actions.ast.internal.Yaml
67

7-
/** An `actions.lock` file. */
8-
class ActionsLock extends YamlDocument {
9-
ActionsLock() { this.getFile().getBaseName() = "actions.lock" }
8+
/** A `.github/workflows/actions.lock` file. */
9+
class ActionsLock extends YamlDocument, YamlMapping {
10+
ActionsLock() { this.getFile().getRelativePath() = ".github/workflows/actions.lock" }
1011

11-
/**
12-
* Holds if the lockfile records `nwo` at `ref` for `workflowPath` with a full commit digest.
13-
* Repository pins also cover sub-actions such as `actions/cache/save`.
14-
*/
15-
bindingset[nwo]
16-
predicate pins(string workflowPath, string nwo, string ref) {
17-
this.getFile().getRelativePath() = ".github/workflows/actions.lock" and
18-
exists(
19-
YamlMapping root, YamlSequence workflowPins, YamlScalar pinNode, YamlMapping dependency,
20-
string pin, string pinnedNwo
21-
|
22-
root = this and
23-
root.lookup("workflows").(YamlMapping).lookup(workflowPath) = workflowPins and
12+
private predicate pins0(string workflowPath, string pinnedNwo, string ref) {
13+
exists(YamlSequence workflowPins, YamlScalar pinNode, YamlMapping dependency, string pin |
14+
this.lookup("workflows").(YamlMapping).lookup(workflowPath) = workflowPins and
2415
workflowPins.getElement(_) = pinNode and
2516
pin = pinNode.getValue() and
2617
pinnedNwo = pin.regexpCapture("^([^/@:]+/[^/@:]+)@([^:]+)$", 1) and
2718
ref = pin.regexpCapture("^([^/@:]+/[^/@:]+)@([^:]+)$", 2) and
28-
(
29-
nwo.toLowerCase() = pinnedNwo.toLowerCase()
30-
or
31-
nwo.toLowerCase().prefix(pinnedNwo.length() + 1) = pinnedNwo.toLowerCase() + "/"
32-
) and
33-
root.lookup("dependencies").(YamlMapping).lookup(pin) = dependency and
19+
this.lookup("dependencies").(YamlMapping).lookup(pin) = dependency and
3420
dependency.lookup("ref").(YamlScalar).getValue() = ref and
3521
dependency
3622
.lookup("commit")
@@ -39,4 +25,20 @@ class ActionsLock extends YamlDocument {
3925
.regexpMatch("^(sha1-[A-Fa-f0-9]{40}|sha256-[A-Fa-f0-9]{64})$")
4026
)
4127
}
28+
29+
/**
30+
* Holds if this lockfile pins the use at `uses` to `ref` with a full commit digest.
31+
* Repository pins also cover sub-actions such as `actions/cache/save`.
32+
*/
33+
predicate pins(UsesStep uses, string ref) {
34+
exists(string workflowPath, string pinnedNwo, string nwo |
35+
this.pins0(workflowPath, pinnedNwo, ref) and
36+
workflowPath = uses.getLocation().getFile().getRelativePath() and
37+
nwo = uses.getCallee()
38+
|
39+
nwo.toLowerCase() = pinnedNwo.toLowerCase()
40+
or
41+
nwo.toLowerCase().prefix(pinnedNwo.length() + 1) = pinnedNwo.toLowerCase() + "/"
42+
)
43+
}
4244
}

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,7 @@ where
6262
uses.getVersion() = version and
6363
not isTrustedOwner(nwo) and
6464
not isSelfRepository(nwo) and
65-
not exists(UsesStep step |
66-
uses = step and
67-
exists(ActionsLock lock |
68-
lock.pins(step.getLocation().getFile().getRelativePath(), nwo, version)
69-
)
70-
) and
65+
not any(ActionsLock lock).pins(uses, version) and
7166
not (
7267
if uses instanceof UsesStep and isContainerImage(nwo)
7368
then isPinnedContainer(version)

0 commit comments

Comments
 (0)