Skip to content

Commit 89c4c9e

Browse files
authored
Merge pull request #1678 from github/henrymercer/default-setup-safeguarding
Flag up functionality that may not exist in default setup workflows
2 parents 9d2dd7c + 9632771 commit 89c4c9e

8 files changed

+138
-12
lines changed

lib/actions-util.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/actions-util.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

queries/codeql-pack.lock.yml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
lockVersion: 1.0.0
3+
dependencies:
4+
codeql-javascript:
5+
version: 0.6.1
6+
codeql/regex:
7+
version: 0.0.12
8+
codeql/tutorial:
9+
version: 0.0.9
10+
codeql/util:
11+
version: 0.0.9
12+
codeql/yaml:
13+
version: 0.0.1
14+
compiled: false
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
name: codeql-action-custom-queries-javascript
22
version: 0.0.0
3-
libraryPathDependencies: codeql-javascript
4-
3+
dependencies:
4+
codeql/javascript-all: 0.6.1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* @name Some environment variables may not exist in default setup workflows
3+
* @id javascript/codeql-action/default-setup-env-vars
4+
* @kind problem
5+
* @severity warning
6+
*/
7+
8+
import javascript
9+
10+
bindingset[envVar]
11+
predicate isSafeForDefaultSetup(string envVar) {
12+
// Ignore internal Code Scanning environment variables
13+
envVar.matches("CODE_SCANNING_%") or
14+
envVar.matches("CODEQL_%") or
15+
envVar.matches("CODESCANNING_%") or
16+
envVar.matches("LGTM_%") or
17+
// We flag up usage of potentially unsafe parts of the GitHub event in `default-setup-event-context.ql`.
18+
envVar = "GITHUB_EVENT_PATH" or
19+
// The following environment variables are known to be safe for use with default setup
20+
envVar =
21+
[
22+
"GITHUB_ACTION_REF", "GITHUB_ACTION_REPOSITORY", "GITHUB_ACTOR", "GITHUB_API_URL",
23+
"GITHUB_BASE_REF", "GITHUB_EVENT_NAME", "GITHUB_JOB", "GITHUB_RUN_ATTEMPT", "GITHUB_RUN_ID",
24+
"GITHUB_SHA", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_TOKEN", "GITHUB_WORKFLOW",
25+
"GITHUB_WORKSPACE", "GOFLAGS", "JAVA_TOOL_OPTIONS", "RUNNER_ARCH", "RUNNER_NAME", "RUNNER_OS",
26+
"RUNNER_TEMP", "RUNNER_TOOL_CACHE"
27+
]
28+
}
29+
30+
predicate envVarRead(DataFlow::Node node, string envVar) {
31+
node =
32+
any(DataFlow::PropRead read |
33+
read = NodeJSLib::process().getAPropertyRead("env").getAPropertyRead() and
34+
envVar = read.getPropertyName()
35+
) or
36+
node =
37+
any(DataFlow::CallNode call |
38+
call.getCalleeName().matches("get%EnvParam") and
39+
envVar = call.getArgument(0).getStringValue()
40+
)
41+
}
42+
43+
from DataFlow::Node read, string envVar
44+
where
45+
envVarRead(read, envVar) and
46+
not isSafeForDefaultSetup(envVar)
47+
select read,
48+
"The environment variable " + envVar +
49+
" may not exist in default setup workflows. If all uses are safe, add it to the list of " +
50+
"environment variables that are known to be safe in " +
51+
"'queries/default-setup-environment-variables.ql'. If this use is safe but others are not, " +
52+
"dismiss this alert as a false positive."
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* @name Some context properties may not exist in default setup workflows
3+
* @id javascript/codeql-action/default-setup-context-properties
4+
* @kind path-problem
5+
* @severity warning
6+
*/
7+
8+
import javascript
9+
import DataFlow::PathGraph
10+
11+
class NotParsedLabel extends DataFlow::FlowLabel {
12+
NotParsedLabel() { this = "not-parsed" }
13+
}
14+
15+
class ParsedLabel extends DataFlow::FlowLabel {
16+
ParsedLabel() { this = "parsed" }
17+
}
18+
19+
class EventContextAccessConfiguration extends DataFlow::Configuration {
20+
EventContextAccessConfiguration() { this = "EventContextAccessConfiguration" }
21+
22+
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) {
23+
source = NodeJSLib::process().getAPropertyRead("env").getAPropertyRead("GITHUB_EVENT_PATH") and
24+
lbl instanceof NotParsedLabel
25+
}
26+
27+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel lbl) {
28+
sink instanceof DataFlow::PropRead and
29+
lbl instanceof ParsedLabel and
30+
not exists(DataFlow::PropRead n | sink = n.getBase()) and
31+
not sink.asExpr().getFile().getBaseName().matches("%.test.ts")
32+
}
33+
34+
override predicate isAdditionalFlowStep(
35+
DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
36+
) {
37+
src = trg.(FileSystemReadAccess).getAPathArgument() and inlbl = outlbl
38+
or
39+
exists(JsonParserCall c |
40+
src = c.getInput() and
41+
trg = c.getOutput() and
42+
inlbl instanceof NotParsedLabel and
43+
outlbl instanceof ParsedLabel
44+
)
45+
or
46+
(
47+
TaintTracking::sharedTaintStep(src, trg) or
48+
DataFlow::SharedFlowStep::step(src, trg) or
49+
DataFlow::SharedFlowStep::step(src, trg, _, _)
50+
) and
51+
inlbl = outlbl
52+
}
53+
}
54+
55+
from EventContextAccessConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
56+
where cfg.hasFlowPath(source, sink)
57+
select sink.getNode(), source, sink,
58+
"This event context property may not exist in default setup workflows."

