Pufferzugriff mit falscher Längenwert
Beschreibung
Pufferzugriff mit falschem Längenwert tritt auf, wenn Software sequentielle Pufferoperationen mit einem Längenwert durchführt, der den zu bearbeitenden Puffer nicht korrekt repräsentiert, was zu Speicherzugriffen außerhalb der Puffergrenzen führt. Dies passiert typischerweise, wenn Kopieroperationen einen Längenwert verwenden, der auf dem falschen Puffer basiert (Quelle statt Ziel), wenn der Längenparameter Null-Terminatoren nicht berücksichtigt oder wenn Längenberechnungen falsch sind. Wenn die berechnete Länge die tatsächliche Größe des Zielpuffers überschreitet, tritt ein Buffer Overflow auf, der es Angreifern ermöglicht, benachbarten Speicher zu überschreiben, Datenstrukturen zu beschädigen oder beliebigen Code auszuführen.
Risiko
Diese Schwachstelle kann zu Abstürzen, beliebiger Codeausführung und vollständiger Systemkompromittierung führen. Pufferüberläufe bleiben eine der gefährlichsten und am häufigsten ausgenutzten Schwachstellenklassen. Wenn der Längenwert den Zielpuffer überschreitet, überschreiben Daten benachbarten Speicher, potenziell einschließlich Rücksprungadressen, Funktionszeiger oder sicherheitskritischer Daten. Angreifer, die den Überlauf kontrollieren, können die Programmausführung zu bösartigem Code umleiten. Selbst ohne Codeausführung kann Speicherbeschädigung Denial of Service durch Abstürze verursachen oder zur Informationsoffenlegung führen. Die Schwachstelle ist besonders häufig in C und C++, wo manuelle Speicherverwaltung erforderlich ist.
Lösung
Verwenden Sie immer die Größe des Zielpuffers für Längenberechnungen bei Kopieroperationen. Überprüfen Sie, ob Puffergrößen und Längenparameter vor Operationen übereinstimmen. Verwenden Sie speichersichere Sprachen wie Java, Python oder Rust, wenn möglich. Verwenden Sie in C/C++ sichere String-Bibliotheken wie SafeStr, Microsofts Strsafe.h oder strlcpy/strlcat. Aktivieren Sie Compiler-Schutzmassnahmen einschließlich Stack-Canaries (/GS-Flag in MSVC, FORTIFY_SOURCE in GCC). Setzen Sie ASLR, PIE und DEP/NX als Defense-in-Depth-Maßnahmen ein. Führen Sie mit minimal notwendigen Privilegien aus, um Schäden durch erfolgreiche Exploits zu begrenzen. Verwenden Sie statische Analysetools, um Pufferverarbeitungsfehler während der Entwicklung zu erkennen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Verfügbarkeit | Bereich: Verfügbarkeit Denial of Service - Pufferüberläufe verursachen häufig Abstürze, Endlosschleifen oder Ressourcenerschöpfung. |
| Integrität, Vertraulichkeit, Verfügbarkeit | Bereich: Integrität, Vertraulichkeit, Verfügbarkeit Unerlaubte Codeausführung - Angreifer können Überläufe nutzen, um beliebigen Code auszuführen und so Systemintegrität und -vertraulichkeit zu kompromittieren. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle Umgehung des Schutzmechanismus - Erfolgreiche Codeausführung kann andere Sicherheitskontrollen untergraben. |
Beispielcode
Anfälliger Code
// Anfällig: Keine Größenbegrenzung beim Kopieren
void vulnerable_copy_hostname(struct hostent *hp) {
char hostname[64];
// Anfällig: strcpy prüft nicht die Zielgröße
// Wenn hp->h_name > 63 Zeichen, tritt Buffer Overflow auf
strcpy(hostname, hp->h_name);
printf("Hostname: %s\n", hostname);
}
// Anfällig: Verwendet Quellpuffergröße für Ziel
void vulnerable_copy(void) {
char source[100] = "Ein String, der länger als das Ziel sein könnte";
char dest[20];
// Anfällig: sizeof(source) ist 100, aber dest ist nur 20
strncpy(dest, source, sizeof(source) - 1);
// Schreibt bis zu 99 Bytes in 20-Byte-Puffer!
}
// Anfällig: Verwendet Längenparameter anstatt Puffergröße
int vulnerable_copy_path(char *filename, int length) {
char buf[MAX_PATH]; // MAX_PATH ist 256
// Anfällig: 'length' könnte größer als MAX_PATH sein
strncpy(buf, filename, length);
// Wenn length > MAX_PATH, Buffer Overflow
process_path(buf);
return 0;
}
Korrigierter Code
// Korrigiert: Verwendet Zielgröße
void fixed_copy_hostname(struct hostent *hp) {
char hostname[64];
// Korrigiert: Verwendet Zielgröße und stellt Null-Terminierung sicher
strncpy(hostname, hp->h_name, sizeof(hostname) - 1);
hostname[sizeof(hostname) - 1] = '\0';
printf("Hostname: %s\n", hostname);
}
// Korrigiert: Verwendet Zielpuffergröße
void fixed_copy(void) {
char source[100] = "Ein String, der länger als das Ziel sein könnte";
char dest[20];
// Korrigiert: Verwendet sizeof(dest), nicht sizeof(source)
strncpy(dest, source, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';
}
// Korrigiert: Validiert Länge gegen Puffergröße
int fixed_copy_path(char *filename, int length) {
char buf[MAX_PATH];
// Korrigiert: Verwendet Minimum von Länge und Puffergröße
size_t copy_len = (length < sizeof(buf)) ? length : sizeof(buf) - 1;
strncpy(buf, filename, copy_len);
buf[copy_len] = '\0';
process_path(buf);
return 0;
}
// Beste Praxis: Verwenden Sie sichere String-Funktionen
#include <stdio.h>
void best_practice_copy(const char* source) {
char dest[32];
// snprintf ist sicher: verwendet immer Zielgröße
snprintf(dest, sizeof(dest), "%s", source);
// Kürzt automatisch und null-terminiert
}
Verwandte CWEs
- CWE-119: Unzureichende Beschränkung von Operationen innerhalb der Grenzen eines Speicherpuffers (Eltern)
- CWE-806: Pufferzugriff unter Verwendung der Größe des Quellpuffers (Kind - spezifische Variante)
- CWE-130: Unzureichende Behandlung von Längenparameter-Inkonsistenz (kann vorangehen)
- CWE-120: Pufferkopie ohne Prüfung der Eingabegröße (verwandt)
- CWE-787: Out-of-bounds-Schreibzugriff (verwandt)
Referenzen
- MITRE Corporation. "CWE-805: Buffer Access with Incorrect Length Value." https://cwe.mitre.org/data/definitions/805.html
- Microsoft. "Strsafe.h Functions." https://docs.microsoft.com/en-us/windows/win32/menurc/strsafe-ovw
- CERT C Coding Standard. "STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator."