|
2 | 2 |
|
3 | 3 | private import semmle.code.java.dataflow.ExternalFlow |
4 | 4 | private import semmle.code.java.dataflow.FlowSources |
5 | | -private import semmle.code.java.dataflow.TaintTracking |
6 | 5 | private import semmle.code.java.Maps |
7 | 6 | private import semmle.code.java.JDK |
8 | 7 |
|
| 8 | +private class MapPutOrRemove extends MethodCall { |
| 9 | + MapPutOrRemove() { |
| 10 | + this.getMethod() instanceof MapMutator and |
| 11 | + this.getMethod().getName().matches(["put%", "remove"]) |
| 12 | + } |
| 13 | +} |
| 14 | + |
9 | 15 | private module ProcessBuilderEnvironmentConfig implements DataFlow::ConfigSig { |
10 | 16 | predicate isSource(DataFlow::Node source) { |
11 | 17 | exists(MethodCall mc | mc = source.asExpr() | |
12 | 18 | mc.getMethod().hasQualifiedName("java.lang", "ProcessBuilder", "environment") |
13 | 19 | ) |
14 | 20 | } |
15 | 21 |
|
16 | | - predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(MapMutation mm).getQualifier() } |
| 22 | + predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(MapPutOrRemove mm).getQualifier() } |
17 | 23 | } |
18 | 24 |
|
19 | 25 | private module ProcessBuilderEnvironmentFlow = DataFlow::Global<ProcessBuilderEnvironmentConfig>; |
20 | 26 |
|
| 27 | +/** |
| 28 | + * A node that acts as a sanitizer in configurations related to environment variable injection. |
| 29 | + */ |
| 30 | +abstract class ExecTaintedEnvironmentSanitizer extends DataFlow::Node { } |
| 31 | + |
21 | 32 | /** |
22 | 33 | * A taint-tracking configuration that tracks flow from unvalidated data to an environment variable for a subprocess. |
23 | 34 | */ |
24 | 35 | module ExecTaintedEnvironmentConfig implements DataFlow::ConfigSig { |
25 | 36 | predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource } |
26 | 37 |
|
| 38 | + predicate isBarrier(DataFlow::Node barrier) { barrier instanceof ExecTaintedEnvironmentSanitizer } |
| 39 | + |
27 | 40 | predicate isSink(DataFlow::Node sink) { |
28 | 41 | sinkNode(sink, "environment-injection") |
29 | 42 | or |
30 | 43 | // sink is a key or value added to a `ProcessBuilder::environment` map. |
31 | | - exists(MapMutation mm | mm.getAnArgument() = sink.asExpr() | |
| 44 | + exists(MapPutOrRemove mm | mm.getAnArgument() = sink.asExpr() | |
32 | 45 | ProcessBuilderEnvironmentFlow::flowToExpr(mm.getQualifier()) |
33 | 46 | ) |
34 | 47 | } |
|
0 commit comments