Übermäßige Code-Komplexität
Beschreibung
Übermäßige Code-Komplexität tritt auf, wenn Code zu komplex ist, gemessen anhand wohldefinierter, quantitativer Maße wie zyklomatische Komplexität, kognitive Komplexität, Verschachtelungstiefe, Codezeilen oder anderer Metriken. Komplexer Code ist schwerer zu verstehen, zu testen, zu warten und auf Sicherheitslücken zu prüfen. Diese Schwachstelle dient als übergeordnete Kategorie für verschiedene spezifische Komplexitätsprobleme einschließlich übermäßiger zyklomatischer Komplexität, Halstead-Komplexität, unbedingter Verzweigungen und anderer messbarer Komplexitätsprobleme.
Risiko
Übermäßige Code-Komplexität hat signifikante indirekte Sicherheitsauswirkungen. Sicherheitslücken sind in komplexem Code schwerer zu identifizieren. Code-Reviewer übersehen möglicherweise subtile Sicherheitsprobleme aufgrund kognitiver Überlastung. Testabdeckung wird schwer zu erreichen und lässt ungetestete Grenzfälle. Wartungsänderungen führen mit größerer Wahrscheinlichkeit neue Schwachstellen ein. Komplexe Codepfade können inkonsistente Sicherheitsprüfungen aufweisen. Statische Analysetools können unzuverlässige Ergebnisse liefern. Entwicklerermüdung führt zu Abkürzungen und Fehlern. Notfall-Patches sind in komplexen Codebasen riskanter.
Lösung
Setzen und erzwingen Sie Komplexitätsschwellenwerte (z.B. zyklomatische Komplexität < 10). Refaktorisieren Sie komplexe Funktionen in kleinere, fokussierte Einheiten. Reduzieren Sie die Verschachtelungstiefe durch frühe Returns und Guard-Klauseln. Verwenden Sie Entwurfsmuster zur Komplexitätsverwaltung. Wenden Sie das Single-Responsibility-Prinzip an. Extrahieren Sie komplexe Bedingungen in gut benannte boolesche Methoden. Eliminieren Sie Code-Duplikation, die die kognitive Last erhöht. Verwenden Sie automatisierte Tools zur Messung und Verfolgung der Komplexität. Nehmen Sie Komplexitätsmetriken in Code-Review-Kriterien auf. Priorisieren Sie das Refactoring sicherheitskritischen komplexen Codes.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Sonstiges | Bereich: Sonstiges Reduzierte Wartbarkeit -- Macht es schwieriger, das Produkt zu verstehen und zu warten, was die Sicherheit indirekt beeinträchtigt, indem Schwachstellen schwerer zu finden und zu beheben sind. Kann die Einführung neuer Schwachstellen erleichtern. |
| Sonstiges | Bereich: Sonstiges Erhöhte analytische Komplexität -- Komplexer Code ist schwerer auf Sicherheitsprobleme zu prüfen und zu analysieren. |
| Sonstiges | Bereich: Sonstiges Reduzierte Leistung -- Kann die Produktleistung verschlechtern. Wenn von einem Angreifer erreichbar, könnten Denial-of-Service-Schwachstellen eingeführt werden. |
Beispielcode und Lösung
Verwundbarer Code
// Verwundbar: Übermäßig komplexe Methode
// Zyklomatische Komplexität > 30, tiefe Verschachtelung, mehrere Verantwortlichkeiten
public class UserProcessor {
public ProcessResult processUserRequest(User user, Request request,
Context context, Options options) {
ProcessResult result = new ProcessResult();
// Tiefe Verschachtelung und komplexe Bedingungen
if (user != null) {
if (user.isActive()) {
if (request != null) {
if (request.getType() != null) {
switch (request.getType()) {
case "CREATE":
if (user.hasPermission("create")) {
if (options.isValidated()) {
if (context.isSecure()) {
try {
if (validateRequest(request)) {
if (checkQuota(user)) {
if (!isDuplicate(request)) {
// Tatsächlich etwas tun
result = createResource(request);
// ... weitere verschachtelte Logik
}
}
}
} catch (Exception e) {
result.setError("exception: " + e.getMessage());
}
}
}
}
break;
case "UPDATE":
// Weitere 50 Zeilen ähnlich tief verschachtelter Code...
break;
}
}
}
}
}
return result;
}
}
Sichere Lösung
// SICHER: In kleinere, fokussierte Methoden mit klaren Verantwortlichkeiten refaktorisiert
public class UserProcessor {
public ProcessResult processUserRequest(User user, Request request,
Context context, Options options) {
// Frühe Validierung mit klarer Fehlerbehandlung
ValidationResult validation = validateInputs(user, request, context, options);
if (!validation.isValid()) {
return ProcessResult.error(validation.getError());
}
// An spezifischen Handler basierend auf Anfrage-Typ delegieren
RequestHandler handler = getHandler(request.getType());
if (handler == null) {
return ProcessResult.error("unknown_request_type");
}
// Mit dem entsprechenden Handler verarbeiten
ProcessResult result = handler.handle(user, request, context);
// Nachverarbeitung (Benachrichtigungen, Protokollierung)
if (result.isSuccess()) {
performPostProcessing(user, request, result, options);
}
return result;
}
private ValidationResult validateInputs(User user, Request request,
Context context, Options options) {
if (user == null) {
return ValidationResult.invalid("null_user");
}
if (!user.isActive()) {
return ValidationResult.invalid("inactive_user");
}
if (request == null || request.getType() == null) {
return ValidationResult.invalid("invalid_request");
}
if (!context.isSecure()) {
return ValidationResult.invalid("insecure_context");
}
if (!options.isValidated()) {
return ValidationResult.invalid("not_validated");
}
return ValidationResult.valid();
}
private RequestHandler getHandler(String requestType) {
return switch (requestType) {
case "CREATE" -> new CreateHandler();
case "UPDATE" -> new UpdateHandler();
case "DELETE" -> new DeleteHandler();
default -> null;
};
}
private void performPostProcessing(User user, Request request,
ProcessResult result, Options options) {
if (options.shouldNotify()) {
notificationService.notify(user, result);
}
if (options.shouldLog()) {
auditService.log(user, request, result);
}
}
}
// Separater Handler mit einzelner Verantwortlichkeit
class CreateHandler implements RequestHandler {
@Override
public ProcessResult handle(User user, Request request, Context context) {
// Guard-Klausel für Berechtigung
if (!user.hasPermission("create")) {
return ProcessResult.error("no_permission");
}
// Validierungskette
if (!requestValidator.validate(request)) {
return ProcessResult.error("invalid_request");
}
if (!quotaService.checkQuota(user)) {
return ProcessResult.error("quota_exceeded");
}
if (duplicateChecker.isDuplicate(request)) {
return ProcessResult.error("duplicate");
}
// Kernlogik
return resourceService.createResource(request);
}
}
# SICHER: In kleinere, fokussierte Funktionen refaktorisiert
def process_order(order: Order, user: User, payment: Payment,
shipping: Shipping, discounts: list[Discount],
inventory: Inventory, config: Config) -> OrderResult:
"""Verarbeitet eine Bestellung mit klaren, handhabbaren Schritten."""
# Schritt 1: Eingaben validieren
validation_error = validate_order_inputs(order, user, payment)
if validation_error:
return OrderResult.error(validation_error)
# Schritt 2: Zahlungsmethode validieren
payment_validation = validate_payment(payment)
if not payment_validation.is_valid:
return OrderResult.error(payment_validation.errors)
# Schritt 3: Inventar prüfen und reservieren
inventory_result = process_inventory(order.items, inventory, config)
if not inventory_result.success:
return OrderResult.error(inventory_result.errors)
# Schritt 4: Rabatte berechnen
discount_amount = calculate_discounts(order, discounts)
# Schritt 5: Zahlung verarbeiten
final_amount = order.total - discount_amount
payment_result = process_payment(payment, final_amount)
if not payment_result.success:
inventory_result.rollback()
return OrderResult.error(payment_result.error)
# Schritt 6: Bestelldatensatz erstellen
return OrderResult.success(
order_id=create_order_record(order, user, payment_result),
total=final_amount,
discount=discount_amount
)
def validate_order_inputs(order: Order, user: User, payment: Payment) -> str | None:
"""Validiert grundlegende Bestelleingaben. Gibt Fehlermeldung oder None zurück."""
if not order or not user or not payment:
return "missing_required_fields"
if not user.is_verified:
return "user_not_verified"
if user.is_banned:
return "user_banned"
if order.total <= 0:
return "invalid_order_total"
return None
CVE-Beispiele
Diese CWE ist als VERBOTEN für direkte CVE-Zuordnung markiert, da sie ein Codequalitätsproblem darstellt und keine direkte Sicherheitslücke.
Verwandte CWEs
- CWE-710: Unsachgemäße Einhaltung von Codierungsstandards (Eltern)
- CWE-1121: Übermäßige McCabe-zyklomatische Komplexität (Kind)
- CWE-1122: Übermäßige Halstead-Komplexität (Kind)
- CWE-1119: Übermäßige Verwendung unbedingter Verzweigungen (Kind)
- CWE-1226: Komplexitätsprobleme (Kategoriemitglied)
Referenzen
- MITRE Corporation. "CWE-1120: Excessive Code Complexity." https://cwe.mitre.org/data/definitions/1120.html
- McCabe, T.J. "A Complexity Measure" IEEE Transactions on Software Engineering
- Halstead, M.H. "Elements of Software Science"
- CISQ Quality Measures - Maintainability