Cookies 🍪

Diese Website verwendet Cookies, die eine Einwilligung erfordern. Mehr in der Datenschutzerklärung.

Zum Inhalt springen
Nordalux
Hey 👋
Wir sind für dich da

Warum Repositories mit Liveständen privat sein müssen

| Tobias Graeger
Entwickler stellt synchronisiertes Shopify-GitHub-Repository mit enthaltenem API-Key öffentlich.
Dieses Bild wurde mit Hilfe
von generativer KI erstellt.

Ein Produktionsschlüssel sollte nach seiner Rotation wertlos sein. In einer kontrollierten Nachprüfung war er es nicht: Der Wert aus einem lokal vorliegenden GitHub-Checkout wurde weiterhin akzeptiert. Damit war aus einem vermeintlich erledigten Konfigurationsproblem ein aktuelles Sicherheitsrisiko geworden.

Der Fall blieb bewusst anonym. Wir nennen weder Unternehmen noch Anbieter, Domain, Schlüssel, Header oder konkrete Schnittstelle. Entscheidend ist nicht, wen es getroffen hat, sondern was sich daraus für jedes Projekt mit Produktionsbezug lernen lässt.

Ein rotierter Schlüssel, der weiter funktionierte

Ausgangspunkt war ein öffentlich zugänglicher Projektstand mit einer echt wirkenden Produktionskonfiguration. Nachdem der Schlüssel laut Rückmeldung rotiert worden war, prüften wir ausschließlich, ob der alte Wert noch akzeptiert wurde. Das Ergebnis war eindeutig: Die serverseitige Ablehnung blieb aus.

Genau hier liegt ein häufiger Irrtum. Einen neuen Schlüssel zu erzeugen reicht nicht, wenn der alte parallel gültig bleibt, ein Deployment die Änderung nicht übernommen hat oder mehrere Systeme unterschiedliche Konfigurationen verwenden. Rotation ist kein Verwaltungsakt, sondern ein überprüfbarer Zustandswechsel.

Ein alter Schlüssel gilt erst dann als rotiert, wenn produktive Systeme ihn zuverlässig abweisen. Die erfolgreiche Nutzung des neuen Werts allein beweist das nicht.

Ein kleiner Frontend-Schlüssel kann große Wirkung haben

Der sichtbare Wert wirkte zunächst wie ein schmaler Zugang für eine einzelne Frontend-Funktion. Die Implementierung zeigte jedoch, dass derselbe Vertrauensnachweis mehrere serverseitige Fähigkeiten berührte. Dazu gehörten kostenpflichtige KI- oder Sprachausgaben, transaktionaler E-Mail-Versand, schreibende Vorgänge für technische Daten und unter bestimmten Bedingungen personalisierte Bestandsdaten.

Das bedeutet nicht, dass all diese Fähigkeiten missbraucht wurden. Es zeigt aber den möglichen Wirkungsradius eines einzelnen Schlüssels. Sobald ein Zugang mehrere Aufgaben bündelt, wird aus einem Konfigurationsleck zugleich ein Kosten-, Datenschutz- und Integritätsrisiko.

Besonders kritisch sind Funktionen, die nach einer Identifikation zusätzliche Daten laden. Eine E-Mail-Adresse darf nicht genügen, um einer frei gewählten Sitzung Vertrauen zu geben. Identität, Sitzungsbindung und Berechtigung müssen serverseitig voneinander getrennt geprüft werden.

Kein Fachwissen nötig, um den Wert zu nutzen

Der Zugang ließ sich ohne jede Vorkenntnis verwenden. Wer den Wert kannte, konnte ihn unverändert übernehmen und beliebige Anfragen stellen, darunter kostenpflichtige KI-Anfragen, für die im Hintergrund reale Tokenkosten entstanden. Ebenso ließ sich damit auf eine größere Zahl angebundener Systeme zugreifen. Welche im Einzelnen, ist hier bewusst zweitrangig.

Die erste Schutzhürde fehlte komplett

Eine grundlegende Absicherung wäre eine Allowlist-Prüfung gewesen: Kommt die Anfrage überhaupt von der erwarteten Domain oder IP-Adresse? Bei einer sauberen Implementierung hätte genau das zur sofortigen Ablehnung geführt. Diese erste Hürde existierte hier nicht.

Ebenso wenig wurde geprüft, ob die anfragende Seite überhaupt berechtigt war, diese Art von Anfrage zu stellen, auf bestehende Konversationen zuzugreifen oder erweiterte Administrationsrechte zu erhalten. Mit demselben Wert wäre im ungünstigsten Fall sogar eine Administratorrolle erreichbar gewesen. Sicherheitstechnisch war dieser einzelne Wert damit hochkritisch.

