1
1
/**
2
- * Provides a taint-tracking configuration for detecting path injection
3
- * vulnerabilities.
2
+ * Provides taint-tracking configurations for detecting "path injection" vulnerabilities.
4
3
*
5
- * We detect cases where a user-controlled path is used in an unsafe manner,
6
- * meaning it is not both normalized and _afterwards_ checked.
7
- *
8
- * It does so by dividing the problematic situation into two cases:
9
- * 1. The file path is never normalized.
10
- * This is easily detected by using normalization as a sanitizer.
11
- *
12
- * 2. The file path is normalized at least once, but never checked afterwards.
13
- * This is detected by finding the earliest normalization and then ensuring that
14
- * no checks happen later. Since we start from the earliest normalization,
15
- * we know that the absence of checks means that no normalization has a
16
- * check after it. (No checks after a second normalization would be ok if
17
- * there was a check between the first and the second.)
18
- *
19
- * Note that one could make the dual split on whether the file path is ever checked. This does
20
- * not work as nicely, however, since checking is modelled as a `BarrierGuard` rather than
21
- * as a `Sanitizer`. That means that only some dataflow paths out of a check will be removed,
22
- * and so identifying the last check is not possible simply by finding a dataflow path from it
23
- * to a sink.
4
+ * Note, for performance reasons: only import this file if
5
+ * the Configurations or the `pathInjection` predicate are needed, otherwise
6
+ * `PathInjectionCustomizations` should be imported instead.
24
7
*/
25
8
26
- import python
27
- import semmle.python.dataflow.new.DataFlow
28
- import semmle.python.dataflow.new.DataFlow2
29
- import semmle.python.dataflow.new.TaintTracking
30
- import semmle.python.dataflow.new.TaintTracking2
31
- import semmle.python.Concepts
32
- import semmle.python.dataflow.new.RemoteFlowSources
9
+ private import python
10
+ private import semmle.python.Concepts
11
+ private import semmle.python.dataflow.new.DataFlow
12
+ private import semmle.python.dataflow.new.DataFlow2
13
+ private import semmle.python.dataflow.new.TaintTracking
14
+ private import semmle.python.dataflow.new.TaintTracking2
33
15
import ChainedConfigs12
34
- import semmle.python.dataflow.new.BarrierGuards
16
+ import PathInjectionCustomizations :: PathInjection
35
17
36
18
// ---------------------------------------------------------------------------
37
19
// Case 1. The path is never normalized.
@@ -40,16 +22,14 @@ import semmle.python.dataflow.new.BarrierGuards
40
22
class PathNotNormalizedConfiguration extends TaintTracking:: Configuration {
41
23
PathNotNormalizedConfiguration ( ) { this = "PathNotNormalizedConfiguration" }
42
24
43
- override predicate isSource ( DataFlow:: Node source ) { source instanceof RemoteFlowSource }
25
+ override predicate isSource ( DataFlow:: Node source ) { source instanceof Source }
44
26
45
- override predicate isSink ( DataFlow:: Node sink ) {
46
- sink = any ( FileSystemAccess e ) .getAPathArgument ( )
47
- }
27
+ override predicate isSink ( DataFlow:: Node sink ) { sink instanceof Sink }
48
28
49
29
override predicate isSanitizer ( DataFlow:: Node node ) { node instanceof Path:: PathNormalization }
50
30
51
31
override predicate isSanitizerGuard ( DataFlow:: BarrierGuard guard ) {
52
- guard instanceof StringConstCompare
32
+ guard instanceof SanitizerGuard
53
33
}
54
34
}
55
35
@@ -68,14 +48,14 @@ predicate pathNotNormalized(CustomPathNode source, CustomPathNode sink) {
68
48
class FirstNormalizationConfiguration extends TaintTracking:: Configuration {
69
49
FirstNormalizationConfiguration ( ) { this = "FirstNormalizationConfiguration" }
70
50
71
- override predicate isSource ( DataFlow:: Node source ) { source instanceof RemoteFlowSource }
51
+ override predicate isSource ( DataFlow:: Node source ) { source instanceof Source }
72
52
73
53
override predicate isSink ( DataFlow:: Node sink ) { sink instanceof Path:: PathNormalization }
74
54
75
55
override predicate isSanitizerOut ( DataFlow:: Node node ) { node instanceof Path:: PathNormalization }
76
56
77
57
override predicate isSanitizerGuard ( DataFlow:: BarrierGuard guard ) {
78
- guard instanceof StringConstCompare
58
+ guard instanceof SanitizerGuard
79
59
}
80
60
}
81
61
@@ -85,14 +65,12 @@ class NormalizedPathNotCheckedConfiguration extends TaintTracking2::Configuratio
85
65
86
66
override predicate isSource ( DataFlow:: Node source ) { source instanceof Path:: PathNormalization }
87
67
88
- override predicate isSink ( DataFlow:: Node sink ) {
89
- sink = any ( FileSystemAccess e ) .getAPathArgument ( )
90
- }
68
+ override predicate isSink ( DataFlow:: Node sink ) { sink instanceof Sink }
91
69
92
70
override predicate isSanitizerGuard ( DataFlow:: BarrierGuard guard ) {
93
71
guard instanceof Path:: SafeAccessCheck
94
72
or
95
- guard instanceof StringConstCompare
73
+ guard instanceof SanitizerGuard
96
74
}
97
75
}
98
76
0 commit comments