Unsichere vererbte Berechtigungen

Beschreibung

Unsichere vererbte Berechtigungen ist eine Schwachstelle, die auftritt, wenn ein Produkt einen Satz unsicherer Berechtigungen definiert, die von Objekten geerbt werden, die vom Programm erstellt werden. Wenn Prozesse Dateien, Verzeichnisse oder andere Objekte erstellen, erben diese neuen Objekte typischerweise Berechtigungen basierend auf den Einstellungen des erstellenden Prozesses (wie umask auf Unix-Systemen) oder übergeordneten Objekt-ACLs. Wenn der erstellende Prozess eine unsichere Berechtigungsvererbungskonfiguration hat, werden alle von ihm erstellten Objekte übermäßig permissive Zugriffskontrollen haben, was möglicherweise sensible Daten offenlegt oder unbefugte Modifikation ermöglicht.

Risiko

Unsichere vererbte Berechtigungen erzeugen systemische Sicherheitsschwächen, bei denen jedes von einem betroffenen Prozess erstellte Objekt unsachgemäße Zugriffskontrollen hat. Anders als explizite Berechtigungsfehler bei einzelnen Dateien betreffen Probleme mit vererbten Berechtigungen alle neu erstellten Objekte, bis die Grundursache behoben ist. Anwendungen, die mit permissiven umask-Einstellungen laufen, erstellen Dateien, die für unbeabsichtigte Benutzer lesbar oder schreibbar sein können. Dienste, die temporäre Dateien, Cache-Dateien oder Benutzerdaten mit geerbten schwachen Berechtigungen erstellen, setzen diese Daten lokalen Angreifern aus. Das Risiko ist besonders akut für Anwendungen, die Dateien mit sensiblen Informationen wie Session-Tokens, temporären Anmeldedaten oder zwischengespeicherten Authentifizierungsdaten erstellen. Core Dumps, die mit geerbten schwachen Berechtigungen erstellt werden, können Speicherinhalte einschließlich Passwörtern und Verschlüsselungsschlüsseln offenlegen.

Lösung

Setzen Sie explizit restriktive Berechtigungen beim Erstellen sicherheitssensibler Objekte, anstatt sich auf geerbte Einstellungen zu verlassen. Setzen Sie eine restriktive umask (z.B. 0077 oder 0027) am Anfang sensibler Operationen. Verwenden Sie Dateierstellungsfunktionen, die explizite Berechtigungsparameter akzeptieren (z.B. open() mit mode, os.open() mit mode, oder CreateFile mit Sicherheitsattributen). Für Verzeichnisse, die sensible Inhalte enthalten werden, setzen Sie sowohl die Verzeichnisberechtigungen als auch alle anwendbaren ACL-Vererbungsregeln. Wenn das Erben von Berechtigungen unvermeidlich ist, verifizieren Sie, dass geerbte Berechtigungen den Sicherheitsanforderungen entsprechen, bevor Sie sensible Daten speichern. Unter Windows konfigurieren Sie ACL-Vererbung auf übergeordneten Containern sorgfältig. Auditieren Sie Anwendungsverhalten, um alle Dateierstellungspunkte zu identifizieren und sicherzustellen, dass jeder angemessene Berechtigungen verwendet.

Häufige Auswirkungen

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

Mit unsicheren geerbten Berechtigungen erstellte Objekte können unbefugtes Lesen sensibler Anwendungsdaten oder unbefugte Modifikation kritischer Dateien ermöglichen. Temporäre Dateien, Cache-Dateien, Logs und Benutzerdaten, die mit schwachen Berechtigungen erstellt werden, sind lokalen Angreifern ausgesetzt.

Beispielcode

Anfälliger Code (C)

Die folgenden Beispiele demonstrieren unsichere vererbte Berechtigungen:

// Anfällig: Verwendet geerbte umask für temporäre Dateien
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

void vulnerable_create_temp_file(const char *sensitive_data) {
    // Prozess hat permissive umask geerbt (z.B. 0000 oder 0022)
    // Neue Datei erbt diese schwachen Berechtigungen

    // Anfällig: Datei mit geerbten (möglicherweise schwachen) Berechtigungen erstellt
    FILE *tmp = fopen("/tmp/app_session_data.tmp", "w");
    if (tmp) {
        fprintf(tmp, "session_token=%s\n", sensitive_data);
        fclose(tmp);
    }
    // Datei kann welt-lesbar sein!
}

