Jede moderne Website spricht mit anderen Diensten: mit einem Zahlungsanbieter, einem Kartendienst, einem Newsletter-System, einem Sprachmodell, dem eigenen Shop-Backend. Für fast jede dieser Verbindungen braucht es einen Schlüssel, eine Zeichenkette, mit der sich die Anwendung beim Dienst ausweist. Manche dieser Schlüssel sind dafür gedacht, öffentlich zu sein. Viele nicht.
In unserem Research Lab lesen wir das öffentliche Web in großem Umfang, also das, was Websites tatsächlich an jeden Browser ausliefern. Eine der Fragen, die wir dort verfolgen: Wie oft stehen funktionierende Zugangsdaten in öffentlich abrufbaren Seiten? Die ehrliche Antwort lautet: oft genug, dass es sich lohnt, die eigene Website darauf zu prüfen. Fast nie steckt Absicht dahinter. Meist ist es eine Abfolge kleiner, nachvollziehbarer Entscheidungen.
Öffentliche und geheime Schlüssel
Zuerst eine Unterscheidung, die in der Praxis oft verwischt wird. Viele Anbieter vergeben zwei Arten von Schlüsseln:
- Öffentliche Schlüssel sind dafür gemacht, im Browser zu stehen. Sie erlauben nur eng begrenzte Aktionen, etwa das Anzeigen einer Karte oder das Starten eines Bezahlvorgangs, und lassen sich häufig auf bestimmte Domains beschränken.
- Geheime Schlüssel gehören ausschließlich auf den Server. Mit ihnen lassen sich Daten lesen, Zahlungen auslösen, E-Mails im Namen des Unternehmens versenden oder kostenpflichtige Dienste nutzen.
Das Problem entsteht, wenn ein geheimer Schlüssel an einer Stelle landet, die der Browser zu sehen bekommt. Ab diesem Moment kann ihn jeder lesen, der die Seite öffnet und in den Quelltext schaut. Dafür braucht es keinen Angriff, nur einen Blick in die Entwicklerwerkzeuge des Browsers.
Wie Schlüssel in den Quelltext gelangen
Die Wege sind fast immer dieselben:
- Der schnelle Prototyp. Für einen ersten Test wird ein Dienst direkt aus dem Frontend aufgerufen, mit dem Schlüssel im Code. Der Prototyp funktioniert, wird erweitert und geht irgendwann live, ohne dass jemand die Verbindung über einen Server umgebaut hat.
- Umgebungsvariablen, die keine sind. Viele Frontend-Werkzeuge übernehmen Variablen mit einem bestimmten Präfix beim Build in den ausgelieferten Code. Wer einen geheimen Schlüssel so benennt, schreibt ihn damit in die öffentliche JavaScript-Datei, auch wenn er in einer
.env-Datei steht. - Konfigurationsdateien im öffentlichen Verzeichnis. Eine Datei mit Zugangsdaten liegt neben den Bildern und Stylesheets und ist damit über eine einfache Adresse abrufbar.
- Sourcemaps und Kommentare. Selbst wenn der Code minimiert ist, liefern mitveröffentlichte Sourcemaps den ursprünglichen Quelltext samt auskommentierter Zeilen und alter Testschlüssel.
- Eingebettete Skripte Dritter. Ein Tracking- oder Chat-Snippet wird mit einer Konfiguration eingebunden, die mehr enthält als nötig.
Mit KI-gestützter Entwicklung kommt ein weiterer Weg hinzu. Ein Assistent, der eine funktionierende Integration erzeugen soll, wählt oft den kürzesten Weg: den Aufruf direkt aus dem Browser. Das Ergebnis läuft, und genau deshalb fällt es nicht auf. Wir arbeiten selbst AI-first und halten das nicht für ein Argument gegen solche Werkzeuge, wohl aber für ein Argument, generierten Code vor dem Livegang auf genau diese Frage zu prüfen. Wie Teams das organisieren, beschreibt der Beitrag KI-Entwürfe im Team.
Ein Beispiel
Ein Händler lässt für seinen Onlineshop einen Produktberater bauen: Kundinnen beschreiben, was sie suchen, ein Sprachmodell schlägt passende Artikel vor. Die erste Version entsteht in wenigen Tagen. Das Frontend ruft die Schnittstelle des Modellanbieters direkt auf, der Schlüssel steht in einer Umgebungsvariable, die beim Build in das Skript übernommen wird. Im Test fällt das niemandem auf, denn alles funktioniert.
Wochen nach dem Start meldet die Buchhaltung, dass die Rechnung des Modellanbieters deutlich höher ist als erwartet. Ein Blick in die Nutzungsstatistik zeigt Anfragen, die nichts mit Produkten zu tun haben. Jemand hat den Schlüssel aus dem Skript gelesen und nutzt ihn für eigene Zwecke.
Die Behebung besteht aus drei Schritten: Der Schlüssel wird beim Anbieter sofort gesperrt und ersetzt. Der Aufruf des Modells wandert auf einen kleinen Server-Endpunkt des Shops, der nur die Anfragen weitergibt, die der Produktberater braucht, mit einem Limit pro Besucher. Und für den Schlüssel wird beim Anbieter ein Ausgabelimit gesetzt. Ein neuer Schlüssel allein hätte nicht gereicht: Solange er im Browser steht, wäre er nach dem nächsten Deploy wieder lesbar gewesen.
Was Sie prüfen und einrichten sollten
| Maßnahme | Wo | Was sie verhindert |
|---|---|---|
| Ausgelieferten Code durchsuchen | Live-Website, nicht nur Repository | Schlüssel, die erst beim Build in den Code gelangen |
| Geheime Aufrufe über den Server führen | Architektur der Integration | Geheime Schlüssel im Browser |
| Öffentliche Schlüssel einschränken | Konsole des jeweiligen Anbieters | Nutzung von fremden Domains |
| Rechte und Limits pro Schlüssel | Konsole des Anbieters | Hohe Schäden, falls doch ein Schlüssel abfließt |
| Secret-Scanning im Repository | Versionsverwaltung und Build | Schlüssel, die vor dem Deploy auffallen könnten |
| Sourcemaps nicht öffentlich ausliefern | Build- und Server-Konfiguration | Rückschluss auf den ursprünglichen Quelltext |
Der wichtigste Punkt steht in der ersten Zeile. Viele Prüfungen laufen nur im Repository. Was der Browser tatsächlich erhält, entsteht aber erst beim Build, und dort kommen Variablen, Konfigurationen und eingebettete Skripte hinzu. Wer wissen will, was öffentlich ist, muss das prüfen, was öffentlich ausgeliefert wird.
Ebenso wichtig ist eine Liste: Welche Dienste nutzt die Website, mit welchem Schlüssel, wer hat ihn angelegt, und wo wird er gesperrt, wenn es nötig ist? Diese Liste fehlt in vielen Unternehmen, weil Integrationen über Jahre von verschiedenen Personen und Agenturen eingerichtet wurden. Bei Onlineshops gehören auch installierte Apps und Erweiterungen dazu, die eigene Skripte mitbringen, wie im Beitrag Apps im Onlineshop beschrieben.
Wenn ein Schlüssel offen lag
Wird ein offener Schlüssel entdeckt, ist die Reihenfolge entscheidend: zuerst sperren, dann ersetzen, dann aufräumen. Das Löschen aus dem Code allein genügt nicht, denn der Schlüssel kann längst kopiert worden sein und steht in alten Versionen, Caches und Archiven weiter zur Verfügung. Danach lohnt der Blick in die Nutzungsprotokolle des Anbieters: Gab es Zugriffe, die nicht von Ihnen stammen? Welche Daten waren mit diesem Schlüssel erreichbar? Ob daraus weitere Pflichten folgen, etwa gegenüber Kundinnen und Kunden, klären Sie mit Ihrer Rechtsberatung oder Ihrem Datenschutzbeauftragten.
Manchmal kommt der Hinweis von außen, per E-Mail von jemandem, der den Schlüssel gefunden hat. Solche Nachrichten wirken leicht wie ein Betrugsversuch und werden deshalb ignoriert. Prüfen Sie den Inhalt trotzdem, ohne Links in der Nachricht zu folgen. Wie ein geordneter Ablauf dafür aussieht, steht im Beitrag Gemeldete Sicherheitslücke.
Fazit
Offene API-Schlüssel im Quelltext entstehen selten durch Leichtsinn, sondern durch Prototypen, die ohne Umbau live gehen, durch Build-Werkzeuge, die Variablen in den ausgelieferten Code übernehmen, und durch Integrationen, für die niemand mehr zuständig ist. Die Gegenmittel sind unspektakulär: geheime Aufrufe nur über den Server, eingeschränkte und begrenzte Schlüssel, eine Prüfung des tatsächlich ausgelieferten Codes und eine Liste aller Integrationen mit einer verantwortlichen Person. Wer diese Punkte einmal sauber einrichtet und regelmäßig wiederholt, schließt eine der häufigsten und zugleich vermeidbarsten Lücken auf der eigenen Website.