Skip to content

Commit 284c52f

Browse files
author
Alvaro Muñoz
committed
Bump qlpack versions
1 parent 28af21c commit 284c52f

File tree

6 files changed

+91
-51
lines changed

6 files changed

+91
-51
lines changed

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

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,51 +17,40 @@ string defaultBranchNames() {
1717
result = default_branch_name
1818
)
1919
or
20-
not exists(string default_branch_name |
21-
repositoryDataModel(_, default_branch_name)
22-
) and
20+
not exists(string default_branch_name | repositoryDataModel(_, default_branch_name)) and
2321
result = ["main", "master"]
2422
}
2523

26-
predicate runsOnDefaultBranch(Job j) {
27-
exists(Event e |
28-
j.getATriggerEvent() = e and
24+
predicate runsOnDefaultBranch(Event e) {
25+
(
26+
e.getName() = defaultBranchTriggerEvent() and
27+
not e.getName() = "pull_request_target"
28+
or
29+
e.getName() = "push" and
30+
e.getAPropertyValue("branches") = defaultBranchNames()
31+
or
32+
e.getName() = "pull_request_target" and
2933
(
30-
e.getName() = defaultBranchTriggerEvent() and
31-
not e.getName() = "pull_request_target"
34+
// no filtering
35+
not e.hasProperty("branches") and not e.hasProperty("branches-ignore")
3236
or
33-
e.getName() = "push" and
37+
// only branches-ignore filter
38+
e.hasProperty("branches-ignore") and
39+
not e.hasProperty("branches") and
40+
not e.getAPropertyValue("branches-ignore") = defaultBranchNames()
41+
or
42+
// only branches filter
43+
e.hasProperty("branches") and
44+
not e.hasProperty("branches-ignore") and
3445
e.getAPropertyValue("branches") = defaultBranchNames()
3546
or
36-
e.getName() = "pull_request_target" and
37-
(
38-
// no filtering
39-
not e.hasProperty("branches") and not e.hasProperty("branches-ignore")
40-
or
41-
// only branches-ignore filter
42-
e.hasProperty("branches-ignore") and
43-
not e.hasProperty("branches") and
44-
not e.getAPropertyValue("branches-ignore") = defaultBranchNames()
45-
or
46-
// only branches filter
47-
e.hasProperty("branches") and
48-
not e.hasProperty("branches-ignore") and
49-
e.getAPropertyValue("branches") = defaultBranchNames()
50-
or
51-
// branches and branches-ignore filters
52-
e.hasProperty("branches") and
53-
e.hasProperty("branches-ignore") and
54-
e.getAPropertyValue("branches") = defaultBranchNames() and
55-
not e.getAPropertyValue("branches-ignore") = defaultBranchNames()
56-
)
47+
// branches and branches-ignore filters
48+
e.hasProperty("branches") and
49+
e.hasProperty("branches-ignore") and
50+
e.getAPropertyValue("branches") = defaultBranchNames() and
51+
not e.getAPropertyValue("branches-ignore") = defaultBranchNames()
5752
)
5853
)
59-
or
60-
j.getATriggerEvent().getName() = "workflow_call" and
61-
exists(ExternalJob call |
62-
call.getCallee() = j.getLocation().getFile().getRelativePath() and
63-
runsOnDefaultBranch(call)
64-
)
6554
}
6655

6756
abstract class CacheWritingStep extends Step { }

ql/lib/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
library: true
33
warnOnImplicitThis: true
44
name: githubsecuritylab/actions-all
5-
version: 0.0.32
5+
version: 0.0.33
66
dependencies:
77
codeql/util: ^0.2.0
88
codeql/yaml: ^0.1.2

ql/src/Security/CWE-349/CachePoisoning.ql

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,25 @@ import codeql.actions.security.UntrustedCheckoutQuery
1616
import codeql.actions.security.CachePoisoningQuery
1717
import codeql.actions.security.PoisonableSteps
1818

19-
from LocalJob j, PRHeadCheckoutStep checkout, Step s
19+
from LocalJob j, Event e, PRHeadCheckoutStep checkout, Step s
2020
where
21-
// the workflow runs in the context of the default branch
22-
runsOnDefaultBranch(j) and
21+
j.getATriggerEvent() = e and
22+
// job can be triggered by an external user
23+
e.isExternallyTriggerable() and
24+
(
25+
// the workflow runs in the context of the default branch
26+
runsOnDefaultBranch(e)
27+
or
28+
// the workflow caller runs in the context of the default branch
29+
e.getName() = "workflow_call" and
30+
exists(ExternalJob caller |
31+
caller.getCallee() = j.getLocation().getFile().getRelativePath() and
32+
runsOnDefaultBranch(caller.getATriggerEvent())
33+
)
34+
) and
2335
// the job checkouts untrusted code from a pull request
2436
// TODO: Consider adding artifact downloads as a potential source of cache poisoning
2537
j.getAStep() = checkout and
26-
// job can be triggered by an external user
27-
j.getATriggerEvent().isExternallyTriggerable() and
2838
(
2939
// the job writes to the cache
3040
// (No need to follow the checkout step as the cache writing is normally done after the job completes)
@@ -35,7 +45,7 @@ where
3545
// (The cache specific token can be leaked even for non-privileged workflows)
3646
checkout.getAFollowingStep() = s and
3747
s instanceof PoisonableStep and
38-
// excluding privileged workflows since they can be easily exploited in similar circumstances
48+
// excluding privileged workflows since they can be exploited in easier circumstances
3949
not j.isPrivileged()
4050
)
4151
select checkout, "Potential cache poisoning in the context of the default branch on step $@.", s,

ql/src/Security/CWE-349/CachePoisoningByCodeInjection.ql

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,26 @@ import codeql.actions.security.CodeInjectionQuery
1717
import codeql.actions.security.CachePoisoningQuery
1818
import CodeInjectionFlow::PathGraph
1919

20-
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, LocalJob j
20+
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, LocalJob j, Event e
2121
where
22-
CodeInjectionFlow::flowPath(source, sink) and
23-
j = sink.getNode().asExpr().getEnclosingJob() and
22+
j.getATriggerEvent() = e and
2423
// job can be triggered by an external user
25-
j.getATriggerEvent().isExternallyTriggerable() and
26-
// excluding privileged workflows since they can be easily exploited in similar circumstances
24+
e.isExternallyTriggerable() and
25+
(
26+
// the workflow runs in the context of the default branch
27+
runsOnDefaultBranch(e)
28+
or
29+
// the workflow caller runs in the context of the default branch
30+
e.getName() = "workflow_call" and
31+
exists(ExternalJob caller |
32+
caller.getCallee() = j.getLocation().getFile().getRelativePath() and
33+
runsOnDefaultBranch(caller.getATriggerEvent())
34+
)
35+
) and
36+
// excluding privileged workflows since they can be exploited in easier circumstances
2737
not j.isPrivileged() and
28-
// The workflow runs in the context of the default branch
29-
runsOnDefaultBranch(j)
38+
CodeInjectionFlow::flowPath(source, sink) and
39+
j = sink.getNode().asExpr().getEnclosingJob()
3040
select sink.getNode(), source, sink,
3141
"Unprivileged code injection in $@, which may lead to cache poisoning.", sink,
3242
sink.getNode().asExpr().(Expression).getRawExpression()

ql/src/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
library: false
33
name: githubsecuritylab/actions-queries
4-
version: 0.0.32
4+
version: 0.0.33
55
groups:
66
- actions
77
- queries
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Test
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
- 'releases/*'
9+
10+
jobs:
11+
verify-build:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
ref: ${{ github.event.pull_request.head.sha }}
18+
19+
- name: Setup Node.js
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version-file: .nvmrc
23+
24+
- name: Install NPM dependencies
25+
run: npm ci
26+
27+
- name: Rebuild the dist/ directory
28+
run: npm run build
29+
30+
- name: Compare the expected and actual dist/ directories
31+
run: bin/check-build-output-in-dist-directory

0 commit comments

Comments
 (0)