Unangemessener Whitespace-Stil
Beschreibung
Unangemessener Whitespace-Stil tritt auf, wenn Quellcode Whitespace enthält, der im Code inkonsistent ist oder nicht den erwarteten Standards für das Produkt folgt. Dies umfasst inkonsistente Einrückung (Mischen von Tabs und Leerzeichen), variierende Anzahl von Leerzeichen für Einrückung, inkonsistente Abstände um Operatoren, unregelmäßige Zeilenlängen und nicht standardmäßige Verwendung von Leerzeilen. Inkonsistenter Whitespace macht Code schwieriger zu lesen, zu verstehen und zu warten und kann Kontrollflussprobleme verbergen, die zu Sicherheitsschwachstellen führen.
Risiko
Unangemessene Whitespace-Stile haben indirekte, aber potenziell schwerwiegende Sicherheitsimplikationen. Das bemerkenswerteste Beispiel ist die Apple "goto fail"-Schwachstelle (CVE-2014-1266), bei der inkonsistente Einrückung einen kritischen Kontrollflussbug verdeckte. Prüfer können fälschlicherweise annehmen, dass Einrückung den tatsächlichen Kontrollfluss widerspiegelt, was zu übersehenen Schwachstellen führt. Merge-Konflikte sind bei inkonsistentem Whitespace häufiger und führen möglicherweise zu Fehlern. Code-Review wird schwieriger, wenn Formatierung inkonsistent ist. Automatisierte Analysetools können inkonsistente Ergebnisse liefern. Sicherheitskritische Codeabschnitte können schwieriger zu identifizieren und ordnungsgemäß zu überprüfen sein.
Lösung
Etablieren und erzwingen Sie konsistente Whitespace-Standards im gesamten Projekt. Wählen Sie entweder Tabs oder Leerzeichen und verwenden Sie sie konsistent. Definieren Sie eine Standard-Einrückungsbreite (z.B. 2 oder 4 Leerzeichen). Verwenden Sie automatisierte Formatierer (Prettier, Black, gofmt, clang-format), um Konsistenz durchzusetzen. Konfigurieren Sie Editor-Einstellungen passend zu Projektstandards. Verwenden Sie Pre-Commit-Hooks, um Whitespace-Konsistenz zu prüfen. Verwenden Sie immer geschweifte Klammern für Kontrollstrukturen, um einrückungsbezogene Bugs zu vermeiden. Dokumentieren Sie Whitespace-Standards in Projektrichtlinien. Verwenden Sie Linting-Tools, um Whitespace-Inkonsistenzen zu erkennen. Überprüfen Sie Whitespace bei Code-Reviews.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Andere | Bereich: Ändere Erhöhte Analysekomplexität - Prüfer könnten fälschlicherweise annehmen, dass Einrückung den tatsächlichen Kontrollfluss widerspiegelt, was die Schwachstellenerkennung erschwert. |
| Andere | Bereich: Ändere Reduzierte Wartbarkeit - Schlechter Whitespace macht Code schwieriger zu verstehen und zu warten, was indirekt die Sicherheit beeinträchtigt. |
Beispielcode
Anfälliger Code
// ANFÄLLIG: Das berühmte "goto fail"-Muster (ähnlich CVE-2014-1266)
// Inkonsistente Einrückung verbirgt kritischen Kontrollflussbug
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa,
SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
OSStatus err;
// Inkonsistente Einrückung durchgehend
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail; // KRITISCHER BUG: Dies wird immer ausgeführt wegen fehlender Klammern!
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
// Der Code nach dem doppelten "goto fail" ist unerreichbar
// SSL-Zertifikatsvalidierung wird umgangen!
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
# ANFÄLLIG: Python mit inkonsistentem Whitespace
def process_user_input(data):
# Mix aus Tabs und Leerzeichen - verursacht IndentationError in Python 3
# oder stille Bugs in Python 2
if data.is_valid: # Tab hier
process(data) # Leerzeichen hier
# Inkonsistente Einrückungsebenen
if user.is_admin:
delete_all() # 2 Leerzeichen
else:
log_attempt() # 4 Leerzeichen
# Inkonsistente Abstände um Operatoren
total=price* quantity+tax
discount = total * 0.1
# Sicherheitsprüfung mit irreführender Einrückung
if not authenticated:
return error
log_intrusion() # Dies sieht aus als wäre es im if-Block
# aber Python sieht es als unerreichbaren Code
// ANFÄLLIG: JavaScript mit inkonsistentem Whitespace
function validateUser(user) {
// Inkonsistente Einrückung
if (user.isAdmin) {
grantAllAccess(user); // 12 Leerzeichen
}
else{ // Kein Leerzeichen vor Klammer
revokeAccess(user); // 6 Leerzeichen
}
// Irreführende Einrückung (JavaScript ignoriert Whitespace)
if (isSecureContext)
validateToken();
authorizeRequest(); // WIRD IMMER Ausgeführt - nicht im if!
// Gemischte Tabs und Leerzeichen
if (user.authenticated) { // Tab
processRequest(); // Leerzeichen
}
// Inkonsistente Zeilenabstände
sensitiveOperation1();sensitiveOperation2(); // Schwer zu reviewen
sensitiveOperation3();
sensitiveOperation4(); // Übermäßige Leerzeilen
}
// ANFÄLLIG: Java mit Whitespace-Problemen
public class VulnerablePaymentProcessor {
// Inkonsistente Methodenabstände
public void processPayment(Payment p){ // Kein Leerzeichen vor Klammer
// Sicherheitsprüfung mit irreführender Einrückung
if (p.isVerified())
validateAmount(p);
processTransaction(p); // WIRD IMMER Ausgeführt - nicht im if-Block!
// Inkonsistente Operatorabstände
double total=p.amount*1.1+fee;
double discount= total *0.05;
// Lange Zeilen die schlecht umbrechen
if (user.hasPermission("admin") && payment.isVerified() && !payment.isFlagged() && securityContext.isActive()) { doAdminStuff(); }
}
public void refund( Payment p ) { // Inkonsistente Parameterabstände
// ...
}
}
Korrigierter Code
// SICHER: Konsistenter Whitespace und immer Klammern verwenden
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa,
SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
OSStatus err;
// Konsistente 4-Leerzeichen-Einrückung durchgehend
// Immer Klammern für Kontrollstrukturen verwenden
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) {
goto fail;
}
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) {
goto fail;
}
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) {
goto fail;
}
// Signatur verifizieren
err = SSLVerifySignature(ctx, isRsa, &hashOut, signature, signatureLen);
if (err != 0) {
goto fail;
}
err = 0; // Erfolg
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
# SICHER: Konsistenter Python-Whitespace (PEP 8-konform)
def process_user_input(data):
"""Benutzereingabe mit ordnungsgemäßer Validierung verarbeiten."""
# Konsistente 4-Leerzeichen-Einrückung (keine Tabs)
if data.is_valid:
process(data)
# Konsistente Einrückungsebenen
if user.is_admin:
delete_all()
else:
log_attempt()
# Konsistente Abstände um Operatoren (PEP 8)
total = price * quantity + tax
discount = total * 0.1
# Klarer Kontrollfluss mit ordnungsgemäßer Struktur
if not authenticated:
log_intrusion() # Klar im if-Block
return error
# Verarbeitung für authentifizierte Benutzer fortsetzen
return success
// SICHER: Konsistenter JavaScript-Whitespace
function validateUser(user) {
// Konsistente 4-Leerzeichen-Einrückung
if (user.isAdmin) {
grantAllAccess(user);
} else {
revokeAccess(user);
}
// Immer Klammern für Klarheit verwenden
if (isSecureContext) {
validateToken();
}
authorizeRequest(); // Klar getrennt vom if-Block
// Konsistente Formatierung
if (user.authenticated) {
processRequest();
}
// Eine Anweisung pro Zeile für Lesbarkeit
sensitiveOperation1();
sensitiveOperation2();
sensitiveOperation3();
sensitiveOperation4();
}
// SICHER: Konsistenter Java-Whitespace
public class FixedPaymentProcessor {
/**
* Zahlungstransaktion verarbeiten.
*
* @param payment Die zu verarbeitende Zahlung
*/
public void processPayment(Payment payment) {
// Immer Klammern verwenden - verhindert versehentlichen Code außerhalb von Blöcken
if (payment.isVerified()) {
validateAmount(payment);
processTransaction(payment);
}
// Konsistente Operatorabstände
double total = payment.amount * 1.1 + fee;
double discount = total * 0.05;
// Lange Zeilen für Lesbarkeit umbrechen
boolean canProcess = user.hasPermission("admin")
&& payment.isVerified()
&& !payment.isFlagged()
&& securityContext.isActive();
if (canProcess) {
doAdminStuff();
}
}
public void refund(Payment payment) {
// Konsistente Parameterabstände (keine extra Leerzeichen)
// ...
}
}
CVE-Beispiele
CVE-2014-1266 (Apple "goto fail"): Obwohl primär ein Logikfehler, machte der irreführende Whitespace/Einrückung in Apples SSL-Implementierung die doppelte "goto fail"-Anweisung schwieriger bei Code-Review zu erkennen. Der Code schien zu zeigen, dass das zweite "goto fail" in einem if-Block war, während es tatsächlich bedingungslos ausgeführt wurde, wodurch die SSL-Zertifikatsvalidierung umgangen wurde.
Verwandte CWEs
- CWE-1078: Unangemessener Quellcode-Stil oder Formatierung (Eltern)
- CWE-1006: Schlechte Programmierpraktiken (Kategoriemitglied)
- CWE-1113: Unangemessener Kommentarstil (verwandt)
- CWE-483: Falsche Blockabgrenzung (verwandt - Folge von irreführendem Whitespace)
Referenzen
-
MITRE. "CWE-1114: Inappropriate Whitespace Style." https://cwe.mitre.org/data/definitions/1114.html
-
CVE-2014-1266 - Apple SSL/TLS Bug
-
PEP 8 - Style Guide für Python-Code
-
Google Style Guides (verschiedene Sprachen)