Falsche Bereitstellung der spezifizierten Funktionalität
Beschreibung
Falsche Bereitstellung der spezifizierten Funktionalität ist eine Schwachstelle, bei der Code nicht gemäß seinen veröffentlichten Spezifikationen oder dokumentiertem Verhalten arbeitet, was potenziell zu falscher Verwendung durch Aufrufer führt, die auf diese Dokumentation vertrauen. Wenn eine Funktion oder API anders als dokumentiert verhält — falsche Fehlercodes zurückgibt, beworbene Validierung weglässt oder undokumentierte Nebeneffekte hat — können Aufrufer, die der Spezifikation vertrauen, den Code falsch verwenden, was zu Sicherheitslücken oder Zuverlässigkeitsproblemen führt.
Risiko
Wenn Code von Spezifikationen abweicht, werden die Sicherheitsannahmen der Aufrufer ungültig. Funktionen, die behaupten, Eingaben zu validieren, es aber nicht tun, können Injektionsangriffe ermöglichen. Fehlercodes, die tatsächliche Fehler nicht widerspiegeln, führen zu unsachgemäßer Fehlerbehandlung. Sicherheitsbibliotheken, die beworbene Prüfungen nicht durchführen, bieten falsches Vertrauen, während sie Systeme verwundbar lassen. API-Konsumenten bauen Systeme unter der Annahme dokumentierten Verhaltens, was systemische Schwachstellen schafft, wenn dieses Verhalten abweicht.
Lösung
Stellen Sie sicher, dass Code strikt seinen dokumentierten Spezifikationen entspricht. Wenn Spezifikationen nicht erfüllt werden können, aktualisieren Sie die Dokumentation, um das tatsächliche Verhalten widerzuspiegeln, und kommunizieren Sie Änderungen an Konsumenten. Implementieren Sie umfassende Tests, die verifizieren, dass Verhalten den Spezifikationen entspricht. Verwenden Sie vertragsbasierte Programmierung oder Assertions, um dokumentierte Vor-/Nachbedingungen durchzusetzen. Führen Sie Code-Reviews durch, die speziell die Spezifikationskonformität prüfen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Sonstiges | Bereich: Sonstige Qualitätsverschlechterung - Anwendungen funktionieren nicht, wenn abhängiger Code sich nicht wie spezifiziert verhält. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle Schutzmechanismus umgehen - Sicherheitsprüfungen, die beworbene Validierung nicht durchführen, ermöglichen Umgehungen. |
| Integrität | Bereich: Integrität Unerwarteter Zustand - Systeme geraten in inkonsistente Zustände, wenn Funktionen dokumentierte Invarianten nicht einhalten. |
Beispielcode und Lösung
Verwundbarer Code
// Verwundbar: Servlet behauptet zu validieren, tut es aber nicht
/**
* Verarbeitet Benutzereingabe.
* @param input Benutzereingabe - validiert für SQL-Injection
* @return verarbeitetes Ergebnis
*/
@WebServlet("/process")
public class VerwundbaresServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String input = request.getParameter("data");
try {
// Dokumentation behauptet SQL-Injection-Validierung
// aber KEINE VALIDIERUNG WIRD TATSÄCHLICH DURCHGEFÜHRT!
String result = processData(input); // Verwundbar!
response.getWriter().write(result);
} catch (Exception e) {
// Verwundbar: Gibt 200 OK auch bei Fehler zurück!
response.setStatus(200); // Sollte Fehlerstatus sein
response.getWriter().write("Verarbeitet");
}
}
private String processData(String input) throws SQLException {
// Verwendet unvalidierte Eingabe direkt in Query
return db.query("SELECT * FROM data WHERE value = '" + input + "'");
}
}
# Verwundbar: Passwortvalidierungsfunktion funktioniert nicht wie dokumentiert
def validiere_passwort(password):
"""
Validiert, dass Passwort Sicherheitsanforderungen erfüllt.
Anforderungen:
- Mindestens 8 Zeichen
- Mindestens ein Großbuchstabe
- Mindestens ein Kleinbuchstabe
- Mindestens eine Ziffer
- Mindestens ein Sonderzeichen
Rückgabe:
True wenn Passwort gültig, sonst False
"""
# VERWUNDBAR: Prüft nur Länge, nicht andere Anforderungen!
if len(password) >= 8:
return True # Dokumentation sagt, es prüft alles!
return False
# Aufrufer vertraut der Dokumentation
def registriere_benutzer(username, password):
if not validiere_passwort(password):
raise ValueError("Passwort erfüllt Anforderungen nicht")
# Aufrufer nimmt an, Passwort hat Großbuchstabe, Ziffer, Sonderzeichen...
# Aber es könnte einfach "aaaaaaaa" sein - erfüllt nur Längenanforderung
erstelle_benutzer(username, password)
// Verwundbar: Cache hält TTL nicht ein wie dokumentiert
/**
* Thread-sicherer Cache mit Time-to-Live-Unterstützung.
* Elemente werden automatisch nach Ablauf der TTL entfernt.
*/
public class VerwundbarerCache<K, V> {
private final Map<K, CacheEntry<V>> cache = new ConcurrentHashMap<>();
/**
* Holt Wert aus Cache.
* @return Wert wenn vorhanden und nicht abgelaufen, sonst null
*/
public V get(K key) {
CacheEntry<V> entry = cache.get(key);
if (entry == null) {
return null;
}
// VERWUNDBAR: TTL-Prüfung ist dokumentiert aber nicht implementiert!
// Abgelaufene Einträge werden trotzdem zurückgegeben
// if (entry.isExpired()) {
// cache.remove(key);
// return null;
// }
return entry.getValue(); // Gibt abgelaufene Einträge zurück!
}
}
Sichere Lösung
// Sicher: Servlet mit ordnungsgemäßer Validierung und Fehlerbehandlung
@WebServlet("/process")
public class SicheresServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String input = request.getParameter("data");
try {
// Sicher: Tatsächlich validieren wie dokumentiert
validateInput(input);
String result = processData(input);
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().write(result);
} catch (ValidationException e) {
// Sicher: Ordnungsgemäße Fehlerantwort
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getWriter().write("Ungültige Eingabe: " + e.getMessage());
} catch (SQLException e) {
// Sicher: Korrekter Fehlercode für Serverfehler
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.getWriter().write("Verarbeitungsfehler");
logger.error("Datenbankfehler", e);
}
}
private void validateInput(String input) throws ValidationException {
// Sicher: Dokumentierte Validierung implementieren
if (input == null) {
throw new ValidationException("Eingabe erforderlich");
}
// Auf SQL-Injection-Muster prüfen
if (containsSqlInjection(input)) {
throw new ValidationException("Ungültige Zeichen in Eingabe");
}
}
private String processData(String input) throws SQLException {
// Sicher: Prepared Statement verwenden
PreparedStatement stmt = db.prepareStatement(
"SELECT * FROM data WHERE value = ?");
stmt.setString(1, input);
return executeAndFormat(stmt);
}
}
# Sicher: Passwortvalidierung entspricht Dokumentation
import re
def validiere_passwort(password: str) -> bool:
"""
Validiert, dass Passwort Sicherheitsanforderungen erfüllt.
Anforderungen:
- Mindestens 8 Zeichen
- Mindestens ein Großbuchstabe
- Mindestens ein Kleinbuchstabe
- Mindestens eine Ziffer
- Mindestens ein Sonderzeichen
Rückgabe:
True wenn Passwort gültig, sonst False
"""
if password is None:
return False
# Sicher: ALLE dokumentierten Anforderungen implementieren
if len(password) < 8:
return False
if not re.search(r'[A-Z]', password):
return False
if not re.search(r'[a-z]', password):
return False
if not re.search(r'\d', password):
return False
if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
return False
return True
// Sicher: Cache hält TTL ein wie dokumentiert
public class SichererCache<K, V> {
public V get(K key) {
CacheEntry<V> entry = cache.get(key);
if (entry == null) {
return null;
}
// Sicher: TTL-Prüfung wie dokumentiert implementieren
if (entry.isExpired()) {
cache.remove(key); // Abgelaufenen Eintrag entfernen
return null; // null für abgelaufene Einträge zurückgeben
}
return entry.getValue();
}
}
Ausgenutzt in der Praxis
PKCS#11-Bibliothek Signaturprüfungsfehler (2002)
Eine PKCS#11-Bibliothek gab "OK" zurück, auch wenn Signaturen ungültig waren. Anwendungen, die der Dokumentation vertrauten, akzeptierten gefälschte Signaturen.
Microsoft Windows "Verlauf löschen" (1999)
Die "Verlauf löschen"-Funktion in Internet Explorer behauptete, alle besuchten URLs zu löschen, tat dies aber nicht vollständig, was zu Datenschutzproblemen führte.
Tools zum Testen und Ausnutzen
-
Contract Testing Tools — Vertragstests zur Verifizierung von API-Verhalten.
-
API Fuzzing Tools — OWASP ZAP für API-Sicherheitstests.
-
Unit Testing Frameworks — JUnit, pytest für Verhaltensverifizierung.
CVE-Beispiele
-
CVE-2002-1446 — PKCS#11-Bibliothek Fehlerprüfung gab "OK" trotz ungültiger Signaturen zurück.
-
CVE-2001-1559 — Systemaufruf gab falschen Wert zurück, führte zu NULL-Pointer-Dereferenzierung.
-
CVE-1999-1446 — "Verlauf löschen" UI-Funktion löschte besuchte URLs-Liste nicht wirklich.
Referenzen
-
MITRE Corporation. "CWE-684: Incorrect Provision of Specified Functionality." https://cwe.mitre.org/data/definitions/684.html
-
Meyer, Bertrand. "Design by Contract." https://www.eiffel.com/values/design-by-contract/
-
OWASP. "API Security Guidelines." https://owasp.org/www-project-api-security/