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

AuswirkungDetails
IntegritätBereich: Integrität

Unerwarteter Zustand - Gefährliche Elemente an nicht geprüften Positionen passieren Filter und verursachen unbeabsichtigtes Anwendungsverhalten.
VertraulichkeitBereich: Vertraulichkeit

Anwendungsdaten lesen - Path-Traversal an ungeprüften Positionen ermöglicht unautorisierten Dateizugriff.
IntegritätBereich: 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

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