Skip to content

Commit 239b16b

Browse files
authored
Merge branch 'main' into felickz-add-spring-r2dbc-models
2 parents 6919c3d + b5b4852 commit 239b16b

253 files changed

Lines changed: 2082 additions & 640 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CODEOWNERS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,14 @@
2424
/rust/ @github/codeql-rust
2525
/rust/extractor/ @github/codeql-rust @github/code-scanning-language-coverage
2626
/shared/ @github/codeql-shared-libraries-reviewers
27+
/shared/cpp/ @github/code-scanning-language-coverage
28+
/shared/yeast/ @github/code-scanning-language-coverage
29+
/shared/yeast-macros/ @github/code-scanning-language-coverage
30+
/shared/yeast-schema/ @github/code-scanning-language-coverage
2731
/swift/ @github/codeql-swift
2832
/swift/extractor/ @github/codeql-swift @github/code-scanning-language-coverage
33+
/unified/extractor/ @github/code-scanning-language-coverage
34+
/unified/swift-syntax-rs/ @github/code-scanning-language-coverage
2935
/misc/codegen/ @github/codeql-swift
3036
/java/kotlin-extractor/ @github/codeql-kotlin @github/code-scanning-language-coverage
3137
/java/ql/test-kotlin1/ @github/codeql-kotlin

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

actions/ql/lib/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## 0.5.0
2+
3+
### Breaking Changes
4+
5+
* The `codeql.actions.security.SelfHostedQuery` module has been removed because runner labels do not reliably distinguish self-hosted runners from managed runners.
6+
7+
### Minor Analysis Improvements
8+
9+
* GitHub Actions analysis now recognizes untrusted data in `github.event.merge_group` for workflows triggered by the `merge_group` event.
10+
111
## 0.4.40
212

313
### Minor Analysis Improvements

actions/ql/lib/change-notes/2026-07-27-merge-group-event-source.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

actions/ql/lib/change-notes/2026-08-03-deprecate-self-hosted-query.md

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## 0.5.0
2+
3+
### Breaking Changes
4+
5+
* The `codeql.actions.security.SelfHostedQuery` module has been removed because runner labels do not reliably distinguish self-hosted runners from managed runners.
6+
7+
### Minor Analysis Improvements
8+
9+
* GitHub Actions analysis now recognizes untrusted data in `github.event.merge_group` for workflows triggered by the `merge_group` event.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
lastReleaseVersion: 0.4.40
2+
lastReleaseVersion: 0.5.0

actions/ql/lib/codeql/actions/dataflow/FlowSources.qll

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,29 +52,43 @@ class GitHubCtxSource extends RemoteFlowSource {
5252
override string getEventName() { result = event }
5353
}
5454

