@@ -69,13 +69,25 @@ private class ExactPathMatchSanitizer extends PathInjectionSanitizer {
69
69
}
70
70
}
71
71
72
- private class AllowedPrefixGuard extends Guard instanceof MethodAccess {
72
+ abstract private class PathGuard extends Guard {
73
+ abstract Expr getCheckedExpr ( ) ;
74
+ }
75
+
76
+ private predicate anyNode ( DataFlow:: Node n ) { any ( ) }
77
+
78
+ private predicate pathGuardNode ( DataFlow:: Node n ) { n .asExpr ( ) = any ( PathGuard g ) .getCheckedExpr ( ) }
79
+
80
+ private predicate localTaintFlowToPathGuard ( Expr e , PathGuard g ) {
81
+ TaintTracking:: LocalTaintFlow< anyNode / 1 , pathGuardNode / 1 > :: hasExprFlow ( e , g .getCheckedExpr ( ) )
82
+ }
83
+
84
+ private class AllowedPrefixGuard extends PathGuard instanceof MethodAccess {
73
85
AllowedPrefixGuard ( ) {
74
86
( isStringPrefixMatch ( this ) or isPathPrefixMatch ( this ) ) and
75
87
not isDisallowedWord ( super .getAnArgument ( ) )
76
88
}
77
89
78
- Expr getCheckedExpr ( ) { result = super .getQualifier ( ) }
90
+ override Expr getCheckedExpr ( ) { result = super .getQualifier ( ) }
79
91
}
80
92
81
93
/**
@@ -91,10 +103,10 @@ private predicate allowedPrefixGuard(Guard g, Expr e, boolean branch) {
91
103
// String strPath = file.getCanonicalPath();
92
104
// if (strPath.startsWith("/safe/dir"))
93
105
// sink(file);
94
- TaintTracking:: localExprTaint ( e , g .( AllowedPrefixGuard ) .getCheckedExpr ( ) ) and
106
+ g instanceof AllowedPrefixGuard and
107
+ localTaintFlowToPathGuard ( e , g ) and
95
108
exists ( Expr previousGuard |
96
- TaintTracking:: localExprTaint ( previousGuard .( PathNormalizeSanitizer ) ,
97
- g .( AllowedPrefixGuard ) .getCheckedExpr ( ) )
109
+ localTaintFlowToPathGuard ( previousGuard .( PathNormalizeSanitizer ) , g )
98
110
or
99
111
previousGuard
100
112
.( PathTraversalGuard )
@@ -121,7 +133,7 @@ private predicate dotDotCheckGuard(Guard g, Expr e, boolean branch) {
121
133
// if (!strPath.contains("..") && strPath.startsWith("/safe/dir"))
122
134
// sink(path);
123
135
branch = g .( PathTraversalGuard ) .getBranch ( ) and
124
- TaintTracking :: localExprTaint ( e , g . ( PathTraversalGuard ) . getCheckedExpr ( ) ) and
136
+ localTaintFlowToPathGuard ( e , g ) and
125
137
exists ( Guard previousGuard |
126
138
previousGuard .( AllowedPrefixGuard ) .controls ( g .getBasicBlock ( ) , true )
127
139
or
@@ -136,13 +148,13 @@ private class DotDotCheckSanitizer extends PathInjectionSanitizer {
136
148
}
137
149
}
138
150
139
- private class BlockListGuard extends Guard instanceof MethodAccess {
151
+ private class BlockListGuard extends PathGuard instanceof MethodAccess {
140
152
BlockListGuard ( ) {
141
153
( isStringPartialMatch ( this ) or isPathPrefixMatch ( this ) ) and
142
154
isDisallowedWord ( super .getAnArgument ( ) )
143
155
}
144
156
145
- Expr getCheckedExpr ( ) { result = super .getQualifier ( ) }
157
+ override Expr getCheckedExpr ( ) { result = super .getQualifier ( ) }
146
158
}
147
159
148
160
/**
@@ -158,10 +170,10 @@ private predicate blockListGuard(Guard g, Expr e, boolean branch) {
158
170
// String strPath = file.getCanonicalPath();
159
171
// if (!strPath.contains("..") && !strPath.startsWith("/dangerous/dir"))
160
172
// sink(file);
161
- TaintTracking:: localExprTaint ( e , g .( BlockListGuard ) .getCheckedExpr ( ) ) and
173
+ g instanceof BlockListGuard and
174
+ localTaintFlowToPathGuard ( e , g ) and
162
175
exists ( Expr previousGuard |
163
- TaintTracking:: localExprTaint ( previousGuard .( PathNormalizeSanitizer ) ,
164
- g .( BlockListGuard ) .getCheckedExpr ( ) )
176
+ localTaintFlowToPathGuard ( previousGuard .( PathNormalizeSanitizer ) , g )
165
177
or
166
178
previousGuard
167
179
.( PathTraversalGuard )
@@ -217,7 +229,7 @@ private predicate isDisallowedWord(CompileTimeConstantExpr word) {
217
229
}
218
230
219
231
/** A complementary guard that protects against path traversal, by looking for the literal `..`. */
220
- private class PathTraversalGuard extends Guard {
232
+ private class PathTraversalGuard extends PathGuard {
221
233
PathTraversalGuard ( ) {
222
234
exists ( MethodAccess ma |
223
235
ma .getMethod ( ) .getDeclaringType ( ) instanceof TypeString and
@@ -235,7 +247,7 @@ private class PathTraversalGuard extends Guard {
235
247
)
236
248
}
237
249
238
- Expr getCheckedExpr ( ) {
250
+ override Expr getCheckedExpr ( ) {
239
251
exists ( MethodAccess ma | ma = this .( EqualityTest ) .getAnOperand ( ) or ma = this |
240
252
result = ma .getQualifier ( )
241
253
)
0 commit comments