diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
similarity index 98%
rename from java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
rename to java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
index 22a4dd1427b..f61c9b47991 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
@@ -8,8 +8,8 @@ directories that are shared between all users on the system.
On most unix-like systems,
the system temporary directory is shared between local users.
-If files/directories are created within the system temporary directory without using
-APIs that explicitly set the correct file permissions, local information disclosure
+If files/directories are created within the system temporary directory without using
+APIs that explicitly set the correct file permissions, local information disclosure
can occur.
Depending upon the particular file contents exposed, this vulnerability can have a
@@ -45,4 +45,4 @@ For example: PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePerm
OSWAP: Insecure Temporary File.
CERT: FIO00-J. Do not operate on files in shared directories
-
+
\ No newline at end of file
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
new file mode 100644
index 00000000000..7464d85a1a4
--- /dev/null
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
@@ -0,0 +1,162 @@
+/**
+ * @name Temporary Directory Local information disclosure
+ * @description Writing information without explicit permissions to a shared temporary directory may disclose it to other users.
+ * @kind path-problem
+ * @problem.severity warning
+ * @precision very-high
+ * @id java/local-temp-file-or-directory-information-disclosure
+ * @tags security
+ * external/cwe/cwe-200
+ * external/cwe/cwe-732
+ */
+
+import java
+import TempDirUtils
+import DataFlow::PathGraph
+
+private class MethodFileSystemFileCreation extends Method {
+ MethodFileSystemFileCreation() {
+ getDeclaringType() instanceof TypeFile and
+ hasName(["mkdir", "mkdirs", "createNewFile"])
+ }
+}
+
+abstract private class FileCreationSink extends DataFlow::Node { }
+
+/**
+ * Sink for tainted `File` having a file or directory creation method called on it.
+ */
+private class FileFileCreationSink extends FileCreationSink {
+ FileFileCreationSink() {
+ exists(MethodAccess ma |
+ ma.getMethod() instanceof MethodFileSystemFileCreation and
+ ma.getQualifier() = this.asExpr()
+ )
+ }
+}
+
+/**
+ * Sink for if tained File/Path having some `Files` method called on it that creates a file or directory.
+ */
+private class FilesFileCreationSink extends FileCreationSink {
+ FilesFileCreationSink() {
+ exists(FilesVulnerableCreationMethodAccess ma | ma.getArgument(0) = this.asExpr())
+ }
+}
+
+/**
+ * Captures all of the vulnerable methods on `Files` that create files/directories without explicitly
+ * setting the permissions.
+ */
+private class FilesVulnerableCreationMethodAccess extends MethodAccess {
+ FilesVulnerableCreationMethodAccess() {
+ exists(Method m |
+ m = this.getMethod() and
+ m.getDeclaringType().hasQualifiedName("java.nio.file", "Files")
+ |
+ m.hasName(["write", "newBufferedWriter", "newOutputStream"])
+ or
+ m.hasName(["createFile", "createDirectory", "createDirectories"]) and
+ getNumArgument() = 1
+ )
+ }
+}
+
+/**
+ * A call to `java.io.File::createTempFile` where the the system temp dir sinks to the last argument.
+ */
+private class FileCreateTempFileSink extends FileCreationSink {
+ FileCreateTempFileSink() {
+ exists(MethodAccess ma |
+ ma.getMethod() instanceof MethodFileCreateTempFile and ma.getArgument(2) = this.asExpr()
+ )
+ }
+}
+
+private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Configuration {
+ TempDirSystemGetPropertyToCreateConfig() { this = "TempDirSystemGetPropertyToCreateConfig" }
+
+ override predicate isSource(DataFlow::Node source) {
+ source.asExpr() instanceof MethodAccessSystemGetPropertyTempDirTainted
+ }
+
+ override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
+ isAdditionalFileTaintStep(node1, node2)
+ }
+
+ override predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink }
+}
+
+abstract class MethodAccessInsecureFileCreation extends MethodAccess {
+ /**
+ * Docstring describing the file system type (ie. file, directory, etc...) returned.
+ */
+ abstract string getFileSystemType();
+}
+
+/**
+ * Insecure calls to `java.io.File::createTempFile`.
+ */
+class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCreation {
+ MethodAccessInsecureFileCreateTempFile() {
+ this.getMethod() instanceof MethodFileCreateTempFile and
+ (
+ this.getNumArgument() = 2
+ or
+ // Vulnerablilty exists when the last argument is `null`
+ getArgument(2) instanceof NullLiteral
+ )
+ }
+
+ override string getFileSystemType() { result = "file" }
+}
+
+class MethodGuavaFilesCreateTempFile extends Method {
+ MethodGuavaFilesCreateTempFile() {
+ getDeclaringType().hasQualifiedName("com.google.common.io", "Files") and
+ hasName("createTempDir")
+ }
+}
+
+class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureFileCreation {
+ MethodAccessInsecureGuavaFilesCreateTempFile() {
+ getMethod() instanceof MethodGuavaFilesCreateTempFile
+ }
+
+ override string getFileSystemType() { result = "directory" }
+}
+
+/**
+ * This is a hack: we include use of inherently insecure methods, which don't have any associated
+ * flow path, in with results describing a path from reading java.io.tmpdir or similar to use
+ * in a file creation op.
+ *
+ * We achieve this by making inherently-insecure method invocations both a source and a sink in
+ * this configuration, resulting in a zero-length path which is type-compatible with the actual
+ * path-flow results.
+ */
+class InsecureMethodPseudoConfiguration extends DataFlow::Configuration {
+ InsecureMethodPseudoConfiguration() { this = "InsecureMethodPseudoConfiguration " }
+
+ override predicate isSource(DataFlow::Node node) {
+ node.asExpr() instanceof MethodAccessInsecureFileCreation
+ }
+
+ override predicate isSink(DataFlow::Node node) {
+ node.asExpr() instanceof MethodAccessInsecureFileCreation
+ }
+}
+
+from DataFlow::PathNode source, DataFlow::PathNode sink, string message
+where
+ any(TempDirSystemGetPropertyToCreateConfig conf).hasFlowPath(source, sink) and
+ message =
+ "Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users."
+ or
+ any(InsecureMethodPseudoConfiguration conf).hasFlowPath(source, sink) and
+ // Note this message has no "$@" placeholder, so the "system temp directory" template parameter below is not used.
+ message =
+ "Local information disclosure vulnerability due to use of " +
+ source.getNode().asExpr().(MethodAccessInsecureFileCreation).getFileSystemType() +
+ " readable by other local users."
+select source.getNode(), source, sink, message, source.getNode(), "system temp directory"
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.qhelp
deleted file mode 100644
index 56b902d84d4..00000000000
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.qhelp
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.qhelp
deleted file mode 100644
index 56b902d84d4..00000000000
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.qhelp
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromSystemProperty.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected
similarity index 86%
rename from java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromSystemProperty.expected
rename to java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected
index aa4bc32d8d9..505dcf666ca 100644
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromSystemProperty.expected
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected
@@ -36,9 +36,11 @@ edges
| Test.java:186:21:186:32 | tempDirChild : File | Test.java:186:21:186:41 | toPath(...) |
| Test.java:202:29:202:104 | new File(...) : File | Test.java:202:29:202:113 | toPath(...) : Path |
| Test.java:202:29:202:113 | toPath(...) : Path | Test.java:205:33:205:44 | tempDirChild |
+| Test.java:202:29:202:113 | toPath(...) : Path | Test.java:209:33:209:44 | tempDirChild |
| Test.java:202:38:202:73 | getProperty(...) : String | Test.java:202:29:202:104 | new File(...) : File |
| Test.java:214:29:214:102 | new File(...) : File | Test.java:214:29:214:111 | toPath(...) : Path |
| Test.java:214:29:214:111 | toPath(...) : Path | Test.java:217:31:217:42 | tempDirChild |
+| Test.java:214:29:214:111 | toPath(...) : Path | Test.java:221:31:221:42 | tempDirChild |
| Test.java:214:38:214:73 | getProperty(...) : String | Test.java:214:29:214:102 | new File(...) : File |
| Test.java:226:29:226:100 | new File(...) : File | Test.java:229:26:229:37 | tempDirChild : File |
| Test.java:226:38:226:73 | getProperty(...) : String | Test.java:226:29:226:100 | new File(...) : File |
@@ -58,6 +60,8 @@ nodes
| Files.java:14:28:14:64 | new File(...) : File | semmle.label | new File(...) : File |
| Files.java:14:37:14:43 | baseDir : File | semmle.label | baseDir : File |
| Files.java:15:17:15:23 | tempDir | semmle.label | tempDir |
+| Test.java:18:25:18:61 | createTempFile(...) | semmle.label | createTempFile(...) |
+| Test.java:26:25:26:67 | createTempFile(...) | semmle.label | createTempFile(...) |
| Test.java:34:24:34:69 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:34:33:34:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:37:63:37:69 | tempDir | semmle.label | tempDir |
@@ -71,6 +75,7 @@ nodes
| Test.java:73:24:73:69 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:73:33:73:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:76:63:76:69 | tempDir | semmle.label | tempDir |
+| Test.java:95:24:95:65 | createTempDir(...) | semmle.label | createTempDir(...) |
| Test.java:108:29:108:84 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:108:38:108:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:111:9:111:20 | tempDirChild | semmle.label | tempDirChild |
@@ -89,10 +94,12 @@ nodes
| Test.java:202:29:202:113 | toPath(...) : Path | semmle.label | toPath(...) : Path |
| Test.java:202:38:202:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:205:33:205:44 | tempDirChild | semmle.label | tempDirChild |
+| Test.java:209:33:209:44 | tempDirChild | semmle.label | tempDirChild |
| Test.java:214:29:214:102 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:214:29:214:111 | toPath(...) : Path | semmle.label | toPath(...) : Path |
| Test.java:214:38:214:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:217:31:217:42 | tempDirChild | semmle.label | tempDirChild |
+| Test.java:221:31:221:42 | tempDirChild | semmle.label | tempDirChild |
| Test.java:226:29:226:100 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:226:38:226:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:229:26:229:37 | tempDirChild : File | semmle.label | tempDirChild : File |
@@ -108,16 +115,21 @@ nodes
subpaths
#select
| Files.java:10:33:10:68 | getProperty(...) | Files.java:10:33:10:68 | getProperty(...) : String | Files.java:15:17:15:23 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Files.java:10:33:10:68 | getProperty(...) | system temp directory |
+| Test.java:18:25:18:61 | createTempFile(...) | Test.java:18:25:18:61 | createTempFile(...) | Test.java:18:25:18:61 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. | Test.java:18:25:18:61 | createTempFile(...) | system temp directory |
+| Test.java:26:25:26:67 | createTempFile(...) | Test.java:26:25:26:67 | createTempFile(...) | Test.java:26:25:26:67 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. | Test.java:26:25:26:67 | createTempFile(...) | system temp directory |
| Test.java:34:33:34:68 | getProperty(...) | Test.java:34:33:34:68 | getProperty(...) : String | Test.java:37:63:37:69 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:34:33:34:68 | getProperty(...) | system temp directory |
| Test.java:48:47:48:82 | getProperty(...) | Test.java:48:47:48:82 | getProperty(...) : String | Test.java:51:63:51:74 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:48:47:48:82 | getProperty(...) | system temp directory |
| Test.java:59:33:59:68 | getProperty(...) | Test.java:59:33:59:68 | getProperty(...) : String | Test.java:62:63:62:69 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:59:33:59:68 | getProperty(...) | system temp directory |
| Test.java:73:33:73:68 | getProperty(...) | Test.java:73:33:73:68 | getProperty(...) : String | Test.java:76:63:76:69 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:73:33:73:68 | getProperty(...) | system temp directory |
+| Test.java:95:24:95:65 | createTempDir(...) | Test.java:95:24:95:65 | createTempDir(...) | Test.java:95:24:95:65 | createTempDir(...) | Local information disclosure vulnerability due to use of directory readable by other local users. | Test.java:95:24:95:65 | createTempDir(...) | system temp directory |
| Test.java:108:38:108:73 | getProperty(...) | Test.java:108:38:108:73 | getProperty(...) : String | Test.java:111:9:111:20 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:108:38:108:73 | getProperty(...) | system temp directory |
| Test.java:132:38:132:73 | getProperty(...) | Test.java:132:38:132:73 | getProperty(...) : String | Test.java:135:9:135:20 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:132:38:132:73 | getProperty(...) | system temp directory |
| Test.java:156:38:156:73 | getProperty(...) | Test.java:156:38:156:73 | getProperty(...) : String | Test.java:157:21:157:41 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:156:38:156:73 | getProperty(...) | system temp directory |
| Test.java:185:38:185:73 | getProperty(...) | Test.java:185:38:185:73 | getProperty(...) : String | Test.java:186:21:186:41 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:185:38:185:73 | getProperty(...) | system temp directory |
| Test.java:202:38:202:73 | getProperty(...) | Test.java:202:38:202:73 | getProperty(...) : String | Test.java:205:33:205:44 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:202:38:202:73 | getProperty(...) | system temp directory |
+| Test.java:202:38:202:73 | getProperty(...) | Test.java:202:38:202:73 | getProperty(...) : String | Test.java:209:33:209:44 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:202:38:202:73 | getProperty(...) | system temp directory |
| Test.java:214:38:214:73 | getProperty(...) | Test.java:214:38:214:73 | getProperty(...) : String | Test.java:217:31:217:42 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:214:38:214:73 | getProperty(...) | system temp directory |
+| Test.java:214:38:214:73 | getProperty(...) | Test.java:214:38:214:73 | getProperty(...) : String | Test.java:221:31:221:42 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:214:38:214:73 | getProperty(...) | system temp directory |
| Test.java:226:38:226:73 | getProperty(...) | Test.java:226:38:226:73 | getProperty(...) : String | Test.java:229:26:229:46 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:226:38:226:73 | getProperty(...) | system temp directory |
| Test.java:247:38:247:73 | getProperty(...) | Test.java:247:38:247:73 | getProperty(...) : String | Test.java:250:31:250:51 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:247:38:247:73 | getProperty(...) | system temp directory |
| Test.java:258:38:258:73 | getProperty(...) | Test.java:258:38:258:73 | getProperty(...) : String | Test.java:261:33:261:53 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:258:38:258:73 | getProperty(...) | system temp directory |
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.qlref b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.qlref
new file mode 100644
index 00000000000..e678a2426e7
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.qlref
@@ -0,0 +1 @@
+Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.qlref b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.qlref
deleted file mode 100644
index 9c785f79c55..00000000000
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromSystemProperty.qlref b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromSystemProperty.qlref
deleted file mode 100644
index 9c3119da5d2..00000000000
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromSystemProperty.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql