Incorrect Permission Assignment for Critical Resource

Description

Incorrect Permission Assignment for Critical Resource occurs when a product specifies permissions for a security-critical resource in a way that allows that resource to be read or modified by unintended actors. Critical resources include configuration files, executables, encryption keys, credential stores, log files, and database files. When these resources have overly permissive access rights, attackers with limited access to a system can escalate privileges, steal credentials, modify application behavior, or access sensitive data. This is particularly dangerous for resources that execute with elevated privileges or contain sensitive information.

Risk

Incorrect permissions are consistently ranked in the CWE Top 25 Most Dangerous Software Weaknesses. CVE-2025-14979 in AirVPN Eddie for macOS exposes XPC services without proper access restriction, enabling privilege escalation to root without authentication. CVE-2025-2947 in IBM i allows remote privileged users to escalate to root through incorrect profile swapping. Kaspersky Security Center (CVSS 7.1) had poor permission management on shared configuration resources. Similar vulnerabilities affect Apache Hive, TeamViewer, and Siemens SIRIUS safety relays. Incorrect permissions often enable complete system compromise from low-privilege starting positions.

Solution

Apply the principle of least privilege—resources should only be accessible to actors that absolutely need them. Set restrictive default permissions for new files and directories. Use proper umask values. For sensitive files (credentials, keys, configs), restrict access to owner only (0600/0700). Audit permissions during deployment and regularly thereafter. Use file system ACLs for fine-grained control. Ensure installed software doesn't create world-writable files. Implement proper group membership for shared resources. Verify permissions after software updates.

Common Consequences

ImpactDetails
ConfidentialityScope: Information Disclosure

Sensitive files like credentials and encryption keys can be read by unauthorized users.
IntegrityScope: Configuration Tampering

Attackers can modify configuration files, executables, or other critical resources.
Access ControlScope: Privilege Escalation

Modifying privileged executables or services enables escalation to higher privilege levels.

Example Code + Solution Code

Vulnerable Code

# VULNERABLE: World-writable configuration file
import os

def create_config():
    config_path = '/etc/myapp/config.json'

    with open(config_path, 'w') as f:
        f.write(json.dumps(config_data))

    # World-readable and writable - anyone can modify!
    os.chmod(config_path, 0o666)

# VULNERABLE: Credentials file with wrong permissions
def save_credentials(username, password):
    cred_file = '/app/credentials.txt'

    with open(cred_file, 'w') as f:
        f.write(f"{username}:{password}")

    # Default umask may leave file readable by others
// VULNERABLE: Log file with sensitive data, wrong permissions
import java.io.File;
import java.io.FileWriter;

public class Logger {
    private File logFile;

    public Logger(String path) {
        this.logFile = new File(path);
        logFile.createNewFile();
        // No permission setting - inherits default (often 0644)
    }

    public void log(String message) {
        // May contain sensitive information readable by other users
        try (FileWriter writer = new FileWriter(logFile, true)) {
            writer.write(message + "\n");
        }
    }
}

// VULNERABLE: World-executable installation script
public void installPlugin(Path pluginPath) throws IOException {
    // Sets executable for everyone!
    Files.setPosixFilePermissions(pluginPath,
        PosixFilePermissions.fromString("rwxrwxrwx"));
}
# VULNERABLE: Installation script with wrong permissions
#!/bin/bash

# Creates world-writable directory
mkdir /var/myapp/data
chmod 777 /var/myapp/data

# Copies credentials with default permissions
cp credentials.conf /etc/myapp/credentials.conf

# Creates setuid binary with wrong ownership
cp myapp /usr/local/bin/myapp
chmod u+s /usr/local/bin/myapp  # Setuid but wrong owner!

Fixed Code

# SAFE: Restrictive permissions for configuration files
import os
import stat

def create_config_safe():
    config_path = '/etc/myapp/config.json'

    # Set restrictive umask before creating file
    old_umask = os.umask(0o077)

    try:
        with open(config_path, 'w') as f:
            f.write(json.dumps(config_data))
    finally:
        os.umask(old_umask)  # Restore original umask

    # Ensure owner-only access (0600)
    os.chmod(config_path, stat.S_IRUSR | stat.S_IWUSR)

    # Set proper ownership
    os.chown(config_path, uid=app_uid, gid=app_gid)

