Unsachgemäße Behandlung unzureichender Berechtigungen oder Privilegien

Beschreibung

Unsachgemäße Behandlung unzureichender Berechtigungen oder Privilegien ist eine Schwachstelle, die auftritt, wenn ein Produkt Situationen nicht behandelt oder falsch behandelt, in denen es unzureichende Privilegien hat, um auf Ressourcen oder Funktionalität wie durch deren Berechtigungen spezifiziert zuzugreifen. Wenn Anwendungen auf Permission-Denied-Fehler beim Ressourcenzugriff stoßen, kann unsachgemäße Behandlung unerwartete Codepfade, ungültige Produktzustände oder Sicherheitsumgehungen verursachen. Diese Schwäche unterscheidet sich von CWE-274 (Improper Handling of Insufficient Privileges) durch ihren Fokus auf berechtigungsbasierte Zugriffskontrollen anstatt privilegienbasierte Autorisierung, obwohl die Konzepte eng verwandt sind.

Risiko

Das Versäumnis, unzureichende Berechtigungsbedingungen ordnungsgemäß zu behandeln, erzeugt unvorhersehbares Anwendungsverhalten, das Sicherheit und Stabilität kompromittieren kann. Wenn Berechtigungsprüfungen unerwartet fehlschlagen, können Anwendungen Fallback-Pfade nehmen, die Sicherheitskontrollen umgehen. FTP-Server, die wegen Berechtigungen nicht auf Benutzer-Heimverzeichnisse zugreifen können, platzieren Benutzer möglicherweise im Root-Verzeichnis und legen das gesamte Dateisystem offen. Anwendungen können ohne erforderliche Konfigurationen weiter operieren, wenn Konfigurationsdateien nicht lesbar sind, was zu unsicherem Standardverhalten führt. Moderne Systeme mit granularen Berechtigungsmodellen (Linux Capabilities, Windows DACLs) können unerwartete Berechtigungsfehler verursachen, die Anwendungen nicht behandeln. Das Risiko wird verstärkt, wenn Anwendungen annehmen, dass Berechtigungsprüfungen immer erfolgreich sind und ordnungsgemäße Fehlerbehandlung fehlt.

Lösung

Implementieren Sie robuste Fehlerbehandlung für alle Ressourcenzugriffsoperationen, die aufgrund von Berechtigungen fehlschlagen können. Verifizieren Sie immer erfolgreichen Ressourcenzugriff, selbst wenn Sie in privilegierten Ausführungsmodi laufen, da granulare Berechtigungsmodelle unerwartete Fehler verursachen können. Entwerfen Sie Fail-Safe-Verhaltensweisen, die Sicherheit aufrechterhalten, wenn Berechtigungen unzureichend sind, anstatt auf weniger restriktiven Zugang zurückzufallen. Implementieren Sie Privilegientrennung durch Systemkompartimentierung mit klaren Vertrauensgrenzen. Wenden Sie das Prinzip der geringsten Privilegien an, um zu bestimmen, wann Zugriffsrechte gewährt und wann sie entzogen werden sollten. Protokollieren Sie Berechtigungsfehler für Sicherheitsüberwachung, aber vermeiden Sie es, sensible Pfadinformationen in benutzerseitigen Fehlermeldungen offenzulegen. Testen Sie Anwendungsverhalten unter verschiedenen Berechtigungskonfigurationen, um sichere Degradation sicherzustellen.

Häufige Auswirkungen

AuswirkungDetails
AndereBereich: Ändere

Die Schwäche kann die Ausführungslogik der Anwendung ändern, wenn Berechtigungsprüfungen unerwartet fehlschlagen. Anwendungen können undefinierte Zustände erreichen, unerwartete Codepfade nehmen oder Sicherheitskontrollen umgehen, die von erfolgreicher Berechtigungsverifikation abhängen.

Beispielcode

Anfälliger Code (C)

Die folgenden Beispiele demonstrieren unsachgemäße Behandlung unzureichender Berechtigungen:

// Anfällig: FTP-Server fällt auf Root zurück bei Berechtigungsfehler
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

char* vulnerable_get_user_directory(const char *username) {
    char *home_dir = get_user_home(username);

    if (chdir(home_dir) != 0) {
        if (errno == EACCES) {
            // Anfällig: Fällt auf Root-Verzeichnis zurück!
            return "/";
        }
        return NULL;
    }

    return home_dir;
}

int vulnerable_read_config(void) {
    FILE *config = fopen("/etc/myapp/config", "r");

    if (config == NULL) {
        if (errno == EACCES) {
            // Anfällig: Verwendet unsichere Defaults wenn Konfiguration nicht lesbar
            printf("Kann Konfiguration nicht lesen - verwende Defaults\n");
            use_default_config();  // Kann unsichere Einstellungen haben
            return 0;  // Gibt Erfolg zurück trotz Fehler
        }
        return -1;
    }

    parse_config(config);
    fclose(config);
    return 0;
}
# Anfällig: Python behandelt Berechtigungsfehler falsch
import os

