Security Blog

Quelltext ansehen, Schlüssel kopieren, alles übernehmen

#43

October 2, 2026 · By Marketing team

← All posts

Eine Sicherheitsforscherin öffnete den Seitenquelltext von ClickUp, fand einen fest im JavaScript hinterlegten API-Schlüssel und zog damit in einer einzigen Anfrage 959 E-Mail-Adressen und 3.165 interne Feature-Flags ab. Der Schlüssel hatte keinen Geltungsbereich, keine Ratenbegrenzung und kein Ablaufdatum.

Eine Sicherheitsforscherin ging zu clickup.com. Öffnete den Seitenquelltext. Fand einen fest im JavaScript hinterlegten API-Schlüssel. Kopierte ihn. Sendete eine einzige GET-Anfrage.

Erhielt 959 E-Mail-Adressen und 3.165 interne Feature-Flags. Mitarbeitende von Home Depot. Fortinet. Autodesk. Tenable. Rakuten. Mayo Clinic.

Eine Zeichenkette. Eine Anfrage. Alles.

Wie das passiert

Jemand brauchte ein Frontend, das eine API aufruft. Die API verlangte eine Authentifizierung. Also legte man den Schlüssel ins JavaScript. Ausliefern, weitermachen, nächster Sprint.

Das ist kein ausgefeilter Angriff. Kein Exploit, keine Zero-Day-Lücke, kein Social Engineering. Es ist view-source: und curl. Ein Browser und ein Terminal. Die Art von Dingen, die ein neugieriger Praktikant am ersten Tag macht.

Der Schlüssel hatte keinen Geltungsbereich — er konnte auf alles zugreifen, was die API offenlegte. Keine Ratenbegrenzung — eine Anfrage lieferte alles. Kein Ablaufdatum — der Schlüssel funktionierte, bis es jemandem auffiel. Kein zweiter Faktor — der Besitz der Zeichenkette war die einzige Sperre.

Der finanzielle Aspekt

Man spricht über Datenpannen. Sprechen wir darüber, was diese Daten wert sind.

959 geschäftliche E-Mail-Adressen von Fortune-500-Unternehmen. Das ist eine Spear-Phishing-Zielliste, für die Bedrohungsakteure zahlen. Namen, Rollen und die Tatsache, dass diese Unternehmen ClickUp nutzen — das ist der Social-Engineering-Kontext, der Phishing erfolgreich macht.

3.165 interne Feature-Flags. Das ist eine Roadmap. Sie zeigt Wettbewerbern, was ClickUp baut, was getestet wird, was hinter einer Sperre steckt. Sie zeigt Angreifern, welche Funktionen halbfertig und vermutlich angreifbar sind.

Das ist kein Datenschutzvorfall. Es ist ein Geschäftsdatenleck.

Warum das immer wieder passiert

Das ist der vierte Vorfall mit Zugangsdaten im Quelltext, über den wir in diesem Monat geschrieben haben. Bei Bitwardens CLI wurden Zugangsdaten abgeschöpft, weil es Klartextdateien waren. Die Umgebungsvariablen bei Vercel waren entschlüsselbar, weil das Flag „sensitive" nicht voreingestellt war. Eine Entwicklerin verlor 634 Chrome-Passwörter, weil der Entschlüsselungsschlüssel auf derselben Festplatte lag.

Das Muster ist immer dasselbe: Zugangsdaten existieren als Zeichenkette — in einer Datei, in einer Variable, im Seitenquelltext — und etwas liest sie. Das Etwas ändert sich. Das Muster nicht.

API-Schlüssel in JavaScript sind die gröbste Variante, weil kein Angriff nötig ist. Der Schlüssel ist veröffentlicht. Er wird jedem Besucher ausgeliefert. Der Browser lädt ihn herunter, rendert ihn und zeigt ihn jedem, der mit der rechten Maustaste klickt.

Was anders hätte sein müssen

Der API-Aufruf hätte nie mit einem statischen Schlüssel aus dem Client heraus authentifiziert werden dürfen. Die Möglichkeiten:

  • Backend-Proxy. Das Frontend ruft das eigene Backend auf, das den Schlüssel serverseitig hält und den API-Aufruf weiterreicht. Der Schlüssel erreicht den Browser nie.
  • Sitzungsgebundene Token. Das Frontend erhält nach der Authentifizierung ein kurzlebiges, eng begrenztes Token. Es läuft ab. Es kann nur das tun, wozu die authentifizierte Person berechtigt ist. Es ist kein Hauptschlüssel.
  • Gar kein Schlüssel. Wenn die Daten öffentlich sind, ohne Authentifizierung ausliefern. Wenn sie nicht öffentlich sind, nicht an nicht authentifiziertes JavaScript ausliefern.

Einen API-Schlüssel fest im Client-Code zu hinterlegen bedeutet, den Haustürschlüssel unter die Fußmatte zu legen und die eigene Adresse zu veröffentlichen.

Das Problem des Zugangsdaten-Lebenszyklus

Dieser ClickUp-Schlüssel wurde vermutlich einmal erzeugt, in eine JavaScript-Datei eingefügt, in ein Repository übertragen, in die Produktion ausgeliefert und nie wieder bedacht. Niemand hat ihn rotiert. Niemand hat seinen Geltungsbereich begrenzt. Niemand hat ein Ablaufdatum gesetzt. Niemand hat überwacht, worauf er zugriff.

Das ist der Lebenszyklus der meisten API-Schlüssel in den meisten Organisationen. Eilig erzeugt, eingefügt wo sie gebraucht werden, vergessen. Sie sammeln sich an über Codebasen, Konfigurationsdateien, CI/CD-Pipelines und offenbar Seitenquelltext — jede eine Tür, die nie abschließt.

Die Frage ist nicht, ob Ihre Organisation einen solchen Schlüssel hat. Die Frage ist, wie viele Sie haben und ob Sie es merken würden, wenn jemand heute einen kopiert.