# SAFE: Credentials file with restrictive permissions
def save_credentials_safe(username, password):
    cred_file = '/app/credentials.txt'

    # Create file with restrictive permissions from the start
    fd = os.open(cred_file,
                 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
                 stat.S_IRUSR | stat.S_IWUSR)  # 0600

    try:
        with os.fdopen(fd, 'w') as f:
            f.write(f"{username}:{password}")
    except:
        os.close(fd)
        raise

    # Verify permissions
    current_mode = os.stat(cred_file).st_mode & 0o777
    if current_mode != 0o600:
        raise SecurityError(f"Credential file has wrong permissions: {oct(current_mode)}")
// SAFE: Log file with proper permissions
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermissions;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;

public class SecureLogger {
    private Path logPath;

    public SecureLogger(String path) throws IOException {
        this.logPath = Path.of(path);

        // Create with restrictive permissions
        Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");

        Files.createFile(logPath,
            PosixFilePermissions.asFileAttribute(perms));
    }

    public void log(String message) throws IOException {
        // Verify permissions haven't changed
        Set<PosixFilePermission> currentPerms = Files.getPosixFilePermissions(logPath);
        if (currentPerms.contains(PosixFilePermission.OTHERS_READ) ||
            currentPerms.contains(PosixFilePermission.GROUP_READ)) {
            throw new SecurityException("Log file permissions too permissive");
        }

        Files.writeString(logPath, message + "\n",
            StandardOpenOption.APPEND);
    }
}

// SAFE: Plugin installation with proper permissions
public void installPluginSafe(Path pluginPath, String owner) throws IOException {
    // Owner execute only
    Set<PosixFilePermission> perms = EnumSet.of(
        PosixFilePermission.OWNER_READ,
        PosixFilePermission.OWNER_EXECUTE
    );

    Files.setPosixFilePermissions(pluginPath, perms);

    // Set proper ownership
    UserPrincipalLookupService lookup = pluginPath.getFileSystem()
        .getUserPrincipalLookupService();
    UserPrincipal ownerPrincipal = lookup.lookupPrincipalByName(owner);
    Files.setOwner(pluginPath, ownerPrincipal);

    // Verify final state
    PosixFileAttributes attrs = Files.readAttributes(pluginPath,
        PosixFileAttributes.class);

    if (attrs.permissions().contains(PosixFilePermission.OTHERS_EXECUTE)) {
        throw new SecurityException("Plugin should not be world-executable");
    }
}
#!/bin/bash
# SAFE: Installation script with proper permissions

set -e  # Exit on error
umask 077  # Restrictive default permissions

# Create directory with proper permissions
install -d -m 0750 -o myapp -g myapp /var/myapp/data

# Copy credentials with restrictive permissions
install -m 0600 -o myapp -g myapp credentials.conf /etc/myapp/credentials.conf

# Verify permissions are correct
PERMS=$(stat -c %a /etc/myapp/credentials.conf)
if [ "$PERMS" != "600" ]; then
    echo "ERROR: Credential file has wrong permissions: $PERMS"
    exit 1
fi

# Install binary with correct ownership (no setuid unless absolutely necessary)
install -m 0755 -o root -g root myapp /usr/local/bin/myapp

# If setuid is truly required, document why and audit
# install -m 4755 -o root -g root myapp /usr/local/bin/myapp

echo "Installation complete with secure permissions"

Exploited in the Wild

AirVPN Eddie macOS Privilege Escalation (AirVPN, 2025)

CVE-2025-14979 in AirVPN Eddie for macOS exposes XPC services without proper access restrictions, enabling local attackers to escalate to root privileges without authentication, with full impact on confidentiality, integrity, and availability.

IBM i Privilege Escalation (IBM, 2025)

CVE-2025-2947 in IBM i 7.6 allows remote privileged users to escalate to root access through incorrect profile swapping during OS command execution.

Kaspersky Security Center (Kaspersky, 2025)

Kaspersky Security Center for Windows (CVSS 7.1) had incorrect permission management on shared configuration resources, allowing compromise of data integrity.


Tools to test/exploit


CVE Examples


References

  1. MITRE. "CWE-732: Incorrect Permission Assignment for Critical Resource." https://cwe.mitre.org/data/definitions/732.html

  2. OWASP. "Insecure Default Configuration." https://owasp.org/www-project-web-security-testing-guide/