CVE-2021-21290 (Java, published 2021-02-08T20:15Z)
Description: value: Netty is an open-source, asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. In Netty before version 4.1.59.Final there is a vulnerability on Unix-like systems involving an insecure temp file. When netty's multipart decoders are used local information disclosure can occur via the local system temporary directory if temporary storing uploads on the disk is enabled. On unix-like systems, the temporary directory is shared between all user. As such, writing to this directory using APIs that do not explicitly set the file/directory permissions can lead to information disclosure. Of note, this does not impact modern MacOS Operating Systems. The method "File.createTempFile" on unix-like systems creates a random file, but, by default will create this file with the permissions "-rw-r--r--". Thus, if sensitive information is written to this file, other local users can read this information. This is the case in netty's "AbstractDiskHttpData" is vulnerable. This has been fixed in version 4.1.59.Final. As a workaround, one may specify your own "java.io.tmpdir" when you start the JVM or use "DefaultHttpDataFactory.setBaseDir(...)" to set the directory to something that is only readable by the current user.
Severity: LOW (CVSS v3 base score: 5.5)
Weakness: CWE-379 \u2014 Creation of Temporary File in Directory with Insecure Permissions
The product creates a temporary file in a directory whose permissions allow unintended actors to determine the file's existence or otherwise access that file.
Repository: https://github.com/netty/netty
Files changed:
buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java
buffer/src/test/java/io/netty/buffer/ReadOnlyDirectByteBufferBufTest.java
codec-http/src/main/java/io/netty/handler/codec/http/multipart/AbstractDiskHttpData.java
codec-http/src/test/java/io/netty/handler/codec/http/HttpChunkedInputTest.java
codec-http/src/test/java/io/netty/handler/codec/http/multipart/AbstractDiskHttpDataTest.java
codec-http/src/test/java/io/netty/handler/codec/http/multipart/AbstractMemoryHttpDataTest.java
codec-http/src/test/java/io/netty/handler/codec/http/multipart/DiskFileUploadTest.java
common/src/main/java/io/netty/util/internal/NativeLibraryLoader.java
common/src/main/java/io/netty/util/internal/PlatformDependent.java
handler/src/main/java/io/netty/handler/ssl/util/SelfSignedCertificate.java
handler/src/test/java/io/netty/handler/stream/ChunkedWriteHandlerTest.java
handler/src/test/java/io/netty/handler/traffic/FileRegionThrottleTest.java
testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketFileRegionTest.java
transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollSpliceTest.java
transport-native-unix-common-tests/src/main/java/io/netty/channel/unix/tests/UnixTestUtils.java
transport/src/test/java/io/netty/channel/DefaultFileRegionTest.java
Commit message: Use Files.createTempFile(...) to ensure the file is created with proper permissions

Motivation:

File.createTempFile(String, String)` will create a temporary file in the system temporary directory if the 'java.io.tmpdir'. The permissions on that file utilize the umask. In a majority of cases, this means that the file that java creates has the permissions: `-rw-r--r--`, thus, any other local user on that system can read the contents of that file.
This can be a security concern if any sensitive data is stored in this file.

This was reported by Jonathan Leitschuh <jonathan.leitschuh@gmail.com> as a security problem.

Modifications:

Use Files.createTempFile(...) which will use safe-defaults when running on java 7 and later. If running on java 6 there isnt much we can do, which is fair enough as java 6 shouldnt be considered "safe" anyway.

Result:

Create temporary files with sane permissions by default.


Vulnerable code:
        File file = File.createTempFile("file-channel", ".tmp");
        File file = File.createTempFile("file-channel", ".tmp");
        File file = File.createTempFile("netty-test", "tmp");
            tmpFile = File.createTempFile(getPrefix(), newpostfix);
            tmpFile = File.createTempFile(getPrefix(), newpostfix, new File(
            TMP = File.createTempFile("netty-chunk-", ".tmp");
            File tmpFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp");
            File tmpFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp");
            File tmpFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp");
            File tmpFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp");
            tmpFile = File.createTempFile(prefix, suffix, WORKDIR);
        File keyFile = File.createTempFile("keyutil_" + fqdn + '_', ".key");
        File certFile = File.createTempFile("keyutil_" + fqdn + '_', ".crt");
            TMP = File.createTempFile("netty-chunk-", ".tmp");
        tmp = File.createTempFile("netty-traffic", ".tmp");
        File file = File.createTempFile("netty-", ".tmp");
        final File file = File.createTempFile("netty-", ".tmp");
        File file = File.createTempFile("netty-splice", null);
                file = File.createTempFile("NETTY", "UDS");
        File file = File.createTempFile("netty-", ".tmp");

Fixed code:
        File file = PlatformDependent.createTempFile("file-channel", ".tmp", null);
        File file = PlatformDependent.createTempFile("file-channel", ".tmp", null);
        File file = PlatformDependent.createTempFile("netty-test", "tmp", null);
import io.netty.util.internal.PlatformDependent;
            tmpFile = PlatformDependent.createTempFile(getPrefix(), newpostfix, null);
            tmpFile = PlatformDependent.createTempFile(getPrefix(), newpostfix, new File(
import io.netty.util.internal.PlatformDependent;
            TMP = PlatformDependent.createTempFile("netty-chunk-", ".tmp", null);
            File tmpFile = PlatformDependent.createTempFile(UUID.randomUUID().toString(), ".tmp", null);
            File tmpFile = PlatformDependent.createTempFile(UUID.randomUUID().toString(), ".tmp", null);
            File tmpFile = PlatformDependent.createTempFile(UUID.randomUUID().toString(), ".tmp", null);
            File tmpFile = PlatformDependent.createTempFile(UUID.randomUUID().toString(), ".tmp", null);
            tmpFile = PlatformDependent.createTempFile(prefix, suffix, WORKDIR);
import java.nio.file.Files;
    @SuppressJava6Requirement(reason = "Guarded by version check")
    public static File createTempFile(String prefix, String suffix, File directory) throws IOException {
        if (javaVersion() >= 7) {
            if (directory == null) {
                return Files.createTempFile(prefix, suffix).toFile();
            }
            return Files.createTempFile(directory.toPath(), prefix, suffix).toFile();
        }
        if (directory == null) {
            return File.createTempFile(prefix, suffix);
        }
        File file = File.createTempFile(prefix, suffix, directory);
        // Try to adjust the perms, if this fails there is not much else we can do...
        file.setReadable(false, false);
        file.setReadable(true, true);
        return file;
    }

import io.netty.util.internal.PlatformDependent;
import java.nio.file.Files;
        File keyFile = PlatformDependent.createTempFile("keyutil_" + fqdn + '_', ".key", null);
        File certFile = PlatformDependent.createTempFile("keyutil_" + fqdn + '_', ".crt", null);
import io.netty.util.internal.PlatformDependent;
            TMP = PlatformDependent.createTempFile("netty-chunk-", ".tmp", null);
import io.netty.util.internal.PlatformDependent;
        tmp = PlatformDependent.createTempFile("netty-traffic", ".tmp", null);
        File file = PlatformDependent.createTempFile("netty-", ".tmp", null);
        final File file = PlatformDependent.createTempFile("netty-", ".tmp", null);
import io.netty.util.internal.PlatformDependent;
        File file = PlatformDependent.createTempFile("netty-splice", null, null);
import io.netty.util.internal.PlatformDependent;
                file = PlatformDependent.createTempFile("NETTY", "UDS", null);
        File file = PlatformDependent.createTempFile("netty-", ".tmp", null);