Insecure Inherited Permissions

Description

Insecure Inherited Permissions is a vulnerability that occurs when a product defines a set of insecure permissions that are inherited by objects created by the program. When processes create files, directories, or other objects, these new objects typically inherit permissions based on the creating process's settings (such as umask on Unix systems) or parent object ACLs. If the creating process has an insecure permission inheritance configuration, all objects it creates will have overly permissive access controls, potentially exposing sensitive data or allowing unauthorized modification.

Risk

Insecure inherited permissions create systemic security weaknesses where every object created by an affected process has improper access controls. Unlike explicit permission errors on individual files, inherited permission issues affect all newly created objects until the root cause is addressed. Applications running with permissive umask settings create files that may be readable or writable by unintended users. Services that create temporary files, cache files, or user data with inherited weak permissions expose that data to local attackers. The risk is particularly acute for applications that create files containing sensitive information like session tokens, temporary credentials, or cached authentication data. Core dumps created with inherited weak permissions may expose memory contents including passwords and encryption keys.

Solution

Explicitly set restrictive permissions when creating security-sensitive objects rather than relying on inherited settings. Set a restrictive umask (e.g., 0077 or 0027) at the start of sensitive operations. Use file creation functions that accept explicit permission parameters (e.g., open() with mode, os.open() with mode, or CreateFile with security attributes). For directories that will contain sensitive content, set both the directory permissions and any applicable ACL inheritance rules. When inheriting permissions is unavoidable, verify inherited permissions match security requirements before storing sensitive data. On Windows, carefully configure ACL inheritance on parent containers. Audit application behavior to identify all file creation points and ensure each uses appropriate permissions.

Common Consequences

ImpactDetails
Confidentiality, IntegrityScope: Confidentiality, Integrity

Objects created with insecure inherited permissions may allow unauthorized reading of sensitive application data or unauthorized modification of critical files. Temporary files, cache files, logs, and user data created with weak permissions are exposed to local attackers.

Example Code

Vulnerable Code (C)

The following examples demonstrate insecure inherited permissions:

// Vulnerable: Uses inherited umask for temporary files
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

void vulnerable_create_temp_file(const char *sensitive_data) {
    // Process inherited a permissive umask (e.g., 0000 or 0022)
    // New file inherits these weak permissions

    // Vulnerable: File created with inherited (possibly weak) permissions
    FILE *tmp = fopen("/tmp/app_session_data.tmp", "w");
    if (tmp) {
        fprintf(tmp, "session_token=%s\n", sensitive_data);
        fclose(tmp);
    }
    // File may be world-readable!
}

// Vulnerable: Core dump permissions inherited from process
void vulnerable_core_dump_setup(void) {
    // Process running with permissive umask
    // Core dumps will inherit these permissions

    // Enable core dumps without considering permission inheritance
    struct rlimit limit;
    limit.rlim_cur = RLIM_INFINITY;
    limit.rlim_max = RLIM_INFINITY;
    setrlimit(RLIMIT_CORE, &limit);

    // If process crashes, core dump created with inherited permissions
    // May be world-readable, exposing memory contents
}
# Vulnerable: Python application with inherited permissive umask
import os
import tempfile

class VulnerableApplication:

    def create_cache_file(self, cache_data):
        # Inherits umask from parent process
        # If parent had umask 0000, files are world-readable

        # Vulnerable: tempfile inherits process umask
        cache_file = tempfile.NamedTemporaryFile(
            mode='w',
            prefix='app_cache_',
            delete=False
        )
        cache_file.write(cache_data)  # Sensitive data
        cache_file.close()
        # File permissions depend on inherited umask

    def create_user_directory(self, username):
        user_dir = f"/var/lib/myapp/users/{username}"

        # Vulnerable: Directory permissions inherited from umask
        os.makedirs(user_dir, exist_ok=True)
        # May be world-readable or world-executable

        # Files created in directory also inherit umask
        with open(f"{user_dir}/profile.json", 'w') as f:
            f.write(self.get_user_profile(username))
// Vulnerable: Java application relying on inherited permissions
import java.io.*;
import java.nio.file.*;

public class VulnerableFileCreation {

    public void saveUserSession(String userId, String sessionToken) throws IOException {
        // Vulnerable: File permissions inherited from system settings
        Path sessionFile = Paths.get("/tmp/sessions/" + userId + ".session");

        // Default file creation inherits process umask
        Files.write(sessionFile, sessionToken.getBytes());
        // File may be readable by other users
    }

    public void createTempDirectory() throws IOException {
        // Vulnerable: Directory inherits permissions
        Path tempDir = Files.createTempDirectory("app_temp");
        // Permissions depend on inherited settings
        // May allow other users to list contents
    }
}

Fixed Code (C)

// Fixed: Explicitly set restrictive permissions
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

void secure_create_temp_file(const char *sensitive_data) {
    // Save original umask and set restrictive one
    mode_t old_umask = umask(0077);

    // Better: Use open() with explicit permissions
    int fd = open("/tmp/app_session_data.tmp",
                  O_WRONLY | O_CREAT | O_TRUNC,
                  S_IRUSR | S_IWUSR);  // 0600 - owner read/write only

    if (fd >= 0) {
        dprintf(fd, "session_token=%s\n", sensitive_data);
        close(fd);
    }

    // Restore original umask
    umask(old_umask);
}

