Zum Inhalt springen

Veraltete API-Versionen bleiben erreichbar

CWE-1059CWE-285OWASP A05:2021Aktualisiert 4. September 20264 Min. Lesezeit

Wird eine neue API-Version veröffentlicht, läuft die alte oft für noch nicht umgestellte Clients weiter. Diese alte Version erhält keine Aufmerksamkeit mehr, entbehrt der seither ergänzten Autorisierungsprüfungen und Validierungen und bildet damit einen Umweg um all diese Verbesserungen herum.

Veröffentlicht ein Team eine neue Fassung seiner API, richtet sich die Aufmerksamkeit auf das Neue. Die alte Version läuft weiter, weil noch Clients davon abhängen, und verschwindet damit aus dem Blick, nicht jedoch aus der Infrastruktur. Im Folgenden lesen Sie, warum genau dieser zurückgelassenen Version die Prüfungen fehlen, die Sie seither ergänzt haben.

Warum bleibt eine alte API-Version bestehen?

Von veralteten API-Versionen, die erreichbar bleiben, spricht man, wenn eine ältere Generation von Endpunkten neben der aktuellen weiterläuft, ohne dieselbe Pflege zu erhalten. Es ist kein Entwurfsfehler, sondern eine Folge davon, wie APIs sich in der Praxis entwickeln: Sie können bestehende Clients nicht von einem Tag auf den anderen abschneiden, also läuft die alte Version eine Weile daneben. Aus dieser Weile werden Jahre.

Was zwischenzeitlich geschieht, ist das eigentliche Problem. Jede Verbesserung an der neuen Version, eine strengere Autorisierungsprüfung, ein Schema zur Eingabevalidierung, eine Ratenbegrenzung, weniger Felder in der Antwort, wird dort umgesetzt und nicht in der alten. Der Abstand wächst stillschweigend, und die alte Version wird damit zu einem Umweg um all diese Verbesserungen herum.

Vergleichen Sie es mit einem Gebäude, an dem ein neuer Eingang mit Zutrittskontrolle errichtet wurde, während die alte Tür auf der Rückseite offen bleibt, weil einige Personen noch einen alten Schlüssel besitzen. Alle Aufmerksamkeit und alle Maßnahmen liegen an der neuen Tür. Der Einbrecher geht zur alten.

Wie findet ein Angreifer alte API-Versionen?

Verwundbar:

// Die aktuelle Version, mit sämtlichen Prüfungen
app.get('/api/v3/kunden/:id',
  erfordertAnmeldung,
  erfordertRolle('kundenbetreuer'),
  ratenbegrenzung,
  async (req, res) => {
    const kunde = await kunden.findeFuerBetreuer(req.params.id, req.nutzer.id);
    res.json(kundenUebersicht(kunde));            // begrenzte Felder
  },
);

// Die alte Version, nie wieder angefasst
app.get('/api/v1/kunden/:id', erfordertAnmeldung, async (req, res) => {
  const kunde = await kunden.finde(req.params.id);
  res.json(kunde);                                 // der vollständige Datensatz
});

Beide Routen bestehen, beide auf demselben Server. Die aktuelle prüft die Rolle, begrenzt das Tempo, sieht nach, ob der Kunde zu diesem Betreuer gehört, und gibt nur die vorgesehenen Felder zurück. Die alte verlangt eine gültige Sitzung und tut weiter nichts. Ein Angreifer mit einem gewöhnlichen Konto muss lediglich die Versionsnummer ändern:

GET /api/v3/kunden/8891 HTTP/1.1     → 403 Kein Zugriff
GET /api/v1/kunden/8891 HTTP/1.1     → 200 OK, vollständiger Datensatz

Das Auffinden kostet wenig Mühe. Versionsnummern sind vorhersehbar, alte Pfade stehen häufig noch in archivierten Dokumentationen, und eine veraltete mobile Anwendung, die noch im Umlauf ist, verrät genau, welche Endpunkte es einst gab.

Sicher:

// Jede Version läuft durch dieselbe Autorisierungs- und Validierungsschicht
const basis = [erfordertAnmeldung, ratenbegrenzung, pruefeZugriff];

app.get('/api/v3/kunden/:id', ...basis, v3.zeigeKunde);
app.get('/api/v2/kunden/:id', ...basis, v2.zeigeKunde);

// Und was nicht mehr unterstützt wird, ist wirklich geschlossen
app.use('/api/v1', (req, res) => {
  res.status(410).json({
    fehler: 'Diese API-Version wird nicht mehr unterstützt',
    dokumentation: 'https://portal.example/api/migration',
  });
});

Die gemeinsame Schicht sorgt dafür, dass eine Verbesserung an der Autorisierung sofort für jede unterstützte Version gilt. Und eine Version, die Sie ausmustern, gibt eine 410 zurück, statt stillschweigend weiterzulaufen; das ist für die noch darauf befindlichen Clients eindeutig und schließt den Umweg.

Es geht nicht allein um Versionsnummern. Endpunkte, die ersetzt wurden, aber weiterbestehen, Testrouten, die in der Produktion gelandet sind, und vorübergehende Anbindungen für eine nie aufgeräumte Migration ergeben alle dasselbe Bild: Funktionen, die laufen, ohne dass noch jemand hinsieht.

