Verwendung veralteter Funktionen
Beschreibung
Die Verwendung veralteter Funktionen ist eine Schwachstelle, bei der Code veraltete oder obsolete Funktionen verwendet, was darauf hindeutet, dass die Codebasis möglicherweise keine aktive Wartung oder Sicherheitsüberprüfung erfährt. Programmiersprachen entwickeln sich im Laufe der Zeit weiter, wodurch Funktionen aufgrund von Sprachfortschritten, verbessertem operativen Verständnis und Sicherheitspraktiken oder geänderten Konventionen für bestimmte Operationen veralten. Veraltete Funktionen werden typischerweise durch neuere Alternativen ersetzt, die dieselbe Aufgabe effektiver oder sicherer erfüllen.
Risiko
Veraltete Funktionen haben oft bekannte Sicherheitslücken oder Designfehler, die zu ihrer Deprecation führten. Die Verwendung von gets() in C ermöglicht Buffer Overflow. Die Verwendung von strcpy() ohne Längenlimit ermöglicht Überlauf-Angriffe. Veraltete Hash-Funktionen wie MD5 oder SHA1 haben bekannte Schwächen. Veraltete Zufallszahlengeneratoren können vorhersagbar sein. Code, der veraltete Funktionen verwendet, signalisiert schlechte Wartungspraktiken und kann andere ungepatchte Schwachstellen enthalten. Das Vorhandensein veralteter Funktionen kann darauf hindeuten, dass die Codebasis nicht gegen aktuelle Sicherheitsstandards überprüft wurde.
Lösung
Überprüfen Sie die Dokumentation der veralteten Funktion, um den Grund für die Deprecation zu verstehen und moderne Alternativen für die Erreichung gleichwertiger Funktionalität zu identifizieren. Während der Anforderungs- und Implementierungsphasen evaluieren Sie Sicherheitsimplikationen sorgfältig und ersetzen Sie veraltete Funktionen durch moderne Alternativen. Verwenden Sie Compiler-Warnungen für veraltete Funktionen (-Wdeprecated in GCC/Clang). Führen Sie eine Liste veralteter Funktionen und prüfen Sie sie bei Code-Reviews. Aktualisieren Sie Build-Systeme, um bei Verwendung bekannter gefährlicher veralteter Funktionen zu scheitern.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Andere | Umfang: Ändere Qualitätsverschlechterung - Code, der veraltete Funktionen verwendet, kann im Vergleich zu Code mit modernen Alternativen reduzierte Sicherheit, Zuverlässigkeit oder Leistung haben. |
| Andere | Umfang: Ändere Indirekte Sicherheitsauswirkung - Veraltete Funktionen können bekannte Schwachstellen oder Designfehler haben, die Sicherheitsschwächen erzeugen. |
Beispielcode
Anfälliger Code
// Anfällig: Verwendung gefährlicher veralteter C-Funktionen
#include <stdio.h>
#include <string.h>
#include <crypt.h>
void vulnerable_gets_usage() {
char buffer[100];
// Anfällig: gets() ist veraltet und gefährlich
// Keine Grenzprüfung - garantiertes Buffer Overflow-Risiko
// AUS C11-Standard ENTFERNT
gets(buffer); // NIEMALS verwenden
printf("Eingabe: %s\n", buffer);
}
void vulnerable_strcpy_usage(const char *input) {
char buffer[50];
// Anfällig: strcpy() hat kein Längenlimit
// Veraltet zugunsten von strncpy() oder strlcpy()
strcpy(buffer, input);
// Anfällig: sprintf() hat kein Längenlimit
// Veraltet zugunsten von snprintf()
sprintf(buffer, "Wert: %s", input);
}
void vulnerable_password_handling(const char *password) {
// Anfällig: crypt() mit DES ist veraltet
// DES hat nur 56-Bit-Schlüssel und andere Schwächen
char *hash = crypt(password, "ab"); // Zwei-Zeichen-DES-Salt
// Anfällig: getpw() ist veraltet und gefährlich
// Buffer Overflow-Risiko, verwenden Sie stattdessen getpwuid()
char buffer[256];
getpw(getuid(), buffer);
}
void vulnerable_random_generation() {
// Anfällig: rand() und srand() sind für Sicherheitszwecke veraltet
// Vorhersagbarer, schwacher PRNG
srand(time(NULL));
int random_value = rand();
// Anfällig: random() ist besser aber immer noch nicht kryptographisch
srandom(time(NULL));
long random_long = random();
}
// Anfällig: Verwendung veralteter Java-APIs
import java.util.*;
import java.security.*;
public class VulnerableObsoleteJava {
// Anfällig: Verwendung veralteter Date-Methoden
public Date vulnerableDateUsage() {
Date date = new Date();
// Veraltet: Verwenden Sie Calendar oder java.time stattdessen
date.setYear(2024); // Veraltet seit JDK 1.1
date.setMonth(11); // Veraltet
date.setDate(25); // Veraltet
return date;
}
// Anfällig: Verwendung veralteter Thread-Methoden
public void vulnerableThreadUsage(Thread thread) {
// Veraltet: stop() ist inhärent unsicher
// Kann Objekte in inkonsistentem Zustand lassen
thread.stop(); // Veraltet
// Veraltet: suspend() und resume() sind deadlock-anfällig
thread.suspend(); // Veraltet
thread.resume(); // Veraltet
}
// Anfällig: Verwendung veralteter String-Konstruktor
public String vulnerableStringUsage(byte[] data) {
// Veraltet: Dieser Konstruktor spezifiziert keinen Zeichensatz
// Verhalten hängt von Plattform-Standardkodierung ab
return new String(data, 0); // Veraltet
}
// Anfällig: Verwendung schwacher kryptographischer Algorithmen
public void vulnerableCrypto() throws Exception {
// Anfällig: DES ist veraltet, verwenden Sie AES
Cipher cipher = Cipher.getInstance("DES");
// Anfällig: MD5 ist für Sicherheitszwecke gebrochen
MessageDigest md5 = MessageDigest.getInstance("MD5");
// Anfällig: SHA1 ist für Signaturen veraltet
Signature sig = Signature.getInstance("SHA1withRSA");
}
}
# Anfällig: Verwendung veralteter Python-APIs
import os
import cgi
import crypt
import hashlib
# Anfällig: os.popen() ist veraltet
def vulnerable_command_execution(command):
# Veraltet: Verwenden Sie stattdessen das subprocess-Modul
output = os.popen(command).read() # Veraltet
return output
# Anfällig: cgi-Modul ist in Python 3.11+ veraltet
def vulnerable_cgi_usage(data):
# Veraltet: cgi-Modul wird ausgemustert
form = cgi.FieldStorage() # Veraltet
return form.getvalue('name')
# Anfällig: Verwendung schwacher Hash-Funktionen
def vulnerable_password_hashing(password):
# Veraltet: MD5 ist kryptographisch gebrochen
md5_hash = hashlib.md5(password.encode()).hexdigest()
# Veraltet: SHA1 ist für Sicherheitszwecke schwach
sha1_hash = hashlib.sha1(password.encode()).hexdigest()
# Veraltet: crypt-Modul verwendet standardmäßig schwaches DES
hash_result = crypt.crypt(password)
return md5_hash, sha1_hash, hash_result
# Anfällig: Verwendung veralteter Formatierung
def vulnerable_string_formatting(name, value):
# Veralteter Stil (funktioniert noch aber abgeraten)
result = "Name: %s, Wert: %d" % (name, value)
return result
Korrigierter Code
// Korrigiert: Verwendung moderner, sicherer C-Funktionen
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/random.h>
void secure_input_handling() {
char buffer[100];
// Korrigiert: fgets() mit explizitem Größenlimit verwenden
if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
// Trailing Newline entfernen
size_t len = strlen(buffer);
if (len > 0 && buffer[len-1] == '\n') {
buffer[len-1] = '\0';
}
}
printf("Eingabe: %s\n", buffer);
}
void secure_string_copy(const char *input) {
char buffer[50];
// Korrigiert: snprintf() mit explizitem Größenlimit verwenden
snprintf(buffer, sizeof(buffer), "%s", input);
// Korrigiert: strlcpy() verwenden wo verfügbar
// strlcpy(buffer, input, sizeof(buffer));
// Korrigiert: snprintf() für formatierte Strings verwenden
snprintf(buffer, sizeof(buffer), "Wert: %s", input);
}
void secure_password_handling(const char *password) {
// Korrigiert: Modernes Passwort-Hashing verwenden
// Option 1: crypt() mit bcrypt (wenn verfügbar)
char *hash = crypt(password, "$2b$12$.....................");
// Option 2: libsodium oder andere moderne Bibliothek verwenden
// crypto_pwhash_str(hash, password, strlen(password),
// crypto_pwhash_OPSLIMIT_MODERATE,
// crypto_pwhash_MEMLIMIT_MODERATE);
// Korrigiert: getpwuid() anstelle von getpw() verwenden
struct passwd *pw = getpwuid(getuid());
if (pw != NULL) {
// pw->pw_name, pw->pw_dir usw. verwenden
}
}
void secure_random_generation() {
// Korrigiert: Kryptographische Zufallsquelle verwenden
unsigned char random_bytes[16];
// Option 1: getrandom() auf Linux
getrandom(random_bytes, sizeof(random_bytes), 0);
// Option 2: /dev/urandom
FILE *f = fopen("/dev/urandom", "rb");
if (f) {
fread(random_bytes, 1, sizeof(random_bytes), f);
fclose(f);
}
// Option 3: arc4random() auf BSD/macOS
// uint32_t random_value = arc4random();
}
// Korrigiert: Verwendung moderner Java-APIs
import java.time.*;
import java.security.*;
import javax.crypto.*;
public class SecureModernJava {
// Korrigiert: java.time-API verwenden
public LocalDate secureDate() {
// Korrigiert: java.time-Klassen verwenden (Java 8+)
return LocalDate.of(2024, 12, 25);
}
// Korrigiert: Sichere Thread-Beendigung
public void secureThreadTermination(Thread thread) {
// Korrigiert: interrupt() und kooperative Beendigung verwenden
thread.interrupt();
// Thread sollte isInterrupted() prüfen und saüber beenden
}
// Korrigiert: Zeichensatz explizit angeben
public String secureStringConversion(byte[] data) {
// Korrigiert: Zeichensatz explizit angeben
return new String(data, java.nio.charset.StandardCharsets.UTF_8);
}
// Korrigiert: Moderne kryptographische Algorithmen verwenden
public void secureCrypto() throws Exception {
// Korrigiert: AES anstelle von DES verwenden
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// Korrigiert: SHA-256 oder SHA-3 anstelle von MD5 verwenden
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
// Korrigiert: SHA-256 oder besser für Signaturen verwenden
Signature sig = Signature.getInstance("SHA256withRSA");
}
}
# Korrigiert: Verwendung moderner Python-APIs
import subprocess
import hashlib
import secrets
import bcrypt # oder argon2-cffi
# Korrigiert: subprocess anstelle von os.popen verwenden
def secure_command_execution(command_args):
# Korrigiert: subprocess mit Argumentenliste verwenden
# shell=True vermeiden wenn möglich
result = subprocess.run(
command_args,
capture_output=True,
text=True,
check=True
)
return result.stdout
# Korrigiert: Moderne Web-Frameworks anstelle von cgi verwenden
def secure_web_input():
# Korrigiert: Flask, Django oder andere moderne Frameworks verwenden
# from flask import request
# return request.form.get('name')
pass
# Korrigiert: Starkes Passwort-Hashing verwenden
def secure_password_hashing(password):
# Korrigiert: bcrypt verwenden
salt = bcrypt.gensalt(rounds=12)
hash_result = bcrypt.hashpw(password.encode(), salt)
# Oder Argon2 verwenden (empfohlen)
# from argon2 import PasswordHasher
# ph = PasswordHasher()
# hash_result = ph.hash(password)
return hash_result
# Korrigiert: secrets-Modul für kryptographische Zufälligkeit verwenden
def secure_random_generation():
# Korrigiert: secrets für sicherheitssensitive Zufälligkeit verwenden
secure_token = secrets.token_hex(16)
secure_bytes = secrets.token_bytes(16)
secure_url = secrets.token_urlsafe(16)
return secure_token, secure_bytes, secure_url
# Korrigiert: f-Strings oder .format() verwenden
def secure_string_formatting(name, value):
# Korrigiert: f-Strings verwenden (Python 3.6+)
result = f"Name: {name}, Wert: {value}"
# Oder .format() verwenden
result = "Name: {}, Wert: {}".format(name, value)
return result
CVE-Beispiele
Keine spezifischen CVEs sind in der MITRE-Datenbank für dieses CWE aufgelistet. Das Muster ist jedoch assoziiert mit:
- Buffer Overflow-Schwachstellen durch
gets(),strcpy(),sprintf() - Kryptographische Schwächen durch MD5-, SHA1-, DES-Verwendung
- Thread-Safety-Probleme durch veraltete Thread-Kontrollmethoden
Referenzen
- MITRE Corporation. "CWE-477: Use of Obsolete Function." https://cwe.mitre.org/data/definitions/477.html
- CERT C Secure Coding Standard. "MSC24-C. Do not use deprecated or obsolescent functions."
- OWASP Top Ten 2025 - A03: Software Supply Chain Failures.