Falschdarstellung kritischer Informationen in der Benutzeroberfläche (UI)

Beschreibung

Falschdarstellung kritischer Informationen in der Benutzeroberfläche ist eine Schwachstelle, bei der die Benutzeroberfläche kritische Informationen nicht genau darstellt, wodurch Daten oder deren Quelle verschleiert oder gefälscht werden können. Diese Schwäche manifestiert sich auf verschiedene Weisen: Falsche Indikatoren, die falsche Informationen über den Systemzustand anzeigen, Overlays, bei denen ein UI-Element ein anderes verdeckt und Clickjacking ermöglicht, Icon-Manipulation, die gefährliche Dateien harmlos erscheinen lässt, Timing-Probleme, die falsche Zustandsindikatoren verursachen, visuelle Kürzung, die kritische Teile von Informationen wie Dateierweiterungen verbirgt, visuelle Unterscheidungsprobleme, die es schwierig machen, kritische Informationen zu identifizieren, und Homograph-Angriffe, die ähnlich aussehende Zeichen verwenden, um Benutzer zu täuschen.

Risiko

UI-Falschdarstellung ermöglicht ein breites Spektrum von Angriffen, insbesondere Phishing und Social Engineering. Angreifer können bösartige Websites legitim erscheinen lassen, indem sie URLs oder Sicherheitsindikatoren fälschen. Ausführbare Dateien können durch Icon- oder Erweiterungsmanipulation als harmlose Dokumente getarnt werden. Clickjacking-Angriffe überlagern unsichtbare Elemente, um unbeabsichtigte Klicks abzufangen. Unicode-Homograph-Angriffe verwenden ähnlich aussehende Zeichen, um überzeugende gefälschte URLs zu erstellen. Das Risiko ist schwerwiegend, weil Benutzer sich auf visuelle Hinweise verlassen, um Sicherheitsentscheidungen zu treffen, und manipulierte Oberflächen dieses Vertrauen untergraben. Diese Angriffe sind besonders effektiv, weil sie menschliche Wahrnehmung ausnutzen, anstatt technische Schwachstellen.

Lösung

Validieren Sie während der Implementierung alle Eingabesyntax, Länge und Format vor der Verarbeitung und Anzeige. Entwickeln Sie während der Architektur und des Designs eine Informationspräsentationsstrategie, die ungewöhnliche Zeichen, Homoglyphen und potenzielle Kürzung berücksichtigt. Stellen Sie sicher, dass kritische Informationen wie URLs, Dateierweiterungen und Sicherheitsindikatoren nicht verschleiert oder manipuliert werden können. Verwenden Sie visuelles Design, das klar zwischen vertrauenswürdigem und nicht vertrauenswürdigem Inhalt unterscheidet. Implementieren Sie Schutzmaßnahmen gegen Frame-basierte Angriffe (X-Frame-Options, CSP frame-ancestors). Zeigen Sie vollständige URLs ohne Kürzung in sicherheitskritischen Kontexten an. Verwenden Sie robuste Homograph-Erkennung für Domainnamen und andere kritische Identifikatoren.

Häufige Auswirkungen

AuswirkungDetails
Nicht-AbstreitbarkeitUmfang: Nicht-Abstreitbarkeit

Aktivitäten verbergen - Angreifer können bösartige Aktivitäten verschleiern, indem sie manipulieren, wie Informationen dem Benutzer angezeigt werden.
ZugriffskontrolleUmfang: Zugriffskontrolle

Schutzmechanismus umgehen - Benutzer können versehentlich Zugriff oder Berechtigungen gewähren, wenn die UI falsch darstellt, welche Aktion ausgeführt wird.

Beispielcode

Anfälliger Code

<!-- Anfällig: URL-Anzeige, die gekürzt oder gefälscht werden kann -->
<div class="url-bar">
    <!-- Anfällig: Länge URLs werden gekürzt, echte Domain verborgen -->
    <input type="text" class="url-display"
           value="https://[email protected]/login"
           style="width: 200px; overflow: hidden;">
    <!-- Benutzer sieht "https://www.secure-bank.com" aber echte Domain ist evil.com -->
</div>

<!-- Anfällig: Schloss-Symbol, das tatsächliche Sicherheit nicht widerspiegelt -->
<div class="security-indicator">
    <!-- Anfällig: Zeigt Schloss auch bei Seiten mit gemischtem Inhalt -->
    <img src="lock-icon.png" class="always-show-lock">
    <!-- Benutzer vertraut darauf, dass Seite sicher ist, während unsicherer Inhalt geladen wird -->
