Unvollständige Filterung mehrerer Instanzen von Sonderzeichen
Beschreibung
Unvollständige Filterung mehrerer Instanzen von Sonderzeichen ist eine Schwachstelle bei der Eingabevalidierung, bei der Software nicht alle Instanzen von Sonderzeichen filtert, wenn sie mehrfach in der Eingabe erscheinen. Dies betrifft sowohl sequentielle Elemente (gefährliche Sequenzen, die nebeneinander erscheinen, wie "....//") als auch nicht-sequentielle Elemente (dieselbe gefährliche Sequenz, die an mehreren Stellen in der Eingabe erscheint). Wenn die Filterung nicht alle Instanzen behandelt, können Angreifer Eingaben konstruieren, bei denen die Entfernung einiger Instanzen zusätzliche gefährliche Sequenzen erzeugt oder offenbart.
Risiko
Diese Schwachstelle ermöglicht ausgeklügelte Bypass-Techniken. Bei sequentiellen Elementen können Angreifer Eingaben wie "....//file" erstellen, bei denen das Entfernen der mittleren ".." und "/" eine neue "../"-Sequenz hinterlässt. Bei nicht-sequentiellen Elementen könnten Eingaben wie "..%2f..%2f../file" einige Traversal-Sequenzen gefiltert haben, während kodierte oder anders formatierte überleben. Das Risiko wird verstärkt, wenn die Filterung nur einmal angewendet wird, ohne zu prüfen, ob das Ergebnis nun gefährlich ist. Diese Bypasses sind besonders effektiv gegen naive Filterimplementierungen, die annehmen, ein einzelner Durchlauf sei ausreichend.
Lösung
Implementieren Sie rekursive oder iterative Filterung, die fortgesetzt wird, bis keine gefährlichen Sequenzen mehr gefunden werden. Wenden Sie die Filterung in einer Schleife an und vergleichen Sie das Ergebnis mit der vorherigen Iteration, bis sie übereinstimmen (was anzeigt, dass keine weiteren Änderungen vorgenommen wurden). Behandeln Sie alle Variationen gefährlicher Elemente einschließlich verschiedener Kodierungen, Groß-/Kleinschreibungsvariationen und Trennzeichenstile. Erwägen Sie mehrere Filterdurchläufe für verschiedene Kategorien gefährlicher Elemente. Verwenden Sie kanonische Darstellung vor der Validierung - für Pfade, lösen Sie diese in absolute kanonische Form auf, bevor Sie sie prüfen. Bevorzugen Sie Allowlist-Validierung, die nur bekannt sichere Zeichen erlaubt. Testen Sie mit komplexen verschachtelten und kodierten Eingaben.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Integrität | Bereich: Integrität Unerwarteter Zustand - Ungefilterte Element-Instanzen verursachen unbeabsichtigtes Anwendungsverhalten. |
| Vertraulichkeit | Bereich: Vertraulichkeit Anwendungsdaten lesen - Sequentielle Traversal-Muster, die die Filterung überleben, ermöglichen Dateizugriff. |
| Integrität | Bereich: Integrität Unautorisierten Code ausführen - Mehrere Kodierungsvariationen gefährlicher Elemente könnten Injection ermöglichen. |
Beispielcode
Verwundbarer Code
# Verwundbar: Einzelner Durchlauf behandelt keine sequentiellen Muster
my $Username = GetUntrustedInput();
# Verwundbar: Entfernt nur literale "../"-Sequenzen
$Username =~ s/\.\.\///g;
my $filename = "/home/user/" . $Username;
ReadAndSendFile($filename);
# Angriff: "....//....//etc/passwd"
# Nach Filter: jedes ".." gefolgt von "." gefolgt von "/" wird anders
# Ergebnis kann je nach genauem Muster immer noch Traversal ermöglichen
# Verwundbar: Behandelt keine doppelt kodierten Sequenzen
import urllib.parse
def vulnerable_filter(path):
# Erster Durchlauf: entferne Path-Traversal
filtered = path.replace('../', '')
# Verwundbar: Behandelt keine kodierten Versionen
return filtered
# Angriff: "..%2f..%2fetc%2fpasswd"
# Nach Filter: unverändert weil %2f nicht / ist
# Bei URL-Dekodierung durch Webserver: "../../../etc/passwd"
Lösungscode
# Behoben: Schleife bis keine weiteren Änderungen
my $Username = GetUntrustedInput();
# Behoben: Rekursive Filterung
my $prev;
do {
$prev = $Username;
# Alle Varianten entfernen
$Username =~ s/\.\.[\/\\]//g; # Literale Traversal
$Username =~ s/%2e%2e[%2f%5c]//gi; # URL-kodiert
$Username =~ s/%252e%252e[%252f%255c]//gi; # Doppelt kodiert
} while ($Username ne $prev);
# Besser: Gegen Allowlist validieren
unless ($Username =~ /^[a-zA-Z0-9_.-]+$/) {
die "Ungültiger Benutzername";
}
my $filename = "/home/user/" . $Username;
# Behoben: Alle Kodierungsvarianten behandeln und Schleife
import urllib.parse
import os.path
def fixed_filter(path):
# Mehrfach dekodieren für doppelte/dreifache Kodierung
decoded = path
for _ in range(3): # Bis zu dreifache Kodierung behandeln
prev = decoded
decoded = urllib.parse.unquote(decoded)
if decoded == prev:
break
# Schleife bis stabil
prev = None
while decoded != prev:
prev = decoded
# Alle Traversal-Varianten entfernen
decoded = decoded.replace('../', '')
decoded = decoded.replace('..\\', '')
return decoded
# Besser: Kanonische Pfadvalidierung verwenden
def fixed_validate_path(base_dir, user_path):
# Benutzereingabe dekodieren
decoded = user_path
for _ in range(3):
prev = decoded
decoded = urllib.parse.unquote(decoded)
if decoded == prev:
break
# Zu kanonischem Pfad auflösen
full_path = os.path.realpath(os.path.join(base_dir, decoded))
base_path = os.path.realpath(base_dir)
# Verifizieren, dass es unter Basisverzeichnis ist
if not full_path.startswith(base_path + os.sep):
raise ValueError("Path-Traversal erkannt")
return full_path
Verwandte CWEs
- CWE-792: Unvollständige Filterung einer oder mehrerer Instanzen von Sonderzeichen (Eltern)
- CWE-793: Nur Filterung einer Instanz eines Sonderzeichens (Geschwister)
- CWE-23: Relative Path-Traversal (verwandte Ausnutzung)
Referenzen
- MITRE Corporation. "CWE-794: Incomplete Filtering of Multiple Instances of Special Elements." https://cwe.mitre.org/data/definitions/794.html
- OWASP. "Path Traversal." https://owasp.org/www-community/attacks/Path_Traversal
- OWASP. "Double Encoding." https://owasp.org/www-community/Double_Encoding