Skip to content

Commit b9ad417

Browse files
committed
JS: List safe environment variables in IndirectCommandInjection
1 parent 4c6711d commit b9ad417

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionCustomizations.qll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,38 @@ module IndirectCommandInjection {
4949
override string describe() { result = "environment variable" }
5050
}
5151

52+
/** Gets a data flow node referring to `process.env`. */
53+
private DataFlow::SourceNode envObject(DataFlow::TypeTracker t) {
54+
t.start() and
55+
result = NodeJSLib::process().getAPropertyRead("env")
56+
or
57+
exists(DataFlow::TypeTracker t2 | result = envObject(t2).track(t2, t))
58+
}
59+
60+
/** Gets a data flow node referring to `process.env`. */
61+
DataFlow::SourceNode envObject() { result = envObject(DataFlow::TypeTracker::end()) }
62+
63+
/**
64+
* Gets the name of an environment variable that is assumed to be safe.
65+
*/
66+
private string getASafeEnvironmentVariable() {
67+
result =
68+
[
69+
"GITHUB_ACTION", "GITHUB_ACTION_PATH", "GITHUB_ACTION_REPOSITORY", "GITHUB_ACTIONS",
70+
"GITHUB_ACTOR", "GITHUB_API_URL", "GITHUB_BASE_REF", "GITHUB_ENV", "GITHUB_EVENT_NAME",
71+
"GITHUB_EVENT_PATH", "GITHUB_GRAPHQL_URL", "GITHUB_JOB", "GITHUB_PATH", "GITHUB_REF",
72+
"GITHUB_REPOSITORY", "GITHUB_REPOSITORY_OWNER", "GITHUB_RUN_ID", "GITHUB_RUN_NUMBER",
73+
"GITHUB_SERVER_URL", "GITHUB_SHA", "GITHUB_WORKFLOW", "GITHUB_WORKSPACE"
74+
]
75+
}
76+
77+
/** Sanitizer that blocks flow through safe environment variables. */
78+
private class SafeEnvVariableSanitizer extends Sanitizer {
79+
SafeEnvVariableSanitizer() {
80+
this = envObject().getAPropertyRead(getASafeEnvironmentVariable())
81+
}
82+
}
83+
5284
/**
5385
* An object containing parsed command-line arguments, considered as a flow source for command injection.
5486
*/

javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
nodes
2+
| actions.js:3:6:3:16 | process.env |
3+
| actions.js:3:6:3:16 | process.env |
4+
| actions.js:3:6:3:29 | process ... _DATA'] |
5+
| actions.js:3:6:3:29 | process ... _DATA'] |
6+
| actions.js:6:15:6:15 | e |
7+
| actions.js:7:10:7:10 | e |
8+
| actions.js:7:10:7:23 | e['TEST_DATA'] |
9+
| actions.js:7:10:7:23 | e['TEST_DATA'] |
10+
| actions.js:11:6:11:16 | process.env |
11+
| actions.js:11:6:11:16 | process.env |
212
| command-line-parameter-command-injection.js:4:10:4:21 | process.argv |
313
| command-line-parameter-command-injection.js:4:10:4:21 | process.argv |
414
| command-line-parameter-command-injection.js:4:10:4:21 | process.argv |
@@ -212,6 +222,15 @@ nodes
212222
| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType |
213223
| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType |
214224
edges
225+
| actions.js:3:6:3:16 | process.env | actions.js:3:6:3:29 | process ... _DATA'] |
226+
| actions.js:3:6:3:16 | process.env | actions.js:3:6:3:29 | process ... _DATA'] |
227+
| actions.js:3:6:3:16 | process.env | actions.js:3:6:3:29 | process ... _DATA'] |
228+
| actions.js:3:6:3:16 | process.env | actions.js:3:6:3:29 | process ... _DATA'] |
229+
| actions.js:6:15:6:15 | e | actions.js:7:10:7:10 | e |
230+
| actions.js:7:10:7:10 | e | actions.js:7:10:7:23 | e['TEST_DATA'] |
231+
| actions.js:7:10:7:10 | e | actions.js:7:10:7:23 | e['TEST_DATA'] |
232+
| actions.js:11:6:11:16 | process.env | actions.js:6:15:6:15 | e |
233+
| actions.js:11:6:11:16 | process.env | actions.js:6:15:6:15 | e |
215234
| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line-parameter-command-injection.js:4:10:4:21 | process.argv |
216235
| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] |
217236
| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] |
@@ -400,6 +419,8 @@ edges
400419
| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType |
401420
| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType |
402421
#select
422+
| actions.js:3:6:3:29 | process ... _DATA'] | actions.js:3:6:3:16 | process.env | actions.js:3:6:3:29 | process ... _DATA'] | This command depends on an unsanitized $@. | actions.js:3:6:3:16 | process.env | environment variable |
423+
| actions.js:7:10:7:23 | e['TEST_DATA'] | actions.js:11:6:11:16 | process.env | actions.js:7:10:7:23 | e['TEST_DATA'] | This command depends on an unsanitized $@. | actions.js:11:6:11:16 | process.env | environment variable |
403424
| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line argument |
404425
| command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line argument |
405426
| command-line-parameter-command-injection.js:11:14:11:20 | args[0] | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line argument |
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { exec } from "@actions/exec";
2+
3+
exec(process.env['TEST_DATA']); // NOT OK
4+
exec(process.env['GITHUB_ACTION']); // OK
5+
6+
function test(e) {
7+
exec(e['TEST_DATA']); // NOT OK
8+
exec(e['GITHUB_ACTION']); // OK
9+
}
10+
11+
test(process.env);

0 commit comments

Comments
 (0)