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
| Auswirkung | Details |
|---|---|
| Andere | Bereich: Ä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
-
Berechtigungsmanipulationstools — Standardtools zum Testen von Anwendungsverhalten mit verschiedenen Berechtigungskonfigurationen.
-
Fehlerinjektions-Frameworks — Tools zum Simulieren von Berechtigungsfehlern während Tests.
-
seccomp/AppArmor — Sicherheits-Frameworks zum Einschränken von Berechtigungen und Testen von Anwendungsreaktionen.
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
-
MITRE Corporation. "CWE-280: Improper Handling of Insufficient Permissions or Privileges." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/280.html
-
OWASP Foundation. "Error Handling." OWASP Cheat Sheet Series. https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html
-
CWE-636. "Not Failing Securely ('Failing Open')." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/636.html