CodeQL 文档

临时目录中的本地信息泄露

ID: java/local-temp-file-or-directory-information-disclosure
Kind: path-problem
Security severity: 6.5
Severity: warning
Precision: medium
Tags:
   - security
   - external/cwe/cwe-200
   - external/cwe/cwe-732
Query suites:
   - java-security-extended.qls
   - java-security-and-quality.qls

单击以查看 CodeQL 存储库中的查询

当文件/目录写入到系统上所有用户共享的目录中时,可能会发生本地信息泄露。

在大多数 类 Unix 系统上,系统临时目录在本地用户之间共享。如果在系统临时目录中创建文件/目录,而没有使用明确设置正确文件权限的 API,则可能会发生本地信息泄露。

根据公开的特定文件内容,此漏洞可能具有 CVSSv3.1 基本分数 6.2/10

建议

使用专门针对此漏洞提供保护的 JDK 方法

示例

在以下示例中,文件和目录创建时具有允许其他本地用户读取其内容的文件权限。

import java.io.File;

public class TempDirUsageVulnerable {
    void exampleVulnerable() {
        File temp1 = File.createTempFile("random", ".txt"); // BAD: File has permissions `-rw-r--r--`

        File temp2 = File.createTempFile("random", "file", null); // BAD: File has permissions `-rw-r--r--`

        File systemTempDir = new File(System.getProperty("java.io.tmpdir"));
        File temp3 = File.createTempFile("random", "file", systemTempDir); // BAD: File has permissions `-rw-r--r--`

        File tempDir = com.google.common.io.Files.createTempDir(); // BAD: CVE-2020-8908: Directory has permissions `drwxr-xr-x`

        new File(System.getProperty("java.io.tmpdir"), "/child").mkdir(); // BAD: Directory has permissions `-rw-r--r--`

        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`
    }
}

在以下示例中,文件和目录创建时具有保护其内容的文件权限。

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;

import java.util.EnumSet;


public class TempDirUsageSafe {
    void exampleSafe() throws IOException {
        Path temp1 = Files.createTempFile("random", ".txt"); // GOOD: File has permissions `-rw-------`

        Path temp2 = Files.createTempDirectory("random-directory"); // GOOD: File has permissions `drwx------`

        // 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(
            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 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<PosixFilePermission> 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<PosixFilePermission> 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);
        }
    }
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私