Creation of Temporary File With Insecure Permissions

Description

Creation of Temporary File With Insecure Permissions is a vulnerability that occurs when an application creates temporary files with permissions that allow unintended access by other users or processes. Many standard library functions for creating temporary files use default permissions that are too permissive, making the file readable or writable by all users on the system. This is particularly problematic in shared directories like /tmp on Unix systems or C:\Windows\Temp on Windows, where multiple users have access.

Risk

Temporary files with insecure permissions expose sensitive data to local attackers. Any data written to world-readable temporary files can be accessed by other users on the system. If the files are writable, attackers can modify the content, potentially leading to code execution if the application trusts the file content. Sensitive information such as session tokens, encryption keys, credentials, or user data may be exposed. In multi-user environments like shared servers, this vulnerability is particularly severe as any user can access another user's temporary files.

Solution

Use contemporary language functions that properly handle temporary file creation with restrictive permissions. Set file permissions to allow access only by the owning process (mode 0600 on Unix). Create temporary files in per-user directories rather than shared system directories. Use mkstemp() in C/C++ which creates files with mode 0600 by default. In Java, use Files.createTempFile() with explicit PosixFilePermission attributes. Verify permissions immediately after file creation. Consider using memory-based temporary storage for small amounts of sensitive data.

Common Consequences

ImpactDetails
ConfidentialityScope: Confidentiality

Attackers may read temporary files containing sensitive information.
IntegrityScope: Integrity

If writable by attackers, files could be modified to alter data structures and process ownership.
AuthorizationScope: Authorization

Modified files could be moved to gain unauthorized resource access.

Example Code

Vulnerable Code

// Vulnerable: tmpfile() creates files with insecure permissions
void vulnerable_tmpfile() {
    FILE *fp = tmpfile();  // May create file with 0666 permissions

    if (fp) {
        fprintf(fp, "Secret key: %s\n", secret_key);
        // Other users can read this!
        fclose(fp);
    }
}

// Vulnerable: Using open() with permissive mode
void vulnerable_open_temp() {
    char template[] = "/tmp/myapp.XXXXXX";
    int fd = mkstemp(template);

    if (fd >= 0) {
        // Vulnerable: Change permissions to world-readable
        chmod(template, 0644);  // Now anyone can read!
        write(fd, secret_data, strlen(secret_data));
        close(fd);
    }
}
// Vulnerable: File.createTempFile() has insecure default permissions
import java.io.*;

public class VulnerableTempPermissions {
    public void storeSecret(String secret) throws IOException {
        // Vulnerable: Creates with -rw-r--r-- (644) on Unix
        File temp = File.createTempFile("secret", ".tmp");

        try (PrintWriter writer = new PrintWriter(temp)) {
            writer.println(secret);  // Readable by all!
        }
    }

    public void storeInSharedDir(String data) throws IOException {
        // Vulnerable: Shared directory with default permissions
        File temp = new File("/tmp", "app_" + System.currentTimeMillis());
        temp.createNewFile();  // World-readable by default

        Files.writeString(temp.toPath(), data);
    }
}
# Vulnerable: os.open with permissive mode
import os
import tempfile

def vulnerable_temp_permissions():
    # Vulnerable: World-readable permissions
    fd = os.open('/tmp/myapp.tmp', os.O_CREAT | os.O_WRONLY, 0o644)
    os.write(fd, b"sensitive data")
    os.close(fd)

def vulnerable_named_temp():
    # Vulnerable: May have insecure default permissions
    with open('/tmp/secrets.txt', 'w') as f:
        f.write("password=secret123")
    # File created with umask, possibly world-readable

Fixed Code

// Fixed: mkstemp() with default secure permissions
void secure_temp_file() {
    char template[] = "/tmp/myapp.XXXXXX";
    int fd;

    // Fixed: mkstemp creates with mode 0600
    fd = mkstemp(template);
    if (fd < 0) {
        perror("mkstemp");
        return;
    }

    // Immediately unlink to hide from other processes
    unlink(template);

    write(fd, secret_data, strlen(secret_data));
    close(fd);
}

// Fixed: Explicit restrictive permissions
void secure_explicit_perms() {
    char template[] = "/tmp/myapp.XXXXXX";
    int fd;
    mode_t old_umask;

    // Fixed: Set restrictive umask
    old_umask = umask(0077);

    fd = mkstemp(template);

    // Restore original umask
    umask(old_umask);

    if (fd >= 0) {
        // Verify permissions are correct
        struct stat st;
        fstat(fd, &st);
        if ((st.st_mode & 0777) != 0600) {
            close(fd);
            unlink(template);
            return;  // Unexpected permissions
        }

        write(fd, secret_data, strlen(secret_data));
        close(fd);
    }
}
// Fixed: Files.createTempFile with explicit permissions
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.Set;

public class SecureTempPermissions {
    public void storeSecret(String secret) throws IOException {
        // Fixed: Explicitly set restrictive permissions
        Set<PosixFilePermission> perms =
            PosixFilePermissions.fromString("rw-------");
        FileAttribute<Set<PosixFilePermission>> attr =
            PosixFilePermissions.asFileAttribute(perms);

        Path temp = Files.createTempFile("secret", ".tmp", attr);

        try {
            Files.writeString(temp, secret);
        } finally {
            Files.deleteIfExists(temp);
        }
    }

    public void storeInSecureDir(String data) throws IOException {
        // Fixed: Create private directory first
        Path privateDir = Paths.get(System.getProperty("user.home"), ".myapp", "tmp");

        if (!Files.exists(privateDir)) {
            Set<PosixFilePermission> dirPerms =
                PosixFilePermissions.fromString("rwx------");
            Files.createDirectories(privateDir,
                PosixFilePermissions.asFileAttribute(dirPerms));
        }

        // Fixed: Create temp file in private directory
        Set<PosixFilePermission> filePerms =
            PosixFilePermissions.fromString("rw-------");
        Path temp = Files.createTempFile(privateDir, "app_", ".tmp",
            PosixFilePermissions.asFileAttribute(filePerms));

        Files.writeString(temp, data);
    }
}
# Fixed: Secure temporary file creation
import os
import tempfile
import stat

def secure_temp_permissions():
    # Fixed: Use os.open with restrictive permissions
    fd = os.open('/tmp/myapp.tmp',
                 os.O_CREAT | os.O_WRONLY | os.O_EXCL,
                 0o600)
    try:
        os.write(fd, b"sensitive data")
    finally:
        os.close(fd)

def secure_named_temp():
    # Fixed: tempfile.NamedTemporaryFile is secure by default
    with tempfile.NamedTemporaryFile(mode='w', delete=True) as f:
        f.write("password=secret123")
        # File created with mode 0600
        process_file(f.name)

def secure_mkstemp():
    # Fixed: mkstemp creates secure file
    fd, path = tempfile.mkstemp(suffix='.tmp', prefix='secure_')
    try:
        # Verify permissions
        mode = os.stat(path).st_mode
        assert (mode & 0o777) == 0o600, "Unexpected permissions"

        os.write(fd, b"sensitive data")
    finally:
        os.close(fd)
        os.unlink(path)

CVE Examples

  • CVE-2022-24823 — A network application framework's use of Java's createTempFile() created files readable by other local system users.

References

  1. MITRE Corporation. "CWE-378: Creation of Temporary File With Insecure Permissions." https://cwe.mitre.org/data/definitions/378.html
  2. OWASP. "Insecure Temporary File." https://owasp.org/www-community/vulnerabilities/Insecure_Temporary_File