Nur Filterung von Sonderzeichen an einer absoluten Position
Beschreibung
Nur Filterung von Sonderzeichen an einer absoluten Position ist eine Schwachstelle bei der Eingabevalidierung, bei der Software gefährliche Elemente nur filtert, wenn sie an bestimmten Byte-Offsets oder Zeichenpositionen innerhalb der Eingabe erscheinen. Der Filter prüft feste Positionen (wie "Byte 0", "Zeichen 0-2" oder "Position 10"), anstatt die gesamte Eingabe nach gefährlichen Sequenzen zu durchsuchen. Dieser Ansatz scheitert, wenn Angreifer bösartigen Inhalt an einer anderen Position als den spezifisch geprüften Positionen platzieren, wodurch die gefährlichen Elemente den Filter unverändert passieren.
Risiko
Diese Schwachstelle ermöglicht eine unkomplizierte Umgehung durch einfaches Positionieren gefährlichen Inhalts an einer ungeprüften Position. Wenn ein Filter nur die Positionen 0-2 auf "../" prüft, kann ein Angreifer "x/../../../etc/passwd" verwenden, wo die Traversal-Sequenzen bei Position 1 statt 0 beginnen. Die Starrheit der positionsbasierten Prüfung macht dies noch einfacher auszunutzen als markierungsrelative Filterung, da jede Eingabestruktur, die den gefährlichen Inhalt auch nur um ein Byte verschiebt, den Schutz besiegt. Die Schwachstelle zeigt ein grundlegendes Missverständnis darüber, wie Eingabevalidierung funktionieren sollte - gefährlicher Inhalt muss neutralisiert werden, unabhängig davon, wo er erscheint.
Lösung
Verlassen Sie sich niemals auf absolute Positionen für Sicherheitsfilterung. Implementieren Sie Mustersuchen, die die gesamte Eingabe von Anfang bis Ende untersuchen. Verwenden Sie String-Suchfunktionen oder reguläre Ausdrücke ohne Positionsbeschränkungen. Für Pfadvalidierung lösen Sie Eingaben zur kanonischen Form auf und überprüfen Sie, ob sie innerhalb erlaubter Verzeichnisse verbleiben. Wenden Sie Allowlist-Validierung an, die nur bekannt sichere Zeichen an jeder Position erlaubt. Wiederholen Sie Filteroperationen in einer Schleife, bis keine Übereinstimmungen mehr gefunden werden, um verschachtelte Muster zu behandeln. Testen Sie mit gefährlichem Inhalt an verschiedenen Positionen einschließlich Anfang, Mitte und Ende der Eingaben.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Integrität | Bereich: Integrität Unerwarteter Zustand - Gefährliche Elemente an nicht geprüften Positionen passieren Filter und verursachen unbeabsichtigtes Anwendungsverhalten. |
| Vertraulichkeit | Bereich: Vertraulichkeit Anwendungsdaten lesen - Path-Traversal an ungeprüften Positionen ermöglicht unautorisierten Dateizugriff. |
| Integrität | Bereich: Integrität Unautorisierten Code ausführen - Injection-Sequenzen, die außerhalb geprüfter Offsets positioniert sind, ermöglichen Angriffe. |
Beispielcode
Verwundbarer Code
# Verwundbar: Prüft nur Substring an absoluter Position 0-2
my $Username = GetUntrustedInput();
# Verwundbar: Prüft nur ob "../" an Position 0-2 ist
if (substr($Username, 0, 3) eq '../') {
$Username = substr($Username, 3);
}
my $filename = "/home/user/" . $Username;
ReadAndSendFile($filename);
# Angriff: "../../../etc/passwd" - nur erstes "../" entfernt
# Angriff: "x/../../../etc/passwd" - "../" an Position 1, nicht geprüft
# Angriff: "a/../../../etc/passwd" - "../" an Position 2, nicht geprüft
// Verwundbar: Prüft nur bestimmte Zeichenpositionen
char* vulnerable_filter(char* input) {
// Verwundbar: Prüft nur Positionen 0-2 auf "../"
if (input[0] == '.' && input[1] == '.' && input[2] == '/') {
return input + 3; // Erste 3 Zeichen überspringen
}
return input;
}
// Angriff: "x/../etc/passwd" - "../" an Position 1
// Angriff: "a/../etc/passwd" - "../" an Position 2
Lösungscode
# Behoben: Gesamten String durchsuchen, nicht spezifische Positionen
my $Username = GetUntrustedInput();
# Behoben: Von überall entfernen, Schleife bis stabil
my $prev;
do {
$prev = $Username;
# Gesamten String mit globaler Ersetzung durchsuchen
$Username =~ s/\.\.[\\/]//g;
} while ($Username ne $prev);
# Besser: Allowlist-Validierung
unless ($Username =~ /^[a-zA-Z0-9_.-]+$/) {
die "Ungültiger Benutzername";
}
my $filename = "/home/user/" . $Username;
// Behoben: Gesamten String durchsuchen
#include <string.h>
#include <stdlib.h>
char* fixed_filter(const char* input) {
size_t len = strlen(input);
char* result = malloc(len + 1);
size_t j = 0;
// Behoben: Jede Position prüfen, nicht nur Position 0
for (size_t i = 0; i < len; i++) {
// Auf "../" an aktueller Position prüfen
if (i + 2 < len &&
input[i] == '.' && input[i+1] == '.' &&
(input[i+2] == '/' || input[i+2] == '\\')) {
i += 2; // "../" überspringen (Schleife fügt 1 mehr hinzu)
} else {
result[j++] = input[i];
}
}
result[j] = '\0';
// Schleife bis stabil (verschachtelte Muster behandeln)
char* final = result;
while (strstr(final, "../") || strstr(final, "..\\")) {
char* temp = fixed_filter(final);
if (final != result) free(final);
final = temp;
}
return final;
}
Verwandte CWEs
- CWE-795: Nur Filterung von Sonderzeichen an einer bestimmten Position (Eltern)
- CWE-796: Nur Filterung von Sonderzeichen relativ zu einer Markierung (Geschwister)
- CWE-791: Unvollständige Filterung von Sonderzeichen (Großeltern)
- CWE-22: Unsachgemäße Einschränkung eines Pfadnamens auf ein beschränktes Verzeichnis (verwandte Ausnutzung)
Referenzen
- MITRE Corporation. "CWE-797: Only Filtering Special Elements at an Absolute Position." https://cwe.mitre.org/data/definitions/797.html
- OWASP. "Path Traversal." https://owasp.org/www-community/attacks/Path_Traversal
- OWASP. "Input Validation Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html