Das eigentliche Problem lag außerhalb von .env

Ein Detail wird dabei oft übersehen: Der Wert lag nicht in einer klassischen Umgebungsdatei. Er steckte als einstellbares Feld in den Theme-Einstellungen eines Shopify-Shops, änderbar direkt im Theme-Editor. Genau dort enden viele automatisierte Schutzmechanismen von Plattformen wie GitHub: Sie kennen die individuelle Struktur eines Themes nicht und erkennen selbst definierte Variablen im Code nicht zuverlässig als sensibel.

Dadurch werden solche Werte unbeabsichtigt mit ausgeliefert und öffentlich sichtbar, ohne dass eine klassische Secret-Scanning-Regel greift. Einmal gepusht, lässt sich das nicht rückgängig machen: Der Wert bleibt auch nach dem Entfernen in der Git-Historie einsehbar, sofern diese nicht aktiv bereinigt wird.

Eine weitere Fehlkonfiguration im selben Repository legte zusätzlich eine Testumgebung offen, aus der sich der vollständige Anwendungsquellcode hätte herunterladen lassen. Der API-Key war damit nicht die einzige Schwachstelle, nur der auffälligste erste Hinweis. Diesen zweiten Fund haben wir bewusst nicht weiterverfolgt: gemeldet und dokumentiert, aber ohne inhaltliche Analyse des Codes. Genau diese Zurückhaltung beschreibt der nächste Abschnitt.

Unsere Prüfung blieb bewusst eng

Für die Verifikation waren keine echten Kundendaten nötig. Wir verwendeten kontrollierte Anfragen und synthetische Testwerte, lösten keine Bestellung aus und änderten weder Shopdaten noch Einstellungen. Auch ein denkbarer Datenexport wurde nicht durchgeführt.

Diese Grenze ist wichtig. Eine Sicherheitsprüfung soll eine konkrete Annahme belegen oder widerlegen, nicht den maximal möglichen Schaden demonstrieren. Schon die fortbestehende Akzeptanz des alten Werts und die aus dem Code erkennbare Rechtebreite lieferten genug Evidenz für die Risikobewertung.

Privat schützt den Bauplan, nicht jede Schnittstelle

Ein privates Repository hätte die unbeabsichtigte Verbreitung des Projektstands deutlich erschwert. Es verhindert, dass Produktionskonfiguration, interne Abläufe und Zugriffsmuster frei kopiert und automatisiert ausgewertet werden. Für Kundenprojekte ist privat deshalb die richtige Voreinstellung.

Trotzdem löst die Sichtbarkeit des Repositories nicht jedes Problem. Was eine Webanwendung an den Browser ausliefert, können Nutzer grundsätzlich einsehen. Ein dort benötigter gemeinsamer Schlüssel ist daher kein dauerhaftes Secret, selbst wenn der Quellcode nur in einem privaten Repository liegt.

Die eigentliche Sicherheitsentscheidung fällt im Backend. Öffentliche oder browsernahe Zugänge müssen eng begrenzt, missbrauchsresistent und überwacht sein. Sensible Lesezugriffe, E-Mail-Versand, kostenpflichtige Verarbeitung und schreibende Aktionen benötigen stärkere, jeweils passende Autorisierung.

Die OWASP API Security Top 10 beschreibt genau solche Grundprobleme, darunter fehlerhafte Autorisierung, unbeschränkten Ressourcenverbrauch und den unkontrollierten Zugriff auf sensible Geschäftsabläufe.

Live-Repositories enthalten Bauplan und Schlüssel

Ein Demo-Repository verrät im schlimmsten Fall Architektur und Programmierstil. Ein Repository mit Livestand enthält dagegen die Konfiguration, mit der ein Shop, eine API oder ein Kundensystem tatsächlich betrieben wird. Selbst wenn aktuelle Werte fehlen, können ältere Commits, Debug-Ausgaben oder Beispielkonfigurationen noch produktive Zugänge enthalten.

Kritisch ist die Kombination. Der Code erklärt, wie Funktionen und Datenflüsse aufgebaut sind, während Konfigurationsreste womöglich den passenden Zugang liefern. Deshalb ist die Entscheidung zwischen privat und öffentlich bei einem Kundenprojekt keine Frage persönlicher Vorliebe.

Secrets gelangen über unspektakuläre Wege ins Repository

In der Praxis entsteht ein Leak selten durch eine spektakuläre Schwachstelle. Meist reichen alltägliche Abkürzungen:

  • Eine lokale Konfigurationsdatei wird beim ersten Commit versehentlich mit erfasst und erst später ignoriert.

  • Ein echter Schlüssel landet für einen schnellen Test direkt im Code und bleibt dort unbemerkt liegen.

  • Ein Produktions-Dump oder eine Diagnoseausgabe wird zur Fehlersuche abgelegt und anschließend vergessen.

  • Zugangsdaten werden in einer Deployment-Datei gespeichert, obwohl die Plattform eine eigene Secrets-Verwaltung anbietet.