55+
bindingset[expression]
56+
pragma[inline_late]
57+
private predicate untrustedEventProperty(Expression expression, string kind) {
58+
exists(string regexp |
59+
untrustedEventPropertiesDataModel(regexp, kind) and
60+
kind != "json" and
61+
normalizeExpr(expression.getExpression()).regexpMatch("(?i)\\s*" + wrapRegexp(regexp) + ".*")
62+
)
63+
}
64+
65+
bindingset[expression, event]
66+
pragma[inline_late]
67+
private predicate expressionContainsEventContext(Expression expression, string event) {
68+
exists(string contextPrefix |
69+
contextTriggerDataModel(event, contextPrefix) and
70+
normalizeExpr(expression.getExpression()).matches("%" + contextPrefix + "%")
71+
)
72+
}
73+
5574
class GitHubEventCtxSource extends RemoteFlowSource {
5675
string flag;
5776
string context;
5877
string event;
5978

6079
GitHubEventCtxSource() {
61-
exists(Expression e, string regexp |
80+
exists(Expression e |
6281
this.asExpr() = e and
6382
context = e.getExpression() and
6483
(
6584
// the context is available for the job trigger events
6685
event = e.getATriggerEvent().getName() and
67-
exists(string context_prefix |
68-
contextTriggerDataModel(event, context_prefix) and
69-
normalizeExpr(context).matches("%" + context_prefix + "%")
70-
)
86+
expressionContainsEventContext(e, event)
7187
or
7288
not exists(e.getATriggerEvent()) and
7389
event = "unknown"
7490
) and
75-
untrustedEventPropertiesDataModel(regexp, flag) and
76-
not flag = "json" and
77-
normalizeExpr(context).regexpMatch("(?i)\\s*" + wrapRegexp(regexp) + ".*")
91+
untrustedEventProperty(e, flag)
7892
)
7993
}
8094

@@ -177,32 +191,41 @@ class GitHubEventPathSource extends RemoteFlowSource, CommandSource {
177191
override Run getEnclosingRun() { result = run }
178192
}
179193

194+
bindingset[expression, event]
195+
pragma[inline_late]
196+
private predicate jsonSourceForEvent(Expression expression, string event) {
197+
exists(string context, string regexp, string contextPrefix |
198+
context = expression.getExpression() and
199+
untrustedEventPropertiesDataModel(regexp, _) and
200+
contextTriggerDataModel(event, contextPrefix) and
201+
normalizeExpr(context).matches("%" + contextPrefix + "%") and
202+
normalizeExpr(context).regexpMatch("(?i).*" + wrapJsonRegexp(regexp) + ".*")
203+
)
204+
or
205+
exists(string context |
206+
context = expression.getExpression() and
207+
untrustedEventPropertiesDataModel(_, _) and
208+
contextTriggerDataModel(event, _) and
209+
normalizeExpr(context).regexpMatch("(?i).*" + wrapJsonRegexp("\\bgithub.event\\b") + ".*")
210+
)
211+
}
212+
180213
class GitHubEventJsonSource extends RemoteFlowSource {
181214
string flag;
182215
string event;
183216

184217
GitHubEventJsonSource() {
185-
exists(Expression e, string context, string regexp |
218+
exists(Expression e |
186219
this.asExpr() = e and
187-
context = e.getExpression() and
188-
untrustedEventPropertiesDataModel(regexp, _) and
189220
(
190221
// only contexts for the triggering events are considered tainted.
191222
// eg: for `pull_request`, we only consider `github.event.pull_request`
192223
event = e.getEnclosingWorkflow().getATriggerEvent().getName() and
193-
exists(string context_prefix |
194-
contextTriggerDataModel(event, context_prefix) and
195-
normalizeExpr(context).matches("%" + context_prefix + "%")
196-
) and
197-
normalizeExpr(context).regexpMatch("(?i).*" + wrapJsonRegexp(regexp) + ".*")
198-
or
199-
// github.event is tainted for all triggers
200-
event = e.getEnclosingWorkflow().getATriggerEvent().getName() and
201-
contextTriggerDataModel(e.getEnclosingWorkflow().getATriggerEvent().getName(), _) and
202-
normalizeExpr(context).regexpMatch("(?i).*" + wrapJsonRegexp("\\bgithub.event\\b") + ".*")
224+
jsonSourceForEvent(e, event)
203225
or
204226
not exists(e.getATriggerEvent()) and
205-
event = "unknown"
227+
event = "unknown" and
228+
untrustedEventPropertiesDataModel(_, _)
206229
) and
207230
flag = "json"
208231
)

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

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ string defaultBranchTriggerEvent() {
55
[
66
"check_run", "check_suite", "delete", "discussion", "discussion_comment", "fork", "gollum",
77
"issue_comment", "issues", "label", "milestone", "project", "project_card", "project_column",
8-
"public", "pull_request_comment", "pull_request_target", "repository_dispatch", "schedule",
9-
"watch", "workflow_run"
8+
"public", "pull_request_comment", "pull_request_target", "repository_dispatch",
9+
"registry_package", "page_build", "schedule", "watch", "workflow_dispatch", "workflow_run"
1010
]
1111
}
1212

@@ -42,6 +42,27 @@ predicate runsOnDefaultBranch(Event e) {
4242
)
4343
}
4444

45+
private string defaultBranchCacheWriteEvent() {
46+
result =
47+
[
48+
"push", "workflow_dispatch", "repository_dispatch", "delete", "registry_package",
49+
"page_build", "schedule"
50+
]
51+
}
52+
53+
private predicate eventHasDefaultBranchCacheWriteAccess(Event event) {
54+
runsOnDefaultBranch(event) and event.getName() = defaultBranchCacheWriteEvent()
55+
}
56+
57+
/**
58+
* Holds if `job` can write to the cache scope of the default branch for `event`.
59+
* Reusable workflow jobs inherit their caller's trigger event.
60+
*/
61+
predicate hasDefaultBranchCacheWriteAccess(LocalJob job, Event event) {
62+
job.getATriggerEvent() = event and
63+
eventHasDefaultBranchCacheWriteAccess(event)
64+
}
65+
4566
abstract class CacheWritingStep extends Step {
4667
abstract string getPath();
4768
}

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

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,10 @@ Event getRelevantCachePoisoningEventForSink(DataFlow::Node sink) {
2929
exists(LocalJob job |
3030
job = sink.asExpr().getEnclosingJob() and
3131
job.getATriggerEvent() = result and
32-
// job can be triggered by an external user
33-
result.isExternallyTriggerable() and
3432
// excluding privileged workflows since they can be exploited in easier circumstances
3533
// which is covered by `actions/code-injection/critical`
3634
not job.isPrivilegedExternallyTriggerable(result) and
37-
(
38-
// the workflow runs in the context of the default branch
39-
runsOnDefaultBranch(result)
40-
or
41-
// the workflow caller runs in the context of the default branch
42-
result.getName() = "workflow_call" and
43-
exists(ExternalJob caller |
44-
caller.getCallee() = job.getLocation().getFile().getRelativePath() and
45-
runsOnDefaultBranch(caller.getATriggerEvent())
46-
)
47-
)
35+
hasDefaultBranchCacheWriteAccess(job, result)
4836
)
4937
}
5038

0 commit comments

Comments
 (0)