14
14
import java
15
15
import semmle.code.java.os.OSCheck
16
16
import TempDirUtils
17
- import DataFlow:: PathGraph
18
- import semmle.code.java.dataflow.TaintTracking2
17
+ import semmle.code.java.dataflow.TaintTracking
19
18
20
19
abstract private class MethodFileSystemFileCreation extends Method {
21
20
MethodFileSystemFileCreation ( ) { this .getDeclaringType ( ) instanceof TypeFile }
@@ -127,19 +126,17 @@ private class IsSpecificWindowsSanitizer extends WindowsOsSanitizer {
127
126
* A taint tracking configuration tracking the access of the system temporary directory
128
127
* flowing to the creation of files or directories.
129
128
*/
130
- private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking:: Configuration {
131
- TempDirSystemGetPropertyToCreateConfig ( ) { this = "TempDirSystemGetPropertyToCreateConfig" }
132
-
133
- override predicate isSource ( DataFlow:: Node source ) {
129
+ module TempDirSystemGetPropertyToCreateConfig implements DataFlow:: ConfigSig {
130
+ predicate isSource ( DataFlow:: Node source ) {
134
131
source .asExpr ( ) instanceof ExprSystemGetPropertyTempDirTainted
135
132
}
136
133
137
- override predicate isSink ( DataFlow:: Node sink ) {
134
+ predicate isSink ( DataFlow:: Node sink ) {
138
135
sink instanceof FileCreationSink and
139
- not any ( TempDirSystemGetPropertyDirectlyToMkdirConfig config ) . hasFlowTo ( sink )
136
+ not TempDirSystemGetPropertyDirectlyToMkdir :: hasFlowTo ( sink )
140
137
}
141
138
142
- override predicate isSanitizer ( DataFlow:: Node sanitizer ) {
139
+ predicate isBarrier ( DataFlow:: Node sanitizer ) {
143
140
exists ( FilesSanitizingCreationMethodAccess sanitisingMethodAccess |
144
141
sanitizer .asExpr ( ) = sanitisingMethodAccess .getArgument ( 0 )
145
142
)
@@ -148,6 +145,9 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
148
145
}
149
146
}
150
147
148
+ module TempDirSystemGetPropertyToCreate =
149
+ TaintTracking:: Make< TempDirSystemGetPropertyToCreateConfig > ;
150
+
151
151
/**
152
152
* Configuration that tracks calls to to `mkdir` or `mkdirs` that are are directly on the temp directory system property.
153
153
* Examples:
@@ -158,30 +158,29 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
158
158
* As such, this code pattern is filtered out as an explicit vulnerability in
159
159
* `TempDirSystemGetPropertyToCreateConfig::isSink`.
160
160
*/
161
- private class TempDirSystemGetPropertyDirectlyToMkdirConfig extends TaintTracking2:: Configuration {
162
- TempDirSystemGetPropertyDirectlyToMkdirConfig ( ) {
163
- this = "TempDirSystemGetPropertyDirectlyToMkdirConfig"
164
- }
165
-
166
- override predicate isSource ( DataFlow:: Node node ) {
161
+ module TempDirSystemGetPropertyDirectlyToMkdirConfig implements DataFlow:: ConfigSig {
162
+ predicate isSource ( DataFlow:: Node node ) {
167
163
exists ( ExprSystemGetPropertyTempDirTainted propertyGetExpr , DataFlow:: Node callSite |
168
164
DataFlow:: localFlow ( DataFlow:: exprNode ( propertyGetExpr ) , callSite )
169
165
|
170
166
isFileConstructorArgument ( callSite .asExpr ( ) , node .asExpr ( ) , 1 )
171
167
)
172
168
}
173
169
174
- override predicate isSink ( DataFlow:: Node node ) {
170
+ predicate isSink ( DataFlow:: Node node ) {
175
171
exists ( MethodAccess ma | ma .getMethod ( ) instanceof MethodFileDirectoryCreation |
176
172
ma .getQualifier ( ) = node .asExpr ( )
177
173
)
178
174
}
179
175
180
- override predicate isSanitizer ( DataFlow:: Node sanitizer ) {
176
+ predicate isBarrier ( DataFlow:: Node sanitizer ) {
181
177
isFileConstructorArgument ( sanitizer .asExpr ( ) , _, _)
182
178
}
183
179
}
184
180
181
+ module TempDirSystemGetPropertyDirectlyToMkdir =
182
+ TaintTracking:: Make< TempDirSystemGetPropertyDirectlyToMkdirConfig > ;
183
+
185
184
//
186
185
// Begin configuration for tracking single-method calls that are vulnerable.
187
186
//
@@ -193,6 +192,8 @@ abstract class MethodAccessInsecureFileCreation extends MethodAccess {
193
192
* Gets the type of entity created (e.g. `file`, `directory`, ...).
194
193
*/
195
194
abstract string getFileSystemEntityType ( ) ;
195
+
196
+ DataFlow:: Node getNode ( ) { result .asExpr ( ) = this }
196
197
}
197
198
198
199
/**
@@ -235,39 +236,47 @@ class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureF
235
236
}
236
237
237
238
/**
238
- * A hack: we include use of inherently insecure methods, which don't have any associated
239
+ * We include use of inherently insecure methods, which don't have any associated
239
240
* flow path, in with results describing a path from reading `java.io.tmpdir` or similar to use
240
241
* in a file creation op.
241
242
*
242
- * We achieve this by making inherently-insecure method invocations both a source and a sink in
243
- * this configuration, resulting in a zero-length path which is type-compatible with the actual
244
- * path-flow results.
243
+ * We achieve this by making inherently-insecure method invocations into an edge-less graph,
244
+ * resulting in a zero-length paths.
245
245
*/
246
- class InsecureMethodPseudoConfiguration extends DataFlow:: Configuration {
247
- InsecureMethodPseudoConfiguration ( ) { this = "InsecureMethodPseudoConfiguration" }
246
+ module InsecureMethodPathGraph implements DataFlow:: PathGraphSig< MethodAccessInsecureFileCreation > {
247
+ predicate edges ( MethodAccessInsecureFileCreation n1 , MethodAccessInsecureFileCreation n2 ) {
248
+ none ( )
249
+ }
248
250
249
- override predicate isSource ( DataFlow :: Node node ) {
250
- node . asExpr ( ) instanceof MethodAccessInsecureFileCreation
251
+ predicate nodes ( MethodAccessInsecureFileCreation n , string key , string val ) {
252
+ key = "semmle.label" and val = n . toString ( )
251
253
}
252
254
253
- override predicate isSink ( DataFlow:: Node node ) {
254
- node .asExpr ( ) instanceof MethodAccessInsecureFileCreation
255
+ predicate subpaths (
256
+ MethodAccessInsecureFileCreation n1 , MethodAccessInsecureFileCreation n2 ,
257
+ MethodAccessInsecureFileCreation n3 , MethodAccessInsecureFileCreation n4
258
+ ) {
259
+ none ( )
255
260
}
256
261
}
257
262
258
- from DataFlow:: PathNode source , DataFlow:: PathNode sink , string message
263
+ module Flow =
264
+ DataFlow:: MergePathGraph< TempDirSystemGetPropertyToCreate:: PathNode , MethodAccessInsecureFileCreation , TempDirSystemGetPropertyToCreate:: PathGraph , InsecureMethodPathGraph > ;
265
+
266
+ import Flow:: PathGraph
267
+
268
+ from Flow:: PathNode source , Flow:: PathNode sink , string message
259
269
where
260
270
(
261
- any ( TempDirSystemGetPropertyToCreateConfig conf ) . hasFlowPath ( source , sink ) and
271
+ TempDirSystemGetPropertyToCreate :: hasFlowPath ( source . asPathNode1 ( ) , sink . asPathNode1 ( ) ) and
262
272
message =
263
273
"Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users."
264
274
or
265
- any ( InsecureMethodPseudoConfiguration conf ) . hasFlowPath ( source , sink ) and
275
+ source = sink and
266
276
// Note this message has no "$@" placeholder, so the "system temp directory" template parameter below is not used.
267
277
message =
268
278
"Local information disclosure vulnerability due to use of " +
269
- source .getNode ( ) .asExpr ( ) .( MethodAccessInsecureFileCreation ) .getFileSystemEntityType ( ) +
270
- " readable by other local users."
279
+ source .asPathNode2 ( ) .getFileSystemEntityType ( ) + " readable by other local users."
271
280
) and
272
281
not isPermissionsProtectedTempDirUse ( sink .getNode ( ) )
273
282
select source .getNode ( ) , source , sink , message , source .getNode ( ) , "system temp directory"
0 commit comments