forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEnvValueAndKeyInjection.ql
More file actions
74 lines (63 loc) · 2.45 KB
/
EnvValueAndKeyInjection.ql
File metadata and controls
74 lines (63 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
* @name User controlled arbitrary environment variable injection
* @description creating arbitrary environment variables from user controlled data is not secure
* @kind path-problem
* @id js/env-key-and-value-injection
* @problem.severity error
* @security-severity 7.5
* @precision medium
* @tags security
* external/cwe/cwe-089
*/
import javascript
/** A taint tracking configuration for unsafe environment injection. */
module EnvValueAndKeyInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
predicate isSink(DataFlow::Node sink) {
sink = keyOfEnv() or
sink = valueOfEnv()
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(DataFlow::InvokeNode ikn |
ikn = DataFlow::globalVarRef("Object").getAMemberInvocation("keys")
|
node1 = ikn.getArgument(0) and
(
node2 = ikn.getAChainedMethodCall(["filter", "map"]) or
node2 = ikn or
node2 = ikn.getAChainedMethodCall("forEach").getABoundCallbackParameter(0, 0)
)
)
}
predicate observeDiffInformedIncrementalMode() {
none() // can't override location accurately because of secondary use in select.
}
}
module EnvValueAndKeyInjectionFlow = TaintTracking::Global<EnvValueAndKeyInjectionConfig>;
DataFlow::Node keyOfEnv() {
result =
NodeJSLib::process().getAPropertyRead("env").getAPropertyWrite().getPropertyNameExpr().flow()
}
DataFlow::Node valueOfEnv() {
result = API::moduleImport("process").getMember("env").getAMember().asSink()
}
private predicate readToProcessEnv(DataFlow::Node envKey, DataFlow::Node envValue) {
exists(DataFlow::PropWrite env |
env = NodeJSLib::process().getAPropertyRead("env").getAPropertyWrite()
|
envKey = env.getPropertyNameExpr().flow() and
envValue = env.getRhs()
)
}
import EnvValueAndKeyInjectionFlow::PathGraph
from
EnvValueAndKeyInjectionFlow::PathNode source, EnvValueAndKeyInjectionFlow::PathNode envKey,
EnvValueAndKeyInjectionFlow::PathNode envValue
where
EnvValueAndKeyInjectionFlow::flowPath(source, envKey) and
envKey.getNode() = keyOfEnv() and
EnvValueAndKeyInjectionFlow::flowPath(source, envValue) and
envValue.getNode() = valueOfEnv() and
readToProcessEnv(envKey.getNode(), envValue.getNode())
select envKey.getNode(), source, envKey, "arbitrary environment variable assignment from this $@.",
source.getNode(), "user controllable source"