Unsachgemäße Filterung von Sonderelementen
Beschreibung
Unsachgemäße Filterung von Sonderelementen ist eine Eingabevalidierungsschwachstelle, bei der Software Daten von einer vorgelagerten Komponente empfängt, aber Sonderzeichen oder Elemente nicht filtert oder falsch filtert, bevor die Daten an eine nachgelagerte Komponente weitergegeben werden. Sonderelemente umfassen Zeichen, die syntaktische Bedeutung im Zielkontext haben, wie Pfadtrennzeichen, Befehlstrennzeichen, SQL-Operatoren, XML/HTML-Tags oder Escape-Sequenzen. Wenn Filterung fehlt oder unvollständig ist, können Angreifer bösartige Inhalte injizieren, die von nachgelagerten Prozessoren als Befehle oder Markup interpretiert werden.
Risiko
Unsachgemäße Filterung ermöglicht eine breite Palette von Injection-Angriffen, abhängig vom nachgelagerten Kontext. Pfadtraversierung wird möglich, wenn Verzeichnistrennzeichen (../) nicht ordnungsgemäß gefiltert werden. Command Injection tritt auf, wenn Shell-Metazeichen durchkommen. SQL Injection resultiert aus ungefilterten Anführungszeichen und SQL-Schlüsselwörtern. XSS-Angriffe sind erfolgreich, wenn HTML/JavaScript-Elemente nicht neutralisiert werden. Unvollständige Filterung (wie nur einzelne Vorkommen entfernen) ist besonders gefährlich, da sie falsches Vertrauen gibt, während sie ausnutzbar bleibt.
Lösung
Implementieren Sie umfassende Eingabefilterung oder Kodierung, die für den Zielkontext geeignet ist. Verwenden Sie Allowlist-Validierung wenn möglich - akzeptieren Sie nur bekannt-gute Zeichen. Wenn Sie Sonderelemente filtern, stellen Sie sicher, dass alle Instanzen behandelt werden (verwenden Sie globales Ersetzen). Bevorzugen Sie Ausgabe-Kodierung gegenüber Eingabe-Filterung - kodieren Sie Daten am Verwendungspunkt für den spezifischen Ausgabekontext. Verwenden Sie parametrisierte Abfragen für SQL, DOM-Methoden für HTML und ordnungsgemäßes Escaping für Shell-Befehle. Schichten Sie Verteidigungen: kombinieren Sie Eingabevalidierung, Ausgabe-Kodierung und kontextgeeignete APIs.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Integrität | Bereich: Integrität Unerwarteter Zustand - Anwendung erreicht unbeabsichtigten Zustand aufgrund unsachgemäß gefilterter Eingabe, die Kontrollfluss oder Daten beeinflusst. |
| Vertraulichkeit | Bereich: Vertraulichkeit Anwendungsdaten lesen - Pfadtraversierung oder Injection-Angriffe können sensible Daten exponieren. |
| Integrität | Bereich: Integrität Unbefugten Code ausführen - Command oder Code Injection wird möglich, wenn Filterung versagt. |
Beispielcode
Verwundbarer Code
# Verwundbar: Entfernt nur erstes Vorkommen von "../"
#!/usr/bin/perl
my $username = GetUntrustedInput();
# Verwundbar: Fehlender /g Modifikator - entfernt nur erstes Vorkommen
$username =~ s/\.\.\///;
my $filename = "/home/user/" . $username;
open(FILE, $filename); # Pfadtraversierung möglich!
# Angriff: Eingabe "....//....//etc/passwd"
# Nach einzelnem Ersetzen: "../../../etc/passwd"
// Verwundbar: Unvollständige Filterung von SQL-Sonderzeichen
<?php
function vulnerable_escape($input) {
// Verwundbar: Escaped nur einfaches Anführungszeichen, nicht doppeltes oder Backslash
$filtered = str_replace("'", "''", $input);
return $filtered;
}
$username = vulnerable_escape($_GET['username']);
$query = "SELECT * FROM users WHERE name = '$username'";
// Weiterhin verwundbar für Injection über doppelte Anführungszeichen oder Backslash
// Angriff: Eingabe: \" OR 1=1 --
// Verwundbar: Filtert nur einige HTML-Tags
public class VulnerableFilter {
public String filterXSS(String input) {
// Verwundbar: Filtert nur <script> Tags
String filtered = input.replaceAll("<script>", "")
.replaceAll("</script>", "");
return filtered;
}
}
// Angriff: <img src=x onerror=alert(1)>
// Angriff: <SCRIPT>alert(1)</SCRIPT> (Groß-/Kleinschreibung)
// Angriff: <scr<script>ipt>alert(1)</scr</script>ipt> (verschachtelt)
# Verwundbar: Einzelnes Ersetzen erlaubt Umgehung
def vulnerable_filter_traversal(path):
# Verwundbar: Einzelnes Ersetzen - verschachtelte Sequenzen überleben
filtered = path.replace('../', '')
return filtered
# Angriff: "....//....//etc/passwd"
# Nach Filterung: "../../etc/passwd" - Traversierung funktioniert weiterhin!
Gefixter Code
# Gefixt: Globales Ersetzen und rekursive Filterung verwenden
#!/usr/bin/perl
my $username = GetUntrustedInput();
# Gefixt: /g für globales Ersetzen verwenden
# Und wiederholen bis keine Treffer mehr
my $prev;
do {
$prev = $username;
$username =~ s/\.\.[\\/]//g; # Sowohl / als auch \ behandeln
} while ($username ne $prev);
# Besser: Gegen Allowlist validieren
if ($username !~ /^[a-zA-Z0-9_]+$/) {
die "Ungültiger Benutzername";
}
my $filename = "/home/user/" . $username;
open(FILE, "<", $filename) or die "Datei kann nicht geöffnet werden";
// Gefixt: Parametrisierte Abfragen anstelle von Filterung verwenden
<?php
function fixed_query($username) {
$pdo = new PDO($dsn, $user, $password);
// Gefixt: Prepared Statement verwenden - kein manuelles Escaping nötig
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$username]);
return $stmt->fetchAll();
}
// Wenn Filterung nötig ist, umfassenden Ansatz verwenden
function fixed_escape($input) {
// Datenbankspezifische Escape-Funktion verwenden
return pg_escape_string($input); // PostgreSQL
// Oder: mysqli_real_escape_string($conn, $input); // MySQL
}
// Gefixt: Umfassende HTML-Filterung
import org.owasp.encoder.Encode;
public class FixedFilter {
public String filterXSS(String input) {
// Gefixt: Ordnungsgemäße HTML-Encoding-Bibliothek verwenden
return Encode.forHtml(input);
}
// Alternative: Allowlist-Ansatz
public String filterAllowlist(String input) {
// Nur alphanumerische und spezifische sichere Zeichen erlauben
return input.replaceAll("[^a-zA-Z0-9\\s.,!?-]", "");
}
}
# Gefixt: Rekursive Filterung bis stabil
import os.path
def fixed_filter_traversal(path):
# Gefixt: Rekursiv entfernen bis keine Änderungen
while True:
filtered = path.replace('../', '').replace('..\\', '')
if filtered == path:
break
path = filtered
return filtered
# Besser: Kanonischen Pfadvergleich verwenden
def fixed_validate_path(base_dir, user_path):
# Zu absolutem Pfad auflösen
full_path = os.path.realpath(os.path.join(base_dir, user_path))
# Sicherstellen dass er weiterhin unter Basisverzeichnis liegt
if not full_path.startswith(os.path.realpath(base_dir) + os.sep):
raise ValueError("Pfadtraversierung erkannt")
return full_path
// Gefixt: Umfassende Null-Byte-Filterung
#include <string.h>
#include <ctype.h>
int fixed_filter_null(const char* input, char* output, size_t output_size) {
size_t j = 0;
size_t i = 0;
while (input[i] != '\0' && j < output_size - 1) {
// URL-encodiertes Null %00 filtern
if (input[i] == '%' && input[i+1] == '0' && input[i+2] == '0') {
i += 3;
continue;
}
// Andere potenziell gefährliche Sequenzen filtern
if (input[i] == '\\' && input[i+1] == '0') {
i += 2;
continue;
}
output[j++] = input[i++];
}
output[j] = '\0';
return (input[i] == '\0') ? 0 : -1; // -1 wenn abgeschnitten
}
// Besser: Allowlist-Validierung
int validate_input(const char* input) {
for (int i = 0; input[i] != '\0'; i++) {
// Nur alphanumerische und spezifische Interpunktion erlauben
if (!isalnum(input[i]) && input[i] != '_' && input[i] != '-') {
return 0; // Ungültig
}
}
return 1; // Gültig
}
Verwandte CWEs
- CWE-791: Unvollständige Filterung von Sonderelementen (Kind-Schwachstelle)
- CWE-22: Pfadtraversierung (spezifische Ausnutzung)
- CWE-89: SQL Injection (spezifische Ausnutzung)
- CWE-79: Cross-site Scripting (spezifische Ausnutzung)
Referenzen
- MITRE Corporation. "CWE-790: Improper Filtering of Special Elements." https://cwe.mitre.org/data/definitions/790.html
- OWASP. "Input Validation Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html
- OWASP. "Testing for Input Validation." OWASP Testing Guide.