Nur Filterung von Sonderzeichen an einer bestimmten Position

Beschreibung

Nur Filterung von Sonderzeichen an einer bestimmten Position ist eine Schwachstelle bei der Eingabevalidierung, bei der Software Sonderzeichen nur an bestimmten Positionen innerhalb der Eingabe filtert und gefährliche Elemente an anderen Stellen in den Daten ungefiltert lässt. Dies beinhaltet Filterung nur relativ zu Markierungen (wie Anfang oder Ende eines Strings) oder an absoluten Positionen (wie bestimmten Byte-Offsets). Die Annahme, dass gefährliche Elemente nur an bestimmten Positionen erscheinen werden, ist fehlerhaft, da Angreifer bösartige Sequenzen überall in der Eingabe positionieren können, um den unvollständigen Filter zu umgehen.

Risiko

Diese Schwachstelle bietet Angreifern einen vorhersehbaren Umgehungsmechanismus. Wenn ein Filter nur "../"-Sequenzen am Anfang eines Strings entfernt, können Angreifer einfach ein beliebiges Zeichen voranstellen oder Eingaben konstruieren, bei denen die gefährlichen Sequenzen nach der geprüften Position erscheinen. Zum Beispiel passiert "foo/../../../etc/passwd" einen Filter, der nur Position 0 prüft. Die Schwachstelle ist besonders gefährlich, weil der Filter ein falsches Sicherheitsgefühl vermittelt - Entwickler könnten glauben, dass Path-Traversal oder Injection behandelt wird, obwohl dies eindeutig nicht der Fall ist. Tests, die nur bösartige Eingaben an der erwarteten Position verwenden, werden bestanden, was die Schwachstelle während der Entwicklung leicht zu übersehen macht.

Lösung

Nehmen Sie niemals an, dass gefährliche Elemente nur an bestimmten Positionen erscheinen werden. Verwenden Sie globales Muster-Matching, das die gesamte Eingabe nach allen Instanzen gefährlicher Sequenzen durchsucht. Für Pfadvalidierung lösen Sie den Pfad in seine kanonische Form auf und überprüfen Sie, ob er innerhalb erlaubter Grenzen liegt. Implementieren Sie Allowlist-Validierung, die nur bekannt sichere Zeichen unabhängig von der Position erlaubt. Wenden Sie Filter iterativ an, bis keine gefährlichen Muster mehr gefunden werden. Für pfadbasierte Operationen verwenden Sie realpath() oder äquivalente kanonische Pfadauflösung und überprüfen Sie dann, ob das Ergebnis innerhalb des beabsichtigten Verzeichnisses liegt. Testen Sie mit gefährlichen Elementen an verschiedenen Positionen: Anfang, Mitte, Ende und mehreren Stellen.

Häufige Auswirkungen

AuswirkungDetails
IntegritätBereich: Integrität

Unerwarteter Zustand - Ungefilterte Elemente an unerwarteten Positionen veranlassen Daten, in einem gefährlichen Zustand durchzukommen.
VertraulichkeitBereich: Vertraulichkeit

Anwendungsdaten lesen - Path-Traversal-Sequenzen außerhalb der geprüften Position ermöglichen unautorisierten Dateizugriff.
IntegritätBereich: Integrität

Unautorisierten Code ausführen - Injection-Sequenzen, die außerhalb gefilterter Positionen positioniert sind, ermöglichen Angriffe.

Beispielcode

Verwundbarer Code

# Verwundbar: Filtert "../" nur am Anfang des Strings
my $Username = GetUntrustedInput();

# Verwundbar: ^ Anker matched nur am String-Anfang
$Username =~ s/^\.\.\///;

my $filename = "/home/user/" . $Username;
ReadAndSendFile($filename);

# Angriff: "foo/../../../etc/passwd" - "../" nicht am Anfang, passiert Filter
# Angriff: "../../../etc/passwd" - nur erstes "../" entfernt, lässt "../../etc/passwd"
// Verwundbar: Entfernt nur Präfix
<?php
function vulnerable_filter($path) {
    // Verwundbar: Entfernt nur führende ../
    if (strpos($path, '../') === 0) {
        $path = substr($path, 3);
    }
    return $path;
}

// Angriff: "foo/../../../etc/passwd" - nicht am Anfang, unverändert
// Angriff: "./../../etc/passwd" - "./" am Anfang, nicht gefiltert

Lösungscode

# Behoben: Alle Vorkommen im gesamten String filtern
my $Username = GetUntrustedInput();

# Behoben: Kein Anker - matched überall; /g für globale Ersetzung
# Schleife behandelt verschachtelte Muster
my $prev;
do {
    $prev = $Username;
    $Username =~ s/\.\.[\\/]//g;  # Alle Vorkommen
} while ($Username ne $prev);

# Besser: Mit Allowlist validieren
unless ($Username =~ /^[a-zA-Z0-9_.-]+$/) {
    die "Ungültiger Benutzername";
}

my $filename = "/home/user/" . $Username;
// Behoben: Kanonische Pfadvalidierung verwenden
<?php
function fixed_validate_path($base, $userPath) {
    // Zu kanonischem Pfad auflösen
    $basePath = realpath($base);
    $fullPath = realpath($base . DIRECTORY_SEPARATOR . $userPath);

    // Prüfen ob aufgelöster Pfad unter Basis ist
    if ($fullPath === false ||
        strpos($fullPath, $basePath . DIRECTORY_SEPARATOR) !== 0) {
        throw new Exception("Path-Traversal erkannt");
    }

    return $fullPath;
}

// Filterfunktion die überall im String funktioniert
function fixed_filter_traversal($input) {
    $prev = null;
    while ($input !== $prev) {
        $prev = $input;
        $input = str_replace('../', '', $input);
        $input = str_replace('..\\', '', $input);
    }
    return $input;
}

Verwandte CWEs

  • CWE-791: Unvollständige Filterung von Sonderzeichen (Eltern)
  • CWE-796: Nur Filterung von Sonderzeichen relativ zu einer Markierung (Kind)
  • CWE-797: Nur Filterung von Sonderzeichen an einer absoluten Position (Kind)
  • CWE-22: Unsachgemäße Einschränkung eines Pfadnamens auf ein beschränktes Verzeichnis (verwandte Ausnutzung)

Referenzen

  1. MITRE Corporation. "CWE-795: Only Filtering Special Elements at a Specified Location." https://cwe.mitre.org/data/definitions/795.html
  2. OWASP. "Input Validation Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html
  3. OWASP. "Path Traversal." https://owasp.org/www-community/attacks/Path_Traversal