Fehlerhafte Eigentümerzuweisung
Beschreibung
Fehlerhafte Eigentümerzuweisung ist eine Schwachstelle, bei der Software einen Eigentümer einer Ressource zuweist, der außerhalb des beabsichtigten Kontrollbereichs liegt. Wenn der Ressourceneigentümer falsch einem anderen Benutzer, einer anderen Gruppe oder Entität zugewiesen wird, entstehen Wege für nicht autorisierte Akteure, auf Ressourcen zuzugreifen, sie zu modifizieren oder zu löschen, über die sie keine Kontrolle haben sollten. Dies tritt häufig bei Dateieigentümerschaft während der Installation, Prozesseigentümerschaft nach Privilegienänderungen oder Datenbankobjekt-Eigentümerschaft bei der Erstellung auf. Die falsch konfigurierte Eigentümerschaft untergräbt das Sicherheitsmodell, das die Ressource schützt.
Risiko
Fehlerhafte Eigentümerzuweisung schafft Privilegieneskalations- und unbefugte Zugriffs-Schwachstellen. Dateien, die unprivilegierten Benutzern gehören, können modifiziert werden, um bösartigen Code einzuschleusen, der mit erhöhten Privilegien ausgeführt wird, wenn die Dateien später von Systemprozessen verwendet werden. Ressourcen mit falscher Gruppeneigentümerschaft können für unbeabsichtigte Benutzer in dieser Gruppe zugänglich sein. Symbolische Link-Eigentümer-Probleme können es Angreifern ermöglichen, Link-Ziele zu manipulieren. Beim Abmelden oder Sitzungswechsel kann das Versäumnis, die ordnungsgemäße Eigentümerschaft wiederherzustellen, Ressourcen für nachfolgende Benutzer zugänglich machen. Das Risiko erstreckt sich auf Konfigurationsdateien, ausführbare Dateien, Datendateien und jede Ressource, bei der die Eigentümerschaft die Zugriffsrechte bestimmt.
Lösung
Setzen Sie die korrekte Eigentümerschaft sofort bei der Ressourcenerstellung. Überprüfen Sie die Eigentümerschaftseinstellungen während der Installation und Bereitstellung. Verwenden Sie das Prinzip der geringsten Privilegien - weisen Sie die Eigentümerschaft der am stärksten eingeschränkten Entität zu, die noch den ordnungsgemäßen Betrieb ermöglicht. Prüfen Sie regelmäßig die Ressourceneigentümerschaft und -berechtigungen. Seien Sie beim Umgang mit symbolischen Links explizit, ob Operationen den Link oder das Ziel betreffen. Stellen Sie die ordnungsgemäße Eigentümerschaft nach Abschluss von Privilegienoperationen wieder her. Verwenden Sie Konfigurationsmanagement-Tools, um die korrekte Eigentümerschaft systemübergreifend durchzusetzen. Testen Sie Eigentümerschaftseinstellungen als Teil der Sicherheitsverifikation.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Vertraulichkeit Anwendungsdaten lesen - Ressourcen mit falscher Eigentümerschaft können von nicht autorisierten Benutzern lesbar sein. |
| Integrität | Bereich: Integrität Anwendungsdaten modifizieren - Falsch zugewiesene Ressourcen können von nicht autorisierten Benutzern modifiziert werden. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle Privilegien erlangen oder Identität annehmen - Eigentümerschaftsfehler können Privilegieneskalation ermöglichen. |
Beispielcode
Verwundbarer Code
// Verwundbar: Datei mit falscher Eigentümerschaft erstellt
#include <stdio.h>
#include <sys/stat.h>
#include <pwd.h>
#include <unistd.h>
void vulnerable_create_config() {
// Konfigurationsdatei erstellen
FILE* f = fopen("/etc/myapp/config.conf", "w");
if (f) {
fprintf(f, "setting=value\n");
fclose(f);
}
// Verwundbar: Datei gehört dem, der diesen Code ausführt
// Wenn als root ausgeführt, gehört sie root
// Wenn Installer als anderer Benutzer ausgeführt wird, ist Eigentümerschaft falsch
// Noch schlimmer: Explizit falsche Eigentümerschaft setzen
struct passwd* nobody = getpwnam("nobody");
if (nobody) {
// Verwundbar: Kritische Konfiguration gehört 'nobody'
// Jeder Prozess, der als 'nobody' läuft, kann sie modifizieren
chown("/etc/myapp/config.conf", nobody->pw_uid, nobody->pw_gid);
}
}
// Verwundbar: Symbolischer Link Eigentümerschaftsverwirrung
void vulnerable_symlink_chown(const char* path, uid_t uid, gid_t gid) {
// Verwundbar: chown folgt Symlinks!
// Wenn path ein Symlink ist, ändert dies die Eigentümerschaft des ZIELS
chown(path, uid, gid);
// Angreifer erstellt Symlink zu /etc/passwd, wir ändern dessen Eigentümerschaft
}
# Verwundbar: Installationsskript mit falscher Eigentümerschaft
import os
import shutil
def vulnerable_install():
# Anwendungsverzeichnis erstellen
app_dir = "/opt/myapp"
os.makedirs(app_dir, exist_ok=True)
# Binary kopieren
shutil.copy("myapp", os.path.join(app_dir, "myapp"))
# Verwundbar: Eigentümerschaft auf unprivilegierten Benutzer für Schreibbarkeit setzen
# Aber diese Binary könnte von root ausgeführt werden!
os.chown(os.path.join(app_dir, "myapp"), 1000, 1000) # uid 1000
# Angreifer (uid 1000) kann jetzt die Binary ersetzen
# Wenn root sie ausführt, wird Angreifers Code als root ausgeführt
# Verwundbar: Datenbank-Eigentümerschaft (CVE-2003-0265 Muster)
def vulnerable_create_db():
import sqlite3
# Datenbank mit Standardberechtigungen erstellen
db_path = "/var/lib/myapp/data.db"
conn = sqlite3.connect(db_path)
# Verwundbar: Datenbankdatei wird mit Eigentümerschaft des aktuellen Benutzers erstellt
# Wenn als root ausgeführt, ist Datei weltweit lesbar
# Wenn als Web-Benutzer ausgeführt, könnte sie für andere Web-Apps zugänglich sein
conn.execute("CREATE TABLE secrets (key TEXT, value TEXT)")
conn.close()
#!/bin/bash
# Verwundbar: Installationsskript mit Eigentümerschaftsproblemen
# Verwundbar: Verzeichnisse mit falscher Eigentümerschaft erstellen
mkdir -p /opt/myapp/bin
mkdir -p /opt/myapp/logs
# Verwundbar: bin-Verzeichnis gehört normalem Benutzer
# CVE-2007-4238 Muster - Binary kann ersetzt werden
chown -R myuser:mygroup /opt/myapp/bin
# Verwundbar: Log-Verzeichnis weltweit beschreibbar
chmod 777 /opt/myapp/logs
# Jeder Benutzer kann Logs schreiben oder löschen, potentiell Angriffe verbergend
# Verwundbar: Konfigurationsdatei mit falscher Gruppe
chown root:users /etc/myapp.conf
chmod 660 /etc/myapp.conf
# Alle Benutzer in 'users'-Gruppe können Konfiguration modifizieren
// Verwundbar: Java-Dateierstellung mit falscher Eigentümerschaft
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
public class VulnerableOwnership {
public void vulnerableCreateFile() throws IOException {
Path path = Paths.get("/tmp/myapp/sensitive.dat");
// Datei erstellen - Eigentümerschaft durch Prozessbenutzer bestimmt
Files.createFile(path);
// Verwundbar: Eigentümerschaft ohne Validierung auf bestimmten Benutzer setzen
UserPrincipal user = path.getFileSystem()
.getUserPrincipalLookupService()
.lookupPrincipalByName("daemon");
// Änderung zu 'daemon' Benutzer - aber warum?
// Dieses Dienstkonto könnte von mehreren Anwendungen geteilt werden
Files.setOwner(path, user);
}
}
Lösungscode
// Behoben: Ordnungsgemäße Eigentümerzuweisung
#include <stdio.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <fcntl.h>
void secure_create_config() {
// Behoben: Privilegien vor Erstellung abgeben wenn als root ausgeführt
// Oder mit expliziter Eigentümerschaft erstellen
// Beabsichtigten Eigentümer holen
struct passwd* app_user = getpwnam("myapp");
struct group* app_group = getgrnam("myapp");
if (!app_user || !app_group) {
return; // Anwendungsbenutzer/-gruppe muss existieren
}
// Datei mit restriktiven Berechtigungen erstellen
int fd = open("/etc/myapp/config.conf",
O_CREAT | O_WRONLY | O_TRUNC,
S_IRUSR | S_IWUSR); // 600 - nur Eigentümer
if (fd < 0) return;
// Behoben: Korrekte Eigentümerschaft für Anwendung setzen
fchown(fd, app_user->pw_uid, app_group->gr_gid);
write(fd, "setting=value\n", 14);
close(fd);
}
// Behoben: lchown für Symlink-sichere Eigentümerschaftsänderung verwenden
void secure_symlink_chown(const char* path, uid_t uid, gid_t gid) {
struct stat st;
// Behoben: Zuerst prüfen ob es ein Symlink ist
if (lstat(path, &st) == 0) {
if (S_ISLNK(st.st_mode)) {
// Behoben: lchown verwenden um Link-Eigentümerschaft zu ändern, nicht Ziel
lchown(path, uid, gid);
} else {
// Reguläre Datei - chown sicher verwendbar
chown(path, uid, gid);
}
}
}
// Alternative: Operationen auf Symlinks ablehnen
void secure_chown_no_symlinks(const char* path, uid_t uid, gid_t gid) {
struct stat st;
if (lstat(path, &st) != 0) return;
if (S_ISLNK(st.st_mode)) {
// Behoben: Eigentümerschaft durch Symlinks nicht ändern
fprintf(stderr, "Ablehnung: chown auf Symlink: %s\n", path);
return;
}
chown(path, uid, gid);
}
# Behoben: Ordnungsgemäße Installation mit korrekter Eigentümerschaft
import os
import shutil
import pwd
import grp
import stat
def secure_install():
app_dir = "/opt/myapp"
# Korrekten Benutzer/Gruppe holen
app_user = pwd.getpwnam("myapp")
app_group = grp.getgrnam("myapp")
# Verzeichnis mit korrekter Eigentümerschaft erstellen
os.makedirs(app_dir, exist_ok=True)
os.chown(app_dir, app_user.pw_uid, app_group.gr_gid)
os.chmod(app_dir, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP) # 750
# Binary kopieren
bin_path = os.path.join(app_dir, "myapp")
shutil.copy("myapp", bin_path)
# Behoben: Binary gehört root, nicht modifizierbar durch App-Benutzer
os.chown(bin_path, 0, 0) # root:root
os.chmod(bin_path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP |
stat.S_IROTH | stat.S_IXOTH) # 755
# Datenverzeichnis erstellen, das App-Benutzer gehört
data_dir = os.path.join(app_dir, "data")
os.makedirs(data_dir, exist_ok=True)
os.chown(data_dir, app_user.pw_uid, app_group.gr_gid)
os.chmod(data_dir, stat.S_IRWXU) # 700 - nur App-Benutzer
# Behoben: Sichere Datenbankerstellung
def secure_create_db():
import sqlite3
import tempfile
db_path = "/var/lib/myapp/data.db"
db_dir = os.path.dirname(db_path)
# Sicherstellen, dass Verzeichnis mit korrekten Berechtigungen existiert
os.makedirs(db_dir, mode=0o700, exist_ok=True)
# Anwendungsbenutzer holen
app_user = pwd.getpwnam("myapp")
os.chown(db_dir, app_user.pw_uid, app_user.pw_gid)
# Datenbank erstellen
conn = sqlite3.connect(db_path)
conn.execute("CREATE TABLE IF NOT EXISTS secrets (key TEXT, value TEXT)")
conn.close()
# Behoben: Korrekte Eigentümerschaft und Berechtigungen setzen
os.chown(db_path, app_user.pw_uid, app_user.pw_gid)
os.chmod(db_path, stat.S_IRUSR | stat.S_IWUSR) # 600
#!/bin/bash
# Behoben: Sicheres Installationsskript
# Verzeichnisse mit korrekter Eigentümerschaft erstellen
mkdir -p /opt/myapp/bin
mkdir -p /opt/myapp/logs
mkdir -p /opt/myapp/data
# Behoben: Binaries gehören root, nicht modifizierbar
chown root:root /opt/myapp/bin
chmod 755 /opt/myapp/bin
# Behoben: Logs gehören Anwendungsbenutzer, eingeschränkte Berechtigungen
chown myapp:myapp /opt/myapp/logs
chmod 750 /opt/myapp/logs # Nur Eigentümer und Gruppe können zugreifen
# Behoben: Datenverzeichnis gehört Anwendungsbenutzer
chown myapp:myapp /opt/myapp/data
chmod 700 /opt/myapp/data # Nur Anwendungsbenutzer
# Behoben: Konfiguration gehört root, lesbar durch App-Gruppe
chown root:myapp /etc/myapp.conf
chmod 640 /etc/myapp.conf # root schreibt, myapp-Gruppe liest
// Behoben: Java mit ordnungsgemäßer Eigentümerschaftsberücksichtigung
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
public class SecureOwnership {
public void secureCreateFile(String expectedOwner) throws IOException {
Path path = Paths.get("/var/lib/myapp/data.dat");
// Behoben: Zuerst mit restriktiven Berechtigungen erstellen
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");
FileAttribute<Set<PosixFilePermission>> attr =
PosixFilePermissions.asFileAttribute(perms);
Files.createFile(path, attr);
// Behoben: Verifizieren, dass Eigentümerschaft dem Erwarteten entspricht
UserPrincipal currentOwner = Files.getOwner(path);
if (!currentOwner.getName().equals(expectedOwner)) {
// Nur ändern wenn nötig und Ziel validieren
if (isValidApplicationUser(expectedOwner)) {
UserPrincipal newOwner = path.getFileSystem()
.getUserPrincipalLookupService()
.lookupPrincipalByName(expectedOwner);
Files.setOwner(path, newOwner);
} else {
throw new SecurityException("Ungültiger Eigentümer: " + expectedOwner);
}
}
}
private boolean isValidApplicationUser(String username) {
// Nur bestimmte Anwendungsbenutzer erlauben
return "myapp".equals(username) || "myapp-worker".equals(username);
}
}
CVE-Beispiele
- CVE-2024-43199: Binaries mit unsicherer Benutzer-/Gruppeneigentümerschaft installiert, die Modifikation ermöglicht.
- CVE-2007-4238: Programm mit bin-Eigentümer installiert, ermöglicht Benutzern Modifikation der ausführbaren Datei.
- CVE-2007-1716: Ressourceneigentümerschaft beim Abmelden nicht wiederhergestellt, ermöglicht Privilegieneskalation.
- CVE-2005-3148: Symbolische Links mit falscher uid/gid wiederhergestellt.
- CVE-2005-1064: Eigentümerschaft auf Symlink-Zielen statt Symlinks selbst geändert.
Referenzen
- MITRE Corporation. "CWE-708: Incorrect Ownership Assignment." https://cwe.mitre.org/data/definitions/708.html
- CWE-282: Improper Ownership Management.
- CERT C Coding Standard. "FIO01-C. Be careful using functions that use file names for identification."