Funktionsaufruf mit falscher Anzahl von Argumenten
Beschreibung
Funktionsaufruf mit falscher Anzahl von Argumenten ist ein Programmierfehler, bei dem Code eine Funktion, Prozedur oder Routine mit entweder zu vielen oder zu wenigen Argumenten aufruft, verglichen mit dem, was die Funktionssignatur erwartet. Dies tritt häufig in Sprachen wie C auf, die variadische Funktionen unterstützen, oder in dynamisch typisierten Sprachen wie Perl, die keine strikte Argumentanzahl zur Kompilierzeit erzwingen. Wenn Funktionen unerwartete Argumentanzahlen erhalten, können sie uninitialisierten Speicher lesen, kritische Verarbeitung überspringen oder undefiniertes Verhalten zeigen.
Risiko
Falsche Argumentanzahlen schaffen ernsthafte Risiken, besonders bei sicherheitskritischen Funktionen. Funktionen, die zu wenige Argumente erhalten, können Müllwerte vom Stack lesen und möglicherweise sensible Daten offenlegen oder Abstürze verursachen. Funktionen, die zu viele Argumente erhalten, könnten die zusätzlichen Werte ignorieren oder den Stack korrumpieren, abhängig von der Aufrufkonvention. Bei Format-String-Funktionen ermöglichen Argumentanzahlunterschiede zwischen Formatspezifikatoren und tatsächlichen Argumenten Format-String-Angriffe.
Lösung
Verwenden Sie Compiler mit aktivierter strikter Typ- und Argumentprüfung. In C verwenden Sie Funktionsprototypen und aktivieren Sie Warnungen wie -Wmissing-prototypes und -Wformat. Für variadische Funktionen stellen Sie sicher, dass Format-Strings mit Argumentlisten übereinstimmen. In dynamisch typisierten Sprachen fügen Sie explizite Argumentvalidierung am Funktionseintritt hinzu. Verwenden Sie statische Analysetools, die Argumentanzahlunterschiede erkennen können. Schreiben Sie umfassende Unit-Tests, die alle Codepfade ausführen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Sonstiges | Bereich: Sonstige Qualitätsverschlechterung - Funktionen erzeugen falsche Ergebnisse oder undefiniertes Verhalten bei falscher Argumentanzahl. |
| Verfügbarkeit | Bereich: Verfügbarkeit DoS: Absturz - Stack-Korruption oder Lesen uninitialisierter Werte kann Programmabstürze verursachen. |
| Vertraulichkeit | Bereich: Vertraulichkeit Speicher lesen - Zu wenige Argumente können Funktionen dazu bringen, uninitialisierte Stack-Daten zu lesen. |
Beispielcode und Lösung
Verwundbarer Code
// Verwundbar: Fehlendes Argument bei printf Format-String
#include <stdio.h>
void verwundbar_printf(char* username, int user_id) {
// Format erwartet 3 Argumente aber nur 2 bereitgestellt
printf("Benutzer: %s, ID: %d, Status: %s\n", username, user_id);
// Fehlendes drittes Argument - liest Müll vom Stack
// Kann sensible Daten offenlegen oder abstürzen
}
// Verwundbar: Variable Argumente Funktion mit falscher Anzahl
void verwundbar_log(const char* format, ...) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
void verwende_verwundbar_log() {
int error_code = 404;
char* path = "/api/users";
// Verwundbar: Format erwartet 3 Argumente, nur 2 bereitgestellt
verwundbar_log("Fehler %d bei %s: %s\n", error_code, path);
// Fehlende Fehlermeldung - undefiniertes Verhalten
}
// Verwundbar: snprintf mit falscher Argumentanzahl
void verwundbar_format(char* buffer, size_t size,
char* user, char* action, char* target) {
// Format erwartet 3 Argumente aber nur 2 bereitgestellt
snprintf(buffer, size,
"Benutzer %s führte %s auf %s aus",
user, action); // Fehlendes 'target' Argument!
// Liest Müll für drittes %s
}
# Verwundbar: Perl erzwingt keine Argumentanzahlen
sub authenticate {
my ($username, $password, $domain) = @_;
# Domain ist undef wenn nicht bereitgestellt
if (!defined $domain) {
$domain = "default"; # Könnte nicht beabsichtigte Domain sein
}
return check_credentials($username, $password, $domain);
}
# Verwundbar: Mit nur 2 Argumenten aufgerufen
my $result = authenticate($user_input, $pass_input);
# Fehlendes Domain-Argument - verwendet Standard, kann domainspezifische Regeln umgehen
# Verwundbar: Zu viele Argumente - Extras stillschweigend ignoriert
my $result2 = authenticate($user, $pass, $domain, $extra_arg);
# $extra_arg wird stillschweigend ignoriert - kann auf Logikfehler hindeuten
Sichere Lösung
// Sicher: Korrekte Argumentanzahl für printf
#include <stdio.h>
void sichere_printf(char* username, int user_id, char* status) {
// Sicher: Alle Formatspezifikatoren haben entsprechende Argumente
printf("Benutzer: %s, ID: %d, Status: %s\n", username, user_id, status);
}
// Sicher: Format-String zur Kompilierzeit validieren
#ifdef __GNUC__
__attribute__((format(printf, 1, 2)))
#endif
void sichere_log(const char* format, ...) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
void verwende_sichere_log() {
int error_code = 404;
char* path = "/api/users";
char* message = "Nicht gefunden";
// Sicher: Korrekte Anzahl von Argumenten
sichere_log("Fehler %d bei %s: %s\n", error_code, path, message);
}
// Sicher: Compiler-Warnungen verwenden
// Kompilieren mit: gcc -Wformat -Werror ...
void sichere_format(char* buffer, size_t size,
char* user, char* action, char* target) {
// Sicher: Alle Argumente bereitgestellt
snprintf(buffer, size,
"Benutzer %s führte %s auf %s aus",
user, action, target);
}
# Sicher: Argumentanzahl in Perl validieren
sub authenticate_secure {
my ($username, $password, $domain) = @_;
# Sicher: Erforderliche Argumente validieren
unless (defined $username && defined $password && defined $domain) {
die "authenticate erfordert Benutzername, Passwort und Domain";
}
return check_credentials($username, $password, $domain);
}
# Alternative: Signaturen verwenden (Perl 5.20+)
use feature 'signatures';
sub authenticate_with_sig($username, $password, $domain) {
# Perl wirft Fehler wenn falsche Anzahl von Argumenten bereitgestellt
return check_credentials($username, $password, $domain);
}
# Sicher: Auf unerwartete zusätzliche Argumente prüfen
sub process_secure {
die "Zu viele Argumente" if @_ > 3;
my ($a, $b, $c) = @_;
# ... Verarbeitung
}
Ausgenutzt in der Praxis
Format-String-Angriffe (diverse Systeme)
Zahlreiche Format-String-Schwachstellen in C-Programmen resultierten aus falscher Argumentanzahl bei printf-ähnlichen Funktionen, was Angreifern das Lesen und Schreiben von Speicher ermöglichte.
Perl CGI-Skript-Schwachstellen (1990er-2000er)
Viele frühe Web-Anwendungen in Perl hatten Schwachstellen durch fehlende Argumentvalidierung, die zu Authentifizierungsumgehungen führten.
Tools zum Testen und Ausnutzen
-
GCC/Clang -Wformat — Compiler-Warnungen für Format-String-Probleme.
-
Cppcheck — Statischer Analyser, der Format-String-Probleme erkennt.
-
Perl::Critic — Perl-Linter mit Argumentvalidierungsregeln.
CVE-Beispiele
-
CVE-2005-2709 — Buffer Overflow in Format-String-Funktion durch falsche Anzahl von Argumenten.
-
CVE-2006-1174 — Funktion mit falscher Anzahl von Argumenten aufgerufen, führt zu Authentifizierungsumgehung.
Referenzen
-
MITRE Corporation. "CWE-685: Function Call With Incorrect Number of Arguments." https://cwe.mitre.org/data/definitions/685.html
-
CERT C Coding Standard. "EXP37-C: Call functions with the correct number and type of arguments." https://wiki.sei.cmu.edu/confluence/display/c/EXP37-C.+Call+functions+with+the+correct+number+and+type+of+arguments
-
CERT C Coding Standard. "FIO47-C: Use valid format strings." https://wiki.sei.cmu.edu/confluence/display/c/FIO47-C.+Use+valid+format+strings