From 3a15678b1ef23b012ac807116256a884c74295d1 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh Local information disclosure can occur when files/directories are written into
+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
+can occur. Depending upon the particular file contents exposed, this vulnerability can have a
+CVSSv3.1 base score of 6.2/10. Use JDK methods that specifically protect against this vulnerability: In the following example, files and directories are created with file permissions allowing other local users to read their contents. In the following example, files and directories are created with file permissions protecting their contents.
+
+Otherwise, create the file/directory by manually specificfying the expected posix file permissions.
+Eg.
PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
+
+
PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
+Otherwise, create the file/directory by manually specificfying the expected posix file permissions.
+Eg. PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OW
In the following example, files and directories are created with file permissions protecting their contents.
+
- OSWAP: Insecure Temporary File.
- - CERT: FIO00-J. Do not operate on files in shared directories
+
- CERT: FIO00-J. Do not operate on files in shared directories
From f910fd4719dcc7ba6ccd38f849861a2cb86b53c8 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Tue, 16 Feb 2021 16:39:53 -0500
Subject: [PATCH 07/39] Remove path flow tracking in
'TempDirLocalInformationDisclosureFromMethodCall'
---
...ocalInformationDisclosureFromMethodCall.ql | 45 ++++++-------------
...InformationDisclosureFromSystemProperty.ql | 14 +++++-
.../src/Security/CWE/CWE-200/TempDirUtils.qll | 12 ++++-
...formationDisclosureFromMethodCall.expected | 10 ++---
...ationDisclosureFromSystemProperty.expected | 16 +++++++
5 files changed, 57 insertions(+), 40 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
index 3e8280d55b45..da6e3698bf07 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
@@ -12,32 +12,13 @@
import TempDirUtils
-/**
- * All `java.io.File::createTempFile` methods.
- */
-class MethodFileCreateTempFile extends Method {
- MethodFileCreateTempFile() {
- this.getDeclaringType() instanceof TypeFile and
- this.hasName("createTempFile")
- }
+abstract class MethodAccessInsecureFileCreation extends MethodAccess {
+ /**
+ * Docstring describing the file system type (ie. file, directory, ect...) returned.
+ */
+ abstract string getFileSystemType();
}
-class TempDirSystemGetPropertyToAnyConfig extends TaintTracking::Configuration {
- TempDirSystemGetPropertyToAnyConfig() { this = "TempDirSystemGetPropertyToAnyConfig" }
-
- override predicate isSource(DataFlow::Node source) {
- source.asExpr() instanceof MethodAccessSystemGetPropertyTempDirTainted
- }
-
- override predicate isSink(DataFlow::Node source) { any() }
-
- override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalFileTaintStep(node1, node2)
- }
-}
-
-abstract class MethodAccessInsecureFileCreation extends MethodAccess { }
-
/**
* Insecure calls to `java.io.File::createTempFile`.
*/
@@ -45,15 +26,14 @@ class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCre
MethodAccessInsecureFileCreateTempFile() {
this.getMethod() instanceof MethodFileCreateTempFile and
(
- this.getNumArgument() = 2 or
+ this.getNumArgument() = 2
+ or
// Vulnerablilty exists when the last argument is `null`
- getArgument(2) instanceof NullLiteral or
- // There exists a flow from the 'java.io.tmpdir' system property to this argument
- exists(TempDirSystemGetPropertyToAnyConfig config |
- config.hasFlowTo(DataFlow::exprNode(getArgument(2)))
- )
+ getArgument(2) instanceof NullLiteral
)
}
+
+ override string getFileSystemType() { result = "file" }
}
class MethodGuavaFilesCreateTempFile extends Method {
@@ -67,8 +47,11 @@ class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureF
MethodAccessInsecureGuavaFilesCreateTempFile() {
getMethod() instanceof MethodGuavaFilesCreateTempFile
}
+
+ override string getFileSystemType() { result = "directory" }
}
from MethodAccessInsecureFileCreation methodAccess
select methodAccess,
- "Local information disclosure vulnerability due to use of file or directory readable by other local users."
+ "Local information disclosure vulnerability due to use of " + methodAccess.getFileSystemType() +
+ " readable by other local users."
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
index 91191d5cb1fc..91f2bb3ebada 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
@@ -56,7 +56,19 @@ private class FilesVulnerableCreationMethodAccess extends MethodAccess {
(
getMethod().hasName(["write", "newBufferedWriter", "newOutputStream"])
or
- getMethod().hasName(["createFile", "createDirectory", "createDirectories"]) and getNumArgument() = 1
+ getMethod().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()
)
}
}
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index cf531a3e17ee..cf829de860f5 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -29,6 +29,16 @@ private class MethodAccessApacheFileUtilsTempDir extends MethodAccessSystemGetPr
}
}
+/**
+ * All `java.io.File::createTempFile` methods.
+ */
+class MethodFileCreateTempFile extends Method {
+ MethodFileCreateTempFile() {
+ this.getDeclaringType() instanceof TypeFile and
+ this.hasName("createTempFile")
+ }
+}
+
/**
* Find dataflow from the temp directory system property to the `File` constructor.
* Examples:
@@ -44,7 +54,7 @@ private predicate isTaintedFileCreation(Expr expSource, Expr exprDest) {
}
/**
- * Any `File` methods that
+ * Any `File` methods where the temporary directory is still part of the root path.
*/
private class TaintFollowingFileMethod extends Method {
TaintFollowingFileMethod() {
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected
index 50f825d9683a..d58eb1544168 100644
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected
@@ -1,7 +1,3 @@
-| Test.java:15:21:15:57 | createTempFile(...) | Local information disclosure vulnerability due to use of file or directory readable by other local users. |
-| Test.java:19:21:19:63 | createTempFile(...) | Local information disclosure vulnerability due to use of file or directory readable by other local users. |
-| Test.java:24:21:24:66 | createTempFile(...) | Local information disclosure vulnerability due to use of file or directory readable by other local users. |
-| Test.java:29:21:29:71 | createTempFile(...) | Local information disclosure vulnerability due to use of file or directory readable by other local users. |
-| Test.java:34:21:34:66 | createTempFile(...) | Local information disclosure vulnerability due to use of file or directory readable by other local users. |
-| Test.java:39:21:39:66 | createTempFile(...) | Local information disclosure vulnerability due to use of file or directory readable by other local users. |
-| Test.java:49:24:49:65 | createTempDir(...) | Local information disclosure vulnerability due to use of file or directory readable by other local users. |
+| Test.java:15:21:15:57 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. |
+| Test.java:19:21:19:63 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. |
+| Test.java:49:24:49:65 | createTempDir(...) | Local information disclosure vulnerability due to use of directory readable by other local users. |
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/TempDirLocalInformationDisclosureFromSystemProperty.expected
index 770a4826c950..d71d23446dc9 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/TempDirLocalInformationDisclosureFromSystemProperty.expected
@@ -1,5 +1,9 @@
edges
| Files.java:10:33:10:68 | getProperty(...) : String | Files.java:15:17:15:23 | tempDir |
+| Test.java:23:33:23:68 | getProperty(...) : String | Test.java:24:59:24:65 | tempDir |
+| Test.java:28:47:28:82 | getProperty(...) : String | Test.java:29:59:29:70 | tempDirChild |
+| Test.java:33:33:33:68 | getProperty(...) : String | Test.java:34:59:34:65 | tempDir |
+| Test.java:38:33:38:68 | getProperty(...) : String | Test.java:39:59:39:65 | tempDir |
| Test.java:53:38:53:73 | getProperty(...) : String | Test.java:54:9:54:20 | tempDirChild |
| Test.java:58:38:58:73 | getProperty(...) : String | Test.java:59:9:59:20 | tempDirChild |
| Test.java:63:38:63:73 | getProperty(...) : String | Test.java:64:21:64:41 | toPath(...) |
@@ -12,6 +16,14 @@ edges
nodes
| Files.java:10:33:10:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Files.java:15:17:15:23 | tempDir | semmle.label | tempDir |
+| Test.java:23:33:23:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:24:59:24:65 | tempDir | semmle.label | tempDir |
+| Test.java:28:47:28:82 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:29:59:29:70 | tempDirChild | semmle.label | tempDirChild |
+| Test.java:33:33:33:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:34:59:34:65 | tempDir | semmle.label | tempDir |
+| Test.java:38:33:38:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:39:59:39:65 | tempDir | semmle.label | tempDir |
| Test.java:53:38:53:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:54:9:54:20 | tempDirChild | semmle.label | tempDirChild |
| Test.java:58:38:58:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
@@ -32,6 +44,10 @@ nodes
| Test.java:105:33:105:53 | toPath(...) | semmle.label | toPath(...) |
#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:23:33:23:68 | getProperty(...) | Test.java:23:33:23:68 | getProperty(...) : String | Test.java:24:59:24:65 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:23:33:23:68 | getProperty(...) | system temp directory |
+| Test.java:28:47:28:82 | getProperty(...) | Test.java:28:47:28:82 | getProperty(...) : String | Test.java:29:59:29:70 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:28:47:28:82 | getProperty(...) | system temp directory |
+| Test.java:33:33:33:68 | getProperty(...) | Test.java:33:33:33:68 | getProperty(...) : String | Test.java:34:59:34:65 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:33:33:33:68 | getProperty(...) | system temp directory |
+| Test.java:38:33:38:68 | getProperty(...) | Test.java:38:33:38:68 | getProperty(...) : String | Test.java:39:59:39:65 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:38:33:38:68 | getProperty(...) | system temp directory |
| Test.java:53:38:53:73 | getProperty(...) | Test.java:53:38:53:73 | getProperty(...) : String | Test.java:54:9:54:20 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:53:38:53:73 | getProperty(...) | system temp directory |
| Test.java:58:38:58:73 | getProperty(...) | Test.java:58:38:58:73 | getProperty(...) : String | Test.java:59:9:59:20 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:58:38:58:73 | getProperty(...) | system temp directory |
| Test.java:63:38:63:73 | getProperty(...) | Test.java:63:38:63:73 | getProperty(...) : String | Test.java:64:21:64:41 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:63:38:63:73 | getProperty(...) | system temp directory |
From 7929faedc005572c4bf9eb7982876cb174aa34e2 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Tue, 16 Feb 2021 16:45:13 -0500
Subject: [PATCH 08/39] Apply suggestions from code review
Co-authored-by: Felicity Chapman
---
.../CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp | 8 ++++----
.../TempDirLocalInformationDisclosureFromMethodCall.ql | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
index dd94c58a9e08..b76b0b5c6cf2 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
@@ -19,11 +19,11 @@ can occur.
Use JDK methods that specifically protect against this vulnerability:
- - java.nio.file.Files#createTempDirectory
- - java.nio.file.Files#createTempFile
+ - java.nio.file.Files#createTempDirectory
+ - java.nio.file.Files#createTempFile
Otherwise, create the file/directory by manually specificfying the expected posix file permissions.
-Eg. PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
+For example: PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
- java.nio.file.Files#createFile
- java.nio.file.Files#createDirectory
@@ -32,7 +32,7 @@ Eg. PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OW
-In the following example, files and directories are created with file permissions allowing other local users to read their contents.
+In the following example, files and directories are created with file permissions that allow other local users to read their contents.
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
index da6e3698bf07..42c961a10962 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
@@ -1,6 +1,6 @@
/**
- * @name Temporary Directory Local information disclosure
- * @description Detect local information disclosure via the java temporary directory
+ * @name Temporary directory local information disclosure
+ * @description Writing information without explicit permissions to a shared temporary directory may disclose it to other users.
* @kind problem
* @problem.severity warning
* @precision very-high
From 41b5011b8198ea219732731cb4872924c2dfa8f2 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Tue, 16 Feb 2021 16:46:12 -0500
Subject: [PATCH 09/39] Apply suggestions from code review
Co-authored-by: Felicity Chapman
---
.../CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
index b76b0b5c6cf2..44c65efa637d 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
@@ -36,7 +36,7 @@ For example: PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePerm
-In the following example, files and directories are created with file permissions protecting their contents.
+In the following example, files and directories are created with file permissions that protect their contents.
From f6067d28f980e1d8db1b472fa0c502932cfd4495 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Wed, 24 Feb 2021 11:36:59 -0500
Subject: [PATCH 10/39] Fix file names and formatting from PR feedback
---
...losure.qhelp => TempDirLocalInformationDisclosure.inc.qhelp} | 0
.../TempDirLocalInformationDisclosureFromMethodCall.qhelp | 2 +-
.../TempDirLocalInformationDisclosureFromSystemProperty.qhelp | 2 +-
3 files changed, 2 insertions(+), 2 deletions(-)
rename java/ql/src/Security/CWE/CWE-200/{TempDirLocalInformationDisclosure.qhelp => TempDirLocalInformationDisclosure.inc.qhelp} (100%)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
similarity index 100%
rename from java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
rename to java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.qhelp
index 41e9af9a730f..56b902d84d4a 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.qhelp
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.qhelp
@@ -2,4 +2,4 @@
"-//Semmle//qhelp//EN"
"qhelp.dtd">
-
+
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.qhelp
index 41e9af9a730f..56b902d84d4a 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.qhelp
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.qhelp
@@ -2,4 +2,4 @@
"-//Semmle//qhelp//EN"
"qhelp.dtd">
-
+
From c19f52cd04fbca929c56fe3183a8c52662ff6c82 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Thu, 25 Feb 2021 12:31:45 -0500
Subject: [PATCH 11/39] Add release notes for "Temporary Directory Local
information disclosure"
---
.../2021-02-25-local-temp-directory-information-disclosure.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md
diff --git a/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md b/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md
new file mode 100644
index 000000000000..540f29d14812
--- /dev/null
+++ b/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md
@@ -0,0 +1,4 @@
+lgtm,codescanning
+* Two new queries, both titled "Temporary directory Local information disclosure"
+ (`java/local-temp-file-or-directory-information-disclosure-path`, `java/local-temp-file-or-directory-information-disclosure-method`), has been added.
+ This query finds uses of APIs that leak potentially sensitive information to other local users via the system temporary directory.
\ No newline at end of file
From 7e55c92eb4098003f85e6a7d96482acd4c52020d Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Mon, 22 Mar 2021 15:07:08 -0400
Subject: [PATCH 12/39] Apply suggestions from code review
Co-authored-by: Anders Schack-Mulligen
---
...LocalInformationDisclosureFromMethodCall.ql | 3 ++-
...lInformationDisclosureFromSystemProperty.ql | 18 +++++++++---------
.../src/Security/CWE/CWE-200/TempDirUtils.qll | 2 +-
3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
index 42c961a10962..2fd5571b7685 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
@@ -10,11 +10,12 @@
* external/cwe/cwe-732
*/
+import java
import TempDirUtils
abstract class MethodAccessInsecureFileCreation extends MethodAccess {
/**
- * Docstring describing the file system type (ie. file, directory, ect...) returned.
+ * Docstring describing the file system type (ie. file, directory, etc...) returned.
*/
abstract string getFileSystemType();
}
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
index 91f2bb3ebada..97c21437d14d 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
@@ -1,6 +1,6 @@
/**
* @name Temporary Directory Local information disclosure
- * @description Detect local information disclosure via the java temporary directory
+ * @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
@@ -10,16 +10,14 @@
* external/cwe/cwe-732
*/
+import java
import TempDirUtils
import DataFlow::PathGraph
private class MethodFileSystemFileCreation extends Method {
MethodFileSystemFileCreation() {
getDeclaringType() instanceof TypeFile and
- (
- hasName(["mkdir", "mkdirs"]) or
- hasName("createNewFile")
- )
+ hasName(["mkdir", "mkdirs", "createNewFile"])
}
}
@@ -52,11 +50,13 @@ private class FilesFileCreationSink extends FileCreationSink {
*/
private class FilesVulnerableCreationMethodAccess extends MethodAccess {
FilesVulnerableCreationMethodAccess() {
- getMethod().getDeclaringType().hasQualifiedName("java.nio.file", "Files") and
- (
- getMethod().hasName(["write", "newBufferedWriter", "newOutputStream"])
+ exists(Method m |
+ m = this.getMethod() and
+ m.getDeclaringType().hasQualifiedName("java.nio.file", "Files")
+ |
+ m.hasName(["write", "newBufferedWriter", "newOutputStream"])
or
- getMethod().hasName(["createFile", "createDirectory", "createDirectories"]) and
+ m.hasName(["createFile", "createDirectory", "createDirectories"]) and
getNumArgument() = 1
)
}
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index cf829de860f5..56d3bf00ebc4 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -30,7 +30,7 @@ private class MethodAccessApacheFileUtilsTempDir extends MethodAccessSystemGetPr
}
/**
- * All `java.io.File::createTempFile` methods.
+ * A `java.io.File::createTempFile` method.
*/
class MethodFileCreateTempFile extends Method {
MethodFileCreateTempFile() {
From 66831989b71b2471e39462b0af5f584ed5832309 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Mon, 22 Mar 2021 16:40:46 -0400
Subject: [PATCH 13/39] Add QLdoc to TempDirUtils
---
java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll | 3 +++
1 file changed, 3 insertions(+)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index 56d3bf00ebc4..8fc9cbacba7c 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -74,6 +74,9 @@ private predicate isTaintFollowingFileTransformation(Expr expSource, Expr exprDe
)
}
+/**
+ * Holds if the system temporary directory is still part of the root of the file path.
+ */
predicate isAdditionalFileTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
isTaintedFileCreation(node1.asExpr(), node2.asExpr()) or
isTaintFollowingFileTransformation(node1.asExpr(), node2.asExpr())
From df716cbaa02cc0d0f4b989f6ffe852bf47604445 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Mon, 22 Mar 2021 16:45:46 -0400
Subject: [PATCH 14/39] Revert changes to MethodAccessSystemGetProperty
---
java/ql/lib/semmle/code/java/JDK.qll | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/ql/lib/semmle/code/java/JDK.qll b/java/ql/lib/semmle/code/java/JDK.qll
index b070ebb532a0..e497740a489c 100644
--- a/java/ql/lib/semmle/code/java/JDK.qll
+++ b/java/ql/lib/semmle/code/java/JDK.qll
@@ -236,14 +236,14 @@ class MethodSystemGetProperty extends Method {
}
/**
- * Any method access to a method named `getProperty` on class `java.lang.System`.
+ * An access to a method named `getProperty` on class `java.lang.System`.
*/
class MethodAccessSystemGetProperty extends MethodAccess {
MethodAccessSystemGetProperty() { this.getMethod() instanceof MethodSystemGetProperty }
/**
- * Holds true if this is a compile-time constant call for the specified `propertyName`.
- * Eg. `System.getProperty("user.dir")`.
+ * Holds if this call has a compile-time constant first argument with the value `propertyName`.
+ * For example: `System.getProperty("user.dir")`.
*/
predicate hasCompileTimeConstantGetPropertyName(string propertyName) {
this.getArgument(0).(CompileTimeConstantExpr).getStringValue() = propertyName
From cb3038568447299c1858e8951e0a605dc5eb6b06 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Thu, 8 Apr 2021 10:13:47 -0400
Subject: [PATCH 15/39] Update
java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
Co-authored-by: Anders Schack-Mulligen
---
java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index 8fc9cbacba7c..570d8c6b5015 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -54,7 +54,7 @@ private predicate isTaintedFileCreation(Expr expSource, Expr exprDest) {
}
/**
- * Any `File` methods where the temporary directory is still part of the root path.
+ * A `File` method where the temporary directory is still part of the root path.
*/
private class TaintFollowingFileMethod extends Method {
TaintFollowingFileMethod() {
From 7e514e9ef9255a2296a3f45a59ca8ca3bf5a1260 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Thu, 8 Apr 2021 10:19:38 -0400
Subject: [PATCH 16/39] Add QLdoc and fix Compiler Errors in Tests
---
.../src/Security/CWE/CWE-200/TempDirUtils.qll | 3 +++
.../security/CWE-200/semmle/tests/Test.java | 18 +++++++++---------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index 570d8c6b5015..81c2d9ae5393 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -1,3 +1,6 @@
+/**
+ * Provides classes and predicates for reasoning about temporary file/directory creations.
+ */
import java
import semmle.code.java.dataflow.FlowSources
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
index c86476ad7636..b87d12199c21 100644
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
@@ -11,35 +11,35 @@
public class Test {
- void vulnerableFileCreateTempFile() {
+ void vulnerableFileCreateTempFile() throws IOException {
File temp = File.createTempFile("random", "file");
}
- void vulnerableFileCreateTempFileNull() {
+ void vulnerableFileCreateTempFileNull() throws IOException {
File temp = File.createTempFile("random", "file", null);
}
- void vulnerableFileCreateTempFileTainted() {
+ void vulnerableFileCreateTempFileTainted() throws IOException {
File tempDir = new File(System.getProperty("java.io.tmpdir"));
File temp = File.createTempFile("random", "file", tempDir);
}
- void vulnerableFileCreateTempFileChildTainted() {
+ void vulnerableFileCreateTempFileChildTainted() throws IOException {
File tempDirChild = new File(new File(System.getProperty("java.io.tmpdir")), "/child");
File temp = File.createTempFile("random", "file", tempDirChild);
}
- void vulnerableFileCreateTempFileCanonical() {
+ void vulnerableFileCreateTempFileCanonical() throws IOException {
File tempDir = new File(System.getProperty("java.io.tmpdir")).getCanonicalFile();
File temp = File.createTempFile("random", "file", tempDir);
}
- void vulnerableFileCreateTempFileAbsolute() {
+ void vulnerableFileCreateTempFileAbsolute() throws IOException {
File tempDir = new File(System.getProperty("java.io.tmpdir")).getAbsoluteFile();
File temp = File.createTempFile("random", "file", tempDir);
}
- void safeFileCreateTempFileTainted() {
+ void safeFileCreateTempFileTainted() throws IOException {
/* Creating a temporary directoy in the current user directory is not a vulnerability. */
File currentDirectory = new File(System.getProperty("user.dir"));
File temp = File.createTempFile("random", "file", currentDirectory);
@@ -59,12 +59,12 @@ void vulnerableFileCreateTempFileMkdirsTainted() {
tempDirChild.mkdirs();
}
- void vulnerableFileCreateTempFilesWrite1() {
+ void vulnerableFileCreateTempFilesWrite1() throws IOException {
File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child.txt");
Files.write(tempDirChild.toPath(), Arrays.asList("secret"), StandardCharsets.UTF_8, StandardOpenOption.CREATE);
}
- void vulnerableFileCreateTempFilesWrite2() {
+ void vulnerableFileCreateTempFilesWrite2() throws IOException {
File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child.txt");
String secret = "secret";
byte[] byteArrray = secret.getBytes();
From e795823d972c0f585b55a69f273dd6bfb761f8a7 Mon Sep 17 00:00:00 2001
From: Chris Smowton
Date: Fri, 16 Apr 2021 11:29:59 +0100
Subject: [PATCH 17/39] Autoformat TempDirUtils.qll
---
java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll | 1 +
1 file changed, 1 insertion(+)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index 81c2d9ae5393..30522c08b616 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -1,6 +1,7 @@
/**
* Provides classes and predicates for reasoning about temporary file/directory creations.
*/
+
import java
import semmle.code.java.dataflow.FlowSources
From a8d25b63ac8ba523b7901207298126db9234d07e Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Fri, 16 Apr 2021 15:16:42 -0400
Subject: [PATCH 18/39] Apply suggestions from code review
Co-authored-by: Chris Smowton
---
...DirLocalInformationDisclosureFromMethodCall.ql | 15 ++++++++-------
...ocalInformationDisclosureFromSystemProperty.ql | 10 +++++-----
java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll | 12 +++++-------
3 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
index 2fd5571b7685..ec47041da0b2 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
@@ -1,10 +1,10 @@
/**
- * @name Temporary directory local information disclosure
- * @description Writing information without explicit permissions to a shared temporary directory may disclose it to other users.
+ * @name Temporary directory local information disclosure (file creation via inherently insecure method)
+ * @description Creating a temporary file in the system shared temporary directory, using a method that always creates it world-readable, may disclose its contents to other users.
* @kind problem
* @problem.severity warning
* @precision very-high
- * @id java/local-temp-file-or-directory-information-disclosure-method
+ * @id java/local-temp-file-or-directory-information-disclosure-insecure-method
* @tags security
* external/cwe/cwe-200
* external/cwe/cwe-732
@@ -15,21 +15,22 @@ import TempDirUtils
abstract class MethodAccessInsecureFileCreation extends MethodAccess {
/**
- * Docstring describing the file system type (ie. file, directory, etc...) returned.
+ * Gets the type of entity created (e.g. `file`, `directory`, ...).
*/
- abstract string getFileSystemType();
+ abstract string getFileSystemEntityType();
}
/**
- * Insecure calls to `java.io.File::createTempFile`.
+ * An insecure call to `java.io.File::createTempFile`.
*/
class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCreation {
MethodAccessInsecureFileCreateTempFile() {
this.getMethod() instanceof MethodFileCreateTempFile and
(
+ // `File.createTempFile(string, string)` always uses the default temporary directory
this.getNumArgument() = 2
or
- // Vulnerablilty exists when the last argument is `null`
+ // The default temporary directory is used when the last argument of `File.createTempFile(string, string, File)` is `null`
getArgument(2) instanceof NullLiteral
)
}
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
index 97c21437d14d..f36a3eff94cd 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
@@ -1,10 +1,10 @@
/**
- * @name Temporary Directory Local information disclosure
- * @description Writing information without explicit permissions to a shared temporary directory may disclose it to other users.
+ * @name Temporary directory local information disclosure (file creation without explicit mode)
+ * @description Creating a temporary file in the system shared temporary directory without specifying explicit access rights (mode) may disclose its contents to other users.
* @kind path-problem
* @problem.severity warning
* @precision very-high
- * @id java/local-temp-file-or-directory-information-disclosure-path
+ * @id java/local-temp-file-or-directory-information-disclosure-missing-mode
* @tags security
* external/cwe/cwe-200
* external/cwe/cwe-732
@@ -36,7 +36,7 @@ private class FileFileCreationSink extends FileCreationSink {
}
/**
- * Sink for if tained File/Path having some `Files` method called on it that creates a file or directory.
+ * Sink for calling a file-creating or directory-creating `Files` method on a tainted `File` or `Path`.
*/
private class FilesFileCreationSink extends FileCreationSink {
FilesFileCreationSink() {
@@ -63,7 +63,7 @@ private class FilesVulnerableCreationMethodAccess extends MethodAccess {
}
/**
- * A call to `java.io.File::createTempFile` where the the system temp dir sinks to the last argument.
+ * The temp directory argument to a call to `java.io.File::createTempFile`, treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
*/
private class FileCreateTempFileSink extends FileCreationSink {
FileCreateTempFileSink() {
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index 30522c08b616..fd09c84e44be 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -63,23 +63,21 @@ private predicate isTaintedFileCreation(Expr expSource, Expr exprDest) {
private class TaintFollowingFileMethod extends Method {
TaintFollowingFileMethod() {
getDeclaringType() instanceof TypeFile and
- (
- hasName("getAbsoluteFile") or
- hasName("getCanonicalFile")
- )
+ hasName(["getAbsoluteFile", "getCanonicalFile"])
}
}
-private predicate isTaintFollowingFileTransformation(Expr expSource, Expr exprDest) {
+private predicate isTaintPropagatingFileTransformation(Expr expSource, Expr exprDest) {
exists(MethodAccess fileMethodAccess |
- fileMethodAccess.getMethod() instanceof TaintFollowingFileMethod and
+ fileMethodAccess.getMethod() instanceof TaintPropagatingFileMethod and
fileMethodAccess.getQualifier() = expSource and
fileMethodAccess = exprDest
)
}
/**
- * Holds if the system temporary directory is still part of the root of the file path.
+ * Holds if taint should propagate from `node1` to `node2` across some file creation or transformation operation.
+ * For example, `taintedFile.getCanonicalFile()` is itself tainted.
*/
predicate isAdditionalFileTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
isTaintedFileCreation(node1.asExpr(), node2.asExpr()) or
From a4b5573f5328ac0a41319c7ca6dae59b4986dfa3 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Mon, 19 Apr 2021 11:54:35 -0400
Subject: [PATCH 19/39] Apply suggestions from code review
Co-authored-by: Chris Smowton
---
...-02-25-local-temp-directory-information-disclosure.md | 2 +-
.../CWE-200/TempDirLocalInformationDisclosure.inc.qhelp | 4 ++--
.../TempDirLocalInformationDisclosureFromMethodCall.ql | 6 ++++++
...empDirLocalInformationDisclosureFromSystemProperty.ql | 9 +++++----
java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll | 2 +-
5 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md b/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md
index 540f29d14812..46654b8f14d8 100644
--- a/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md
+++ b/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md
@@ -1,4 +1,4 @@
lgtm,codescanning
* Two new queries, both titled "Temporary directory Local information disclosure"
(`java/local-temp-file-or-directory-information-disclosure-path`, `java/local-temp-file-or-directory-information-disclosure-method`), has been added.
- This query finds uses of APIs that leak potentially sensitive information to other local users via the system temporary directory.
\ No newline at end of file
+ These queries find uses of APIs that leak potentially sensitive information to other local users via the system temporary directory.
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
index 44c65efa637d..f54bee00b556 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
@@ -19,10 +19,10 @@ can occur.
Use JDK methods that specifically protect against this vulnerability:
- - java.nio.file.Files#createTempDirectory
+ - java.nio.file.Files.createTempDirectory
- java.nio.file.Files#createTempFile
-Otherwise, create the file/directory by manually specificfying the expected posix file permissions.
+
Otherwise, create the file/directory by manually specifying the expected posix file permissions.
For example: PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
- java.nio.file.Files#createFile
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
index ec47041da0b2..6e2afd3b1134 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
@@ -38,6 +38,9 @@ class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCre
override string getFileSystemType() { result = "file" }
}
+/**
+ * The `com.google.common.io.Files.createTempDir` method.
+ */
class MethodGuavaFilesCreateTempFile extends Method {
MethodGuavaFilesCreateTempFile() {
getDeclaringType().hasQualifiedName("com.google.common.io", "Files") and
@@ -45,6 +48,9 @@ class MethodGuavaFilesCreateTempFile extends Method {
}
}
+/**
+ * A call to the `com.google.common.io.Files.createTempDir` method.
+ */
class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureFileCreation {
MethodAccessInsecureGuavaFilesCreateTempFile() {
getMethod() instanceof MethodGuavaFilesCreateTempFile
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
index f36a3eff94cd..45b82a2aa1ef 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
@@ -24,7 +24,7 @@ private class MethodFileSystemFileCreation extends Method {
abstract private class FileCreationSink extends DataFlow::Node { }
/**
- * Sink for tainted `File` having a file or directory creation method called on it.
+ * The qualifier of a call to one of `File`'s file-creating or directory-creating methods, treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
*/
private class FileFileCreationSink extends FileCreationSink {
FileFileCreationSink() {
@@ -36,7 +36,8 @@ private class FileFileCreationSink extends FileCreationSink {
}
/**
- * Sink for calling a file-creating or directory-creating `Files` method on a tainted `File` or `Path`.
+ * The argument to
+ a call to one of `Files` file-creating or directory-creating methods, treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
*/
private class FilesFileCreationSink extends FileCreationSink {
FilesFileCreationSink() {
@@ -45,8 +46,8 @@ private class FilesFileCreationSink extends FileCreationSink {
}
/**
- * Captures all of the vulnerable methods on `Files` that create files/directories without explicitly
- * setting the permissions.
+ * A call to a `Files` method that create files/directories without explicitly
+ * setting the newly-created file or directory's permissions.
*/
private class FilesVulnerableCreationMethodAccess extends MethodAccess {
FilesVulnerableCreationMethodAccess() {
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index fd09c84e44be..dbc0cc7d1558 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -49,7 +49,7 @@ class MethodFileCreateTempFile extends Method {
* - `new File(System.getProperty("java.io.tmpdir"))`
* - `new File(new File(System.getProperty("java.io.tmpdir")), "/child")`
*/
-private predicate isTaintedFileCreation(Expr expSource, Expr exprDest) {
+private predicate isFileConstructorArgument(Expr expSource, Expr exprDest) {
exists(ConstructorCall construtorCall |
construtorCall.getConstructedType() instanceof TypeFile and
construtorCall.getArgument(0) = expSource and
From f7a4aac52586f051db45cc71314da4465b31c6cf Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Tue, 20 Apr 2021 12:19:41 -0400
Subject: [PATCH 20/39] Apply suggestions from code review
Co-authored-by: Chris Smowton
---
.../TempDirLocalInformationDisclosure.inc.qhelp | 8 ++++----
...TempDirLocalInformationDisclosureFromMethodCall.ql | 11 +++++++----
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
index f54bee00b556..22a4dd1427b1 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.inc.qhelp
@@ -20,14 +20,14 @@ can occur.
Use JDK methods that specifically protect against this vulnerability:
- java.nio.file.Files.createTempDirectory
- - java.nio.file.Files#createTempFile
+ - java.nio.file.Files.createTempFile
Otherwise, create the file/directory by manually specifying the expected posix file permissions.
For example: PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
index 6e2afd3b1134..2d9836a94cea 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
@@ -13,6 +13,9 @@
import java
import TempDirUtils
+/**
+ * A MethodAccess against a method that creates a temporary file or directory in a shared temporary directory.
+ */
abstract class MethodAccessInsecureFileCreation extends MethodAccess {
/**
* Gets the type of entity created (e.g. `file`, `directory`, ...).
@@ -21,7 +24,7 @@ abstract class MethodAccessInsecureFileCreation extends MethodAccess {
}
/**
- * An insecure call to `java.io.File::createTempFile`.
+ * An insecure call to `java.io.File.createTempFile`.
*/
class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCreation {
MethodAccessInsecureFileCreateTempFile() {
@@ -35,7 +38,7 @@ class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCre
)
}
- override string getFileSystemType() { result = "file" }
+ override string getFileSystemEntityType() { result = "file" }
}
/**
@@ -56,10 +59,10 @@ class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureF
getMethod() instanceof MethodGuavaFilesCreateTempFile
}
- override string getFileSystemType() { result = "directory" }
+ override string getFileSystemEntityType() { result = "directory" }
}
from MethodAccessInsecureFileCreation methodAccess
select methodAccess,
- "Local information disclosure vulnerability due to use of " + methodAccess.getFileSystemType() +
+ "Local information disclosure vulnerability due to use of " + methodAccess.getFileSystemEntityType() +
" readable by other local users."
From d5c9af31b224d7ca62985ce8d2359ab5e3b195b7 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Tue, 20 Apr 2021 13:12:05 -0400
Subject: [PATCH 21/39] Fixup documentation/code from PR feedback
---
...DirLocalInformationDisclosureFromSystemProperty.ql | 10 ++++++++--
java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll | 11 ++++-------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
index 45b82a2aa1ef..267ae0de4a3c 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
@@ -36,8 +36,8 @@ private class FileFileCreationSink extends FileCreationSink {
}
/**
- * The argument to
- a call to one of `Files` file-creating or directory-creating methods, treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
+ * The argument to
+ * a call to one of `Files` file-creating or directory-creating methods, treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
*/
private class FilesFileCreationSink extends FileCreationSink {
FilesFileCreationSink() {
@@ -81,6 +81,12 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
source.asExpr() instanceof MethodAccessSystemGetPropertyTempDirTainted
}
+ /**
+ * Find dataflow from the temp directory system property to the `File` constructor.
+ * Examples:
+ * - `new File(System.getProperty("java.io.tmpdir"))`
+ * - `new File(new File(System.getProperty("java.io.tmpdir")), "/child")`
+ */
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalFileTaintStep(node1, node2)
}
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index dbc0cc7d1558..0613006f71f9 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -44,10 +44,7 @@ class MethodFileCreateTempFile extends Method {
}
/**
- * Find dataflow from the temp directory system property to the `File` constructor.
- * Examples:
- * - `new File(System.getProperty("java.io.tmpdir"))`
- * - `new File(new File(System.getProperty("java.io.tmpdir")), "/child")`
+ * Holds if `expDest` is some constructor call `new java.io.File(x)` and `expSource` is `x`.
*/
private predicate isFileConstructorArgument(Expr expSource, Expr exprDest) {
exists(ConstructorCall construtorCall |
@@ -69,7 +66,7 @@ private class TaintFollowingFileMethod extends Method {
private predicate isTaintPropagatingFileTransformation(Expr expSource, Expr exprDest) {
exists(MethodAccess fileMethodAccess |
- fileMethodAccess.getMethod() instanceof TaintPropagatingFileMethod and
+ fileMethodAccess.getMethod() instanceof TaintFollowingFileMethod and
fileMethodAccess.getQualifier() = expSource and
fileMethodAccess = exprDest
)
@@ -80,6 +77,6 @@ private predicate isTaintPropagatingFileTransformation(Expr expSource, Expr expr
* For example, `taintedFile.getCanonicalFile()` is itself tainted.
*/
predicate isAdditionalFileTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
- isTaintedFileCreation(node1.asExpr(), node2.asExpr()) or
- isTaintFollowingFileTransformation(node1.asExpr(), node2.asExpr())
+ isFileConstructorArgument(node1.asExpr(), node2.asExpr()) or
+ isTaintPropagatingFileTransformation(node1.asExpr(), node2.asExpr())
}
From 79db76dcf8717f11fae353bdfc37079d27b1b104 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Wed, 21 Apr 2021 18:19:12 -0400
Subject: [PATCH 22/39] Fix test failures
TempDirLocalInformationDisclosureFromSystemProperty
---
...ationDisclosureFromSystemProperty.expected | 79 +++++++++++++++++--
1 file changed, 72 insertions(+), 7 deletions(-)
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/TempDirLocalInformationDisclosureFromSystemProperty.expected
index d71d23446dc9..dc3f39a8d714 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/TempDirLocalInformationDisclosureFromSystemProperty.expected
@@ -1,46 +1,111 @@
edges
+| Files.java:10:24:10:69 | new File(...) : File | Files.java:14:37:14:43 | baseDir : File |
+| Files.java:10:24:10:69 | new File(...) : File | Files.java:15:17:15:23 | tempDir |
+| Files.java:10:33:10:68 | getProperty(...) : String | Files.java:10:24:10:69 | new File(...) : File |
+| Files.java:10:33:10:68 | getProperty(...) : String | Files.java:14:37:14:43 | baseDir : File |
| Files.java:10:33:10:68 | getProperty(...) : String | Files.java:15:17:15:23 | tempDir |
+| Files.java:14:28:14:64 | new File(...) : File | Files.java:15:17:15:23 | tempDir |
+| Files.java:14:37:14:43 | baseDir : File | Files.java:14:28:14:64 | new File(...) : File |
+| Test.java:23:24:23:69 | new File(...) : File | Test.java:24:59:24:65 | tempDir |
+| Test.java:23:33:23:68 | getProperty(...) : String | Test.java:23:24:23:69 | new File(...) : File |
| Test.java:23:33:23:68 | getProperty(...) : String | Test.java:24:59:24:65 | tempDir |
+| Test.java:28:29:28:94 | new File(...) : File | Test.java:29:59:29:70 | tempDirChild |
+| Test.java:28:38:28:83 | new File(...) : File | Test.java:28:29:28:94 | new File(...) : File |
+| Test.java:28:38:28:83 | new File(...) : File | Test.java:29:59:29:70 | tempDirChild |
+| Test.java:28:47:28:82 | getProperty(...) : String | Test.java:28:38:28:83 | new File(...) : File |
| Test.java:28:47:28:82 | getProperty(...) : String | Test.java:29:59:29:70 | tempDirChild |
+| Test.java:33:24:33:69 | new File(...) : File | Test.java:34:59:34:65 | tempDir |
+| Test.java:33:33:33:68 | getProperty(...) : String | Test.java:33:24:33:69 | new File(...) : File |
| Test.java:33:33:33:68 | getProperty(...) : String | Test.java:34:59:34:65 | tempDir |
+| Test.java:38:24:38:69 | new File(...) : File | Test.java:39:59:39:65 | tempDir |
+| Test.java:38:33:38:68 | getProperty(...) : String | Test.java:38:24:38:69 | new File(...) : File |
| Test.java:38:33:38:68 | getProperty(...) : String | Test.java:39:59:39:65 | tempDir |
+| Test.java:53:29:53:84 | new File(...) : File | Test.java:54:9:54:20 | tempDirChild |
+| Test.java:53:38:53:73 | getProperty(...) : String | Test.java:53:29:53:84 | new File(...) : File |
| Test.java:53:38:53:73 | getProperty(...) : String | Test.java:54:9:54:20 | tempDirChild |
+| Test.java:58:29:58:84 | new File(...) : File | Test.java:59:9:59:20 | tempDirChild |
+| Test.java:58:38:58:73 | getProperty(...) : String | Test.java:58:29:58:84 | new File(...) : File |
| Test.java:58:38:58:73 | getProperty(...) : String | Test.java:59:9:59:20 | tempDirChild |
-| Test.java:63:38:63:73 | getProperty(...) : String | Test.java:64:21:64:41 | toPath(...) |
-| Test.java:68:38:68:73 | getProperty(...) : String | Test.java:71:21:71:41 | toPath(...) |
-| Test.java:75:38:75:73 | getProperty(...) : String | Test.java:76:33:76:53 | toPath(...) |
-| Test.java:80:38:80:73 | getProperty(...) : String | Test.java:81:31:81:51 | toPath(...) |
-| Test.java:85:38:85:73 | getProperty(...) : String | Test.java:86:26:86:46 | toPath(...) |
-| Test.java:99:38:99:73 | getProperty(...) : String | Test.java:100:31:100:51 | toPath(...) |
-| Test.java:104:38:104:73 | getProperty(...) : String | Test.java:105:33:105:53 | toPath(...) |
+| Test.java:63:29:63:88 | new File(...) : File | Test.java:64:21:64:32 | tempDirChild : File |
+| Test.java:63:38:63:73 | getProperty(...) : String | Test.java:63:29:63:88 | new File(...) : File |
+| Test.java:63:38:63:73 | getProperty(...) : String | Test.java:64:21:64:32 | tempDirChild : File |
+| Test.java:64:21:64:32 | tempDirChild : File | Test.java:64:21:64:41 | toPath(...) |
+| Test.java:68:29:68:88 | new File(...) : File | Test.java:71:21:71:32 | tempDirChild : File |
+| Test.java:68:38:68:73 | getProperty(...) : String | Test.java:68:29:68:88 | new File(...) : File |
+| Test.java:68:38:68:73 | getProperty(...) : String | Test.java:71:21:71:32 | tempDirChild : File |
+| Test.java:71:21:71:32 | tempDirChild : File | Test.java:71:21:71:41 | toPath(...) |
+| Test.java:75:29:75:104 | new File(...) : File | Test.java:76:33:76:44 | tempDirChild : File |
+| Test.java:75:38:75:73 | getProperty(...) : String | Test.java:75:29:75:104 | new File(...) : File |
+| Test.java:75:38:75:73 | getProperty(...) : String | Test.java:76:33:76:44 | tempDirChild : File |
+| Test.java:76:33:76:44 | tempDirChild : File | Test.java:76:33:76:53 | toPath(...) |
+| Test.java:80:29:80:102 | new File(...) : File | Test.java:81:31:81:42 | tempDirChild : File |
+| Test.java:80:38:80:73 | getProperty(...) : String | Test.java:80:29:80:102 | new File(...) : File |
+| Test.java:80:38:80:73 | getProperty(...) : String | Test.java:81:31:81:42 | tempDirChild : File |
+| Test.java:81:31:81:42 | tempDirChild : File | Test.java:81:31:81:51 | toPath(...) |
+| Test.java:85:29:85:100 | new File(...) : File | Test.java:86:26:86:37 | tempDirChild : File |
+| Test.java:85:38:85:73 | getProperty(...) : String | Test.java:85:29:85:100 | new File(...) : File |
+| Test.java:85:38:85:73 | getProperty(...) : String | Test.java:86:26:86:37 | tempDirChild : File |
+| Test.java:86:26:86:37 | tempDirChild : File | Test.java:86:26:86:46 | toPath(...) |
+| Test.java:99:29:99:101 | new File(...) : File | Test.java:100:31:100:42 | tempDirChild : File |
+| Test.java:99:38:99:73 | getProperty(...) : String | Test.java:99:29:99:101 | new File(...) : File |
+| Test.java:99:38:99:73 | getProperty(...) : String | Test.java:100:31:100:42 | tempDirChild : File |
+| Test.java:100:31:100:42 | tempDirChild : File | Test.java:100:31:100:51 | toPath(...) |
+| Test.java:104:29:104:109 | new File(...) : File | Test.java:105:33:105:44 | tempDirChild : File |
+| Test.java:104:38:104:73 | getProperty(...) : String | Test.java:104:29:104:109 | new File(...) : File |
+| Test.java:104:38:104:73 | getProperty(...) : String | Test.java:105:33:105:44 | tempDirChild : File |
+| Test.java:105:33:105:44 | tempDirChild : File | Test.java:105:33:105:53 | toPath(...) |
nodes
+| Files.java:10:24:10:69 | new File(...) : File | semmle.label | new File(...) : File |
| Files.java:10:33:10:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| 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:23:24:23:69 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:23:33:23:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:24:59:24:65 | tempDir | semmle.label | tempDir |
+| Test.java:28:29:28:94 | new File(...) : File | semmle.label | new File(...) : File |
+| Test.java:28:38:28:83 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:28:47:28:82 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:29:59:29:70 | tempDirChild | semmle.label | tempDirChild |
+| Test.java:33:24:33:69 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:33:33:33:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:34:59:34:65 | tempDir | semmle.label | tempDir |
+| Test.java:38:24:38:69 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:38:33:38:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:39:59:39:65 | tempDir | semmle.label | tempDir |
+| Test.java:53:29:53:84 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:53:38:53:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:54:9:54:20 | tempDirChild | semmle.label | tempDirChild |
+| Test.java:58:29:58:84 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:58:38:58:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:59:9:59:20 | tempDirChild | semmle.label | tempDirChild |
+| Test.java:63:29:63:88 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:63:38:63:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:64:21:64:32 | tempDirChild : File | semmle.label | tempDirChild : File |
| Test.java:64:21:64:41 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:68:29:68:88 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:68:38:68:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:71:21:71:32 | tempDirChild : File | semmle.label | tempDirChild : File |
| Test.java:71:21:71:41 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:75:29:75:104 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:75:38:75:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:76:33:76:44 | tempDirChild : File | semmle.label | tempDirChild : File |
| Test.java:76:33:76:53 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:80:29:80:102 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:80:38:80:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:81:31:81:42 | tempDirChild : File | semmle.label | tempDirChild : File |
| Test.java:81:31:81:51 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:85:29:85:100 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:85:38:85:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:86:26:86:37 | tempDirChild : File | semmle.label | tempDirChild : File |
| Test.java:86:26:86:46 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:99:29:99:101 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:99:38:99:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:100:31:100:42 | tempDirChild : File | semmle.label | tempDirChild : File |
| Test.java:100:31:100:51 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:104:29:104:109 | new File(...) : File | semmle.label | new File(...) : File |
| Test.java:104:38:104:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:105:33:105:44 | tempDirChild : File | semmle.label | tempDirChild : File |
| Test.java:105:33:105:53 | toPath(...) | semmle.label | toPath(...) |
#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 |
From 0a621c2801565e5da810fee581de7a05918f9dea Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Mon, 26 Apr 2021 11:58:19 -0400
Subject: [PATCH 23/39] Fix the formatting in
TempDirLocalInformationDisclosureFromMethodCall
---
.../TempDirLocalInformationDisclosureFromMethodCall.ql | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
index 2d9836a94cea..43812530d44d 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
@@ -64,5 +64,5 @@ class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureF
from MethodAccessInsecureFileCreation methodAccess
select methodAccess,
- "Local information disclosure vulnerability due to use of " + methodAccess.getFileSystemEntityType() +
- " readable by other local users."
+ "Local information disclosure vulnerability due to use of " +
+ methodAccess.getFileSystemEntityType() + " readable by other local users."
From 9299c7996db0d64b81d3448f6e55172db8af05b6 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Fri, 28 Jan 2022 19:24:48 +0000
Subject: [PATCH 24/39] Add information disclosure test fix suggestions
---
.../security/CWE-200/semmle/tests/Test.java | 193 ++++++++++++++++--
1 file changed, 176 insertions(+), 17 deletions(-)
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
index b87d12199c21..44b8210e6584 100644
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
@@ -3,6 +3,8 @@
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.PosixFilePermission;
@@ -12,96 +14,253 @@
public class Test {
void vulnerableFileCreateTempFile() throws IOException {
- File temp = File.createTempFile("random", "file");
+ // VULNERABLE VERSION:
+ File tempVuln = File.createTempFile("random", "file");
+
+ // TO MAKE SAFE REWRITE TO:
+ File tempSafe = Files.createTempFile("random", "file").toFile();
}
void vulnerableFileCreateTempFileNull() throws IOException {
- File temp = File.createTempFile("random", "file", null);
+ // VULNERABLE VERSION:
+ File tempVuln = File.createTempFile("random", "file", null);
+
+ // TO MAKE SAFE REWRITE TO:
+ File tempSafe = Files.createTempFile("random", "file").toFile();
}
void vulnerableFileCreateTempFileTainted() throws IOException {
+ // GIVEN:
File tempDir = new File(System.getProperty("java.io.tmpdir"));
- File temp = File.createTempFile("random", "file", tempDir);
+
+ // VULNERABLE VERSION:
+ File tempVuln = File.createTempFile("random", "file", tempDir);
+
+ // TO MAKE SAFE REWRITE TO (v1):
+ File tempSafe1 = Files.createTempFile(tempDir.toPath(), "random", "file").toFile();
+
+ // TO MAKE SAFE REWRITE TO (v2):
+ File tempSafe2 = Files.createTempFile("random", "file").toFile();
}
void vulnerableFileCreateTempFileChildTainted() throws IOException {
+ // GIVEN:
File tempDirChild = new File(new File(System.getProperty("java.io.tmpdir")), "/child");
- File temp = File.createTempFile("random", "file", tempDirChild);
+
+ // VULNERABLE VERSION:
+ File tempVuln = File.createTempFile("random", "file", tempDirChild);
+
+ // TO MAKE SAFE REWRITE TO:
+ File tempSafe = Files.createTempFile(tempDirChild.toPath(), "random", "file").toFile();
}
void vulnerableFileCreateTempFileCanonical() throws IOException {
+ // GIVEN:
File tempDir = new File(System.getProperty("java.io.tmpdir")).getCanonicalFile();
- File temp = File.createTempFile("random", "file", tempDir);
+
+ // VULNERABLE VERSION:
+ File tempVuln = File.createTempFile("random", "file", tempDir);
+
+ // TO MAKE SAFE REWRITE TO (v1):
+ File tempSafe1 = Files.createTempFile(tempDir.toPath(), "random", "file").toFile();
+
+ // TO MAKE SAFE REWRITE TO (v2):
+ File tempSafe2 = Files.createTempFile("random", "file").toFile();
}
void vulnerableFileCreateTempFileAbsolute() throws IOException {
+ // GIVEN:
File tempDir = new File(System.getProperty("java.io.tmpdir")).getAbsoluteFile();
- File temp = File.createTempFile("random", "file", tempDir);
+
+ // VULNERABLE VERSION:
+ File tempVuln = File.createTempFile("random", "file", tempDir);
+
+ // TO MAKE SAFE REWRITE TO (v1):
+ File tempSafe1 = Files.createTempFile(tempDir.toPath(), "random", "file").toFile();
+ // TO MAKE SAFE REWRITE TO (v2):
+ File tempSafe2 = Files.createTempFile("random", "file").toFile();
}
void safeFileCreateTempFileTainted() throws IOException {
- /* Creating a temporary directoy in the current user directory is not a vulnerability. */
+ /*
+ * Creating a temporary directoy in the current user directory is not a
+ * vulnerability.
+ */
File currentDirectory = new File(System.getProperty("user.dir"));
File temp = File.createTempFile("random", "file", currentDirectory);
}
void vulnerableGuavaFilesCreateTempDir() {
+ // VULNERABLE VERSION:
File tempDir = com.google.common.io.Files.createTempDir();
+
+ // TO MAKE SAFE REWRITE TO:
+ File tempSafe;
+ try {
+ Files.createTempDirectory("random").toFile();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to create temporary directory", e);
+ }
}
void vulnerableFileCreateTempFileMkdirTainted() {
+ // GIVEN:
File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child");
+
+ // VULNERABLE VERSION:
tempDirChild.mkdir();
+
+ // TO MAKE SAFE REWRITE TO (v1):
+ File tempSafe1;
+ try {
+ tempSafe1 = Files.createTempDirectory(tempDirChild.toPath(), "random").toFile();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to create temporary directory", e);
+ }
+
+ // TO MAKE SAFE REWRITE TO (v2):
+ File tempSafe2;
+ try {
+ tempSafe2 = Files.createTempDirectory("random").toFile();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to create temporary directory", e);
+ }
}
void vulnerableFileCreateTempFileMkdirsTainted() {
+ // GIVEN:
File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child");
+
+ // VULNERABLE VERSION:
tempDirChild.mkdirs();
+
+ // TO MAKE SAFE REWRITE TO (v1):
+ File tempSafe1;
+ try {
+ tempSafe1 = Files.createTempDirectory(tempDirChild.toPath(), "random").toFile();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to create temporary directory", e);
+ }
+
+ // TO MAKE SAFE REWRITE TO (v2):
+ File tempSafe2;
+ try {
+ tempSafe2 = Files.createTempDirectory("random").toFile();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to create temporary directory", e);
+ }
}
void vulnerableFileCreateTempFilesWrite1() throws IOException {
+ // VULNERABLE VERSION:
File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child.txt");
Files.write(tempDirChild.toPath(), Arrays.asList("secret"), StandardCharsets.UTF_8, StandardOpenOption.CREATE);
+
+ // TO MAKE SAFE REWRITE TO (v1):
+ // Use this version if you care that the file has the exact path of `[java.io.tmpdir]/child.txt`
+ try {
+ Path tempSafe = Paths.get(System.getProperty("java.io.tmpdir"), "child.txt");
+ Files.createFile(tempSafe, PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
+ Files.write(tempSafe, Arrays.asList("secret"));
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to write temporary file", e);
+ }
+
+ // TO MAKE SAFE REWRITE TO (v2):
+ // Use this version if you don't care that the file has an exact path. This will write to a file of the name `[java.io.tmpdir]/random[random string]child.txt`
+ try {
+ Path tempSafe = Files.createTempFile("random", "child.txt");
+ Files.write(tempSafe, Arrays.asList("secret"), StandardCharsets.UTF_8, StandardOpenOption.CREATE);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to write temporary file", e);
+ }
}
-
+
void vulnerableFileCreateTempFilesWrite2() throws IOException {
- File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child.txt");
+ // GIVEN:
String secret = "secret";
byte[] byteArrray = secret.getBytes();
+
+ // VULNERABLE VERSION:
+ File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child.txt");
Files.write(tempDirChild.toPath(), byteArrray, StandardOpenOption.CREATE);
+
+ // TO MAKE SAFE REWRITE TO (v1):
+ // Use this version if you care that the file has the exact path of `[java.io.tmpdir]/child.txt`
+ Path tempSafe1 = Paths.get(System.getProperty("java.io.tmpdir"), "child.txt");
+ Files.createFile(tempSafe1, PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
+ Files.write(tempSafe1, byteArrray);
+
+ // TO MAKE SAFE REWRITE TO (v2):
+ // Use this version if you don't care that the file has an exact path. This will write to a file of the name `[java.io.tmpdir]/random[random string]child.txt`
+ Path tempSafe2 = Files.createTempFile("random", "child.txt");
+ Files.write(tempSafe2, byteArrray);
}
void vulnerableFileCreateTempFilesNewBufferedWriter() throws IOException {
- File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child-buffered-writer.txt");
- Files.newBufferedWriter(tempDirChild.toPath());
+ // GIVEN:
+ Path tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child-buffered-writer.txt").toPath();
+
+ // VULNERABLE VERSION:
+ Files.newBufferedWriter(tempDirChild);
+
+ // TO MAKE SAFE REWRITE TO:
+ Files.createFile(tempDirChild, PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
+ Files.newBufferedWriter(tempDirChild);
}
void vulnerableFileCreateTempFilesNewOutputStream() throws IOException {
- File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child-output-stream.txt");
- Files.newOutputStream(tempDirChild.toPath()).close();
+ // GIVEN:
+ Path tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child-output-stream.txt").toPath();
+
+ // VULNERABLE VERSION:
+ Files.newOutputStream(tempDirChild).close();
+
+ // TO MAKE SAFE REWRITE TO:
+ Files.createFile(tempDirChild, PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
+ Files.newOutputStream(tempDirChild).close();
}
void vulnerableFileCreateTempFilesCreateFile() throws IOException {
+ // GIVEN:
File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child-create-file.txt");
+
+ // VULNERABLE VERSION:
Files.createFile(tempDirChild.toPath());
+
+ // TO MAKE SAFE REWRITE TO:
+ Files.createFile(tempDirChild.toPath(), PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
}
void safeFileCreateTempFilesCreateFile() throws IOException {
- // Clear permissions intentions by setting the 'OWNER_READ' and 'OWNER_WRITE' permissions.
+ // Clear permissions intentions by setting the 'OWNER_READ' and 'OWNER_WRITE'
+ // permissions.
File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child-create-file.txt");
Files.createFile(
- tempDirChild.toPath(),
- PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
- );
+ tempDirChild.toPath(),
+ PosixFilePermissions
+ .asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
}
void vulnerableFileCreateDirectory() throws IOException {
+ // GIVEN:
File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child-create-directory");
+
+ // VULNERABLE VERSION:
Files.createDirectory(tempDirChild.toPath()); // Creates with permissions 'drwxr-xr-x'
+
+ // TO MAKE SAFE REWRITE TO:
+ Files.createDirectory(tempDirChild.toPath(), PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
}
void vulnerableFileCreateDirectories() throws IOException {
+ // GIVEN:
File tempDirChild = new File(System.getProperty("java.io.tmpdir"), "/child-create-directories/child");
+
+ // VULNERABLE VERSION:
Files.createDirectories(tempDirChild.toPath()); // Creates with permissions 'drwxr-xr-x'
+
+ // TO MAKE SAFE REWRITE TO:
+ Files.createDirectories(tempDirChild.toPath(), PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
}
}
From 0268dd9f0ab5f0fe9ade5fdbbf7ae5f4c6714812 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Tue, 1 Feb 2022 16:45:33 +0000
Subject: [PATCH 25/39] Add file creation sanitizer
---
...ocalInformationDisclosureFromMethodCall.ql | 2 +-
...InformationDisclosureFromSystemProperty.ql | 33 ++-
...formationDisclosureFromMethodCall.expected | 6 +-
...ationDisclosureFromSystemProperty.expected | 215 +++++++++---------
4 files changed, 140 insertions(+), 116 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
index 43812530d44d..1b291ee7d3f2 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
@@ -34,7 +34,7 @@ class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCre
this.getNumArgument() = 2
or
// The default temporary directory is used when the last argument of `File.createTempFile(string, string, File)` is `null`
- getArgument(2) instanceof NullLiteral
+ DataFlow::localExprFlow(any(NullLiteral n), getArgument(2))
)
}
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
index 267ae0de4a3c..c895ff9d6adc 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
@@ -16,8 +16,8 @@ import DataFlow::PathGraph
private class MethodFileSystemFileCreation extends Method {
MethodFileSystemFileCreation() {
- getDeclaringType() instanceof TypeFile and
- hasName(["mkdir", "mkdirs", "createNewFile"])
+ this.getDeclaringType() instanceof TypeFile and
+ this.hasName(["mkdir", "mkdirs", "createNewFile"])
}
}
@@ -58,7 +58,26 @@ private class FilesVulnerableCreationMethodAccess extends MethodAccess {
m.hasName(["write", "newBufferedWriter", "newOutputStream"])
or
m.hasName(["createFile", "createDirectory", "createDirectories"]) and
- getNumArgument() = 1
+ this.getNumArgument() = 1
+ or
+ m.hasName("newByteChannel") and
+ this.getNumArgument() = 2
+ )
+ }
+}
+
+/**
+ * A call to a `File` method that create files/directories with a specific set of permissions explicitly set.
+ * We can safely assume that any calls to these methods with explicit `PosixFilePermissions.asFileAttribute` contains a certain level of intentionality behind it.
+ */
+private class FilesSanitiznignCreationMethodAccess extends MethodAccess {
+ FilesSanitiznignCreationMethodAccess() {
+ exists(Method m |
+ m = this.getMethod() and
+ m.getDeclaringType().hasQualifiedName("java.nio.file", "Files")
+ |
+ m.hasName(["createFile", "createDirectory", "createDirectories"]) and
+ this.getNumArgument() = 2
)
}
}
@@ -92,10 +111,16 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
}
override predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink }
+
+ override predicate isSanitizer(DataFlow::Node sanitizer) {
+ exists(FilesSanitiznignCreationMethodAccess sanitisingMethodAccess |
+ sanitizer.asExpr() = sanitisingMethodAccess.getArgument(0)
+ )
+ }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, TempDirSystemGetPropertyToCreateConfig conf
where conf.hasFlowPath(source, sink)
-select source.getNode(), source, sink,
+select sink.getNode(), source, sink,
"Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users.",
source.getNode(), "system temp directory"
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected
index d58eb1544168..35f5487ad8c0 100644
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected
@@ -1,3 +1,3 @@
-| Test.java:15:21:15:57 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. |
-| Test.java:19:21:19:63 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. |
-| Test.java:49:24:49:65 | createTempDir(...) | Local information disclosure vulnerability due to use of directory readable by other local users. |
+| Test.java:18:25:18:61 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. |
+| Test.java:26:25:26:67 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. |
+| Test.java:95:24:95:65 | createTempDir(...) | Local information disclosure vulnerability due to use of directory readable by other local users. |
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/TempDirLocalInformationDisclosureFromSystemProperty.expected
index dc3f39a8d714..aa4bc32d8d90 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/TempDirLocalInformationDisclosureFromSystemProperty.expected
@@ -6,119 +6,118 @@ edges
| Files.java:10:33:10:68 | getProperty(...) : String | Files.java:15:17:15:23 | tempDir |
| Files.java:14:28:14:64 | new File(...) : File | Files.java:15:17:15:23 | tempDir |
| Files.java:14:37:14:43 | baseDir : File | Files.java:14:28:14:64 | new File(...) : File |
-| Test.java:23:24:23:69 | new File(...) : File | Test.java:24:59:24:65 | tempDir |
-| Test.java:23:33:23:68 | getProperty(...) : String | Test.java:23:24:23:69 | new File(...) : File |
-| Test.java:23:33:23:68 | getProperty(...) : String | Test.java:24:59:24:65 | tempDir |
-| Test.java:28:29:28:94 | new File(...) : File | Test.java:29:59:29:70 | tempDirChild |
-| Test.java:28:38:28:83 | new File(...) : File | Test.java:28:29:28:94 | new File(...) : File |
-| Test.java:28:38:28:83 | new File(...) : File | Test.java:29:59:29:70 | tempDirChild |
-| Test.java:28:47:28:82 | getProperty(...) : String | Test.java:28:38:28:83 | new File(...) : File |
-| Test.java:28:47:28:82 | getProperty(...) : String | Test.java:29:59:29:70 | tempDirChild |
-| Test.java:33:24:33:69 | new File(...) : File | Test.java:34:59:34:65 | tempDir |
-| Test.java:33:33:33:68 | getProperty(...) : String | Test.java:33:24:33:69 | new File(...) : File |
-| Test.java:33:33:33:68 | getProperty(...) : String | Test.java:34:59:34:65 | tempDir |
-| Test.java:38:24:38:69 | new File(...) : File | Test.java:39:59:39:65 | tempDir |
-| Test.java:38:33:38:68 | getProperty(...) : String | Test.java:38:24:38:69 | new File(...) : File |
-| Test.java:38:33:38:68 | getProperty(...) : String | Test.java:39:59:39:65 | tempDir |
-| Test.java:53:29:53:84 | new File(...) : File | Test.java:54:9:54:20 | tempDirChild |
-| Test.java:53:38:53:73 | getProperty(...) : String | Test.java:53:29:53:84 | new File(...) : File |
-| Test.java:53:38:53:73 | getProperty(...) : String | Test.java:54:9:54:20 | tempDirChild |
-| Test.java:58:29:58:84 | new File(...) : File | Test.java:59:9:59:20 | tempDirChild |
-| Test.java:58:38:58:73 | getProperty(...) : String | Test.java:58:29:58:84 | new File(...) : File |
-| Test.java:58:38:58:73 | getProperty(...) : String | Test.java:59:9:59:20 | tempDirChild |
-| Test.java:63:29:63:88 | new File(...) : File | Test.java:64:21:64:32 | tempDirChild : File |
-| Test.java:63:38:63:73 | getProperty(...) : String | Test.java:63:29:63:88 | new File(...) : File |
-| Test.java:63:38:63:73 | getProperty(...) : String | Test.java:64:21:64:32 | tempDirChild : File |
-| Test.java:64:21:64:32 | tempDirChild : File | Test.java:64:21:64:41 | toPath(...) |
-| Test.java:68:29:68:88 | new File(...) : File | Test.java:71:21:71:32 | tempDirChild : File |
-| Test.java:68:38:68:73 | getProperty(...) : String | Test.java:68:29:68:88 | new File(...) : File |
-| Test.java:68:38:68:73 | getProperty(...) : String | Test.java:71:21:71:32 | tempDirChild : File |
-| Test.java:71:21:71:32 | tempDirChild : File | Test.java:71:21:71:41 | toPath(...) |
-| Test.java:75:29:75:104 | new File(...) : File | Test.java:76:33:76:44 | tempDirChild : File |
-| Test.java:75:38:75:73 | getProperty(...) : String | Test.java:75:29:75:104 | new File(...) : File |
-| Test.java:75:38:75:73 | getProperty(...) : String | Test.java:76:33:76:44 | tempDirChild : File |
-| Test.java:76:33:76:44 | tempDirChild : File | Test.java:76:33:76:53 | toPath(...) |
-| Test.java:80:29:80:102 | new File(...) : File | Test.java:81:31:81:42 | tempDirChild : File |
-| Test.java:80:38:80:73 | getProperty(...) : String | Test.java:80:29:80:102 | new File(...) : File |
-| Test.java:80:38:80:73 | getProperty(...) : String | Test.java:81:31:81:42 | tempDirChild : File |
-| Test.java:81:31:81:42 | tempDirChild : File | Test.java:81:31:81:51 | toPath(...) |
-| Test.java:85:29:85:100 | new File(...) : File | Test.java:86:26:86:37 | tempDirChild : File |
-| Test.java:85:38:85:73 | getProperty(...) : String | Test.java:85:29:85:100 | new File(...) : File |
-| Test.java:85:38:85:73 | getProperty(...) : String | Test.java:86:26:86:37 | tempDirChild : File |
-| Test.java:86:26:86:37 | tempDirChild : File | Test.java:86:26:86:46 | toPath(...) |
-| Test.java:99:29:99:101 | new File(...) : File | Test.java:100:31:100:42 | tempDirChild : File |
-| Test.java:99:38:99:73 | getProperty(...) : String | Test.java:99:29:99:101 | new File(...) : File |
-| Test.java:99:38:99:73 | getProperty(...) : String | Test.java:100:31:100:42 | tempDirChild : File |
-| Test.java:100:31:100:42 | tempDirChild : File | Test.java:100:31:100:51 | toPath(...) |
-| Test.java:104:29:104:109 | new File(...) : File | Test.java:105:33:105:44 | tempDirChild : File |
-| Test.java:104:38:104:73 | getProperty(...) : String | Test.java:104:29:104:109 | new File(...) : File |
-| Test.java:104:38:104:73 | getProperty(...) : String | Test.java:105:33:105:44 | tempDirChild : File |
-| Test.java:105:33:105:44 | tempDirChild : File | Test.java:105:33:105:53 | toPath(...) |
+| Test.java:34:24:34:69 | new File(...) : File | Test.java:37:63:37:69 | tempDir |
+| Test.java:34:33:34:68 | getProperty(...) : String | Test.java:34:24:34:69 | new File(...) : File |
+| Test.java:34:33:34:68 | getProperty(...) : String | Test.java:37:63:37:69 | tempDir |
+| Test.java:48:29:48:94 | new File(...) : File | Test.java:51:63:51:74 | tempDirChild |
+| Test.java:48:38:48:83 | new File(...) : File | Test.java:48:29:48:94 | new File(...) : File |
+| Test.java:48:38:48:83 | new File(...) : File | Test.java:51:63:51:74 | tempDirChild |
+| Test.java:48:47:48:82 | getProperty(...) : String | Test.java:48:38:48:83 | new File(...) : File |
+| Test.java:48:47:48:82 | getProperty(...) : String | Test.java:51:63:51:74 | tempDirChild |
+| Test.java:59:24:59:69 | new File(...) : File | Test.java:62:63:62:69 | tempDir |
+| Test.java:59:33:59:68 | getProperty(...) : String | Test.java:59:24:59:69 | new File(...) : File |
+| Test.java:59:33:59:68 | getProperty(...) : String | Test.java:62:63:62:69 | tempDir |
+| Test.java:73:24:73:69 | new File(...) : File | Test.java:76:63:76:69 | tempDir |
+| Test.java:73:33:73:68 | getProperty(...) : String | Test.java:73:24:73:69 | new File(...) : File |
+| Test.java:73:33:73:68 | getProperty(...) : String | Test.java:76:63:76:69 | tempDir |
+| Test.java:108:29:108:84 | new File(...) : File | Test.java:111:9:111:20 | tempDirChild |
+| Test.java:108:38:108:73 | getProperty(...) : String | Test.java:108:29:108:84 | new File(...) : File |
+| Test.java:108:38:108:73 | getProperty(...) : String | Test.java:111:9:111:20 | tempDirChild |
+| Test.java:132:29:132:84 | new File(...) : File | Test.java:135:9:135:20 | tempDirChild |
+| Test.java:132:38:132:73 | getProperty(...) : String | Test.java:132:29:132:84 | new File(...) : File |
+| Test.java:132:38:132:73 | getProperty(...) : String | Test.java:135:9:135:20 | tempDirChild |
+| Test.java:156:29:156:88 | new File(...) : File | Test.java:157:21:157:32 | tempDirChild : File |
+| Test.java:156:38:156:73 | getProperty(...) : String | Test.java:156:29:156:88 | new File(...) : File |
+| Test.java:156:38:156:73 | getProperty(...) : String | Test.java:157:21:157:32 | tempDirChild : File |
+| Test.java:157:21:157:32 | tempDirChild : File | Test.java:157:21:157:41 | toPath(...) |
+| Test.java:185:29:185:88 | new File(...) : File | Test.java:186:21:186:32 | tempDirChild : File |
+| Test.java:185:38:185:73 | getProperty(...) : String | Test.java:185:29:185:88 | new File(...) : File |
+| Test.java:185:38:185:73 | getProperty(...) : String | Test.java:186:21:186:32 | tempDirChild : File |
+| 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: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: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 |
+| Test.java:226:38:226:73 | getProperty(...) : String | Test.java:229:26:229:37 | tempDirChild : File |
+| Test.java:229:26:229:37 | tempDirChild : File | Test.java:229:26:229:46 | toPath(...) |
+| Test.java:247:29:247:101 | new File(...) : File | Test.java:250:31:250:42 | tempDirChild : File |
+| Test.java:247:38:247:73 | getProperty(...) : String | Test.java:247:29:247:101 | new File(...) : File |
+| Test.java:247:38:247:73 | getProperty(...) : String | Test.java:250:31:250:42 | tempDirChild : File |
+| Test.java:250:31:250:42 | tempDirChild : File | Test.java:250:31:250:51 | toPath(...) |
+| Test.java:258:29:258:109 | new File(...) : File | Test.java:261:33:261:44 | tempDirChild : File |
+| Test.java:258:38:258:73 | getProperty(...) : String | Test.java:258:29:258:109 | new File(...) : File |
+| Test.java:258:38:258:73 | getProperty(...) : String | Test.java:261:33:261:44 | tempDirChild : File |
+| Test.java:261:33:261:44 | tempDirChild : File | Test.java:261:33:261:53 | toPath(...) |
nodes
| Files.java:10:24:10:69 | new File(...) : File | semmle.label | new File(...) : File |
| Files.java:10:33:10:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| 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:23:24:23:69 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:23:33:23:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:24:59:24:65 | tempDir | semmle.label | tempDir |
-| Test.java:28:29:28:94 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:28:38:28:83 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:28:47:28:82 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:29:59:29:70 | tempDirChild | semmle.label | tempDirChild |
-| Test.java:33:24:33:69 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:33:33:33:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:34:59:34:65 | tempDir | semmle.label | tempDir |
-| Test.java:38:24:38:69 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:38:33:38:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:39:59:39:65 | tempDir | semmle.label | tempDir |
-| Test.java:53:29:53:84 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:53:38:53:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:54:9:54:20 | tempDirChild | semmle.label | tempDirChild |
-| Test.java:58:29:58:84 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:58:38:58:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:59:9:59:20 | tempDirChild | semmle.label | tempDirChild |
-| Test.java:63:29:63:88 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:63:38:63:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:64:21:64:32 | tempDirChild : File | semmle.label | tempDirChild : File |
-| Test.java:64:21:64:41 | toPath(...) | semmle.label | toPath(...) |
-| Test.java:68:29:68:88 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:68:38:68:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:71:21:71:32 | tempDirChild : File | semmle.label | tempDirChild : File |
-| Test.java:71:21:71:41 | toPath(...) | semmle.label | toPath(...) |
-| Test.java:75:29:75:104 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:75:38:75:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:76:33:76:44 | tempDirChild : File | semmle.label | tempDirChild : File |
-| Test.java:76:33:76:53 | toPath(...) | semmle.label | toPath(...) |
-| Test.java:80:29:80:102 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:80:38:80:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:81:31:81:42 | tempDirChild : File | semmle.label | tempDirChild : File |
-| Test.java:81:31:81:51 | toPath(...) | semmle.label | toPath(...) |
-| Test.java:85:29:85:100 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:85:38:85:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:86:26:86:37 | tempDirChild : File | semmle.label | tempDirChild : File |
-| Test.java:86:26:86:46 | toPath(...) | semmle.label | toPath(...) |
-| Test.java:99:29:99:101 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:99:38:99:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:100:31:100:42 | tempDirChild : File | semmle.label | tempDirChild : File |
-| Test.java:100:31:100:51 | toPath(...) | semmle.label | toPath(...) |
-| Test.java:104:29:104:109 | new File(...) : File | semmle.label | new File(...) : File |
-| Test.java:104:38:104:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
-| Test.java:105:33:105:44 | tempDirChild : File | semmle.label | tempDirChild : File |
-| Test.java:105:33:105:53 | toPath(...) | semmle.label | toPath(...) |
+| 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 |
+| Test.java:48:29:48:94 | new File(...) : File | semmle.label | new File(...) : File |
+| Test.java:48:38:48:83 | new File(...) : File | semmle.label | new File(...) : File |
+| Test.java:48:47:48:82 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:51:63:51:74 | tempDirChild | semmle.label | tempDirChild |
+| Test.java:59:24:59:69 | new File(...) : File | semmle.label | new File(...) : File |
+| Test.java:59:33:59:68 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:62:63:62:69 | tempDir | semmle.label | tempDir |
+| 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: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 |
+| Test.java:132:29:132:84 | new File(...) : File | semmle.label | new File(...) : File |
+| Test.java:132:38:132:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:135:9:135:20 | tempDirChild | semmle.label | tempDirChild |
+| Test.java:156:29:156:88 | new File(...) : File | semmle.label | new File(...) : File |
+| Test.java:156:38:156:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:157:21:157:32 | tempDirChild : File | semmle.label | tempDirChild : File |
+| Test.java:157:21:157:41 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:185:29:185:88 | new File(...) : File | semmle.label | new File(...) : File |
+| Test.java:185:38:185:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:186:21:186:32 | tempDirChild : File | semmle.label | tempDirChild : File |
+| Test.java:186:21:186:41 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:202:29:202:104 | new File(...) : File | semmle.label | new File(...) : File |
+| 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: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: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 |
+| Test.java:229:26:229:46 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:247:29:247:101 | new File(...) : File | semmle.label | new File(...) : File |
+| Test.java:247:38:247:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:250:31:250:42 | tempDirChild : File | semmle.label | tempDirChild : File |
+| Test.java:250:31:250:51 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:258:29:258:109 | new File(...) : File | semmle.label | new File(...) : File |
+| Test.java:258:38:258:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
+| Test.java:261:33:261:44 | tempDirChild : File | semmle.label | tempDirChild : File |
+| Test.java:261:33:261:53 | toPath(...) | semmle.label | toPath(...) |
+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:23:33:23:68 | getProperty(...) | Test.java:23:33:23:68 | getProperty(...) : String | Test.java:24:59:24:65 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:23:33:23:68 | getProperty(...) | system temp directory |
-| Test.java:28:47:28:82 | getProperty(...) | Test.java:28:47:28:82 | getProperty(...) : String | Test.java:29:59:29:70 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:28:47:28:82 | getProperty(...) | system temp directory |
-| Test.java:33:33:33:68 | getProperty(...) | Test.java:33:33:33:68 | getProperty(...) : String | Test.java:34:59:34:65 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:33:33:33:68 | getProperty(...) | system temp directory |
-| Test.java:38:33:38:68 | getProperty(...) | Test.java:38:33:38:68 | getProperty(...) : String | Test.java:39:59:39:65 | tempDir | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:38:33:38:68 | getProperty(...) | system temp directory |
-| Test.java:53:38:53:73 | getProperty(...) | Test.java:53:38:53:73 | getProperty(...) : String | Test.java:54:9:54:20 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:53:38:53:73 | getProperty(...) | system temp directory |
-| Test.java:58:38:58:73 | getProperty(...) | Test.java:58:38:58:73 | getProperty(...) : String | Test.java:59:9:59:20 | tempDirChild | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:58:38:58:73 | getProperty(...) | system temp directory |
-| Test.java:63:38:63:73 | getProperty(...) | Test.java:63:38:63:73 | getProperty(...) : String | Test.java:64:21:64:41 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:63:38:63:73 | getProperty(...) | system temp directory |
-| Test.java:68:38:68:73 | getProperty(...) | Test.java:68:38:68:73 | getProperty(...) : String | Test.java:71:21:71:41 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:68:38:68:73 | getProperty(...) | system temp directory |
-| Test.java:75:38:75:73 | getProperty(...) | Test.java:75:38:75:73 | getProperty(...) : String | Test.java:76:33:76:53 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:75:38:75:73 | getProperty(...) | system temp directory |
-| Test.java:80:38:80:73 | getProperty(...) | Test.java:80:38:80:73 | getProperty(...) : String | Test.java:81:31:81:51 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:80:38:80:73 | getProperty(...) | system temp directory |
-| Test.java:85:38:85:73 | getProperty(...) | Test.java:85:38:85:73 | getProperty(...) : String | Test.java:86:26:86:46 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:85:38:85:73 | getProperty(...) | system temp directory |
-| Test.java:99:38:99:73 | getProperty(...) | Test.java:99:38:99:73 | getProperty(...) : String | Test.java:100:31:100:51 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:99:38:99:73 | getProperty(...) | system temp directory |
-| Test.java:104:38:104:73 | getProperty(...) | Test.java:104:38:104:73 | getProperty(...) : String | Test.java:105:33:105:53 | toPath(...) | Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users. | Test.java:104:38:104:73 | getProperty(...) | 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: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: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: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 |
From 1f47ea51640a602e4b05351428c683f07d2c282d Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Fri, 4 Feb 2022 17:16:12 -0500
Subject: [PATCH 26/39] Update to new change note format
---
...021-02-25-local-temp-directory-information-disclosure.md | 4 ----
...4-local-temp-file-or-directory-information-disclosure.md | 6 ++++++
2 files changed, 6 insertions(+), 4 deletions(-)
delete mode 100644 java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md
create mode 100644 java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md
diff --git a/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md b/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md
deleted file mode 100644
index 46654b8f14d8..000000000000
--- a/java/old-change-notes/2021-02-25-local-temp-directory-information-disclosure.md
+++ /dev/null
@@ -1,4 +0,0 @@
-lgtm,codescanning
-* Two new queries, both titled "Temporary directory Local information disclosure"
- (`java/local-temp-file-or-directory-information-disclosure-path`, `java/local-temp-file-or-directory-information-disclosure-method`), has been added.
- These queries find uses of APIs that leak potentially sensitive information to other local users via the system temporary directory.
diff --git a/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md b/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md
new file mode 100644
index 000000000000..9206d2b60ea4
--- /dev/null
+++ b/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md
@@ -0,0 +1,6 @@
+---
+category: newQuery
+---
+* Two new querys both titled "Temporary directory Local information disclosure" (`java/local-temp-file-or-directory-information-disclosure-path`, `java/local-temp-file-or-directory-information-disclosure-method`) have been added.
+ These queries find uses of APIs that leak potentially sensitive information to other local users via the system temporary directory.
+ This query was originally [submitted as query by @JLLeitschuh](https://github.com/github/codeql/pull/4388).
\ No newline at end of file
From de38638db61ec4dae3c64913497e9c36ae491fd0 Mon Sep 17 00:00:00 2001
From: Chris Smowton
Date: Mon, 7 Feb 2022 12:36:30 +0000
Subject: [PATCH 27/39] Combine CWE-200 queries
---
...> TempDirLocalInformationDisclosure.qhelp} | 6 +-
.../TempDirLocalInformationDisclosure.ql | 162 ++++++++++++++++++
...lInformationDisclosureFromMethodCall.qhelp | 5 -
...ormationDisclosureFromSystemProperty.qhelp | 5 -
...empDirLocalInformationDisclosure.expected} | 12 ++
.../TempDirLocalInformationDisclosure.qlref | 1 +
...lInformationDisclosureFromMethodCall.qlref | 1 -
...ormationDisclosureFromSystemProperty.qlref | 1 -
8 files changed, 178 insertions(+), 15 deletions(-)
rename java/ql/src/Security/CWE/CWE-200/{TempDirLocalInformationDisclosure.inc.qhelp => TempDirLocalInformationDisclosure.qhelp} (98%)
create mode 100644 java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
delete mode 100644 java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.qhelp
delete mode 100644 java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.qhelp
rename java/ql/test/query-tests/security/CWE-200/semmle/tests/{TempDirLocalInformationDisclosureFromSystemProperty.expected => TempDirLocalInformationDisclosure.expected} (86%)
create mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.qlref
delete mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.qlref
delete mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromSystemProperty.qlref
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 22a4dd1427b1..f61c9b479919 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 000000000000..7464d85a1a4f
--- /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 56b902d84d4a..000000000000
--- 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 56b902d84d4a..000000000000
--- 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 aa4bc32d8d90..505dcf666caa 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 000000000000..e678a2426e75
--- /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 9c785f79c55e..000000000000
--- 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 9c3119da5d2f..000000000000
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromSystemProperty.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
From c4112e6d4ce043ab424205749996ea6bc1448503 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Mon, 7 Feb 2022 15:02:13 -0500
Subject: [PATCH 28/39] Post refactor fixiup
---
.../TempDirLocalInformationDisclosure.ql | 78 ++++++++---
...ocalInformationDisclosureFromMethodCall.ql | 68 ----------
...InformationDisclosureFromSystemProperty.ql | 126 ------------------
...formationDisclosureFromMethodCall.expected | 3 -
4 files changed, 62 insertions(+), 213 deletions(-)
delete mode 100644 java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
delete mode 100644 java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
delete mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
index 7464d85a1a4f..b8cc75d37c79 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
@@ -16,15 +16,16 @@ import DataFlow::PathGraph
private class MethodFileSystemFileCreation extends Method {
MethodFileSystemFileCreation() {
- getDeclaringType() instanceof TypeFile and
- hasName(["mkdir", "mkdirs", "createNewFile"])
+ this.getDeclaringType() instanceof TypeFile and
+ this.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.
+ * The qualifier of a call to one of `File`'s file-creating or directory-creating methods,
+ * treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
*/
private class FileFileCreationSink extends FileCreationSink {
FileFileCreationSink() {
@@ -36,7 +37,8 @@ private class FileFileCreationSink extends FileCreationSink {
}
/**
- * Sink for if tained File/Path having some `Files` method called on it that creates a file or directory.
+ * The argument to a call to one of `Files` file-creating or directory-creating methods,
+ * treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
*/
private class FilesFileCreationSink extends FileCreationSink {
FilesFileCreationSink() {
@@ -45,8 +47,8 @@ private class FilesFileCreationSink extends FileCreationSink {
}
/**
- * Captures all of the vulnerable methods on `Files` that create files/directories without explicitly
- * setting the permissions.
+ * A call to a `Files` method that create files/directories without explicitly
+ * setting the newly-created file or directory's permissions.
*/
private class FilesVulnerableCreationMethodAccess extends MethodAccess {
FilesVulnerableCreationMethodAccess() {
@@ -57,13 +59,34 @@ private class FilesVulnerableCreationMethodAccess extends MethodAccess {
m.hasName(["write", "newBufferedWriter", "newOutputStream"])
or
m.hasName(["createFile", "createDirectory", "createDirectories"]) and
- getNumArgument() = 1
+ this.getNumArgument() = 1
+ or
+ m.hasName("newByteChannel") and
+ this.getNumArgument() = 2
)
}
}
/**
- * A call to `java.io.File::createTempFile` where the the system temp dir sinks to the last argument.
+ * A call to a `File` method that create files/directories with a specific set of permissions explicitly set.
+ * We can safely assume that any calls to these methods with explicit `PosixFilePermissions.asFileAttribute`
+ * contains a certain level of intentionality behind it.
+ */
+private class FilesSanitiznignCreationMethodAccess extends MethodAccess {
+ FilesSanitiznignCreationMethodAccess() {
+ exists(Method m |
+ m = this.getMethod() and
+ m.getDeclaringType().hasQualifiedName("java.nio.file", "Files")
+ |
+ m.hasName(["createFile", "createDirectory", "createDirectories"]) and
+ this.getNumArgument() = 2
+ )
+ }
+}
+
+/**
+ * The temp directory argument to a call to `java.io.File::createTempFile`,
+ * treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
*/
private class FileCreateTempFileSink extends FileCreationSink {
FileCreateTempFileSink() {
@@ -80,37 +103,57 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
source.asExpr() instanceof MethodAccessSystemGetPropertyTempDirTainted
}
+ /**
+ * Find dataflow from the temp directory system property to the `File` constructor.
+ * Examples:
+ * - `new File(System.getProperty("java.io.tmpdir"))`
+ * - `new File(new File(System.getProperty("java.io.tmpdir")), "/child")`
+ */
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalFileTaintStep(node1, node2)
}
override predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink }
+
+ override predicate isSanitizer(DataFlow::Node sanitizer) {
+ exists(FilesSanitiznignCreationMethodAccess sanitisingMethodAccess |
+ sanitizer.asExpr() = sanitisingMethodAccess.getArgument(0)
+ )
+ }
}
+// Below this, configuration for tracking single-method calls that are vulnerable.
+/**
+ * A MethodAccess against a method that creates a temporary file or directory in a shared temporary directory.
+ */
abstract class MethodAccessInsecureFileCreation extends MethodAccess {
/**
- * Docstring describing the file system type (ie. file, directory, etc...) returned.
+ * Gets the type of entity created (e.g. `file`, `directory`, ...).
*/
- abstract string getFileSystemType();
+ abstract string getFileSystemEntityType();
}
/**
- * Insecure calls to `java.io.File::createTempFile`.
+ * An insecure call to `java.io.File.createTempFile`.
*/
class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCreation {
MethodAccessInsecureFileCreateTempFile() {
this.getMethod() instanceof MethodFileCreateTempFile and
(
+ // `File.createTempFile(string, string)` always uses the default temporary directory
this.getNumArgument() = 2
or
- // Vulnerablilty exists when the last argument is `null`
- getArgument(2) instanceof NullLiteral
+ // The default temporary directory is used when the last argument of `File.createTempFile(string, string, File)` is `null`
+ DataFlow::localExprFlow(any(NullLiteral n), getArgument(2))
)
}
- override string getFileSystemType() { result = "file" }
+ override string getFileSystemEntityType() { result = "file" }
}
+/**
+ * The `com.google.common.io.Files.createTempDir` method.
+ */
class MethodGuavaFilesCreateTempFile extends Method {
MethodGuavaFilesCreateTempFile() {
getDeclaringType().hasQualifiedName("com.google.common.io", "Files") and
@@ -118,12 +161,15 @@ class MethodGuavaFilesCreateTempFile extends Method {
}
}
+/**
+ * A call to the `com.google.common.io.Files.createTempDir` method.
+ */
class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureFileCreation {
MethodAccessInsecureGuavaFilesCreateTempFile() {
getMethod() instanceof MethodGuavaFilesCreateTempFile
}
- override string getFileSystemType() { result = "directory" }
+ override string getFileSystemEntityType() { result = "directory" }
}
/**
@@ -157,6 +203,6 @@ where
// 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() +
+ source.getNode().asExpr().(MethodAccessInsecureFileCreation).getFileSystemEntityType() +
" 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.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
deleted file mode 100644
index 1b291ee7d3f2..000000000000
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @name Temporary directory local information disclosure (file creation via inherently insecure method)
- * @description Creating a temporary file in the system shared temporary directory, using a method that always creates it world-readable, may disclose its contents to other users.
- * @kind problem
- * @problem.severity warning
- * @precision very-high
- * @id java/local-temp-file-or-directory-information-disclosure-insecure-method
- * @tags security
- * external/cwe/cwe-200
- * external/cwe/cwe-732
- */
-
-import java
-import TempDirUtils
-
-/**
- * A MethodAccess against a method that creates a temporary file or directory in a shared temporary directory.
- */
-abstract class MethodAccessInsecureFileCreation extends MethodAccess {
- /**
- * Gets the type of entity created (e.g. `file`, `directory`, ...).
- */
- abstract string getFileSystemEntityType();
-}
-
-/**
- * An insecure call to `java.io.File.createTempFile`.
- */
-class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCreation {
- MethodAccessInsecureFileCreateTempFile() {
- this.getMethod() instanceof MethodFileCreateTempFile and
- (
- // `File.createTempFile(string, string)` always uses the default temporary directory
- this.getNumArgument() = 2
- or
- // The default temporary directory is used when the last argument of `File.createTempFile(string, string, File)` is `null`
- DataFlow::localExprFlow(any(NullLiteral n), getArgument(2))
- )
- }
-
- override string getFileSystemEntityType() { result = "file" }
-}
-
-/**
- * The `com.google.common.io.Files.createTempDir` method.
- */
-class MethodGuavaFilesCreateTempFile extends Method {
- MethodGuavaFilesCreateTempFile() {
- getDeclaringType().hasQualifiedName("com.google.common.io", "Files") and
- hasName("createTempDir")
- }
-}
-
-/**
- * A call to the `com.google.common.io.Files.createTempDir` method.
- */
-class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureFileCreation {
- MethodAccessInsecureGuavaFilesCreateTempFile() {
- getMethod() instanceof MethodGuavaFilesCreateTempFile
- }
-
- override string getFileSystemEntityType() { result = "directory" }
-}
-
-from MethodAccessInsecureFileCreation methodAccess
-select methodAccess,
- "Local information disclosure vulnerability due to use of " +
- methodAccess.getFileSystemEntityType() + " readable by other local users."
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
deleted file mode 100644
index c895ff9d6adc..000000000000
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * @name Temporary directory local information disclosure (file creation without explicit mode)
- * @description Creating a temporary file in the system shared temporary directory without specifying explicit access rights (mode) may disclose its contents to other users.
- * @kind path-problem
- * @problem.severity warning
- * @precision very-high
- * @id java/local-temp-file-or-directory-information-disclosure-missing-mode
- * @tags security
- * external/cwe/cwe-200
- * external/cwe/cwe-732
- */
-
-import java
-import TempDirUtils
-import DataFlow::PathGraph
-
-private class MethodFileSystemFileCreation extends Method {
- MethodFileSystemFileCreation() {
- this.getDeclaringType() instanceof TypeFile and
- this.hasName(["mkdir", "mkdirs", "createNewFile"])
- }
-}
-
-abstract private class FileCreationSink extends DataFlow::Node { }
-
-/**
- * The qualifier of a call to one of `File`'s file-creating or directory-creating methods, treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
- */
-private class FileFileCreationSink extends FileCreationSink {
- FileFileCreationSink() {
- exists(MethodAccess ma |
- ma.getMethod() instanceof MethodFileSystemFileCreation and
- ma.getQualifier() = this.asExpr()
- )
- }
-}
-
-/**
- * The argument to
- * a call to one of `Files` file-creating or directory-creating methods, treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
- */
-private class FilesFileCreationSink extends FileCreationSink {
- FilesFileCreationSink() {
- exists(FilesVulnerableCreationMethodAccess ma | ma.getArgument(0) = this.asExpr())
- }
-}
-
-/**
- * A call to a `Files` method that create files/directories without explicitly
- * setting the newly-created file or directory's 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
- this.getNumArgument() = 1
- or
- m.hasName("newByteChannel") and
- this.getNumArgument() = 2
- )
- }
-}
-
-/**
- * A call to a `File` method that create files/directories with a specific set of permissions explicitly set.
- * We can safely assume that any calls to these methods with explicit `PosixFilePermissions.asFileAttribute` contains a certain level of intentionality behind it.
- */
-private class FilesSanitiznignCreationMethodAccess extends MethodAccess {
- FilesSanitiznignCreationMethodAccess() {
- exists(Method m |
- m = this.getMethod() and
- m.getDeclaringType().hasQualifiedName("java.nio.file", "Files")
- |
- m.hasName(["createFile", "createDirectory", "createDirectories"]) and
- this.getNumArgument() = 2
- )
- }
-}
-
-/**
- * The temp directory argument to a call to `java.io.File::createTempFile`, treated as a sink by `TempDirSystemGetPropertyToCreateConfig`.
- */
-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
- }
-
- /**
- * Find dataflow from the temp directory system property to the `File` constructor.
- * Examples:
- * - `new File(System.getProperty("java.io.tmpdir"))`
- * - `new File(new File(System.getProperty("java.io.tmpdir")), "/child")`
- */
- override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalFileTaintStep(node1, node2)
- }
-
- override predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink }
-
- override predicate isSanitizer(DataFlow::Node sanitizer) {
- exists(FilesSanitiznignCreationMethodAccess sanitisingMethodAccess |
- sanitizer.asExpr() = sanitisingMethodAccess.getArgument(0)
- )
- }
-}
-
-from DataFlow::PathNode source, DataFlow::PathNode sink, TempDirSystemGetPropertyToCreateConfig conf
-where conf.hasFlowPath(source, sink)
-select sink.getNode(), source, sink,
- "Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users.",
- source.getNode(), "system temp directory"
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected
deleted file mode 100644
index 35f5487ad8c0..000000000000
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosureFromMethodCall.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-| Test.java:18:25:18:61 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. |
-| Test.java:26:25:26:67 | createTempFile(...) | Local information disclosure vulnerability due to use of file readable by other local users. |
-| Test.java:95:24:95:65 | createTempDir(...) | Local information disclosure vulnerability due to use of directory readable by other local users. |
From 79654592d92a5d9532b60affb3f41e1df0485383 Mon Sep 17 00:00:00 2001
From: Chris Smowton
Date: Tue, 8 Feb 2022 10:23:46 +0000
Subject: [PATCH 29/39] Apply suggestions from code review
---
.../TempDirLocalInformationDisclosure.ql | 17 ++++++++++-------
...-file-or-directory-information-disclosure.md | 4 ++--
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
index b8cc75d37c79..29664ed0ae9b 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
@@ -72,8 +72,8 @@ private class FilesVulnerableCreationMethodAccess extends MethodAccess {
* We can safely assume that any calls to these methods with explicit `PosixFilePermissions.asFileAttribute`
* contains a certain level of intentionality behind it.
*/
-private class FilesSanitiznignCreationMethodAccess extends MethodAccess {
- FilesSanitiznignCreationMethodAccess() {
+private class FilesSanitizingCreationMethodAccess extends MethodAccess {
+ FilesSanitizingCreationMethodAccess() {
exists(Method m |
m = this.getMethod() and
m.getDeclaringType().hasQualifiedName("java.nio.file", "Files")
@@ -116,15 +116,18 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
override predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink }
override predicate isSanitizer(DataFlow::Node sanitizer) {
- exists(FilesSanitiznignCreationMethodAccess sanitisingMethodAccess |
+ exists(FilesSanitizingCreationMethodAccess sanitisingMethodAccess |
sanitizer.asExpr() = sanitisingMethodAccess.getArgument(0)
)
}
}
-// Below this, configuration for tracking single-method calls that are vulnerable.
+//
+// Begin configuration for tracking single-method calls that are vulnerable.
+//
+
/**
- * A MethodAccess against a method that creates a temporary file or directory in a shared temporary directory.
+ * A `MethodAccess` against a method that creates a temporary file or directory in a shared temporary directory.
*/
abstract class MethodAccessInsecureFileCreation extends MethodAccess {
/**
@@ -174,7 +177,7 @@ class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureF
/**
* 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
+ * 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
@@ -182,7 +185,7 @@ class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureF
* path-flow results.
*/
class InsecureMethodPseudoConfiguration extends DataFlow::Configuration {
- InsecureMethodPseudoConfiguration() { this = "InsecureMethodPseudoConfiguration " }
+ InsecureMethodPseudoConfiguration() { this = "InsecureMethodPseudoConfiguration" }
override predicate isSource(DataFlow::Node node) {
node.asExpr() instanceof MethodAccessInsecureFileCreation
diff --git a/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md b/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md
index 9206d2b60ea4..8112470d2b3e 100644
--- a/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md
+++ b/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md
@@ -1,6 +1,6 @@
---
category: newQuery
---
-* Two new querys both titled "Temporary directory Local information disclosure" (`java/local-temp-file-or-directory-information-disclosure-path`, `java/local-temp-file-or-directory-information-disclosure-method`) have been added.
- These queries find uses of APIs that leak potentially sensitive information to other local users via the system temporary directory.
+* A new query titled "Temporary directory Local information disclosure" (`java/local-temp-file-or-directory-information-disclosure`) has been added.
+ This query finds uses of APIs that leak potentially sensitive information to other local users via the system temporary directory.
This query was originally [submitted as query by @JLLeitschuh](https://github.com/github/codeql/pull/4388).
\ No newline at end of file
From a6596ea7ce6539809f5b72526abbcbb4b33bbc7e Mon Sep 17 00:00:00 2001
From: Chris Smowton
Date: Tue, 8 Feb 2022 12:01:32 +0000
Subject: [PATCH 30/39] Fix test requirements, formatting
---
.../CWE/CWE-200/TempDirLocalInformationDisclosure.ql | 1 -
.../semmle/tests/TempDirLocalInformationDisclosure.expected | 6 ------
2 files changed, 7 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
index 29664ed0ae9b..be14d44b5766 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
@@ -125,7 +125,6 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
//
// Begin configuration for tracking single-method calls that are vulnerable.
//
-
/**
* A `MethodAccess` against a method that creates a temporary file or directory in a shared temporary directory.
*/
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected
index 505dcf666caa..48e09b70f3c3 100644
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected
@@ -36,11 +36,9 @@ 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 |
@@ -94,12 +92,10 @@ 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 |
@@ -127,9 +123,7 @@ subpaths
| 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 |
From 7f466401762f8ec2884246fe7f5913ff29a9030a Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Tue, 8 Feb 2022 17:57:10 -0500
Subject: [PATCH 31/39] Consider calls to setReadable(false, false) then
setReadable(true, true) to be safe
---
.../TempDirLocalInformationDisclosure.ql | 23 +++++----
.../src/Security/CWE/CWE-200/TempDirUtils.qll | 51 ++++++++++++++++++-
.../security/CWE-200/semmle/tests/Test.java | 6 +++
3 files changed, 68 insertions(+), 12 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
index be14d44b5766..7d0a7ecca3e0 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
@@ -197,14 +197,17 @@ class InsecureMethodPseudoConfiguration extends DataFlow::Configuration {
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).getFileSystemEntityType() +
- " readable by other local users."
+ (
+ 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).getFileSystemEntityType() +
+ " readable by other local users."
+ ) and
+ not isPermissionsProtectedTempDirUse(sink.getNode())
select source.getNode(), source, sink, message, source.getNode(), "system temp directory"
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index 0613006f71f9..c6df9549dc65 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -59,8 +59,8 @@ private predicate isFileConstructorArgument(Expr expSource, Expr exprDest) {
*/
private class TaintFollowingFileMethod extends Method {
TaintFollowingFileMethod() {
- getDeclaringType() instanceof TypeFile and
- hasName(["getAbsoluteFile", "getCanonicalFile"])
+ this.getDeclaringType() instanceof TypeFile and
+ this.hasName(["getAbsoluteFile", "getCanonicalFile"])
}
}
@@ -80,3 +80,50 @@ predicate isAdditionalFileTaintStep(DataFlow::Node node1, DataFlow::Node node2)
isFileConstructorArgument(node1.asExpr(), node2.asExpr()) or
isTaintPropagatingFileTransformation(node1.asExpr(), node2.asExpr())
}
+
+/**
+ * A method call to `java.io.File::setReadable`.
+ */
+private class FileSetRedableMethodAccess extends MethodAccess {
+ FileSetRedableMethodAccess() {
+ exists(Method m | this.getMethod() = m |
+ m.getDeclaringType() instanceof TypeFile and
+ m.hasName("setReadable")
+ )
+ }
+
+ predicate isCallWithArguments(boolean arg1, boolean arg2) {
+ this.isCallWithArgument(0, arg1) and this.isCallToSecondArgumentWithValue(arg2)
+ }
+
+ private predicate isCallToSecondArgumentWithValue(boolean value) {
+ this.getMethod().getNumberOfParameters() = 1 and value = true
+ or
+ isCallWithArgument(1, value)
+ }
+
+ private predicate isCallWithArgument(int index, boolean arg) {
+ DataFlow::localExprFlow(any(CompileTimeConstantExpr e | e.getBooleanValue() = arg),
+ this.getArgument(index))
+ }
+}
+
+/**
+ * Hold's if temporary directory's use is protected if there is an explicit call to
+ * `setReadable(false, false)`, then `setRedabale(true, true)`.
+ */
+predicate isPermissionsProtectedTempDirUse(DataFlow::Node sink) {
+ exists(FileSetRedableMethodAccess setReadable1, FileSetRedableMethodAccess setReadable2 |
+ setReadable1.isCallWithArguments(false, false) and
+ setReadable2.isCallWithArguments(true, true)
+ |
+ exists(DataFlow::Node setReadableNode1, DataFlow::Node setReadableNode2 |
+ setReadableNode1.asExpr() = setReadable1.getQualifier() and
+ setReadableNode2.asExpr() = setReadable2.getQualifier()
+ |
+ DataFlow::localFlow(sink, setReadableNode1) and // Flow from sink to setReadable(false, false)
+ DataFlow::localFlow(sink, setReadableNode2) and // Flow from sink to setReadable(true, true)
+ DataFlow::localFlow(setReadableNode1, setReadableNode2) // Flow from setReadable(false, false) to setReadable(true, true)
+ )
+ )
+}
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
index 44b8210e6584..fc1e9eb09048 100644
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
@@ -263,4 +263,10 @@ void vulnerableFileCreateDirectories() throws IOException {
// TO MAKE SAFE REWRITE TO:
Files.createDirectories(tempDirChild.toPath(), PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
}
+
+ void safeFileCreationWithPermissions() throws IOException {
+ File tempFile = File.createTempFile("temp", "file.txt");
+ tempFile.setReadable(false, false);
+ tempFile.setReadable(true, true);
+ }
}
From 787e3dac31c4d6fcf76354192328e3dee3a04148 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Wed, 9 Feb 2022 10:07:56 -0500
Subject: [PATCH 32/39] Update
java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
Co-authored-by: Chris Smowton
---
.../Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
index 7d0a7ecca3e0..60721dbf7f27 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
@@ -3,7 +3,7 @@
* @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
+ * @precision medium
* @id java/local-temp-file-or-directory-information-disclosure
* @tags security
* external/cwe/cwe-200
From 49a73673b64dd02e1581be5cbf13d5fbfc3ca330 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Wed, 9 Feb 2022 11:01:54 -0500
Subject: [PATCH 33/39] Fix FP from mkdirs call on exact temp directory
---
.../TempDirLocalInformationDisclosure.ql | 57 +++++++++++++++++--
.../src/Security/CWE/CWE-200/TempDirUtils.qll | 7 ++-
.../security/CWE-200/semmle/tests/Test.java | 10 ++++
3 files changed, 65 insertions(+), 9 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
index 60721dbf7f27..9a3fbfe55fbd 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
@@ -13,12 +13,18 @@
import java
import TempDirUtils
import DataFlow::PathGraph
+import semmle.code.java.dataflow.TaintTracking2
-private class MethodFileSystemFileCreation extends Method {
- MethodFileSystemFileCreation() {
- this.getDeclaringType() instanceof TypeFile and
- this.hasName(["mkdir", "mkdirs", "createNewFile"])
- }
+abstract private class MethodFileSystemFileCreation extends Method {
+ MethodFileSystemFileCreation() { this.getDeclaringType() instanceof TypeFile }
+}
+
+private class MethodFileDirectoryCreation extends MethodFileSystemFileCreation {
+ MethodFileDirectoryCreation() { this.hasName(["mkdir", "mkdirs"]) }
+}
+
+private class MethodFileFileCreation extends MethodFileSystemFileCreation {
+ MethodFileFileCreation() { this.hasName(["createNewFile"]) }
}
abstract private class FileCreationSink extends DataFlow::Node { }
@@ -113,7 +119,10 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
isAdditionalFileTaintStep(node1, node2)
}
- override predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink }
+ override predicate isSink(DataFlow::Node sink) {
+ sink instanceof FileCreationSink and
+ exists(TempDirSystemGetPropertyDirectlyToMkdirConfig config | not config.hasFlowTo(sink))
+ }
override predicate isSanitizer(DataFlow::Node sanitizer) {
exists(FilesSanitizingCreationMethodAccess sanitisingMethodAccess |
@@ -122,6 +131,42 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
}
}
+/**
+ * Configuration that tracks calls to to `mkdir` or `mkdirs` that are are directly on the temp directory system property.
+ * Examples:
+ * - `File tempDir = new File(System.getProperty("java.io.tmpdir")); tempDir.mkdir();`
+ * - `File tempDir = new File(System.getProperty("java.io.tmpdir")); tempDir.mkdirs();`
+ *
+ * These are examples of code that is simply verifying that the temp directory exists.
+ * As such, this code pattern is filtered out as an explicit vulnerability in
+ * `TempDirSystemGetPropertyToCreateConfig::isSink`.
+ */
+private class TempDirSystemGetPropertyDirectlyToMkdirConfig extends TaintTracking2::Configuration {
+ TempDirSystemGetPropertyDirectlyToMkdirConfig() {
+ this = "TempDirSystemGetPropertyDirectlyToMkdirConfig"
+ }
+
+ override predicate isSource(DataFlow::Node node) {
+ exists(
+ MethodAccessSystemGetPropertyTempDirTainted propertyGetMethodAccess, DataFlow::Node callSite
+ |
+ DataFlow::localFlow(DataFlow::exprNode(propertyGetMethodAccess), callSite)
+ |
+ isFileConstructorArgument(callSite.asExpr(), node.asExpr(), 1)
+ )
+ }
+
+ override predicate isSink(DataFlow::Node node) {
+ exists(MethodAccess ma | ma.getMethod() instanceof MethodFileDirectoryCreation |
+ ma.getQualifier() = node.asExpr()
+ )
+ }
+
+ override predicate isSanitizer(DataFlow::Node sanitizer) {
+ isFileConstructorArgument(sanitizer.asExpr(), _, _)
+ }
+}
+
//
// Begin configuration for tracking single-method calls that are vulnerable.
//
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index c6df9549dc65..0c2409c04084 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -46,11 +46,12 @@ class MethodFileCreateTempFile extends Method {
/**
* Holds if `expDest` is some constructor call `new java.io.File(x)` and `expSource` is `x`.
*/
-private predicate isFileConstructorArgument(Expr expSource, Expr exprDest) {
+predicate isFileConstructorArgument(Expr expSource, Expr exprDest, int paramCount) {
exists(ConstructorCall construtorCall |
construtorCall.getConstructedType() instanceof TypeFile and
construtorCall.getArgument(0) = expSource and
- construtorCall = exprDest
+ construtorCall = exprDest and
+ construtorCall.getConstructor().getNumberOfParameters() = paramCount
)
}
@@ -77,7 +78,7 @@ private predicate isTaintPropagatingFileTransformation(Expr expSource, Expr expr
* For example, `taintedFile.getCanonicalFile()` is itself tainted.
*/
predicate isAdditionalFileTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
- isFileConstructorArgument(node1.asExpr(), node2.asExpr()) or
+ isFileConstructorArgument(node1.asExpr(), node2.asExpr(), _) or
isTaintPropagatingFileTransformation(node1.asExpr(), node2.asExpr())
}
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
index fc1e9eb09048..b5b708692f1b 100644
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/Test.java
@@ -269,4 +269,14 @@ void safeFileCreationWithPermissions() throws IOException {
tempFile.setReadable(false, false);
tempFile.setReadable(true, true);
}
+
+ void notVulnerableCreateOnSystemPropertyDir() throws IOException {
+ File tempDir = new File(System.getProperty("java.io.tmpdir"));
+ tempDir.mkdir();
+ }
+
+ void notVulnerableCreateOnSystemPropertyDirs() throws IOException {
+ File tempDir = new File(System.getProperty("java.io.tmpdir"));
+ tempDir.mkdirs();
+ }
}
From bafcce17d43064db7995948c03c24ad4a981ff94 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Wed, 9 Feb 2022 22:14:17 -0500
Subject: [PATCH 34/39] Apply suggestions from code review
Co-authored-by: Chris Smowton
---
.../Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql | 2 +-
java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
index 9a3fbfe55fbd..b2649a079625 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
@@ -121,7 +121,7 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
override predicate isSink(DataFlow::Node sink) {
sink instanceof FileCreationSink and
- exists(TempDirSystemGetPropertyDirectlyToMkdirConfig config | not config.hasFlowTo(sink))
+ not any(TempDirSystemGetPropertyDirectlyToMkdirConfig config).hasFlowTo(sink)
}
override predicate isSanitizer(DataFlow::Node sanitizer) {
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
index 0c2409c04084..d2a2bcb5a6fb 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll
@@ -44,7 +44,7 @@ class MethodFileCreateTempFile extends Method {
}
/**
- * Holds if `expDest` is some constructor call `new java.io.File(x)` and `expSource` is `x`.
+ * Holds if `expDest` is some constructor call `new java.io.File(expSource)`, where the specific `File` constructor being used has `paramCount` parameters.
*/
predicate isFileConstructorArgument(Expr expSource, Expr exprDest, int paramCount) {
exists(ConstructorCall construtorCall |
From eee521e6cee2c649ad9f02d12e88c828b75ed901 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Thu, 10 Feb 2022 10:40:40 -0500
Subject: [PATCH 35/39] Fix test failure for TempDirLocalInformationDisclosure
---
.../semmle/tests/TempDirLocalInformationDisclosure.expected | 1 +
1 file changed, 1 insertion(+)
diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected
index 48e09b70f3c3..7c21c3667a3f 100644
--- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected
+++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure.expected
@@ -108,6 +108,7 @@ nodes
| Test.java:258:38:258:73 | getProperty(...) : String | semmle.label | getProperty(...) : String |
| Test.java:261:33:261:44 | tempDirChild : File | semmle.label | tempDirChild : File |
| Test.java:261:33:261:53 | toPath(...) | semmle.label | toPath(...) |
+| Test.java:268:25:268:63 | createTempFile(...) | semmle.label | createTempFile(...) |
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 |
From 7dee22a1302ae997d8d2ed62bb73c51ce4f1fb09 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Mon, 14 Feb 2022 11:00:41 -0500
Subject: [PATCH 36/39] Fix implicit 'this' usage
---
.../CWE/CWE-200/TempDirLocalInformationDisclosure.ql | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
index b2649a079625..c32a139f0f2d 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql
@@ -24,7 +24,7 @@ private class MethodFileDirectoryCreation extends MethodFileSystemFileCreation {
}
private class MethodFileFileCreation extends MethodFileSystemFileCreation {
- MethodFileFileCreation() { this.hasName(["createNewFile"]) }
+ MethodFileFileCreation() { this.hasName("createNewFile") }
}
abstract private class FileCreationSink extends DataFlow::Node { }
@@ -191,7 +191,7 @@ class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCre
this.getNumArgument() = 2
or
// The default temporary directory is used when the last argument of `File.createTempFile(string, string, File)` is `null`
- DataFlow::localExprFlow(any(NullLiteral n), getArgument(2))
+ DataFlow::localExprFlow(any(NullLiteral n), this.getArgument(2))
)
}
@@ -203,8 +203,8 @@ class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCre
*/
class MethodGuavaFilesCreateTempFile extends Method {
MethodGuavaFilesCreateTempFile() {
- getDeclaringType().hasQualifiedName("com.google.common.io", "Files") and
- hasName("createTempDir")
+ this.getDeclaringType().hasQualifiedName("com.google.common.io", "Files") and
+ this.hasName("createTempDir")
}
}
@@ -213,14 +213,14 @@ class MethodGuavaFilesCreateTempFile extends Method {
*/
class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureFileCreation {
MethodAccessInsecureGuavaFilesCreateTempFile() {
- getMethod() instanceof MethodGuavaFilesCreateTempFile
+ this.getMethod() instanceof MethodGuavaFilesCreateTempFile
}
override string getFileSystemEntityType() { result = "directory" }
}
/**
- * This is a hack: we include use of inherently insecure methods, which don't have any associated
+ * 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.
*
From bb580ddbab7da0a1bca46d4a2bbb1e3a6c6b79f6 Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Mon, 14 Feb 2022 11:02:05 -0500
Subject: [PATCH 37/39] Apply suggestions from code review
Co-authored-by: Felicity Chapman
---
.../CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp | 1 +
.../Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
index f61c9b479919..883186f46ea8 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.qhelp
@@ -22,6 +22,7 @@ can occur.
- java.nio.file.Files.createTempDirectory
- java.nio.file.Files.createTempFile
Otherwise, create the file/directory by manually specifying the expected posix file permissions.
For example: PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePerm
- OSWAP: Insecure Temporary File.
- - CERT: FIO00-J. Do not operate on files in shared directories
+ - CERT: FIO00-J. Do not operate on files in shared directories.
\ No newline at end of file
From 2048aed0a9dd5731ae9fd8eb4835b0bcfa0851ec Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh
Date: Mon, 14 Feb 2022 11:29:16 -0500
Subject: [PATCH 39/39] Review feedback and improve temp dir vulnerable/safe
code sugestion
---
.../CWE/CWE-200/TempDirUsageSafe.java | 87 ++++++++++++++++++-
.../CWE/CWE-200/TempDirUsageVulnerable.java | 4 +
...ile-or-directory-information-disclosure.md | 2 +-
3 files changed, 89 insertions(+), 4 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUsageSafe.java b/java/ql/src/Security/CWE/CWE-200/TempDirUsageSafe.java
index 96227d63d454..f44ead7accbe 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUsageSafe.java
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUsageSafe.java
@@ -1,3 +1,5 @@
+import java.io.File;
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
@@ -9,11 +11,90 @@ void exampleSafe() throws IOException {
Path temp2 = Files.createTempDirectory("random-directory"); // GOOD: File has permissions `drwx------`
- File tempDirChildFile = new File(System.getProperty("java.io.tmpdir"), "/child-create-file.txt");
+ // Creating a temporary file with a non-randomly generated name
+ File tempChildFile = new File(System.getProperty("java.io.tmpdir"), "/child-create-file.txt");
+ // Warning: This will fail on windows as it doesn't support PosixFilePermissions.
+ // See `exampleSafeWithWindowsSupportFile` if your code needs to support windows and unix-like systems.
Files.createFile(
- tempDirChildFile.toPath(),
- tempDirChild.toPath(),
+ tempChildFile.toPath(),
PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
); // GOOD: Good has permissions `-rw-------`
}
+
+ /*
+ * An example of a safe use of createFile or createDirectory if your code must support windows and unix-like systems.
+ */
+ void exampleSafeWithWindowsSupportFile() {
+ // Creating a temporary file with a non-randomly generated name
+ File tempChildFile = new File(System.getProperty("java.io.tmpdir"), "/child-create-file.txt");
+ createTempFile(tempChildFile.toPath()); // GOOD: Good has permissions `-rw-------`
+ }
+
+ static void createTempFile(Path tempDir) {
+ try {
+ if (tempDirChild.getFileSystem().supportedFileAttributeViews().contains("posix")) {
+ // Explicit permissions setting is only required on unix-like systems because
+ // the temporary directory is shared between all users.
+ // This is not necessary on Windows, each user has their own temp directory
+ final EnumSet posixFilePermissions =
+ EnumSet.of(
+ PosixFilePermission.OWNER_READ,
+ PosixFilePermission.OWNER_WRITE
+ );
+ if (!Files.exists(tempDirChild)) {
+ Files.createFile(
+ tempDirChild,
+ PosixFilePermissions.asFileAttribute(posixFilePermissions)
+ ); // GOOD: Directory has permissions `-rw-------`
+ } else {
+ Files.setPosixFilePermissions(
+ tempDirChild,
+ posixFilePermissions
+ ); // GOOD: Good has permissions `-rw-------`, or will throw an exception if this fails
+ }
+ } else if (!Files.exists(tempDirChild)) {
+ // On Windows, we still need to create the directory, when it doesn't already exist.
+ Files.createDirectory(tempDirChild); // GOOD: Windows doesn't share the temp directory between users
+ }
+ } catch (IOException exception) {
+ throw new UncheckedIOException("Failed to create temp file", exception);
+ }
+ }
+
+ void exampleSafeWithWindowsSupportDirectory() {
+ File tempDirChildDir = new File(System.getProperty("java.io.tmpdir"), "/child-dir");
+ createTempDirectories(tempDirChildDir.toPath()); // GOOD: Directory has permissions `drwx------`
+ }
+
+ static void createTempDirectories(Path tempDirChild) {
+ try {
+ if (tempDirChild.getFileSystem().supportedFileAttributeViews().contains("posix")) {
+ // Explicit permissions setting is only required on unix-like systems because
+ // the temporary directory is shared between all users.
+ // This is not necessary on Windows, each user has their own temp directory
+ final EnumSet posixFilePermissions =
+ EnumSet.of(
+ PosixFilePermission.OWNER_READ,
+ PosixFilePermission.OWNER_WRITE,
+ PosixFilePermission.OWNER_EXECUTE
+ );
+ if (!Files.exists(tempDirChild)) {
+ Files.createDirectories(
+ tempDirChild,
+ PosixFilePermissions.asFileAttribute(posixFilePermissions)
+ ); // GOOD: Directory has permissions `drwx------`
+ } else {
+ Files.setPosixFilePermissions(
+ tempDirChild,
+ posixFilePermissions
+ ); // GOOD: Good has permissions `drwx------`, or will throw an exception if this fails
+ }
+ } else if (!Files.exists(tempDirChild)) {
+ // On Windows, we still need to create the directory, when it doesn't already exist.
+ Files.createDirectories(tempDirChild); // GOOD: Windows doesn't share the temp directory between users
+ }
+ } catch (IOException exception) {
+ throw new UncheckedIOException("Failed to create temp dir", exception);
+ }
+ }
}
diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirUsageVulnerable.java b/java/ql/src/Security/CWE/CWE-200/TempDirUsageVulnerable.java
index a55226ad5b68..7d1d212409ea 100644
--- a/java/ql/src/Security/CWE/CWE-200/TempDirUsageVulnerable.java
+++ b/java/ql/src/Security/CWE/CWE-200/TempDirUsageVulnerable.java
@@ -15,5 +15,9 @@ void exampleVulnerable() {
File tempDirChildFile = new File(System.getProperty("java.io.tmpdir"), "/child-create-file.txt");
Files.createFile(tempDirChildFile.toPath()); // BAD: File has permissions `-rw-r--r--`
+
+ File tempDirChildDir = new File(System.getProperty("java.io.tmpdir"), "/child-dir");
+ tempDirChildDir.mkdir(); // BAD: Directory has permissions `drwxr-xr-x`
+ Files.createDirectory(tempDirChildDir.toPath()); // BAD: Directory has permissions `drwxr-xr-x`
}
}
diff --git a/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md b/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md
index 8112470d2b3e..23f3a476e793 100644
--- a/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md
+++ b/java/ql/src/change-notes/2022-02-04-local-temp-file-or-directory-information-disclosure.md
@@ -1,6 +1,6 @@
---
category: newQuery
---
-* A new query titled "Temporary directory Local information disclosure" (`java/local-temp-file-or-directory-information-disclosure`) has been added.
+* A new query titled "Local information disclosure in a temporary directory" (`java/local-temp-file-or-directory-information-disclosure`) has been added.
This query finds uses of APIs that leak potentially sensitive information to other local users via the system temporary directory.
This query was originally [submitted as query by @JLLeitschuh](https://github.com/github/codeql/pull/4388).
\ No newline at end of file