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
| Auswirkung | Details |
|---|---|
| Vertraulichkeit, Integrität | Bereich: 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
-
MITRE Corporation. "CWE-279: Incorrect Execution-Assigned Permissions." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/279.html
-
CERT C Secure Coding Standard. "FIO06-C. Create files with appropriate access permissions." https://wiki.sei.cmu.edu/confluence/display/c/FIO06-C
-
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