class VulnerableApplication:

    def load_user_data(self, user_id):
        user_file = f'/var/lib/myapp/users/{user_id}/data.json'

        try:
            with open(user_file, 'r') as f:
                return json.load(f)
        except PermissionError:
            # Anfällig: Fällt auf Standarddaten zurück die Admin-Privilegien enthalten können
            return self.get_default_user_data()  # Kann zu viel Zugang gewähren

    def apply_security_policy(self, policy_file):
        try:
            with open(policy_file, 'r') as f:
                policy = f.read()
                self.enforce_policy(policy)
        except PermissionError:
            # Anfällig: Fährt stillschweigend ohne Sicherheitsrichtlinie fort
            print(f"Warnung: Konnte {policy_file} nicht lesen")
            pass  # Keine Richtliniendurchsetzung!

    def verify_user_access(self, user, resource):
        try:
            return self.access_control.check(user, resource)
        except PermissionError:
            # Anfällig: Erlaubt Zugang wenn nicht verifizierbar
            return True  # Fail-Open-Verhalten
// Anfällig: Java Berechtigungsfehlerbehandlung
import java.io.*;
import java.nio.file.*;

public class VulnerableResourceAccess {

    public String getUserHome(String username) {
        Path homePath = Paths.get("/home", username);

        try {
            if (Files.isReadable(homePath)) {
                return homePath.toString();
            }
        } catch (SecurityException e) {
            // Anfällig: Gibt Root bei Berechtigungsfehler zurück
            return "/";
        }

        return "/tmp";  // Auch problematischer Fallback
    }

    public Properties loadConfig(String configPath) throws IOException {
        Properties props = new Properties();

        try {
            props.load(new FileInputStream(configPath));
        } catch (SecurityException e) {
            // Anfällig: Verwendet unsichere Defaults
            props.setProperty("security.enabled", "false");
            props.setProperty("debug.mode", "true");
        }

        return props;
    }
}

Korrigierter Code (C)

// Korrigiert: Ordnungsgemäße Behandlung von Berechtigungsfehlern
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>

int secure_get_user_directory(const char *username, char *result, size_t len) {
    char *home_dir = get_user_home(username);

    if (home_dir == NULL) {
        syslog(LOG_ERR, "Kein Heimverzeichnis für Benutzer %s", username);
        return -1;
    }

    if (chdir(home_dir) != 0) {
        if (errno == EACCES) {
            // Korrigiert: Zugang verweigern anstatt Fallback
            syslog(LOG_WARNING,
                   "Berechtigung verweigert für Zugriff auf Home von %s", username);
            return -1;  // Fehler zurückgeben, nicht auf Root zurückfallen
        }
        syslog(LOG_ERR, "Kann nicht auf Heimverzeichnis zugreifen: %s", strerror(errno));
        return -1;
    }

    strncpy(result, home_dir, len);
    return 0;
}

int secure_read_config(void) {
    FILE *config = fopen("/etc/myapp/config", "r");

    if (config == NULL) {
        if (errno == EACCES) {
            // Korrigiert: Sicher fehlschlagen wenn Konfiguration nicht lesbar
            syslog(LOG_CRIT,
                   "SICHERHEIT: Kann Konfigurationsdatei nicht lesen - Start verweigert");
            fprintf(stderr, "Fehler: Konfigurationsdatei nicht zugänglich\n");
            return -1;  // Start fehlschlagen lassen
        }
        syslog(LOG_ERR, "Kann Konfiguration nicht öffnen: %s", strerror(errno));
        return -1;
    }

    int result = parse_config(config);
    fclose(config);
    return result;
}

int secure_check_permissions(const char *path, int required_perms) {
    if (access(path, required_perms) != 0) {
        if (errno == EACCES) {
            syslog(LOG_WARNING, "Unzureichende Berechtigungen für %s", path);
            // Pfad nicht in benutzerseitiger Meldung offenlegen
            return -1;
        }
        return -1;
    }
    return 0;
}
# Korrigiert: Python mit ordnungsgemäßer Berechtigungsfehlerbehandlung
import os
import json
import logging

logger = logging.getLogger(__name__)

