Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 13fed0e

Browse files
committed
Temp Dir Info Disclosure: Final pass and add documentation
1 parent bc12e99 commit 13fed0e

15 files changed

Lines changed: 152 additions & 19 deletions
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Local information disclosure can occur when files/directories are written into
7+
directories that are shared between all users on the system.</p>
8+
9+
<p>On most <a href="https://en.wikipedia.org/wiki/Unix-like">unix-like</a> systems,
10+
the system temporary directory is shared between local users.
11+
If files/directories are created within the system temporary directory without using
12+
APIs that explicitly set the correct file permissions, local information disclosure
13+
can occur.</p>
14+
15+
<p>Depending upon the particular file contents exposed, this vulnerability can have a
16+
<a href="https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N&amp;version=3.1">CVSSv3.1 base score of 6.2/10</a>.</p>
17+
</overview>
18+
19+
<recommendation>
20+
<p>Use JDK methods that specifically protect against this vulnerability:</p>
21+
<ul>
22+
<li><a href="https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#createTempDirectory">java.nio.file.Files#createTempDirectory</a></li>
23+
<li><a href="https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#createTempFile">java.nio.file.Files#createTempFile</a></li>
24+
<ul>
25+
Otherwise, create the file/directory by manually specificfying the expected posix file permissions.
26+
Eg. <code>PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))</code>
27+
<ul>
28+
<li><a href="https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#createFile-java.nio.file.Path-java.nio.file.attribute.FileAttribute...-">java.nio.file.Files#createFile</a></li>
29+
<li><a href="https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#createDirectory-java.nio.file.Path-java.nio.file.attribute.FileAttribute...-">java.nio.file.Files#createDirectory</a></li>
30+
<li><a href="https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#createDirectories-java.nio.file.Path-java.nio.file.attribute.FileAttribute...-">java.nio.file.Files#createDirectories</a></li>
31+
</ul>
32+
</recommendation>
33+
34+
<example>
35+
<p>In the following example, files and directories are created with file permissions allowing other local users to read their contents.</p>
36+
37+
<sample src="TempDirUsageVulnerable.java"/>
38+
39+
<p>In the following example, files and directories are created with file permissions protecting their contents.</p>
40+
41+
<sample src="TempDirUsageSafe.java"/>
42+
43+
<references>
44+
<li>OSWAP: <a href="https://owasp.org/www-community/vulnerabilities/Insecure_Temporary_File">Insecure Temporary File</a>.</li>
45+
<li>CERT: <a href="https://wiki.sei.cmu.edu/confluence/display/java/FIO00-J.+Do+not+operate+on+files+in+shared+directories">FIO00-J. Do not operate on files in shared directories</a>
46+
</references>
47+
</qhelp>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<include src="TempDirLocalInformationDisclosure.qhelp" /></qhelp>

java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure1.ql renamed to java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromMethodCall.ql

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
* @kind problem
55
* @problem.severity warning
66
* @precision very-high
7-
* @id java/local-information-disclosure
7+
* @id java/local-temp-file-or-directory-information-disclosure-method
88
* @tags security
99
* external/cwe/cwe-200
10+
* external/cwe/cwe-732
1011
*/
1112