void secure_core_dump_setup(void) {
    // Set restrictive umask before enabling core dumps
    umask(0077);

    // Optionally, configure core dump directory with secure permissions
    // Or disable core dumps for sensitive processes
    struct rlimit limit;
    limit.rlim_cur = RLIM_INFINITY;
    limit.rlim_max = RLIM_INFINITY;
    setrlimit(RLIMIT_CORE, &limit);

    // On Linux, can also set core pattern permissions
    // echo "0600" > /proc/sys/fs/suid_dumpable
}

// Even better: Use library functions designed for secure temporary files
#include <stdlib.h>

void secure_temp_file_alternative(const char *sensitive_data) {
    char template[] = "/tmp/app_XXXXXX";
    mode_t old_umask = umask(0077);

    int fd = mkstemp(template);  // Creates with 0600 permissions

    if (fd >= 0) {
        dprintf(fd, "session_token=%s\n", sensitive_data);
        close(fd);
        unlink(template);  // Clean up after use
    }

    umask(old_umask);
}
# Fixed: Python application with explicit permissions
import os
import stat
import tempfile

class SecureApplication:

    def create_cache_file(self, cache_data):
        # Save and set restrictive umask
        old_umask = os.umask(0o077)

        try:
            # Create temp file with explicit restrictive permissions
            fd, cache_path = tempfile.mkstemp(prefix='app_cache_')
            try:
                os.write(fd, cache_data.encode())
            finally:
                os.close(fd)

            # Verify permissions
            file_stat = os.stat(cache_path)
            if file_stat.st_mode & 0o077:  # Check if others have any access
                os.chmod(cache_path, stat.S_IRUSR | stat.S_IWUSR)

            return cache_path
        finally:
            os.umask(old_umask)

    def create_user_directory(self, username):
        user_dir = f"/var/lib/myapp/users/{username}"

        # Create directory with explicit restrictive permissions
        os.makedirs(user_dir, mode=0o700, exist_ok=True)

        # Ensure permissions are correct even if directory existed
        os.chmod(user_dir, 0o700)

        # Create files with explicit permissions
        profile_path = f"{user_dir}/profile.json"
        fd = os.open(profile_path,
                     os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
                     0o600)
        try:
            os.write(fd, self.get_user_profile(username).encode())
        finally:
            os.close(fd)
// Fixed: Java application with explicit permissions
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.*;

public class SecureFileCreation {

    public void saveUserSession(String userId, String sessionToken) throws IOException {
        Path sessionFile = Paths.get("/tmp/sessions/" + userId + ".session");

        // Create parent directory with restrictive permissions if needed
        Path sessionDir = sessionFile.getParent();
        if (!Files.exists(sessionDir)) {
            Set<PosixFilePermission> dirPerms = PosixFilePermissions.fromString("rwx------");
            Files.createDirectories(sessionDir,
                PosixFilePermissions.asFileAttribute(dirPerms));
        }

        // Create file with explicit restrictive permissions
        Set<PosixFilePermission> filePerms = PosixFilePermissions.fromString("rw-------");
        Files.write(sessionFile, sessionToken.getBytes(),
            StandardOpenOption.CREATE,
            StandardOpenOption.TRUNCATE_EXISTING);

        // Set permissions explicitly after creation
        Files.setPosixFilePermissions(sessionFile, filePerms);
    }

    public Path createSecureTempDirectory() throws IOException {
        // Create temp directory with explicit permissions
        Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwx------");
        FileAttribute<Set<PosixFilePermission>> attr =
            PosixFilePermissions.asFileAttribute(perms);

        return Files.createTempDirectory("app_temp", attr);
    }
}

The fix explicitly sets restrictive permissions during object creation rather than relying on inherited settings.


Exploited in the Wild

Temporary File Exposure (Various Applications, Ongoing)

Applications creating temporary files with inherited permissive umask settings have exposed sensitive session data, credentials, and temporary authentication tokens. Local attackers monitor /tmp directories for newly created files with weak permissions.

Core Dump Credential Exposure (Unix Systems, Historical)

Core dumps created with inherited umask settings exposed process memory containing passwords and encryption keys. CVE-2002-1786 documented insecure umask settings for core dumps that allowed local credential theft.

User Data Exposure Through Umask (Unix Applications, Historical)

Applications running with user-controlled umask settings have created files with unexpected permissions. CVE-2005-1841 documented user's umask being incorrectly applied to temporary files created by privileged applications.


Tools to Test/Exploit

  • umask auditing scripts — Scripts that check process umask and file permission inheritance.

  • Inotify watchers — Tools to monitor file creation and check permissions of newly created files.

  • Lynis — Security auditing tool that checks for umask and permission inheritance issues.


CVE Examples

  • CVE-2005-1841 — User's umask applied when creating temporary files, exposing sensitive data.

  • CVE-2002-1786 — Insecure umask settings for core dumps exposed process memory.


References

  1. MITRE Corporation. "CWE-277: Insecure Inherited Permissions." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/277.html

  2. Linux man pages. "umask(2) - set file mode creation mask." https://man7.org/linux/man-pages/man2/umask.2.html

  3. CERT C Secure Coding Standard. "FIO06-C. Create files with appropriate access permissions." https://wiki.sei.cmu.edu/confluence/display/c/FIO06-C