Pufferzugriff unter Verwendung der Größe des Quellpuffers

Beschreibung

Pufferzugriff unter Verwendung der Größe des Quellpuffers ist eine spezifische Speichersicherheits-Schwachstelle, bei der Software fälschlicherweise die Größe eines Quellpuffers verwendet, um zu bestimmen, wie viele Bytes in einen Zielpuffer kopiert werden sollen. Dies ist ein häufiger Programmierfehler: Entwickler verwenden sizeof(source) oder die Länge der Quelle, obwohl der Zielpuffer kleiner ist, was dazu führt, dass Daten über die Grenzen des Ziels hinaus geschrieben werden. Wenn der Quellpuffer größer als das Ziel ist, führt diese Diskrepanz zu einem Buffer Overflow, der benachbarten Speicher beschädigen, die Anwendung zum Absturz bringen oder beliebige Codeausführung ermöglichen kann.

Risiko

Diese Schwachstelle stellt eine besonders gefährliche Klasse von Pufferüberläufen dar, da das Fehlermuster subtil ist und bei Code-Reviews leicht übersehen wird. Der Code mag auf den ersten Blick korrekt erscheinen - er verwendet eine Größenbegrenzung - aber der falsche Puffer wird gemessen. Die Konsequenzen sind schwerwiegend: Erfolgreiche Ausnutzung kann zu Denial of Service durch Abstürze, Informationsoffenlegung durch Speicherbeschädigung oder vollständiger Systemkompromittierung durch Codeausführung führen. Moderne Exploit-Techniken wie Return-Oriented Programming (ROP) können diese Überläufe selbst mit aktivierten Schutzmassnahmen wie DEP/NX ausnutzen.

Lösung

Verwenden Sie immer die Größe des Zielpuffers bei Kopieroperationen. Dies ist eine grundlegende Regel: strncpy(dest, src, sizeof(dest)-1), nicht sizeof(src). Überprüfen Sie alle Pufferkopieroperationen, um sicherzustellen, dass der richtige Puffer dimensioniert wird. Verwenden Sie statische Analysetools, die konfiguriert sind, dieses spezifische Muster zu erkennen. Erwägen Sie die Verwendung sichererer Alternativen wie snprintf(), strlcpy() (BSD) oder StringCchCopy() (Windows), die die explizite Angabe der Zielgröße erfordern. Bevorzugen Sie in C++ std::string oder std::vector, die ihren eigenen Speicher verwalten. Aktivieren Sie Compiler-Warnungen und behandeln Sie sie als Fehler. Setzen Sie Defense-in-Depth-Maßnahmen wie ASLR, Stack-Canaries und DEP ein.

Häufige Auswirkungen

AuswirkungDetails
VerfügbarkeitBereich: Verfügbarkeit

Denial of Service - Pufferüberläufe verursachen typischerweise Abstürze oder Hänger und storen die Dienstverfügbarkeit.
Integrität, Vertraulichkeit, VerfügbarkeitBereich: Integrität, Vertraulichkeit, Verfügbarkeit

Unerlaubte Codeausführung - Angreifer können Überläufe ausnutzen, um beliebigen Code außerhalb der Sicherheitsrichtlinie des Programms auszuführen.
ZugriffskontrolleBereich: Zugriffskontrolle

Umgehung des Schutzmechanismus - Erfolgreiche Codeausführung kann andere Sicherheitsmechanismen kompromittieren oder deaktivieren.

Beispielcode

Anfälliger Code

// Anfällig: Verwendet sizeof(source) anstatt sizeof(dest)
void vulnerable_copy(void) {
    char source[21] = "die Zeichenkette";
    char dest[12];

    // Anfällig: sizeof(source) ist 21, aber dest ist nur 12 Bytes
    strncpy(dest, source, sizeof(source) - 1);
    // Schreibt 20 Bytes in 12-Byte-Puffer - Überlauf!
}
// Anfällig: Verwendet Quelllange in memcpy
void vulnerable_memcpy(const char* source) {
    char dest[32];
    size_t source_len = strlen(source);

    // Anfällig: Verwendet Quelllange, nicht Zielgröße
    memcpy(dest, source, source_len + 1);  // +1 für Null

    // Wenn source länger als 32 Bytes ist, tritt Überlauf auf
}
// Anfällig: Übergibt Quellgröße an Funktion
void vulnerable_wrapper(void) {
    char large_buffer[256];
    char small_buffer[32];

    get_data(large_buffer, sizeof(large_buffer));

    // Anfällig: Übergibt falsche Größe
    process_data(small_buffer, large_buffer, sizeof(large_buffer));
}

void process_data(char* dest, const char* src, size_t len) {
    // Verwendet die übergebene Länge, die Quellgröße ist
    strncpy(dest, src, len);
}

Korrigierter Code

// Korrigiert: Verwendet sizeof(dest)
void fixed_copy(void) {
    char source[21] = "die Zeichenkette";
    char dest[12];

    // Korrigiert: Verwendet Zielgröße
    strncpy(dest, source, sizeof(dest) - 1);
    dest[sizeof(dest) - 1] = '\0';  // Stellt Null-Terminierung sicher
}
// Korrigiert: Validiert gegen Zielgröße
void fixed_memcpy(const char* source) {
    char dest[32];
    size_t source_len = strlen(source);

    // Korrigiert: Verwendet Minimum von Quelllange und Zielgröße
    size_t copy_len = (source_len < sizeof(dest) - 1) ?
                      source_len : sizeof(dest) - 1;

    memcpy(dest, source, copy_len);
    dest[copy_len] = '\0';
}
// Korrigiert: Übergibt Zielgröße explizit
void fixed_wrapper(void) {
    char large_buffer[256];
    char small_buffer[32];

    get_data(large_buffer, sizeof(large_buffer));

    // Korrigiert: Übergibt Zielgröße
    process_data_safe(small_buffer, sizeof(small_buffer),
                      large_buffer, strlen(large_buffer));
}

void process_data_safe(char* dest, size_t dest_size,
                       const char* src, size_t src_len) {
    // Verwendet Zielgröße für Limit
    size_t copy_len = (src_len < dest_size - 1) ?
                      src_len : dest_size - 1;
    strncpy(dest, src, copy_len);
    dest[copy_len] = '\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-805: Pufferzugriff mit falschem Längenwert (Eltern)
  • CWE-119: Unzureichende Beschränkung von Operationen innerhalb der Grenzen eines Speicherpuffers (Großeltern)
  • CWE-120: Pufferkopie ohne Prüfung der Eingabegröße (verwandt)
  • CWE-787: Out-of-bounds-Schreibzugriff (verwandt)

Referenzen

  1. MITRE Corporation. "CWE-806: Buffer Access Using Size of Source Buffer." https://cwe.mitre.org/data/definitions/806.html
  2. CERT C Secure Coding Standard. "STR31-C. Guarantee that storage for strings has sufficient space."
  3. Microsoft. "Safe String Functions." https://docs.microsoft.com/en-us/windows/win32/menurc/strsafe-ovw