Funktionsaufruf mit falsch spezifiziertem Argumentwert
Beschreibung
Funktionsaufruf mit falsch spezifiziertem Argumentwert ist ein Programmierfehler, bei dem Code eine Funktion mit einem Argument aufruft, das einen falschen Wert für den beabsichtigten Zweck der Funktion enthält, obwohl der Typ korrekt sein kann. Dies unterscheidet sich von Typunterschieden - das Argument hat den richtigen Typ, aber den falschen Wert. Häufige Beispiele sind das Übergeben von 0 statt 1 für Boolean-Flags, die Verwendung falscher Konstanten, hartcodierte Werte die dynamisch sein sollten, oder invertierte Boolean-Logik. Diese Fehler können dazu führen, dass Funktionen sich gegenteilig zur Absicht des Programmierers verhalten oder kritische Verarbeitung überspringen.
Risiko
Falsche Argumentwerte erzeugen ernsthafte Sicherheitsrisiken, wenn sie sicherheitskritische Funktionen betreffen. Authentifizierungsfunktionen, die mit falschen Flag-Werten aufgerufen werden, melden Fehler möglicherweise nicht korrekt. Autorisierungsprüfungen mit invertierten Boolean-Argumenten gewähren möglicherweise Zugriff, wenn sie ihn verweigern sollten. Fehlerbehandlungsfunktionen, die falsche Fehlercodes erhalten, ergreifen möglicherweise unangemessene Maßnahmen. Das Risiko wird verstärkt, weil diese Bugs oft die Code-Review passieren - der Code sieht syntaktisch korrekt aus und besteht die Typüberprüfung erfolgreich. Sie manifestieren sich typischerweise nur in bestimmten Ausführungspfaden, was ihre Erkennung durch Tests erschwert.
Lösung
Verwenden Sie benannte Konstanten oder Enums statt magischer Zahlen, um die Absicht des Arguments deutlich zu machen. Erstellen Sie Wrapper-Funktionen mit expliziten Namen, die die ausgeführte Operation anzeigen. Verwenden Sie benannte Parameter, wo die Sprache dies unterstützt. Implementieren Sie gründliche Unit-Tests, die das Funktionsverhalten mit verschiedenen Argumentwerten verifizieren. Führen Sie Code-Reviews mit besonderem Fokus auf Argumentwerte in sicherheitskritischen Funktionen durch. Verwenden Sie statische Analysetools, die häufige falsche Wertmuster erkennen können. Erwägen Sie die Verwendung von Builder-Patterns oder Konfigurationsobjekten für Funktionen mit vielen Boolean- oder Flag-Parametern.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Sonstiges | Bereich: Sonstiges Qualitätsverschlechterung - Funktionen verhalten sich falsch, wenn sie mit falschen Werten aufgerufen werden, und produzieren unerwartete Ergebnisse. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle Schutzmechanismus umgehen - Sicherheitsfunktionen mit falschen Flag-Werten erzwingen Prüfungen möglicherweise nicht. |
| Integrität | Bereich: Integrität Unerwarteter Zustand - Systeme geraten in inkonsistente Zustände, wenn Funktionen mit falschen Parametern arbeiten. |
Beispielcode
Anfälliger Code
# Anfällig: Falscher Boolean-Wert für Fehlerbehandlungs-Flag
sub ReportAuth {
my ($username, $result, $die_on_error) = @_;
if ($result != 0) {
# Authentifizierung fehlgeschlagen
if ($die_on_error) {
die "Authentifizierung fehlgeschlagen für $username";
}
# Nur loggen wenn nicht beendet wird
log_failure($username);
}
}
# Anfällig: Mit 0 statt 1 aufgerufen
sub authenticate_user {
my ($username, $password) = @_;
my $result = check_credentials($username, $password);
# Anfällig: Sollte 1 sein um bei Fehler zu beenden, aber 0 wird übergeben
ReportAuth($username, $result, 0); # FALSCHER WERT!
# Authentifizierungsfehler werden stillschweigend geloggt, nicht beendet
return $result == 0;
}
// Anfällig: Falscher Modus-Wert für Dateioperationen
#include <fcntl.h>
#include <sys/stat.h>
void vulnerable_create_file(const char* path) {
// Anfällig: Falschen Modus verwenden - 0 statt korrekter Berechtigungen
int fd = open(path, O_CREAT | O_WRONLY, 0); // Modus 0 = keine Berechtigungen!
// Datei mit keinen Lese/Schreib/Ausführung-Berechtigungen für niemanden erstellt
write(fd, "data", 4);
close(fd);
}
// Anfällig: Falsches Flag für Socket-Optionen
#include <sys/socket.h>
int vulnerable_socket_setup(int sockfd) {
int optval = 0; // Sollte 1 sein um Option zu aktivieren
// Anfällig: optval=0 deaktiviert Option statt sie zu aktivieren
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
// SO_REUSEADDR nicht wirklich aktiviert!
return 0;
}
// Anfällig: Invertierte Boolean-Logik
int vulnerable_is_valid(int error_code) {
// error_code 0 bedeutet Erfolg, ungleich null bedeutet Fehler
// Anfällig: Logik ist rückwärts
return error_code; // Gibt true (ungleich null) bei FEHLER zurück
// Sollte sein: return error_code == 0;
}
// Anfällig: Falsche Flag-Werte
public class VulnerableFlags {
private static final int FLAG_SECURE = 1;
private static final int FLAG_INSECURE = 0;
public void processRequest(Request request) {
// Anfällig: Falsches Flag übergeben
validateInput(request.getData(), FLAG_INSECURE); // FALSCH!
// Sollte FLAG_SECURE sein für sicherheitskritische Validierung
}
public void validateInput(String data, int securityLevel) {
if (securityLevel == FLAG_SECURE) {
// Gründliche Validierung durchführen
strictValidation(data);
} else {
// Nur minimale Validierung
basicValidation(data); // Weniger sicherer Pfad genommen!
}
}
}
// Anfällig: Falsche Konstante für Vergleich
public class VulnerableComparison {
public static final int STATUS_SUCCESS = 0;
public static final int STATUS_FAILURE = 1;
public static final int STATUS_PENDING = 2;
public boolean isOperationSuccessful(int status) {
// Anfällig: Vergleich mit falscher Konstante
return status == STATUS_FAILURE; // FALSCH! Sollte STATUS_SUCCESS sein
// Gibt true zurück wenn Operation fehlgeschlagen ist!
}
}
# Anfällig: Falscher Standard- oder hartcodierter Wert
import ssl
def vulnerable_ssl_connection(host, port):
context = ssl.create_default_context()
# Anfällig: Falscher Wert deaktiviert Zertifikatsverifizierung
context.check_hostname = False # FALSCH! Sollte True sein
context.verify_mode = ssl.CERT_NONE # FALSCH! Sollte CERT_REQUIRED sein
# Verbindung erfolgt ohne Zertifikatsverifizierung
return context.wrap_socket(socket.socket(), server_hostname=host)
# Anfällig: Falscher Array-Index
def vulnerable_get_permission(permissions, user_type):
ADMIN_INDEX = 0
USER_INDEX = 1
GUEST_INDEX = 2
# Anfällig: Falschen Index verwenden
if user_type == 'admin':
return permissions[USER_INDEX] # FALSCH! Holt Benutzer-Berechtigungen, nicht Admin
elif user_type == 'user':
return permissions[ADMIN_INDEX] # FALSCH! Holt Admin-Berechtigungen
return permissions[GUEST_INDEX]
Lösung
# Korrigiert: Benannte Konstanten und klare Parameternamen verwenden
use constant {
DIE_ON_ERROR => 1,
LOG_ONLY => 0,
};
sub ReportAuth {
my ($username, $result, $die_on_error) = @_;
if ($result != 0) {
if ($die_on_error) {
die "Authentifizierung fehlgeschlagen für $username";
}
log_failure($username);
}
}
# Korrigiert: Benannte Konstante für Klarheit verwenden
sub authenticate_user {
my ($username, $password) = @_;
my $result = check_credentials($username, $password);
# Korrigiert: Klare Absicht mit benannter Konstante
ReportAuth($username, $result, DIE_ON_ERROR);
return $result == 0;
}
# Alternative: Wrapper-Funktionen verwenden
sub authenticate_or_die {
my ($username, $password) = @_;
my $result = check_credentials($username, $password);
ReportAuth($username, $result, 1); # Immer bei Fehler beenden
return $result == 0;
}
// Korrigiert: Korrekte Modus-Werte mit benannten Konstanten verwenden
#include <fcntl.h>
#include <sys/stat.h>
#define SECURE_FILE_MODE (S_IRUSR | S_IWUSR) // Nur Eigentümer lesen/schreiben
void secure_create_file(const char* path) {
// Korrigiert: Korrekte Berechtigungen
int fd = open(path, O_CREAT | O_WRONLY, SECURE_FILE_MODE);
if (fd < 0) {
return; // Fehler behandeln
}
write(fd, "data", 4);
close(fd);
}
// Korrigiert: Korrekter Options-Wert
#include <sys/socket.h>
int secure_socket_setup(int sockfd) {
int optval = 1; // Korrigiert: 1 um Option zu aktivieren
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
&optval, sizeof(optval)) < 0) {
return -1;
}
return 0;
}
// Korrigiert: Korrekte Boolean-Logik
int secure_is_valid(int error_code) {
// Korrigiert: 0 bedeutet Erfolg (gültig), ungleich null bedeutet Fehler (ungültig)
return error_code == 0;
}
// Alternative: Wrapper mit klarem Namen
int is_success(int result_code) {
return result_code == 0;
}
int is_error(int result_code) {
return result_code != 0;
}
// Korrigiert: Enums für typsichere Flags verwenden
public class SecureFlags {
public enum SecurityLevel {
INSECURE,
BASIC,
SECURE,
PARANOID
}
public void processRequest(Request request) {
// Korrigiert: Klares, typsicheres Flag
validateInput(request.getData(), SecurityLevel.SECURE);
}
public void validateInput(String data, SecurityLevel level) {
switch (level) {
case PARANOID:
case SECURE:
strictValidation(data);
break;
case BASIC:
basicValidation(data);
break;
case INSECURE:
// Minimale Validierung
break;
}
}
}
// Korrigiert: Korrekter Konstanten-Vergleich
public class SecureComparison {
public enum OperationStatus {
SUCCESS,
FAILURE,
PENDING
}
public boolean isOperationSuccessful(OperationStatus status) {
// Korrigiert: Mit SUCCESS vergleichen
return status == OperationStatus.SUCCESS;
}
}
# Korrigiert: Korrekte SSL-Konfiguration
import ssl
def secure_ssl_connection(host, port):
context = ssl.create_default_context()
# Korrigiert: Sicherheitsfunktionen aktivieren
context.check_hostname = True
context.verify_mode = ssl.CERT_REQUIRED
return context.wrap_socket(socket.socket(), server_hostname=host)
# Korrigiert: Korrekte Array-Indizes mit explizitem Mapping
from enum import IntEnum
class UserType(IntEnum):
ADMIN = 0
USER = 1
GUEST = 2
def secure_get_permission(permissions, user_type: str):
# Korrigiert: Enum für klares Mapping verwenden
type_map = {
'admin': UserType.ADMIN,
'user': UserType.USER,
'guest': UserType.GUEST
}
index = type_map.get(user_type, UserType.GUEST)
return permissions[index]
# Alternative: Dictionary für explizites Mapping verwenden
def secure_get_permission_dict(user_type: str):
permissions = {
'admin': ['read', 'write', 'delete', 'admin'],
'user': ['read', 'write'],
'guest': ['read']
}
return permissions.get(user_type, permissions['guest'])
CVE-Beispiele
- CVE-2008-2121: Falscher Argumentwert in Sicherheitsfunktion erlaubte Umgehung von Zugriffskontrollen.
- CVE-2006-4243: Falscher Flag-Wert an Authentifizierungsfunktion übergeben, Sicherheit geschwächt.
Referenzen
- MITRE Corporation. "CWE-687: Function Call With Incorrectly Specified Argument Value." https://cwe.mitre.org/data/definitions/687.html
- CERT C Coding Standard. "DCL00-C. Const-qualify immutable objects."