queries/inconsistent-action-input.ql

+9-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* must be defined in an identical way to avoid confusion for the user.
55
* This also makes writing queries like required-action-input.ql easier.
66
* @kind problem
7-
* @problem.severity error
7+
* @severity error
88
* @id javascript/codeql-action/inconsistent-action-input
99
*/
1010

@@ -15,7 +15,9 @@ import javascript
1515
*/
1616
class ActionDeclaration extends File {
1717
ActionDeclaration() {
18-
getRelativePath().matches("%/action.yml")
18+
getRelativePath().matches("%/action.yml") and
19+
// Ignore internal Actions
20+
not getRelativePath().matches(".github/actions/%")
1921
}
2022

2123
/**
@@ -25,19 +27,19 @@ class ActionDeclaration extends File {
2527
result = getRelativePath().regexpCapture("(.*)/action.yml", 1)
2628
}
2729

28-
YAMLDocument getRootNode() {
30+
YamlDocument getRootNode() {
2931
result.getFile() = this
3032
}
3133

32-
YAMLValue getInput(string inputName) {
33-
result = getRootNode().(YAMLMapping).lookup("inputs").(YAMLMapping).lookup(inputName)
34+
YamlValue getInput(string inputName) {
35+
result = getRootNode().(YamlMapping).lookup("inputs").(YamlMapping).lookup(inputName)
3436
}
3537
}
3638

37-
predicate areNotEquivalent(YAMLValue x, YAMLValue y) {
39+
predicate areNotEquivalent(YamlValue x, YamlValue y) {
3840
x.getTag() != y.getTag()
3941
or
40-
x.(YAMLScalar).getValue() != y.(YAMLScalar).getValue()
42+
x.(YamlScalar).getValue() != y.(YamlScalar).getValue()
4143
or
4244
x.getNumChild() != y.getNumChild()
4345
or

src/actions-util.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ export async function isAnalyzingDefaultBranch(): Promise<boolean> {
648648
let defaultBranch = event?.repository?.default_branch;
649649

650650
if (process.env.GITHUB_EVENT_NAME === "schedule") {
651-
defaultBranch = removeRefsHeadsPrefix(getRequiredEnvParam("GITHUB_REF"));
651+
defaultBranch = removeRefsHeadsPrefix(getRefFromEnv());
652652
}
653653

654654
return currentRef === defaultBranch;

0 commit comments

Comments
 (0)