// Anfällig: Core-Dump-Berechtigungen vom Prozess geerbt
void vulnerable_core_dump_setup(void) {
    // Prozess läuft mit permissiver umask
    // Core Dumps werden diese Berechtigungen erben

    // Core Dumps aktivieren ohne Berechtigungsvererbung zu berücksichtigen
    struct rlimit limit;
    limit.rlim_cur = RLIM_INFINITY;
    limit.rlim_max = RLIM_INFINITY;
    setrlimit(RLIMIT_CORE, &limit);

    // Wenn Prozess abstürzt, Core Dump mit geerbten Berechtigungen erstellt
    // Kann welt-lesbar sein, Speicherinhalte offenlegend
}
# Anfällig: Python-Anwendung mit geerbter permissiver umask
import os
import tempfile

class VulnerableApplication:

    def create_cache_file(self, cache_data):
        # Erbt umask vom übergeordneten Prozess
        # Wenn übergeordneter umask 0000 hatte, sind Dateien welt-lesbar

        # Anfällig: tempfile erbt Prozess-umask
        cache_file = tempfile.NamedTemporaryFile(
            mode='w',
            prefix='app_cache_',
            delete=False
        )
        cache_file.write(cache_data)  # Sensible Daten
        cache_file.close()
        # Dateiberechtigungen hängen von geerbter umask ab

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

        # Anfällig: Verzeichnisberechtigungen von umask geerbt
        os.makedirs(user_dir, exist_ok=True)
        # Kann welt-lesbar oder welt-ausführbar sein

        # In Verzeichnis erstellte Dateien erben auch umask
        with open(f"{user_dir}/profile.json", 'w') as f:
            f.write(self.get_user_profile(username))
// Anfällig: Java-Anwendung verlässt sich auf geerbte Berechtigungen
import java.io.*;
import java.nio.file.*;

public class VulnerableFileCreation {

    public void saveUserSession(String userId, String sessionToken) throws IOException {
        // Anfällig: Dateiberechtigungen von Systemeinstellungen geerbt
        Path sessionFile = Paths.get("/tmp/sessions/" + userId + ".session");

        // Standard-Dateierstellung erbt Prozess-umask
        Files.write(sessionFile, sessionToken.getBytes());
        // Datei kann von anderen Benutzern lesbar sein
    }

    public void createTempDirectory() throws IOException {
        // Anfällig: Verzeichnis erbt Berechtigungen
        Path tempDir = Files.createTempDirectory("app_temp");
        // Berechtigungen hängen von geerbten Einstellungen ab
        // Kann anderen Benutzern erlauben, Inhalte aufzulisten
    }
}

Korrigierter Code (C)

// Korrigiert: Explizit restriktive Berechtigungen setzen
#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) {
    // Ursprüngliche umask speichern und restriktive setzen
    mode_t old_umask = umask(0077);

    // Besser: open() mit expliziten Berechtigungen verwenden
    int fd = open("/tmp/app_session_data.tmp",
                  O_WRONLY | O_CREAT | O_TRUNC,
                  S_IRUSR | S_IWUSR);  // 0600 - nur Eigentümer lesen/schreiben

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

    // Ursprüngliche umask wiederherstellen
    umask(old_umask);
}

void secure_core_dump_setup(void) {
    // Restriktive umask setzen vor Aktivierung von Core Dumps
    umask(0077);

    // Optional Core-Dump-Verzeichnis mit sicheren Berechtigungen konfigurieren
    // Oder Core Dumps für sensible Prozesse deaktivieren
    struct rlimit limit;
    limit.rlim_cur = RLIM_INFINITY;
    limit.rlim_max = RLIM_INFINITY;
    setrlimit(RLIMIT_CORE, &limit);

    // Auf Linux kann auch Core-Pattern-Berechtigungen setzen
    // echo "0600" > /proc/sys/fs/suid_dumpable
}

// Noch besser: Bibliotheksfunktionen für sichere temporäre Dateien verwenden
#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);  // Erstellt mit 0600 Berechtigungen

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

    umask(old_umask);
}
# Korrigiert: Python-Anwendung mit expliziten Berechtigungen
import os
import stat
import tempfile

