1414import java
1515import semmle.code.java.os.OSCheck
1616import TempDirUtils
17- import DataFlow:: PathGraph
18- import semmle.code.java.dataflow.TaintTracking2
17+ import semmle.code.java.dataflow.TaintTracking
1918
2019abstract private class MethodFileSystemFileCreation extends Method {
2120 MethodFileSystemFileCreation ( ) { this .getDeclaringType ( ) instanceof TypeFile }
@@ -127,19 +126,17 @@ private class IsSpecificWindowsSanitizer extends WindowsOsSanitizer {
127126 * A taint tracking configuration tracking the access of the system temporary directory
128127 * flowing to the creation of files or directories.
129128 */
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 ) {
134131 source .asExpr ( ) instanceof ExprSystemGetPropertyTempDirTainted
135132 }
136133
137- override predicate isSink ( DataFlow:: Node sink ) {
134+ predicate isSink ( DataFlow:: Node sink ) {
138135 sink instanceof FileCreationSink and
139- not any ( TempDirSystemGetPropertyDirectlyToMkdirConfig config ) . hasFlowTo ( sink )
136+ not TempDirSystemGetPropertyDirectlyToMkdir :: hasFlowTo ( sink )
140137 }
141138
142- override predicate isSanitizer ( DataFlow:: Node sanitizer ) {
139+ predicate isBarrier ( DataFlow:: Node sanitizer ) {
143140 exists ( FilesSanitizingCreationMethodAccess sanitisingMethodAccess |
144141 sanitizer .asExpr ( ) = sanitisingMethodAccess .getArgument ( 0 )
145142 )
@@ -148,6 +145,9 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
148145 }
149146}
150147
148+ module TempDirSystemGetPropertyToCreate =
149+ TaintTracking:: Make< TempDirSystemGetPropertyToCreateConfig > ;
150+
151151/**
152152 * Configuration that tracks calls to to `mkdir` or `mkdirs` that are are directly on the temp directory system property.
153153 * Examples:
@@ -158,30 +158,29 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
158158 * As such, this code pattern is filtered out as an explicit vulnerability in
159159 * `TempDirSystemGetPropertyToCreateConfig::isSink`.
160160 */
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 ) {
167163 exists ( ExprSystemGetPropertyTempDirTainted propertyGetExpr , DataFlow:: Node callSite |
168164 DataFlow:: localFlow ( DataFlow:: exprNode ( propertyGetExpr ) , callSite )
169165 |
170166 isFileConstructorArgument ( callSite .asExpr ( ) , node .asExpr ( ) , 1 )
171167 )
172168 }
173169
174- override predicate isSink ( DataFlow:: Node node ) {
170+ predicate isSink ( DataFlow:: Node node ) {
175171 exists ( MethodAccess ma | ma .getMethod ( ) instanceof MethodFileDirectoryCreation |
176172 ma .getQualifier ( ) = node .asExpr ( )
177173 )
178174 }
179175
180- override predicate isSanitizer ( DataFlow:: Node sanitizer ) {
176+ predicate isBarrier ( DataFlow:: Node sanitizer ) {
181177 isFileConstructorArgument ( sanitizer .asExpr ( ) , _, _)
182178 }
183179}
184180
181+ module TempDirSystemGetPropertyDirectlyToMkdir =
182+ TaintTracking:: Make< TempDirSystemGetPropertyDirectlyToMkdirConfig > ;
183+
185184//
186185// Begin configuration for tracking single-method calls that are vulnerable.
187186//
@@ -193,6 +192,8 @@ abstract class MethodAccessInsecureFileCreation extends MethodAccess {
193192 * Gets the type of entity created (e.g. `file`, `directory`, ...).
194193 */
195194 abstract string getFileSystemEntityType ( ) ;
195+
196+ DataFlow:: Node getNode ( ) { result .asExpr ( ) = this }
196197}
197198
198199/**
@@ -235,39 +236,47 @@ class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureF
235236}
236237
237238/**
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
239240 * flow path, in with results describing a path from reading `java.io.tmpdir` or similar to use
240241 * in a file creation op.
241242 *
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.
245245 */
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+ }
248250
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 ( )
251253 }
252254
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 ( )
255260 }
256261}
257262
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
259269where
260270 (
261- any ( TempDirSystemGetPropertyToCreateConfig conf ) . hasFlowPath ( source , sink ) and
271+ TempDirSystemGetPropertyToCreate :: hasFlowPath ( source . asPathNode1 ( ) , sink . asPathNode1 ( ) ) and
262272 message =
263273 "Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users."
264274 or
265- any ( InsecureMethodPseudoConfiguration conf ) . hasFlowPath ( source , sink ) and
275+ source = sink and
266276 // Note this message has no "$@" placeholder, so the "system temp directory" template parameter below is not used.
267277 message =
268278 "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."
271280 ) and
272281 not isPermissionsProtectedTempDirUse ( sink .getNode ( ) )
273282select source .getNode ( ) , source , sink , message , source .getNode ( ) , "system temp directory"
0 commit comments