</div>

<!-- Anfällig: Clickjacking durch transparentes Overlay -->
<style>
.visible-content {
    position: relative;
    z-index: 1;
}
.hidden-action {
    /* Anfällig: Unsichtbarer iframe fängt Klicks ab */
    position: absolute;
    opacity: 0;
    z-index: 2;
    width: 100%;
    height: 100%;
}
</style>
<div class="visible-content">
    <button>Hier klicken für Gratispreis!</button>
    <iframe class="hidden-action" src="https://bank.com/transfer?to=attacker&amount=1000"></iframe>
    <!-- Benutzer klickt auf "Gratispreis" aber initiiert tatsächlich Banküberweisung -->
</div>
# Anfällig: Dateianzeige mit versteckter Erweiterung
class VulnerableFileDisplay:
    def display_filename(self, filename, max_length=20):
        # Anfällig: Kürzt Dateinamen, kann gefährliche Erweiterung verbergen
        if len(filename) > max_length:
            return filename[:max_length] + "..."

        # "wichtiges_dokument.txt.exe" wird zu "wichtiges_dokument...."
        # Benutzer sieht .exe Erweiterung nicht
        return filename

    def get_file_icon(self, filename):
        # Anfällig: Verwendet eingebettetes Icon aus Datei
        # Malware kann Dokument-Icon in .exe Datei einbetten
        try:
            return extract_embedded_icon(filename)  # Aus der Datei selbst
        except:
            return self.get_default_icon(filename)

        # Benutzer sieht Word-Dokument-Icon für malware.exe
// Anfällig: Dialogfeld mit irreführendem Ursprung
class VulnerableDialogManager {

    showAlert(message, title) {
        // Anfällig: Dialog zeigt nicht, welche Webseite ihn ausgelöst hat
        const dialog = document.createElement('div');
        dialog.className = 'system-dialog';  // Sieht aus wie OS-Dialog
        dialog.innerHTML = `
            <h2>${title}</h2>
            <p>${message}</p>
            <button onclick="handleOK()">OK</button>
        `;

        // Benutzer kann nicht erkennen, dass dies von einer Webseite kommt, nicht vom System
        // Angreifer zeigt: "Ihr Computer ist infiziert! Klicken Sie OK zum Bereinigen"
        document.body.appendChild(dialog);
    }

    // Anfällig: Passwort-Eingabe, die echtes Ziel verbirgt
    showPasswordPrompt() {
        // Dialog zeigt "Passwort eingeben für secure-site.com"
        // Aber sendet tatsächlich an attacker.com

        return prompt("Geben Sie Ihr Passwort für secure-site.com ein");
        // Wird an Domain der aktuellen Seite gesendet (Angreifer-kontrolliert)
    }
}
// Anfällig: Homograph-Angriff in URL-Anzeige
public class VulnerableURLDisplay {

    public String displayURL(String url) {
        // Anfällig: Erkennt keine Unicode-Homoglyphen
        // "аpple.com" (kyrillisches 'а') sieht aus wie "apple.com" (lateinisches 'a')

        return url;  // Wird unverändert angezeigt, Benutzer kann Unterschied nicht sehen
    }

    // Anfällig: Zertifikatanzeige ohne ordnungsgemäße Verifizierung
    public void displayCertificateInfo(X509Certificate cert) {
        // Anfällig: Zeigt Subjekt ohne Validierung
        String subject = cert.getSubjectDN().getName();

        // Angreifer verwendet Zertifikat für "secure-bаnk.com" (kyrillisches 'а')
        // Anzeige zeigt was aussieht wie "secure-bank.com"

        System.out.println("Zertifikat für: " + subject);
    }
}

Korrigierter Code

<!-- Korrigiert: URL-Anzeige mit Sicherheitsschutz -->
<style>
.url-bar {
    display: flex;
    align-items: center;
}
.url-display {
    /* Korrigiert: Zeigt vollständige URL, erlaubt horizontales Scrollen */
    width: 100%;
    overflow-x: auto;
    white-space: nowrap;
    font-family: monospace;  /* Feste Breite für bessere Lesbarkeit */
}
.domain-highlight {
    /* Korrigiert: Hebt tatsächliche Domain hervor */
    font-weight: bold;
    color: #000;
}
.path-portion {
    color: #666;
}
</style>

<div class="url-bar">
    <!-- Korrigiert: Parst und zeigt URL-Komponenten klar an -->
    <span class="protocol">https://</span>
    <span class="domain-highlight" id="actual-domain">evil.com</span>
    <span class="path-portion">/www.secure-bank.com/login</span>