class SecureApplication:

    def load_user_data(self, user_id):
        user_file = f'/var/lib/myapp/users/{user_id}/data.json'

        try:
            with open(user_file, 'r') as f:
                return json.load(f)
        except PermissionError:
            # Korrigiert: Zugang verweigern anstatt Defaults zurückgeben
            logger.warning(f"Berechtigung verweigert beim Laden von Benutzer-{user_id}-Daten")
            raise AccessDeniedError(f"Kann nicht auf Benutzerdaten für {user_id} zugreifen")
        except FileNotFoundError:
            # Neuer Benutzer - mit minimalen Privilegien erstellen
            return self.create_new_user_data(user_id)

    def apply_security_policy(self, policy_file):
        try:
            with open(policy_file, 'r') as f:
                policy = f.read()
        except PermissionError:
            # Korrigiert: Sicher fehlschlagen - Betrieb ohne Richtlinie verweigern
            logger.critical(
                f"SICHERHEIT: Kann Richtliniendatei nicht lesen - Start verweigert"
            )
            raise SecurityConfigurationError(
                "Erforderliche Sicherheitsrichtlinie nicht zugänglich"
            )

        self.enforce_policy(policy)

    def verify_user_access(self, user, resource):
        try:
            return self.access_control.check(user, resource)
        except PermissionError:
            # Korrigiert: Zugang verweigern wenn Verifikation fehlschlägt
            logger.warning(
                f"Berechtigungsfehler während Zugriffsprüfung für {user}"
            )
            return False  # Fail-Closed-Verhalten
// Korrigiert: Java mit sicherer Berechtigungsbehandlung
import java.io.*;
import java.nio.file.*;
import java.util.logging.*;

public class SecureResourceAccess {

    private static final Logger logger =
        Logger.getLogger(SecureResourceAccess.class.getName());

    public String getUserHome(String username) throws AccessDeniedException {
        Path homePath = Paths.get("/home", username);

        try {
            if (Files.isReadable(homePath) && Files.isDirectory(homePath)) {
                return homePath.toString();
            } else {
                throw new AccessDeniedException(
                    "Heimverzeichnis nicht zugänglich: " + username);
            }
        } catch (SecurityException e) {
            // Korrigiert: Exception werfen anstatt Fallback
            logger.warning("Security-Exception beim Zugriff auf Home für " + username);
            throw new AccessDeniedException(
                "Berechtigung verweigert für Zugriff auf Heimverzeichnis");
        }
    }

    public Properties loadConfig(String configPath) throws ConfigurationException {
        Properties props = new Properties();

        try {
            props.load(new FileInputStream(configPath));
        } catch (SecurityException e) {
            // Korrigiert: Sicher fehlschlagen
            logger.severe("SICHERHEIT: Kann Konfiguration nicht lesen - Start verweigert");
            throw new ConfigurationException(
                "Erforderliche Konfigurationsdatei nicht zugänglich", e);
        } catch (IOException e) {
            throw new ConfigurationException("Fehler beim Lesen der Konfiguration", e);
        }

        // Validieren, dass Konfiguration erforderliche Sicherheitseinstellungen hat
        validateSecurityConfig(props);

        return props;
    }
}

Die Korrektur stellt sicher, dass Berechtigungsfehler zu sicherer Verweigerung oder kontrolliertem Fehlschlagen führen, anstatt auf unsichere Defaults zurückzufallen.


Ausgenutzt in der Praxis

FTP Root-Verzeichnis-Fallback (FTP-Server, Historisch)

CVE-2004-0148 dokumentierte FTP-Server-Implementierungen, die Benutzer im Root-Verzeichnis platzierten, wenn ihre Heimverzeichnisse wegen Berechtigungen nicht zugänglich waren. Angreifer nutzten dies aus, um das gesamte Dateisystem zu durchsuchen.

Konfigurationsumgehung durch Berechtigungen (Verschiedene Anwendungen, Fortlaufend)

Anwendungen, die auf unsichere Standardkonfigurationen zurückfallen, wenn Sicherheitsrichtlinien nicht lesbar sind, wurden ausgenutzt, um Sicherheitskontrollen durch Manipulation von Dateiberechtigungen zu umgehen.

Setuid-Programm-Konfigurationsangriffe (Unix-Systeme, Historisch)

CVE-2003-0501 dokumentierte, wie Dateisysteme Angreifern ermöglichten, Berechtigungsänderungen zu verhindern, indem sie Einträge vor der Setuid-Programmausführung vorab öffneten, wobei sie unsachgemäße Berechtigungsbehandlung ausnutzten.


Tools zum Testen/Ausnutzen


CVE-Beispiele

  • CVE-2003-0501 — Dateisystem ermöglichte Angreifern, Berechtigungsänderungen zu verhindern, indem sie Einträge vor Setuid-Programmausführung vorab öffneten.

  • CVE-2004-0148 — FTP-Server platzierte Benutzer im Root-Verzeichnis, wenn Heimverzeichnis-Berechtigungen unzureichend waren.


Referenzen

  1. MITRE Corporation. "CWE-280: Improper Handling of Insufficient Permissions or Privileges." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/280.html

  2. OWASP Foundation. "Error Handling." OWASP Cheat Sheet Series. https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html

  3. CWE-636. "Not Failing Securely ('Failing Open')." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/636.html