1213
import TempDirUtils
@@ -25,7 +26,7 @@ class TempDirSystemGetPropertyToAnyConfig extends TaintTracking::Configuration {
2526
TempDirSystemGetPropertyToAnyConfig() { this = "TempDirSystemGetPropertyToAnyConfig" }
2627

2728
override predicate isSource(DataFlow::Node source) {
28-
source.asExpr() instanceof MethodAccessSystemGetPropertyTempDir
29+
source.asExpr() instanceof MethodAccessSystemGetPropertyTempDirTainted
2930
}
3031

3132
override predicate isSink(DataFlow::Node source) { any() }
@@ -45,6 +46,7 @@ class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCre
4546
this.getMethod() instanceof MethodFileCreateTempFile and
4647
(
4748
this.getNumArgument() = 2 or
49+
// Vulnerablilty exists when the last argument is `null`
4850
getArgument(2) instanceof NullLiteral or
4951
// There exists a flow from the 'java.io.tmpdir' system property to this argument
5052
exists(TempDirSystemGetPropertyToAnyConfig config |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<include src="TempDirLocalInformationDisclosure.qhelp" /></qhelp>

java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure2.ql renamed to java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosureFromSystemProperty.ql

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
* @kind path-problem
55
* @problem.severity warning
66
* @precision very-high
7-
* @id java/local-information-disclosure
7+
* @id java/local-temp-file-or-directory-information-disclosure-path
88
* @tags security
99
* external/cwe/cwe-200
10+
* external/cwe/cwe-732
1011
*/
1112

1213
import TempDirUtils
@@ -24,6 +25,9 @@ private class MethodFileSystemFileCreation extends Method {
2425

2526
abstract private class FileCreationSink extends DataFlow::Node { }
2627

28+
/**
29+
* Sink for tainted `File` having a file or directory creation method called on it.
30+
*/
2731
private class FileFileCreationSink extends FileCreationSink {
2832
FileFileCreationSink() {
2933
exists(MethodAccess ma |
@@ -33,12 +37,19 @@ private class FileFileCreationSink extends FileCreationSink {
3337
}
3438
}
3539

40+
/**
41+
* Sink for if tained File/Path having some `Files` method called on it that creates a file or directory.
42+
*/
3643
private class FilesFileCreationSink extends FileCreationSink {
3744
FilesFileCreationSink() {
3845
exists(FilesVulnerableCreationMethodAccess ma | ma.getArgument(0) = this.asExpr())
3946
}
4047
}
4148

49+
/**
50+
* Captures all of the vulnerable methods on `Files` that create files/directories without explicitly
51+
* setting the permissions.
52+
*/
4253
private class FilesVulnerableCreationMethodAccess extends MethodAccess {
4354
FilesVulnerableCreationMethodAccess() {
4455
getMethod().getDeclaringType().hasQualifiedName("java.nio.file", "Files") and
@@ -54,7 +65,7 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
5465
TempDirSystemGetPropertyToCreateConfig() { this = "TempDirSystemGetPropertyToCreateConfig" }
5566

5667
override predicate isSource(DataFlow::Node source) {
57-
source.asExpr() instanceof MethodAccessSystemGetPropertyTempDir
68+
source.asExpr() instanceof MethodAccessSystemGetPropertyTempDirTainted
5869
}
5970

6071
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import java.nio.file.Files;
2+
import java.nio.file.attribute.PosixFilePermission;
3+
import java.nio.file.attribute.PosixFilePermissions;
4+
import java.util.EnumSet;
5+
6+
public class TempDirUsageSafe {
7+
void exampleSafe() throws IOException {
8+
Path temp1 = Files.createTempFile("random", ".txt"); // GOOD: File has permissions `-rw-------`
9+
10+
Path temp2 = Files.createTempDirectory("random-directory"); // GOOD: File has permissions `drwx------`
11+
12+
File tempDirChildFile = new File(System.getProperty("java.io.tmpdir"), "/child-create-file.txt");
13+
Files.createFile(
14+
tempDirChildFile.toPath(),
15+
tempDirChild.toPath(),
16+
PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))
17+
); // GOOD: Good has permissions `-rw-------`
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import java.io.File;
2+
3+
public class TempDirUsageVulnerable {
4+
void exampleVulnerable() {
5+
File temp1 = File.createTempFile("random", ".txt"); // BAD: File has permissions `-rw-r--r--`
6+
7+
File temp2 = File.createTempFile("random", "file", null); // BAD: File has permissions `-rw-r--r--`
8+
9+
File systemTempDir = new File(System.getProperty("java.io.tmpdir"));
10+
File temp3 = File.createTempFile("random", "file", systemTempDir); // BAD: File has permissions `-rw-r--r--`
11+
12+
File tempDir = com.google.common.io.Files.createTempDir(); // BAD: CVE-2020-8908: Directory has permissions `drwxr-xr-x`
13+
14+
new File(System.getProperty("java.io.tmpdir"), "/child").mkdir(); // BAD: Directory has permissions `-rw-r--r--`
15+
16+
File tempDirChildFile = new File(System.getProperty("java.io.tmpdir"), "/child-create-file.txt");
17+
Files.createFile(tempDirChildFile.toPath()); // BAD: File has permissions `-rw-r--r--`
18+
}
19+
}

java/ql/src/Security/CWE/CWE-200/TempDirUtils.qll

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,32 @@
11
import java
22
import semmle.code.java.dataflow.FlowSources
33

4-
class MethodAccessSystemGetPropertyTempDir extends MethodAccessSystemGetProperty {
5-
MethodAccessSystemGetPropertyTempDir() { this.hasCompileTimeConstantGetPropertyName("java.io.tmpdir") }
4+
/**
5+
* A method that returns a `String` or `File` that has been tainted by `System.getProperty("java.io.tmpdir")`.
6+
*/
7+
abstract class MethodAccessSystemGetPropertyTempDirTainted extends MethodAccess { }
8+
9+
/**
10+
* Method access `System.getProperty("java.io.tmpdir")`.
11+
*/
12+
private class MethodAccessSystemGetPropertyTempDir extends MethodAccessSystemGetPropertyTempDirTainted,
13+
MethodAccessSystemGetProperty {
14+
MethodAccessSystemGetPropertyTempDir() {
15+
this.hasCompileTimeConstantGetPropertyName("java.io.tmpdir")
16+
}
17+
}
18+
19+
/**
20+
* A method call to the `org.apache.commons.io.FileUtils` methods `getTempDirectory` or `getTempDirectoryPath`.
21+
*/
22+
private class MethodAccessApacheFileUtilsTempDir extends MethodAccessSystemGetPropertyTempDirTainted {
23+
MethodAccessApacheFileUtilsTempDir() {
24+
exists(Method m |
25+
m.getDeclaringType().hasQualifiedName("org.apache.commons.io", "FileUtils") and
26+
m.hasName(["getTempDirectory", "getTempDirectoryPath"]) and
27+
this.getMethod() = m
28+
)
29+
}
630
}
731

832
/**
@@ -20,7 +44,7 @@ private predicate isTaintedFileCreation(Expr expSource, Expr exprDest) {
2044
}
2145

2246
/**
23-
* Any `File` methods that
47+
* Any `File` methods that
2448
*/
2549
private class TaintFollowingFileMethod extends Method {
2650
TaintFollowingFileMethod() {

java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure1.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.

java/ql/test/query-tests/security/CWE-200/semmle/tests/TempDirLocalInformationDisclosure2.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)