</div>

<script>
// Korrigiert: Parst URL und hebt tatsächliche Domain hervor
function displayURL(url) {
    try {
        const parsed = new URL(url);
        document.querySelector('.protocol').textContent = parsed.protocol + '//';
        document.querySelector('.domain-highlight').textContent = parsed.hostname;
        document.querySelector('.path-portion').textContent = parsed.pathname + parsed.search;
    } catch (e) {
        // Korrigiert: Zeigt Warnung für ungültige URLs
        document.querySelector('.url-bar').classList.add('invalid-url');
    }
}
</script>

<!-- Korrigiert: Clickjacking-Schutz -->
<head>
    <!-- Korrigiert: Verhindert Framing -->
    <meta http-equiv="Content-Security-Policy" content="frame-ancestors 'self'">
</head>

<!-- Korrigiert: Server-seitiger Header -->
<!-- X-Frame-Options: DENY -->
<!-- Content-Security-Policy: frame-ancestors 'self' -->
# Korrigiert: Dateianzeige mit Erweiterungsschutz
import os
from pathlib import Path

class SecureFileDisplay:
    DANGEROUS_EXTENSIONS = {'.exe', '.bat', '.cmd', '.ps1', '.vbs', '.js', '.msi', '.scr'}

    def display_filename(self, filename, max_length=50):
        # Korrigiert: Verbirgt niemals die Erweiterung
        name = Path(filename).stem
        ext = Path(filename).suffix

        if len(filename) <= max_length:
            return filename

        # Korrigiert: Kürzt nur Namensteil, zeigt immer Erweiterung
        available_for_name = max_length - len(ext) - 3  # "..." benötigt 3
        if available_for_name < 10:
            available_for_name = 10  # Minimale Namenslänge

        return f"{name[:available_for_name]}...{ext}"

    def get_file_icon(self, filename):
        # Korrigiert: Verwendet erweiterungsbasiertes Icon, vertraut niemals eingebetteten Icons
        ext = Path(filename).suffix.lower()

        # Korrigiert: Ordnet Erweiterungen bekannten sicheren Icons zu
        icon_map = {
            '.txt': 'text-icon.png',
            '.pdf': 'pdf-icon.png',
            '.doc': 'doc-icon.png',
            '.docx': 'doc-icon.png',
            '.exe': 'executable-warning-icon.png',  # Warn-Icon für ausführbare Dateien
        }

        return icon_map.get(ext, 'unknown-file-icon.png')

    def analyze_filename_risks(self, filename):
        """Erkennt potenziell täuschende Dateinamen."""
        risks = []

        # Korrigiert: Prüft auf doppelte Erweiterungen
        parts = filename.split('.')
        if len(parts) > 2:
            for ext in parts[1:-1]:
                if f'.{ext}' in self.DANGEROUS_EXTENSIONS:
                    risks.append(f"Versteckte gefährliche Erweiterung: .{ext}")

        # Korrigiert: Prüft auf Unicode-Tricks
        if any(ord(c) > 127 for c in filename):
            risks.append("Dateiname enthält Nicht-ASCII-Zeichen")

        # Korrigiert: Prüft auf RTL-Override
        if '\u202e' in filename:
            risks.append("Dateiname enthält RTL-Override-Zeichen")

        return risks
// Korrigiert: Dialogfeld mit klarer Ursprungsangabe
class SecureDialogManager {

    showAlert(message, title) {
        // Korrigiert: Zeigt Webseiten-Ursprung klar an
        const origin = window.location.hostname;

        const dialog = document.createElement('div');
        dialog.className = 'webpage-dialog';  // Unterscheidet sich von System-Dialogen
        dialog.innerHTML = `
            <div class="dialog-origin">
                ⚠️ Diese Nachricht kommt von: ${this.escapeHtml(origin)}
            </div>
            <h2>${this.escapeHtml(title)}</h2>
            <p>${this.escapeHtml(message)}</p>
            <button onclick="this.closest('.webpage-dialog').remove()">OK</button>
        `;

        // Korrigiert: Stil macht klar, dass dies von Webseite kommt
        dialog.style.cssText = `
            border: 3px solid orange;
            background: #fff3cd;
        `;

        document.body.appendChild(dialog);
    }

    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    // Korrigiert: Anmeldeinformations-Eingaben müssen echtes Ziel zeigen
    showCredentialPrompt(action, destination) {
        // Korrigiert: Verwendet Browser-eigene Anmeldeinformations-Verwaltung
        // Oder zeigt klares, verifiziertes Ziel

        if (destination !== window.location.hostname) {
            alert(`Warnung: Anmeldedaten werden an ${destination} gesendet, nicht an diese Website.`);
            return null;
        }

        // Korrigiert: Verwendet Credential Management API
        return navigator.credentials.get({
            password: true,
            mediation: 'required'
        });
    }
}
// Korrigiert: Homograph-Erkennung in URL-Anzeige
import java.text.Normalizer;
import java.util.regex.Pattern;