.gitignore wirkt nur für noch nicht versionierte Dateien. Ein späterer Eintrag entfernt keine Werte aus bereits vorhandenen Commits.

Öffentlich gepusht bleibt potenziell kopiert

Öffentliche Repositories und Änderungen werden automatisiert ausgewertet. Plattformen suchen selbst nach bekannten Secret-Mustern, gleichzeitig können Dritte öffentliche Inhalte klonen oder archivieren. Eine belastbare Entwarnung allein aufgrund einer kurzen Sichtbarkeit gibt es deshalb nicht.

GitHub beschreibt in der Dokumentation zum Secret Scanning, wie Zugangsdaten in der gesamten Git-Historie erkannt werden können. Die Erkennung begrenzt den Schaden jedoch nicht automatisch. Ein gefundener Wert muss weiterhin beim ausstellenden System widerrufen werden.

Auch das Entfernen sensibler Daten aus einem Repository ist nur ein Teil der Reaktion. Umschreiben und Aufräumen reduzieren die künftige Sichtbarkeit, machen bereits erfolgte Kopien aber nicht rückgängig.

Drei Schutzebenen müssen zusammenpassen

Der Praxisfall lässt sich nicht mit einer einzelnen Maßnahme lösen. Drei Ebenen müssen gleichzeitig funktionieren:

  • Repository-Vertraulichkeit: Kundenprojekte starten privat. Produktionswerte bleiben außerhalb von Git, und ein Wechsel auf öffentlich erfordert eine bewusste Prüfung der gesamten Historie.

  • Secret-Lebenszyklus: Zugänge sind pro Umgebung getrennt, werden inventarisiert und bei einem Verdacht vollständig widerrufen. Die Ablehnung alter Werte wird anschließend ausdrücklich getestet.

  • API-Berechtigungen: Browsernahe Funktionen erhalten minimale Rechte. Personenbezogene Daten, E-Mail-Versand, kostenpflichtige Verarbeitung und Änderungen am System werden getrennt autorisiert und protokolliert.

Ergänzend helfen Push Protection, lokales Secret-Scanning, Rate Limits, Kostenlimits und Alarme für ungewöhnliche Nutzung. Solche Kontrollen fangen Fehler früher ab und begrenzen ihre Auswirkungen.

Nach einem Fund kommt Sperren vor Aufräumen

Sobald ein echter Zugang öffentlich gewesen sein könnte, gilt er als kompromittiert. Zuerst wird er serverseitig gesperrt. Danach werden abhängige Systeme aktualisiert, die Ablehnung des alten Werts geprüft und Zugriffs-, Versand- sowie Kostenprotokolle auf Auffälligkeiten untersucht.

Erst anschließend folgen das Bereinigen der Git-Historie und die Ursachenanalyse. Diese Reihenfolge schließt das aktive Risiko, bevor Zeit in kosmetische Aufräumarbeit fließt.

Ein ähnliches Muster zeigt unser Beitrag über Vibe Coding und fehlende Sicherheitsgrenzen: Nicht die eingesetzte Technik entscheidet allein über das Risiko, sondern die Rechte und Kontrollen, die um sie herum gebaut werden.

Fazit

Private Repositories sind für Projekte mit Produktionsbezug die notwendige Basis. Der aktuelle Praxisfall zeigt zugleich ihre Grenze: Wenn alte Schlüssel gültig bleiben oder ein sichtbarer Zugang zu viele Rechte bündelt, verlagert sich das Risiko lediglich vom Repository zur Schnittstelle.

Saubere Absicherung entsteht erst aus Vertraulichkeit, überprüfter Rotation und minimalen Berechtigungen. Wer den eigenen Projektstand oder die Zugriffskonzepte eines Shops einordnen lassen möchte, kann uns kontaktieren oder sich direkt über unser Custom Coding informieren.

T

Tobias Graeger

Inhaber & Shopify-Entwickler

Tobias leitet alle Projekte persönlich. Mit über 50 abgeschlossenen Shopify-Projekten kennt er die Plattform vom Liquid-Template bis zur API-Integration. Sein Fokus: technisch saubere Lösungen, die mit dem Business mitwachsen.

LinkedIn

Hat dir der Beitrag gefallen?

Ein Klick reicht und wir wissen, welche Themen wir weiter vertiefen sollen.

Feedback konnte gerade nicht gespeichert werden.

Beitrag teilen