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