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
| Impact | Details |
|---|---|
| Confidentiality, Integrity | Scope: 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
-
MITRE Corporation. "CWE-277: Insecure Inherited Permissions." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/277.html
-
Linux man pages. "umask(2) - set file mode creation mask." https://man7.org/linux/man-pages/man2/umask.2.html
-
CERT C Secure Coding Standard. "FIO06-C. Create files with appropriate access permissions." https://wiki.sei.cmu.edu/confluence/display/c/FIO06-C