class SecureApplication:

    def create_cache_file(self, cache_data):
        # Restriktive umask speichern und setzen
        old_umask = os.umask(0o077)

        try:
            # Temporäre Datei mit explizit restriktiven Berechtigungen erstellen
            fd, cache_path = tempfile.mkstemp(prefix='app_cache_')
            try:
                os.write(fd, cache_data.encode())
            finally:
                os.close(fd)

            # Berechtigungen verifizieren
            file_stat = os.stat(cache_path)
            if file_stat.st_mode & 0o077:  # Prüfen ob andere Zugang haben
                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}"

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

        # Sicherstellen, dass Berechtigungen korrekt sind, auch wenn Verzeichnis existierte
        os.chmod(user_dir, 0o700)

        # Dateien mit expliziten Berechtigungen erstellen
        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)
// Korrigiert: Java-Anwendung mit expliziten Berechtigungen
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");

        // Übergeordnetes Verzeichnis mit restriktiven Berechtigungen erstellen falls nötig
        Path sessionDir = sessionFile.getParent();
        if (!Files.exists(sessionDir)) {
            Set<PosixFilePermission> dirPerms = PosixFilePermissions.fromString("rwx------");
            Files.createDirectories(sessionDir,
                PosixFilePermissions.asFileAttribute(dirPerms));
        }

        // Datei mit explizit restriktiven Berechtigungen erstellen
        Set<PosixFilePermission> filePerms = PosixFilePermissions.fromString("rw-------");
        Files.write(sessionFile, sessionToken.getBytes(),
            StandardOpenOption.CREATE,
            StandardOpenOption.TRUNCATE_EXISTING);

        // Berechtigungen explizit nach Erstellung setzen
        Files.setPosixFilePermissions(sessionFile, filePerms);
    }

    public Path createSecureTempDirectory() throws IOException {
        // Temporäres Verzeichnis mit expliziten Berechtigungen erstellen
        Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwx------");
        FileAttribute<Set<PosixFilePermission>> attr =
            PosixFilePermissions.asFileAttribute(perms);

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

Die Korrektur setzt explizit restriktive Berechtigungen während der Objekterstellung, anstatt sich auf geerbte Einstellungen zu verlassen.


Ausgenutzt in der Praxis

Temporäre-Datei-Offenlegung (Verschiedene Anwendungen, Fortlaufend)

Anwendungen, die temporäre Dateien mit geerbten permissiven umask-Einstellungen erstellen, haben sensible Session-Daten, Anmeldedaten und temporäre Authentifizierungstoken offengelegt. Lokale Angreifer überwachen /tmp-Verzeichnisse auf neu erstellte Dateien mit schwachen Berechtigungen.

Core-Dump-Anmeldedaten-Offenlegung (Unix-Systeme, Historisch)

Core Dumps, die mit geerbten umask-Einstellungen erstellt wurden, legten Prozessspeicher mit Passwörtern und Verschlüsselungsschlüsseln offen. CVE-2002-1786 dokumentierte unsichere umask-Einstellungen für Core Dumps, die lokalen Anmeldedatendiebstahl ermöglichten.

Benutzerdaten-Offenlegung durch Umask (Unix-Anwendungen, Historisch)

Anwendungen, die mit benutzergesteuerter umask-Einstellungen liefen, haben Dateien mit unerwarteten Berechtigungen erstellt. CVE-2005-1841 dokumentierte, dass die umask des Benutzers fälschlicherweise auf temporäre Dateien angewendet wurde, die von privilegierten Anwendungen erstellt wurden.


Tools zum Testen/Ausnutzen

  • umask-Audit-Skripte — Skripte, die Prozess-umask und Dateiberechtigungsvererbung prüfen.

  • Inotify-Watcher — Tools zum Überwachen der Dateierstellung und Prüfen der Berechtigungen neu erstellter Dateien.

  • Lynis — Sicherheitsaudit-Tool, das auf umask- und Berechtigungsvererbungsprobleme prüft.


CVE-Beispiele

  • CVE-2005-1841 — Umask des Benutzers beim Erstellen temporärer Dateien angewendet, sensible Daten offenlegend.

  • CVE-2002-1786 — Unsichere umask-Einstellungen für Core Dumps legten Prozessspeicher offen.


Referenzen

  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