Preisgabe privater personenbezogener Daten an einen unautorisierten Akteur

Beschreibung

Preisgabe privater personenbezogener Daten an einen unautorisierten Akteur tritt auf, wenn ein Produkt nicht ordnungsgemäß verhindert, dass private, personenbezogene Informationen einer Person von Akteuren eingesehen werden, die entweder nicht explizit zum Zugriff auf die Informationen autorisiert sind oder nicht die implizite Zustimmung der betroffenen Person haben. Private personenbezogene Informationen (PPI) umfassen Passwörter, Telefonnummern, geografische Standorte, persönliche Nachrichten, Kreditkartennummern, Sozialversicherungsnummern, medizinische Akten und andere Daten, bei denen Einzelpersonen eine berechtigte Erwartung an Privatsphäre haben. Dies unterscheidet sich von allgemeiner Informationspreisgabe dadurch, dass es speziell persönliche, identifizierbare Informationen über Einzelpersonen betrifft.

Risiko

PPI-Preisgabe hat schwerwiegende Folgen für betroffene Personen und Organisationen. CVE-2025-41685 in SMAs Sunny Portal ermöglichte Angreifern, Benutzernamen durch Einreichung von E-Mail-Adressen zu erhalten. CVE-2025-62362 im niederländischen Regierungs-Bürgerportal legte Mitarbeiternamen und E-Mails über Browser-Entwicklertools offen, was gezielte Phishing-Kampagnen ermöglichte. CVE-2025-13008 in M-Files Server ermöglichte die Erfassung von Session-Tokens anderer Benutzer (CVSS 8.6). Diese Preisgaben verstoßen gegen DSGVO, HIPAA und andere Datenschutzvorschriften und führen zu erheblichen Bußgeldern. Preisgegebene personenbezogene Daten ermöglichen Identitätsdiebstahl, Betrug, Social Engineering und Belästigung betroffener Personen.

Lösung

Implementieren Sie strenge Zugriffskontrollen für alle personenbezogenen Daten. Wenden Sie das Prinzip der minimalen Rechtevergabe an -- legen Sie nur Daten offen, die für die aktuelle Operation notwendig sind. Validieren Sie die Benutzerautorisierung, bevor personenbezogene Informationen zurückgegeben werden. Entfernen Sie sensible Daten aus API-Antworten, Logs und Fehlermeldungen. Implementieren Sie Datenminimierung -- sammeln oder speichern Sie nicht mehr personenbezogene Daten als nötig. Verwenden Sie ordnungsgemäße Session-Isolierung, um benutzerübergreifenden Datenzugriff zu verhindern. Führen Sie Datenschutzfolgenabschätzungen durch. Implementieren Sie Audit-Logging für Zugriffe auf personenbezogene Daten. Wenden Sie Datenmaskierung für Anzeigezwecke an.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Datenschutzverletzung

Personenbezogene Informationen werden unautorisierten Parteien offengelegt, was die Privatsphäre Einzelner verletzt.
ComplianceBereich: Regulatorische Strafen

DSGVO, HIPAA, CCPA und andere Vorschriften schreiben den Schutz personenbezogener Daten vor, mit erheblichen Strafen bei Verstoßen.
ReputationBereich: Vertrauensverlust

Organisationen verlieren das Vertrauen der Nutzer, wenn personenbezogene Daten offengelegt werden, was zu Nutzerabwanderung und Markenschäden führt.

Beispielcode und Lösung

Verwundbarer Code

# VERWUNDBAR: Benutzerdaten ohne Autorisierungsprüfung offenlegen
@app.route('/api/user/<user_id>')
def get_user(user_id):
    user = User.query.get(user_id)
    # Gibt ALLE Benutzerdaten an JEDEN Anfragenden zurück!
    return jsonify({
        'id': user.id,
        'email': user.email,
        'phone': user.phone_number,
        'ssn': user.social_security_number,  # Extrem sensibel!
        'address': user.home_address,
        'credit_card': user.credit_card_number
    })

# VERWUNDBAR: Benutzerenumeration durch Fehlermeldungen
@app.route('/forgot-password', methods=['POST'])
def forgot_password():
    email = request.form['email']
    user = User.query.filter_by(email=email).first()
    if user:
        send_reset_email(user)
        return "Reset email sent"
    else:
        return "Email not found"  # Verraat, ob E-Mail existiert!
// VERWUNDBAR: Personenbezogene Daten protokollieren
import org.slf4j.Logger;

public class UserService {
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    public void processUserRegistration(User user) {
        // PII protokollieren!
        logger.info("Registering user: " + user.getEmail() +
                   ", SSN: " + user.getSsn() +
                   ", DOB: " + user.getDateOfBirth());
    }

    // VERWUNDBAR: Daten anderer Benutzer zurückgeben
    public List<User> searchUsers(String query) {
        // Gibt vollständige Benutzerobjekte einschließlich PII an jeden authentifizierten Benutzer zurück
        return userRepository.findByNameContaining(query);
    }
}
// VERWUNDBAR: Clientseitige Preisgabe sensibler Daten
app.get('/api/search/users', (req, res) => {
    const users = db.searchUsers(req.query.q);
    // Vollständige Benutzerobjekte an Client senden
    res.json(users.map(u => ({
        id: u.id,
        name: u.name,
        email: u.email,  // PII offengelegt
        phone: u.phone,  // PII offengelegt
        ssn: u.ssn,      // Extrem sensibel!
        salary: u.salary // Private Information
    })));
});

// VERWUNDBAR: PII in URL-Parametern
<a href="/profile?ssn=${user.ssn}&email=${user.email}">
    View Profile
</a>

Sichere Lösung

