Aufrufbares Kontrollelement mit übermäßigem Volumen auskommentierten Codes
Beschreibung
Aufrufbares Kontrollelement mit übermäßigem Volumen auskommentierten Codes tritt auf, wenn eine Funktion, Methode oder ein ähnliches Codeelement eine übermäßige Menge von Code enthält, der innerhalb seines Körpers auskommentiert wurde. CISQ empfiehlt einen Schwellenwert von 2% als Standardmaß für übermäßigen auskommentierten Code. Auskommentierter Code überlädt die Codebasis, macht Funktionen schwerer zu verstehen und deutet oft auf unvollständige Änderungen, zurückgelassenen Debug-Code oder Unsicherheit darüber hin, ob Code benötigt wird.
Risiko
Übermäßiger auskommentierter Code hat indirekte Sicherheitsimplikationen. Er erzeugt Verwirrung darüber, welcher Code tatsächlich ausgeführt wird, was Sicherheitsüberprüfungen erschwert. Alter auskommentierter Code kann Sicherheitsschwachstellen enthalten, die Entwickler versehentlich wieder einkommentieren könnten. Der auskommentierte Code kann auf veraltete APIs verweisen oder veraltete Sicherheitspraktiken enthalten. Er erhöht die kognitive Last, wodurch Entwickler eher tatsächliche Sicherheitsprobleme übersehen. Versionskontrolle macht auskommentierten Code unnötig - wenn er benötigt wird, kann er aus der History abgerufen werden. Auskommentierter Code kann sensible Informationen wie Passwörter oder API-Schlüssel enthalten.
Lösung
Entfernen Sie auskommentierten Code - verwenden Sie Versionskontrolle, um die History zu bewahren. Wenn Code möglicherweise benötigt wird, erstellen Sie einen Branch oder Tag vor dem Entfernen. Dokumentieren Sie, warum Code entfernt wurde, in Commit-Nachrichten. Verwenden Sie Feature-Flags anstelle von auskommentiertem Code für A/B-Tests. Richten Sie Linting-Regeln ein, um auskommentierte Codeblöcke zu erkennen. Überprüfen Sie auskommentierten Code während Code-Reviews und fordern Sie die Entfernung. Wenn Code vorübergehend deaktiviert ist, verwenden Sie ordnungsgemäße Feature-Toggle-Mechanismen. Hinterlassen Sie niemals Debug-Code oder sensible Informationen in Kommentaren.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Andere | Bereich: Ändere Reduzierte Wartbarkeit - Auskommentierter Code überlädt die Codebasis und verwirrt Leser. |
| Andere | Bereich: Ändere Erhöhte analytische Komplexität - Sicherheitsüberprüfung ist schwieriger mit totem Code gemischt mit aktivem Code. |
| Vertraulichkeit | Bereich: Vertraulichkeit Informationspreisgabe - Auskommentierter Code kann sensible Informationen enthalten. |
Beispielcode
Anfälliger Code
// Anfällig: Methode mit übermäßigem auskommentiertem Code
public class VulnerablePaymentProcessor {
public PaymentResult processPayment(PaymentRequest request) {
// Zahlung initialisieren
PaymentResult result = new PaymentResult();
// Alte Validierungslogik - behalte nur für alle Fälle
// if (request.getAmount() == null) {
// throw new ValidationException("Betrag erforderlich");
// }
// if (request.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
// throw new ValidationException("Betrag muss positiv sein");
// }
// String cardNumber = request.getCardNumber();
// if (cardNumber == null || cardNumber.length() < 13) {
// throw new ValidationException("Ungültige Kartennummer");
// }
// Anfrage validieren
validateRequest(request);
// Alte Zahlungsgateway-Integration - NICHT Löschen
// PaymentGateway gateway = new OldPaymentGateway();
// gateway.setApiKey("sk_live_old_key_12345"); // ALTER API-SCHLÜSSEL!
// gateway.setEndpoint("https://old-api.payment.com/v1");
// try {
// GatewayResponse response = gateway.charge(
// request.getCardNumber(),
// request.getExpiry(),
// request.getCvv(),
// request.getAmount()
// );
// if (response.isSuccess()) {
// result.setTransactionId(response.getTransactionId());
// }
// } catch (GatewayException e) {
// logger.error("Zahlung fehlgeschlagen", e);
// throw new PaymentException("Zahlungsverarbeitung fehlgeschlagen");
// }
// Debug-Code - vor Produktion entfernen
// System.out.println("Karte: " + request.getCardNumber());
// System.out.println("CVV: " + request.getCvv());
// System.out.println("Betrag: " + request.getAmount());
// Aktuelle Implementierung
PaymentGateway gateway = gatewayFactory.createGateway();
GatewayResponse response = gateway.charge(request);
// Alte Antwortverarbeitung
// if (response.getCode() == 200) {
// result.setSuccess(true);
// } else if (response.getCode() == 401) {
// // Auth fehlgeschlagen - mit Backup-Schlüssel wiederholen
// gateway.setApiKey("sk_live_backup_key_67890");
// response = gateway.charge(request);
// } else if (response.getCode() == 500) {
// // Serverfehler - warten und wiederholen
// Thread.sleep(1000);
// response = gateway.charge(request);
// }
result.setTransactionId(response.getTransactionId());
result.setSuccess(response.isSuccess());
// Protokollierung die wir später brauchen könnten
// logTransaction(request, result);
// notifyFraudDetection(request);
// updateMetrics(result);
return result;
}
// Probleme:
// 1. ~40% der Methode ist auskommentierter Code
// 2. Enthält alte API-Schlüssel (Sicherheitsrisiko!)
// 3. Enthält Debug-Code der sensible Daten ausgibt
// 4. Schwer zu verstehen welcher Code tatsächlich ausgeführt wird
// 5. Alter Code kann Schwachstellen enthalten
}
# Anfällig: Funktion mit übermäßigem auskommentiertem Code
class VulnerableUserService:
def create_user(self, user_data: dict) -> User:
"""Erstellt ein neues Benutzerkonto."""
# Alte Validierung - ersetzt durch Schema-Validierung
# if not user_data.get('email'):
# raise ValueError("E-Mail erforderlich")
# if not user_data.get('password'):
# raise ValueError("Passwort erforderlich")
# if len(user_data.get('password', '')) < 8:
# raise ValueError("Passwort zu kurz")
# if not '@' in user_data.get('email', ''):
# raise ValueError("Ungültige E-Mail")
# Mit neuem Schema validieren
validated = UserSchema().load(user_data)
# Altes Passwort-Hashing - NICHT VERWENDEN
# import md5
# password_hash = md5.new(user_data['password']).hexdigest()
# Etwas besser aber immer noch schlecht
# import hashlib
# password_hash = hashlib.sha256(
# user_data['password'].encode()
# ).hexdigest()
# Aktuelles sicheres Hashing
password_hash = bcrypt.hashpw(
validated['password'].encode(),
bcrypt.gensalt()
)
# Alte Benutzererstellung mit rohem SQL
# cursor = self.db.cursor()
# cursor.execute(
# f"INSERT INTO users (email, password) VALUES "
# f"('{validated['email']}', '{password_hash}')"
# ) # SQL-INJECTION!
# self.db.commit()
# user_id = cursor.lastrowid
# Debug-Code
# print(f"Erstelle Benutzer: {validated['email']}")
# print(f"Passwort-Hash: {password_hash}")
# import pdb; pdb.set_trace()
# Benutzer mit ORM erstellen
user = User(
email=validated['email'],
password_hash=password_hash
)
self.session.add(user)
self.session.commit()
# Alter Benachrichtigungscode
# send_welcome_email(user.email)
# notify_admin_new_user(user)
# update_user_count_metric()
return user
# Probleme:
# - Zeigt Evolution von unsicherem zu sicherem Code
# - Enthält SQL-Injection-Schwachstelle
# - Enthält MD5/SHA256-Passwort-Hashing (unsicher)
# - Enthält Debug-Code mit sensiblen Daten
Korrigierter Code
// Korrigiert: Saubere Methode ohne auskommentierten Code
public class FixedPaymentProcessor {
private final PaymentGatewayFactory gatewayFactory;
private final PaymentValidator validator;
private final TransactionLogger transactionLogger;
/**
* Verarbeitet eine Zahlungsanfrage.
*
* @param request Die zu verarbeitende Zahlungsanfrage
* @return Das Ergebnis der Zahlungsverarbeitung
* @throws PaymentValidationException wenn Anfrage ungültig ist
* @throws PaymentProcessingException wenn Zahlung fehlschlägt
*/
public PaymentResult processPayment(PaymentRequest request) {
// Anfrage validieren
validator.validate(request);
// Durch Gateway verarbeiten
PaymentGateway gateway = gatewayFactory.createGateway();
GatewayResponse response = gateway.charge(request);
// Ergebnis erstellen
PaymentResult result = new PaymentResult();
result.setTransactionId(response.getTransactionId());
result.setSuccess(response.isSuccess());
// Transaktion protokollieren (async, nicht-blockierend)
transactionLogger.logAsync(request, result);
return result;
}
}
// Unterstützende Dokumentation in separaten Dateien:
// CHANGELOG.md oder Git-History:
// ## Payment Gateway Migration (2024-01-15)
// - Von OldPaymentGateway auf NewPaymentGateway migriert
// - Alte Implementierung verfügbar in Git-History: Commit abc123
// - Migrationsanleitung: docs/payment-migration.md
// docs/payment-migration.md:
// ## Warum wir Zahlungsgateways gewechselt haben
// - Altes Gateway veraltet seit 2023-12
// - Neues Gateway hat bessere Betrugserkennung
// - Siehe Commit abc123 für alte Implementierung falls Rollback nötig
# Korrigiert: Saubere Funktion ohne auskommentierten Code
class FixedUserService:
"""Benutzerverwaltungsdienst."""
def __init__(self, session, password_hasher, event_publisher):
self._session = session
self._password_hasher = password_hasher
self._event_publisher = event_publisher
def create_user(self, user_data: dict) -> User:
"""Erstellt ein neues Benutzerkonto.
Args:
user_data: Dictionary mit E-Mail und Passwort
Returns:
Das erstellte User-Objekt
Raises:
ValidationError: Wenn Benutzerdaten ungültig sind
"""
# Mit Schema validieren
validated = UserSchema().load(user_data)
# Passwort sicher hashen
password_hash = self._password_hasher.hash(validated['password'])
# Benutzer erstellen
user = User(
email=validated['email'],
password_hash=password_hash
)
self._session.add(user)
self._session.commit()
# Event für async Benachrichtigungen veröffentlichen
self._event_publisher.publish(UserCreatedEvent(user))
return user
# Passwort-Hasher-Implementierung (separate Datei)
class BcryptPasswordHasher:
"""Sicheres Passwort-Hashing mit bcrypt.
Hinweis: Ersetzt MD5/SHA256-Hashing in v2.0.
Siehe CHANGELOG.md für Migrationsdetails.
"""
def __init__(self, rounds: int = 12):
self._rounds = rounds
def hash(self, password: str) -> bytes:
return bcrypt.hashpw(
password.encode(),
bcrypt.gensalt(rounds=self._rounds)
)
def verify(self, password: str, hash: bytes) -> bool:
return bcrypt.checkpw(password.encode(), hash)
# CHANGELOG.md:
"""
## v2.0.0 (2024-01-15)
### Sicherheit
- **BREAKING**: MD5/SHA256-Passwort-Hashing durch bcrypt ersetzt
- Frühere Implementierungen sind Sicherheitsschwachstellen
- Siehe Migrationsanleitung für Upgrade bestehender Passwort-Hashes
### Entfernt
- Rohe SQL-Abfragen durch ORM ersetzt
- Debug-Print-Anweisungen entfernt
- Inline-Validierung durch Schema-Validierung ersetzt
### Für historische Referenz
- Alte Implementierungen verfügbar im Git-Tag v1.9.9
- Verwenden Sie NICHT die alten Passwort-Hashing-Methoden
"""
// Korrigiert: Sauberes JavaScript ohne auskommentierten Code
class FixedUserController {
constructor(userService, logger) {
this.userService = userService;
this.logger = logger;
}
/**
* Erstellt einen neuen Benutzer.
* @param {Object} req - Express-Request
* @param {Object} res - Express-Response
*/
async createUser(req, res) {
try {
const user = await this.userService.create(req.body);
this.logger.info('Benutzer erstellt', { userId: user.id });
return res.status(201).json({
success: true,
user: user.toPublicJSON()
});
} catch (error) {
this.logger.error('Benutzererstellung fehlgeschlagen', { error: error.message });
if (error instanceof ValidationError) {
return res.status(400).json({
success: false,
error: error.message
});
}
return res.status(500).json({
success: false,
error: 'Interner Serverfehler'
});
}
}
}
// Wenn Sie alte Implementierungen als Referenz behalten müssen:
// 1. Git-Tags verwenden: git tag v1.0-before-refactor
// 2. In CHANGELOG.md dokumentieren
// 3. Migrationsanleitungen in docs/ erstellen
// 4. NIEMALS alten Code als Kommentare hinterlassen
CVE-Beispiele
Obwohl auskommentierter Code selbst selten direkte Schwachstellen verursacht, wurde er mit Informationspreisgabe (Offenlegung von API-Schlüsseln, Passwörtern) assoziiert und hat zu Verwirrung beigetragen, die zu Sicherheitsfehlern führte.
Verwandte CWEs
- CWE-1071: Empty Code Block (Elternkategorie)
- CWE-546: Suspicious Comment (verwandt)
- CWE-615: Inclusion of Sensitive Information in Source Code Comments (verwandt)
Referenzen
-
MITRE Corporation. "CWE-1085: Invokable Control Element with Excessive Volume of Commented-out Code." https://cwe.mitre.org/data/definitions/1085.html
-
CISQ. "Automated Source Code Quality Measures."
-
Martin, Robert C. "Clean Code" - Kommentar-Kapitel.