Falsche ausführungszugewiesene Berechtigungen

Beschreibung

Falsche ausführungszugewiesene Berechtigungen ist eine Schwachstelle, die auftritt, wenn ein Produkt Objektberechtigungen während der Ausführung auf eine Weise setzt, die die beabsichtigten Spezifikationen des Benutzers verletzt. Anders als Berechtigungsfehler zur Installationszeit manifestiert sich diese Schwäche, wenn Anwendungen dynamisch Dateien, Verzeichnisse oder andere Objekte mit Berechtigungen erstellen oder modifizieren, die von dem abweichen, was Benutzer oder Administratoren erwartet haben. Dies kann auftreten, wenn Anwendungen hart codierte Berechtigungswerte verwenden, vom Benutzer spezifizierte Einstellungen ignorieren, ordnungsgemäße Beschränkungen nicht auf neu erstellte Objekte anwenden oder falsche Zugriffskontrollen auf zur Laufzeit generierte Ressourcen anwenden.

Risiko

Laufzeit-Berechtigungsfehlzuweisung erzeugt Sicherheitsschwachstellen, die schwer zu erkennen sein können, da die falschen Berechtigungen während des normalen Betriebs und nicht bei der Installation gesetzt werden. Log-Dateien, die mit Lese-/Schreibberechtigungen für alle Benutzer erstellt werden, ermöglichen Angreifern, sensible protokollierte Informationen zu lesen oder Logs zu manipulieren, um bösartige Aktivitäten zu verbergen. Temporäre Dateien, die mit übermäßig permissivem Zugang erstellt werden, legen Session-Daten, Anmeldedaten oder andere sensible Laufzeitinformationen offen. Konfigurationsdateien, die während der Ausführung generiert werden, können andere Berechtigungen haben als vom Benutzer erstellte Konfigurationen, was unerwartete Sicherheitslücken erzeugt. Das Risiko wird verstärkt, weil diese dynamisch erstellten Objekte oft die sensibelsten Laufzeitdaten enthalten.

Lösung

Verwalten Sie Berechtigungseinstellungen während der Programmausführung sorgfältig und verwalten Sie Vertrauenszonen explizit. Vor dem Erstellen von Dateien oder anderen Objekten bestimmen Sie die minimal erforderlichen Berechtigungen und wenden Sie diese während der Erstellung an. Verwenden Sie Dateierstellungs-APIs, die explizite Berechtigungsparameter akzeptieren, anstatt sich auf Defaults zu verlassen. Implementieren Sie Privilegientrennung durch Systemkompartimentierung mit klaren Vertrauensgrenzen. Wenden Sie das Prinzip der geringsten Privilegien an, wenn Sie Berechtigungen für dynamisch erstellte Objekte bestimmen. Verifizieren Sie, dass erstellte Objekte die beabsichtigten Berechtigungen haben, indem Sie nach der Erstellung prüfen. Für Log-Dateien und andere sensible Laufzeitdaten stellen Sie sicher, dass Berechtigungen unbefugten Zugriff verhindern, selbst wenn sie von verschiedenen Anwendungskomponenten erstellt werden. Respektieren Sie vom Benutzer spezifizierte Berechtigungseinstellungen und überschreiben Sie sie nicht mit weniger restriktiven Defaults.

Häufige Auswirkungen

AuswirkungDetails
Vertraulichkeit, IntegritätBereich: Vertraulichkeit, Integrität

Unbefugtes Lesen von Anwendungsdaten legt sensible Laufzeitinformationen einschließlich Logs, Session-Daten und temporärer Dateien offen. Unbefugte Modifikation ermöglicht Manipulation von Logs, Änderung von Konfiguration oder Injection bösartiger Inhalte in dynamisch erstellte Dateien.

Beispielcode

Anfälliger Code (C)

Die folgenden Beispiele demonstrieren falsche ausführungszugewiesene Berechtigungen:

// Anfällig: Log-Datei mit Lese-/Schreibberechtigungen für alle geöffnet
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>

void vulnerable_create_log(const char *log_path) {
    // Anfällig: Erstellt Log mit welt-lesbar/schreibbaren Berechtigungen
    int fd = open(log_path, O_WRONLY | O_CREAT | O_APPEND, 0666);
    // Jeder Benutzer kann die Log-Datei lesen und schreiben!

    if (fd >= 0) {
        write(fd, "Anwendung gestartet\n", 21);
        close(fd);
    }
}

void vulnerable_create_temp_file(void) {
    // Anfällig: Temp-Datei mit übermäßigen Berechtigungen
    FILE *tmp = fopen("/tmp/app_session.tmp", "w");
    // Datei mit Standardberechtigungen erstellt (umask-abhängig)
    // Wahrscheinlich welt-lesbar

    if (tmp) {
        fprintf(tmp, "session_token=abc123\n");
        fclose(tmp);
    }
}
# Anfällig: Python Laufzeit-Berechtigungsfehler
import os

class VulnerableApplication:

    def create_runtime_config(self, config_data):
        # Anfällig: Keine expliziten Berechtigungen spezifiziert
        # Verwendet Standard-umask die permissiv sein kann
        with open('/var/lib/myapp/runtime.conf', 'w') as f:
            f.write(config_data)
        # Konfiguration kann sensible Einstellungen enthalten aber welt-lesbar sein

    def create_log_directory(self):
        # Anfällig: Erstellt Log-Verzeichnis mit welt-schreibbaren Berechtigungen
        os.makedirs('/var/log/myapp', mode=0o777, exist_ok=True)

        # Einzelne Log-Dateien auch zu permissiv erstellt
        log_path = '/var/log/myapp/app.log'
        with open(log_path, 'a') as f:
            f.write("Anwendung initialisiert\n")
        # Log-Datei standardmäßig welt-lesbar

    def save_user_data(self, user_id, data):
        # Anfällig: Benutzerspezifische Daten mit falschen Berechtigungen
        user_file = f'/var/lib/myapp/users/{user_id}/data.json'
        os.makedirs(os.path.dirname(user_file), exist_ok=True)

        with open(user_file, 'w') as f:
            f.write(data)
        # Alle Benutzerdaten-Dateien haben dieselben (falschen) Berechtigungen
// Anfällig: Java Laufzeit-Dateierstellung
import java.io.*;
import java.nio.file.*;

public class VulnerableRuntimeFiles {

    public void createLogFile(String message) throws IOException {
        // Anfällig: Standardberechtigungen auf Log-Datei
        FileWriter fw = new FileWriter("/var/log/app/runtime.log", true);
        fw.write(message + "\n");
        fw.close();
        // Log-Dateiberechtigungen durch Systemstandards bestimmt
    }

    public void cacheUserSession(String userId, String sessionData) throws IOException {
        Path cachePath = Paths.get("/tmp/app_cache/" + userId + ".session");

        // Anfällig: Keine expliziten Berechtigungen
        Files.createDirectories(cachePath.getParent());
        Files.write(cachePath, sessionData.getBytes());
        // Session-Daten für andere Benutzer zugänglich
    }
}

Korrigierter Code (C)

// Korrigiert: Ordnungsgemäße Berechtigungen während Ausführung
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

void secure_create_log(const char *log_path) {
    // Restriktive umask für diese Operation setzen
    mode_t old_umask = umask(0077);

    // Log mit nur-Eigentümer-Schreiben erstellen, Gruppen-Lesen für Log-Aggregatoren
    int fd = open(log_path,
                  O_WRONLY | O_CREAT | O_APPEND,
                  S_IRUSR | S_IWUSR | S_IRGRP);  // 0640

    if (fd >= 0) {
        write(fd, "Anwendung gestartet\n", 21);
        close(fd);

        // Verifizieren, dass Berechtigungen korrekt gesetzt wurden
        struct stat st;
        if (stat(log_path, &st) == 0) {
            if (st.st_mode & S_IWGRP || st.st_mode & S_IROTH) {
                // Berechtigungen zu offen - korrigieren
                chmod(log_path, S_IRUSR | S_IWUSR | S_IRGRP);
            }
        }
    }

    umask(old_umask);
}

void secure_create_temp_file(void) {
    char template[] = "/tmp/app_session_XXXXXX";

    // mkstemp erstellt standardmäßig mit 0600 Berechtigungen
    int fd = mkstemp(template);

    if (fd >= 0) {
        dprintf(fd, "session_token=abc123\n");
        close(fd);
        // Nach Fertigstellung aufräumen
        unlink(template);
    }
}

void secure_create_log_dir(const char *log_dir) {
    // Verzeichnis mit angemessenen Berechtigungen erstellen
    if (mkdir(log_dir, 0750) != 0 && errno != EEXIST) {
        // Fehler behandeln
        return;
    }

    // Korrekte Berechtigungen sicherstellen auch wenn Verzeichnis existierte
    chmod(log_dir, 0750);

    // Eigentum zu Log-Benutzer/Gruppe ändern
    struct passwd *log_user = getpwnam("syslog");
    if (log_user) {
        chown(log_dir, log_user->pw_uid, log_user->pw_gid);
    }
}
# Korrigiert: Python mit ordnungsgemäßen Laufzeit-Berechtigungen
import os
import stat
import tempfile

class SecureApplication:

    def create_runtime_config(self, config_data):
        config_path = '/var/lib/myapp/runtime.conf'

        # Sicherstellen, dass Verzeichnis mit ordnungsgemäßen Berechtigungen existiert
        config_dir = os.path.dirname(config_path)
        os.makedirs(config_dir, mode=0o700, exist_ok=True)

        # Restriktive umask setzen
        old_umask = os.umask(0o077)
        try:
            # Datei mit explizit restriktiven Berechtigungen erstellen
            fd = os.open(config_path,
                        os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
                        0o600)
            try:
                os.write(fd, config_data.encode())
            finally:
                os.close(fd)
        finally:
            os.umask(old_umask)

    def create_log_directory(self):
        log_dir = '/var/log/myapp'
        log_path = os.path.join(log_dir, 'app.log')

        # Log-Verzeichnis mit ordnungsgemäßen Berechtigungen erstellen
        os.makedirs(log_dir, mode=0o750, exist_ok=True)

        # Log-Datei mit angemessenen Berechtigungen erstellen
        # Lesbar durch Gruppe (für Log-Aggregation), schreibbar durch Eigentümer
        fd = os.open(log_path,
                    os.O_WRONLY | os.O_CREAT | os.O_APPEND,
                    0o640)
        try:
            os.write(fd, b"Anwendung initialisiert\n")
        finally:
            os.close(fd)

    def save_user_data(self, user_id, data):
        user_dir = f'/var/lib/myapp/users/{user_id}'
        user_file = os.path.join(user_dir, 'data.json')

        # Benutzerverzeichnis mit restriktiven Berechtigungen erstellen
        os.makedirs(user_dir, mode=0o700, exist_ok=True)

        # Benutzerdaten mit nur-Eigentümer-Zugang speichern
        fd = os.open(user_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
        try:
            os.write(fd, data.encode())
        finally:
            os.close(fd)
// Korrigiert: Java mit expliziten Laufzeit-Berechtigungen
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.*;

public class SecureRuntimeFiles {

    private static final Set<PosixFilePermission> LOG_PERMS =
        PosixFilePermissions.fromString("rw-r-----");  // 640
    private static final Set<PosixFilePermission> SESSION_PERMS =
        PosixFilePermissions.fromString("rw-------");  // 600
    private static final Set<PosixFilePermission> DIR_PERMS =
        PosixFilePermissions.fromString("rwx------");  // 700

    public void createLogFile(String message) throws IOException {
        Path logPath = Paths.get("/var/log/app/runtime.log");

        // Sicherstellen, dass Verzeichnis mit ordnungsgemäßen Berechtigungen existiert
        if (!Files.exists(logPath.getParent())) {
            Files.createDirectories(logPath.getParent(),
                PosixFilePermissions.asFileAttribute(
                    PosixFilePermissions.fromString("rwxr-x---")));
        }

        // Log-Eintrag schreiben
        Files.write(logPath, (message + "\n").getBytes(),
            StandardOpenOption.CREATE,
            StandardOpenOption.APPEND);

        // Korrekte Berechtigungen setzen
        Files.setPosixFilePermissions(logPath, LOG_PERMS);
    }

    public void cacheUserSession(String userId, String sessionData) throws IOException {
        Path cacheDir = Paths.get("/tmp/app_cache");
        Path cachePath = cacheDir.resolve(userId + ".session");

        // Cache-Verzeichnis mit restriktiven Berechtigungen erstellen
        if (!Files.exists(cacheDir)) {
            Files.createDirectories(cacheDir,
                PosixFilePermissions.asFileAttribute(DIR_PERMS));
        }

        // Session-Daten schreiben
        Files.write(cachePath, sessionData.getBytes(),
            StandardOpenOption.CREATE,
            StandardOpenOption.TRUNCATE_EXISTING);

        // Restriktive Berechtigungen auf Session-Datei setzen
        Files.setPosixFilePermissions(cachePath, SESSION_PERMS);
    }
}

Die Korrektur stellt sicher, dass alle zur Laufzeit erstellten Objekte explizite, angemessene Berechtigungen haben, anstatt sich auf potenziell unsichere Defaults zu verlassen.


Ausgenutzt in der Praxis

Log-Datei-Manipulationsangriffe (Verschiedene Anwendungen, Fortlaufend)

Anwendungen, die Log-Dateien mit Lese-/Schreibberechtigungen für alle Benutzer erstellen, haben Angreifern ermöglicht, sowohl sensible protokollierte Informationen zu lesen als auch Logs zu modifizieren, um bösartige Aktivitäten zu verbergen. CVE-2002-0265, CVE-2003-0876 und CVE-2002-1694 dokumentierten Log-Dateien, die mit übermäßig permissiven Lese-/Schreibberechtigungen geöffnet wurden.

Session-Datei-Offenlegung (Webanwendungen, Fortlaufend)

Webanwendungen, die Session-Daten in Dateien mit falschen Laufzeit-Berechtigungen speichern, haben Session-Tokens und Authentifizierungsdaten lokalen Angreifern offengelegt, was Session-Hijacking und Privilegieneskalation ermöglichte.

Temporäre-Datei-Angriffe (Unix/Linux-Systeme, Historisch)

Anwendungen, die temporäre Dateien mit falschen Berechtigungen erstellen, haben lokale Informationsoffenlegung und Code-Injection-Angriffe durch Symlink-Ausnutzung und Race Conditions ermöglicht.


Tools zum Testen/Ausnutzen

  • Inotify-Watcher — Dateierstellung überwachen und Berechtigungen neu erstellter Dateien während der Anwendungslaufzeit prüfen.

  • strace — Systemaufrufe verfolgen, um Berechtigungsargumente in Dateierstellungsaufrufen zu beobachten.

  • Auditd — Linux-Audit-Daemon zur Überwachung von Dateiberechtigungsänderungen.


CVE-Beispiele

  • CVE-2002-0265 — Log-Dateien mit Lese-/Schreibberechtigungen geöffnet, die unbefugten Zugriff ermöglichten.

  • CVE-2003-0876 — Log-Dateien mit welt-lesbar/schreibbaren Berechtigungen erstellt.

  • CVE-2002-1694 — Laufzeit-Log-Dateien mit falschen Berechtigungen.


Referenzen

  1. MITRE Corporation. "CWE-279: Incorrect Execution-Assigned Permissions." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/279.html

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

  3. CERT Oracle Secure Coding Standard for Java. "FIO01-J. Create files with appropriate access permissions." https://wiki.sei.cmu.edu/confluence/display/java/FIO01-J