Welche Auswirkungen haben veraltete API-Versionen?

Der Schweregrad reicht von mittel bis hoch und bestimmt sich danach, wie groß der Abstand zwischen den Versionen geworden ist. Bei einem Unterschied von einigen Monaten hält es sich in Grenzen; bei einer vor Jahren eingefrorenen Version können sämtliche inzwischen ergänzten Prüfungen fehlen.

Kennzeichnend für diesen Befund ist, dass er den Wert Ihrer eigenen Verbesserungen zunichtemacht. Ein Team, das die Autorisierung auf Objektebene ordentlich eingerichtet, die Eingabevalidierung verschärft und die Zahl der zurückgegebenen Felder begrenzt hat, hat all das in der neuen Version getan. Solange die alte erreichbar ist, entspricht die tatsächliche Absicherung der der schwächsten Version.

Hinzu kommt, dass alte Versionen selten von der Überwachung erfasst werden. Alarme greifen bei ungewöhnlicher Nutzung der aktuellen Endpunkte; die alten stehen oft nicht einmal in der Übersicht. Ein Angreifer, der dort systematisch Daten abruft, fällt dadurch weniger schnell auf.

Wie spürt man veraltete API-Versionen auf?

Ein Tester probiert bei jedem gefundenen Endpunkt aus, ob andere Versionen bestehen: die Versionsnummer verringern, andere Schreibweisen versuchen und nach Pfaden wie /api/alt, /api/beta oder /api/intern suchen. Für jeden gefundenen Endpunkt wird anschließend verglichen, welche Prüfungen vorhanden sind und welche nicht.

Zusätzlich werden Quellen außerhalb der Anwendung genutzt. Archivierte Dokumentationen, alte Fassungen der mobilen Anwendung, JavaScript-Bündel früherer Releases und Suchmaschinentreffer liefern regelmäßig Endpunkte, die nirgends mehr genannt werden, aber weiterhin antworten. Auch aus dem Internet erreichbare Abnahme- und Testumgebungen erhalten Aufmerksamkeit, denn diese laufen häufig auf einer älteren Version mit vergleichbaren Daten. AssistSec gleicht diese Bestandsaufnahme mit Ihrer eigenen Übersicht ab, denn der Unterschied zwischen dem, was laut Dokumentation läuft, und dem, was tatsächlich antwortet, ist meist der Kern des Befunds.

Wie verhindert man veraltete API-Versionen?

  • Führen Sie eine aktuelle Übersicht aller API-Versionen und Endpunkte, die tatsächlich erreichbar sind.
  • Lassen Sie jede unterstützte Version durch dieselbe Autorisierungs-, Validierungs- und Ratenbegrenzungsschicht laufen.
  • Kündigen Sie das Ausmustern einer Version mit einem Enddatum an und setzen Sie dieses durch.
  • Antworten Sie bei abgeschalteten Versionen mit einer eindeutigen 410, statt sie stillschweigend weiterlaufen zu lassen.
  • Nutzen Sie Ihre Protokolldateien, um zu sehen, wer eine alte Version noch verwendet, und sprechen Sie diese Nutzer gezielt an.
  • Entfernen Sie Testrouten, vorübergehende Anbindungen und ersetzte Endpunkte, sobald sie nicht mehr benötigt werden.
  • Schirmen Sie Abnahme- und Testumgebungen mit Netzwerkbeschränkungen oder Authentifizierung ab.
  • Beziehen Sie alle Versionen in Überwachung und Alarmierung ein, nicht nur die aktuelle.
  • Prüfen Sie bei einer Sicherheitsverbesserung, ob sie auch für die noch laufenden älteren Versionen gilt.

Quellen

Häufige Fragen

Woher weiß ich, welche Versionen noch laufen?

Über eine Bestandsaufnahme, die sich nicht auf die Dokumentation stützt, sondern auf die Wirklichkeit: Routenkonfiguration, Protokolldateien der vergangenen Monate und aktives Suchen nach vorhersehbaren Pfaden. Die Dokumentation beschreibt, was vorhanden sein sollte; die Protokolle sagen, was tatsächlich aufgerufen wird.

Was, wenn Kunden noch auf der alten Version sind?

Kündigen Sie ein Enddatum an, sprechen Sie die Nutzer dieser Version anhand Ihrer Protokolle gezielt an und erzwingen Sie es danach. Solange die alte Version weiterläuft, führen Sie sie zumindest durch dieselbe Autorisierungs- und Validierungsschicht wie die neue. Veraltet muss nicht ungepflegt bedeuten.

Sind Testumgebungen dasselbe Problem?

In der Praxis oft schlimmer. Eine Abnahmeumgebung hat denselben Funktionsumfang, weniger Aufmerksamkeit und mitunter echte Daten. Bleibt sie aus dem Internet erreichbar, ist sie ein attraktiveres Ziel als die Produktionsumgebung selbst.

Hilft es, die Version aus der Dokumentation zu nehmen?

Kaum. Alte Endpunkte werden gefunden, indem vorhersehbare Pfade ausprobiert, alte Clients untersucht und archivierte Dokumentationen durchgesehen werden. Unbekanntheit ist keine Maßnahme; das Schließen sehr wohl.

Verwandte Artikel

Zum Suchen / drücken · Esc