# SICHER: Autorisierungsprüfung und Datenminimierung
from functools import wraps

def require_owner_or_admin(f):
    @wraps(f)
    def decorated(user_id, *args, **kwargs):
        current_user = get_current_user()
        if current_user.id != user_id and not current_user.is_admin:
            abort(403)
        return f(user_id, *args, **kwargs)
    return decorated

@app.route('/api/user/<user_id>')
@require_owner_or_admin
def get_user_safe(user_id):
    user = User.query.get(user_id)
    current_user = get_current_user()

    # Unterschiedliche Daten basierend auf Autorisierungsebene zurückgeben
    if current_user.id == user_id:
        # Benutzer sieht eigenes Profil - voller Zugang
        return jsonify({
            'id': user.id,
            'email': user.email,
            'phone': mask_phone(user.phone_number),  # Sensible Daten maskieren
            'address': user.home_address
            # SSN, Kreditkarte niemals in API-Antworten zurückgeben
        })
    else:
        # Andere sehen eingeschränkte öffentliche Informationen
        return jsonify({
            'id': user.id,
            'name': user.display_name
        })

# SICHER: Benutzerenumeration verhindern
@app.route('/forgot-password', methods=['POST'])
def forgot_password_safe():
    email = request.form['email']
    user = User.query.filter_by(email=email).first()

    if user:
        send_reset_email(user)

    # Gleiche Nachricht unabhängig davon, ob Benutzer existiert
    return "If an account exists with this email, a reset link has been sent"

def mask_phone(phone):
    if not phone:
        return None
    return '***-***-' + phone[-4:]  # Nur letzte 4 Ziffern anzeigen
// SICHER: Kein PII in Logs, Datenzugriffskontrollen
import org.slf4j.Logger;

public class UserService {
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    public void processUserRegistration(User user) {
        // Nur nicht-sensible Identifikatoren protokollieren
        logger.info("Registering user with ID: {}", user.getId());
    }

    // SICHER: DTOs mit eingeschränkten Daten zurückgeben
    public List<UserSearchResultDTO> searchUsers(String query, User requestingUser) {
        List<User> users = userRepository.findByNameContaining(query);

        return users.stream()
            .map(user -> new UserSearchResultDTO(
                user.getId(),
                user.getDisplayName(),
                user.getPublicBio()
                // Keine E-Mail, Telefon, SSN oder andere PPI
            ))
            .collect(Collectors.toList());
    }

    // SICHER: Audit-Logging für PII-Zugriff
    @PreAuthorize("hasRole('ADMIN') or #userId == authentication.principal.id")
    public UserPrivateDTO getUserPrivateInfo(Long userId) {
        auditLogger.logPIIAccess(getCurrentUser(), userId);
        User user = userRepository.findById(userId).orElseThrow();
        return new UserPrivateDTO(user);
    }
}
// SICHER: Datenminimierung und Zugriffskontrolle
app.get('/api/search/users', authenticateUser, (req, res) => {
    const users = db.searchUsers(req.query.q);

    // Nur öffentliche Informationen zurückgeben
    res.json(users.map(u => ({
        id: u.id,
        name: u.name,
        avatar: u.avatarUrl
        // Keine E-Mail, Telefon, SSN, Gehalt
    })));
});

// SICHER: POST-Anfragen für sensible Operationen, kein PII in URLs
app.post('/api/profile/view', authenticateUser, (req, res) => {
    const { userId } = req.body;  // Nicht in URL

    // Autorisierung prüfen
    if (req.user.id !== userId && !req.user.isAdmin) {
        return res.status(403).json({ error: 'Unauthorized' });
    }

    // Audit-Log
    auditLog.record({
        action: 'VIEW_PROFILE',
        actor: req.user.id,
        target: userId,
        timestamp: new Date()
    });

    const profile = db.getUserProfile(userId);
    res.json(sanitizeForClient(profile));
});

function sanitizeForClient(profile) {
    // Alle Felder entfernen, die nicht an den Client gehen sollten
    const { ssn, creditCard, internalNotes, ...safe } = profile;
    return {
        ...safe,
        phone: maskPhone(safe.phone),
        email: maskEmail(safe.email)
    };
}

Ausgenutzt in der Praxis

SMA Sunny Portal Benutzernamen-Preisgabe (SMA, 2025)

CVE-2025-41685 in SMAs ennexos.sunnyportal.com ermöglichte Angreifern, Benutzernamen durch Einreichung von E-Mail-Adressen zu erhalten, was gezielte Angriffe auf Benutzer von Solarenergiesystemen ermöglichte.

Niederländisches Regierungs-Bürgerportal (GPP, 2025)

CVE-2025-62362 legte Mitarbeiternamen und E-Mail-Adressen in Netzwerkantworten offen, die über Browser-Entwicklertools sichtbar waren, was gezielte Phishing- und Social-Engineering-Kampagnen gegen Regierungsmitarbeiter ermöglichte.

M-Files Server Session-Token-Erfassung (M-Files, 2025)

CVE-2025-13008 ermöglichte authentifizierten Angreifern die Erfassung von Session-Tokens anderer aktiver Benutzer über die M-Files Web-Schnittstelle, mit CVSS 8.6 hoher Schweregrad eingestuft, mit potenzieller Offenlegung vertraulicher Dokumente.


Tools zum Testen und Ausnutzen


CVE-Beispiele


Referenzen

  1. MITRE. "CWE-359: Exposure of Private Personal Information to an Unauthorized Actor." https://cwe.mitre.org/data/definitions/359.html

  2. OWASP. "OWASP Top 10 Privacy Risks." https://owasp.org/www-project-top-10-privacy-risks/