public class SecureURLDisplay {

    // Unicode-Blockbereiche für verwechselbare Schriften
    private static final Pattern CYRILLIC = Pattern.compile("[\\u0400-\\u04FF]");
    private static final Pattern GREEK = Pattern.compile("[\\u0370-\\u03FF]");

    public DisplayResult displayURL(String url) {
        DisplayResult result = new DisplayResult();

        // Korrigiert: Prüft auf gemischte Schriften (potenzieller Homograph)
        String domain = extractDomain(url);

        if (containsMixedScripts(domain)) {
            result.warning = "Warnung: Domain enthält Zeichen aus mehreren Schriften (mögliches Spoofing)";
            result.displayDomain = convertToAscii(domain);  // Zeigt Punycode
        } else {
            result.displayDomain = domain;
        }

        // Korrigiert: Hebt verwechselbare Zeichen hervor
        result.highlightedDomain = highlightConfusables(domain);

        return result;
    }

    private boolean containsMixedScripts(String text) {
        boolean hasLatin = text.matches(".*[a-zA-Z].*");
        boolean hasCyrillic = CYRILLIC.matcher(text).find();
        boolean hasGreek = GREEK.matcher(text).find();

        // Gemischte Schriften sind verdächtig
        int scriptCount = 0;
        if (hasLatin) scriptCount++;
        if (hasCyrillic) scriptCount++;
        if (hasGreek) scriptCount++;

        return scriptCount > 1;
    }

    private String convertToAscii(String domain) {
        // Korrigiert: Konvertiert IDN zu ASCII (Punycode)
        try {
            return java.net.IDN.toASCII(domain, java.net.IDN.ALLOW_UNASSIGNED);
        } catch (IllegalArgumentException e) {
            return "[Ungültige Domain]";
        }
    }

    public CertificateDisplayResult displayCertificateInfo(X509Certificate cert) {
        CertificateDisplayResult result = new CertificateDisplayResult();

        String subject = cert.getSubjectX500Principal().getName();

        // Korrigiert: Extrahiert und validiert CN
        String cn = extractCN(subject);

        // Korrigiert: Prüft auf Homograph im Zertifikat-CN
        if (containsMixedScripts(cn)) {
            result.warning = "Zertifikat enthält Zeichen aus gemischten Schriften";
            result.asciiCN = convertToAscii(cn);
        }

        // Korrigiert: Zeigt vollständige Zertifikatdetails einschließlich Aussteller
        result.subject = subject;
        result.issuer = cert.getIssuerX500Principal().getName();
        result.validFrom = cert.getNotBefore();
        result.validTo = cert.getNotAfter();

        return result;
    }
}

CVE-Beispiele

  • CVE-2004-2227 - Dateidialog kürzte lange Dateinamen und verbarg ausführbare Erweiterungen vor Benutzern.
  • CVE-2004-1104 - Browser wurde dazu gebracht, falsche URL in der Adressleiste anzuzeigen.
  • CVE-2005-0143 - Schloss-Symbol wurde angezeigt, obwohl die Seite unsicheren Inhalt lud (Mixed-Content-Schwachstelle).
  • CVE-2004-0537 - Breites Icon überlagerte und verdeckte Adressleiste und ermöglichte URL-Spoofing.
  • CVE-2005-2271 - JavaScript-Dialoge zeigten nicht klar an, welche Webseite sie ausgelöst hatte.
  • CVE-2003-1025 - Spezielles URL-Zeichen kürzte Benutzerteil und verbarg echte Domain vor Benutzern.
  • CVE-2004-1451 - Null-Zeichen in URL verhinderte vollständige URL-Anzeige im Browser.

Referenzen

  1. MITRE Corporation. "CWE-451: User Interface (UI) Misrepresentation of Critical Information." https://cwe.mitre.org/data/definitions/451.html
  2. OWASP. "Clickjacking Defense Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
  3. The Unicode Consortium. "Unicode Security Mechanisms." https://www.unicode.org/reports/tr39/