Kritisches Datenelement als Public deklariert
Beschreibung
Kritisches Datenelement als Public deklariert ist eine Kapselungsschwachstelle, bei der Software eine kritische Variable, ein Feld oder ein Member als public deklariert, obwohl die beabsichtigte Sicherheitsrichtlinie erfordert, dass es privat ist. Dies tritt typischerweise in objektorientierten Sprachen auf, in denen Zugriffsmodifikatoren die Sichtbarkeit von Klassenmembern steuern. Wenn sicherheitsrelevante Daten wie Passwörter, kryptografische Schlüssel oder interne Zustandsvariablen als public deklariert werden, kann jeder Code mit Zugriff auf das Objekt diese Werte lesen oder ändern und dabei beabsichtigte Zugriffskontrollen und Sicherheitsgrenzen umgehen.
Risiko
Die Deklaration kritischer Datenelemente als public erzeugt erhebliche Sicherheits- und Wartbarkeitsrisiken. Angreifer oder bösartiger Code mit Zugriff auf das Objekt können direkt sensible Informationen lesen (Passwörter, Token, Schlüssel) oder kritische Zustandsvariablen ändern, um Sicherheitsprüfungen zu umgehen. Dies verletzt das Prinzip des Information Hiding und bricht die Kapselung, was es schwierig macht, Sicherheitsinvarianten durchzusetzen. Das Problem wirkt sich auch auf die Wartbarkeit aus, da es eine enge Kopplung zwischen Komponenten erzeugt und Sicherheitskorrekturen erschwert.
Lösung
Deklarieren Sie sicherheitskritische Variablen immer als private (oder protected, wenn Vererbung dies erfordert). Verwenden Sie Accessor (Getter) und Mutator (Setter) Methoden, die Validierung und Zugriffskontrolle durchsetzen können. Markieren Sie Felder als final/const, wenn sich der Wert nach der Initialisierung nicht ändern soll. Wenden Sie das Prinzip der geringsten Privilegien auf den Datenzugriff an - exponieren Sie nur das absolut Notwendige durch kontrollierte Schnittstellen. Verwenden Sie automatisierte statische Analysetools, um public-Deklarationen sensibler Datentypen zu erkennen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Vertraulichkeit Anwendungsdaten lesen - Public-Deklaration erlaubt jedem Code mit Objektzugriff, sensible Werte direkt zu lesen. |
| Integrität | Bereich: Integrität Anwendungsdaten ändern - Public-Deklaration erlaubt jedem Code, kritische Werte zu ändern und möglicherweise Sicherheitsprüfungen zu umgehen. |
| Sonstiges | Bereich: Sonstiges Wartbarkeit reduziert - Erschwert Änderungen der internen Implementierung ohne Auswirkungen auf abhängigen Code. |
Beispielcode
Verwundbarer Code
// Verwundbar: Passwort als public deklariert
class UserAccount {
public:
char* username;
char* password; // Verwundbar: Sollte private sein
int accountBalance; // Verwundbar: Sollte private sein
bool isAdmin; // Verwundbar: Kritisches Sicherheitsflag public
void authenticate(const char* inputPassword) {
if (strcmp(password, inputPassword) == 0) {
// Authentifiziert
}
}
};
void exploit() {
UserAccount user;
// Angreifer kann direkt auf sensible Daten zugreifen
printf("Password: %s\n", user.password); // Direkter Lesezugriff
user.isAdmin = true; // Privilegieneskalation
user.accountBalance = 999999; // Datenmanipulation
}
// Verwundbar: Java-Klasse mit public sensiblen Feldern
public class BankAccount {
public String accountNumber;
public double balance; // Verwundbar: Sollte private sein
public String pin; // Verwundbar: Kritische Anmeldedaten public
public String[] transactionHistory; // Verwundbar: Sensible Daten
public BankAccount(String accountNumber, String pin) {
this.accountNumber = accountNumber;
this.pin = pin;
this.balance = 0;
}
}
// Ausnutzung
class AttackerCode {
public void steal(BankAccount victim) {
System.out.println("PIN: " + victim.pin); // Direkter Zugriff
victim.balance = 0; // Direkte Manipulation
}
}
Gefixter Code
// Gefixt: Korrekte Kapselung mit privaten Membern
class UserAccount {
private:
std::string username;
std::string password; // Private: Vor direktem Zugriff geschützt
int accountBalance; // Private: Kontrollierter Zugriff
bool isAdmin; // Private: Sicherheitsflag geschützt
public:
UserAccount(const std::string& user, const std::string& pass)
: username(user), password(pass), accountBalance(0), isAdmin(false) {}
// Kontrollierte Accessoren mit Validierung
std::string getUsername() const { return username; }
bool authenticate(const std::string& inputPassword) const {
return password == inputPassword;
}
int getBalance() const { return accountBalance; }
bool deposit(int amount) {
if (amount > 0) {
accountBalance += amount;
return true;
}
return false;
}
// Kein public Setter für isAdmin - nur durch System kontrolliert
bool checkAdmin() const { return isAdmin; }
};
// Gefixt: Korrekte Kapselung in Java
public class BankAccount {
private final String accountNumber; // Unveränderlicher Identifier
private double balance;
private String pin;
private final List<String> transactionHistory;
public BankAccount(String accountNumber, String pin) {
this.accountNumber = accountNumber;
this.pin = pin;
this.balance = 0;
this.transactionHistory = new ArrayList<>();
}
public String getAccountNumber() {
return accountNumber;
}
public double getBalance() {
return balance;
}
// Kein Getter für PIN - nur Validierungsmethode
public boolean validatePin(String inputPin) {
return MessageDigest.isEqual(
pin.getBytes(StandardCharsets.UTF_8),
inputPin.getBytes(StandardCharsets.UTF_8)
);
}
public synchronized void deposit(double amount) {
if (amount > 0) {
balance += amount;
transactionHistory.add("Einzahlung: " + amount);
}
}
// Defensive Kopie der Transaktionshistorie zurückgeben
public List<String> getTransactionHistory() {
return new ArrayList<>(transactionHistory);
}
}
CVE-Beispiele
- CVE-2010-3860: JBoss MicroContainer erlaubte entfernten Angreifern das Lesen von Systemeigenschaften wie Benutzername und Home-Verzeichnis über als public deklarierte Variablen in Klassendefinitionen.
Referenzen
- MITRE Corporation. "CWE-766: Critical Data Element Declared Public." https://cwe.mitre.org/data/definitions/766.html
- CERT C++ Coding Standard. "OOP03-CPP. Use accessor and mutator methods for data encapsulation."
- Oracle Java Secure Coding Guidelines. "SECCODE-4: Restrict privileges and expose minimal data."