← Stack-Leitfäden

Firebase

Sicherheit für deine App mit Firebase

Die Sicherheit von Firebase hängt fast ganz von den Regeln ab, die du schreibst. Mit Regeln im Testmodus oder zu offen ist deine Datenbank für jeden erreichbar. Prüf das, bevor du deine App öffnest.

Typische Risiken bei Firebase

Regeln im Testmodus

Der Testmodus erlaubt jedem Lesen und Schreiben. Viele starten, ohne ihn zu ändern, und lassen die Datenbank sperrangelweit offen.

Den öffentlichen Schlüssel mit Sicherheit verwechseln

Die Firebase-Config ist absichtlich öffentlich; was deine Daten schützt, sind die Regeln, nicht das Verstecken dieses Schlüssels. Das Gegenteil anzunehmen führt zu offengelegten Daten.

Andere Schlüssel im Frontend

Neben der Firebase-Config schleichen sich oft Schlüssel ein, die wirklich geheim sind (Zahlungen, E-Mail, KI). Die dürfen niemals im Browser-JavaScript stehen.

„Firebase-Sicherheit" sind zwei Dinge, die man auseinanderhalten sollte. Das erste ist das Modell von Firebase: Der Browser spricht direkt mit der Datenbank und dem Speicher, es filtert also kein Server, und der Schutz liegt in den Regeln, in App Check und in der Projektkonfiguration. Das zweite ist, was Lovable, Bolt oder Cursor mit Firebase anstellen, wenn sie Code erzeugen, und daher stammen fast alle Löcher. Dieser Guide erklärt das Modell, geht durch, was die KI falsch macht, gibt dir eine firebase.json und Basisregeln zum Einfügen, einen Review-Prompt und die Prüfung von außen. Die zehn häufigsten Regelfehler, jeweils mit schlechter und guter Regel, stehen in die häufigsten Sicherheitsfehler in Firebase.

Teil 1: Wie Sicherheit in Firebase funktioniert

Der Client spricht mit den Diensten, nicht mit deinem Server

In einer typischen Firebase-App gibt es kein eigenes Backend: Das Browser-SDK liest und schreibt direkt in Firestore, Realtime Database und Storage. Das heißt, das Konfigurationsobjekt mit apiKey und projectId ist absichtlich öffentlich (es identifiziert das Projekt, es autorisiert nichts), und die einzige Barriere zwischen einem Besucher und deinen Daten sind die Sicherheitsregeln. Jedes Produkt hat eigene: Firestore, Realtime Database und Storage werden getrennt konfiguriert, und offen ist in einer App meist das, was niemand angeschaut hat.

Regeln beantworten „wer darf was"

Eine Regel bekommt die Anfrage mit dem authentifizierten Nutzer (request.auth), dem Dokument, das gelesen oder geschrieben werden soll, und den neuen Daten (request.resource.data). Damit entscheidet sie. Der entscheidende Unterschied ist der zwischen authentifiziert (es gibt eine Sitzung) und autorisiert (diese Sitzung darf dieses Dokument sehen): request.auth != null prüft nur Ersteres, und Registrieren ist kostenlos. Regeln validieren auch, was geschrieben wird, damit ein Nutzer sich nicht selbst isAdmin: true ins Profil setzt.

Was zusätzlich zu den Regeln schützt

  • App Check. Verlangt, dass Anfragen aus deiner echten App kommen (per reCAPTCHA oder Play Integrity) und nicht aus einem Skript mit deiner projectId. Bremst Missbrauch und unerwartete Rechnungen durch Massenlesezugriffe.
  • Einschränkung des API-Schlüssels. Beschränke den Schlüssel in der Google-Cloud-Konsole auf die Domains deiner Website und die APIs, die du nutzt. Ersetzt die Regeln nicht, schließt aber eine Tür.
  • Auth. Autorisierte Domains für die Anmeldung, Schutz vor E-Mail-Enumeration, E-Mail-Verifizierung, nur die Anmeldemethoden, die du wirklich nutzt, Multi-Faktor-Authentifizierung bei sensiblen Daten.
  • Cloud Functions als Server. Alles, was einen geheimen Schlüssel braucht (Zahlungen, E-Mail, KI), kommt in eine Function, mit dem Geheimnis im Secret Manager, und der Client ruft die Function auf. Achtung: Eine HTTP-Function ist für das ganze Internet öffentlich, es sei denn, du prüfst das Token des Nutzers oder nutzt eine callable Function mit App Check.
  • Budget. Firebase rechnet pro Lesezugriff und pro Aufruf ab. Budget-Alarme in Google Cloud und Limits in den Regeln (request.query.limit) verhindern, dass dir eine Schleife oder ein Angreifer eine Rechnung hinterlässt.

Hosting: Was Firebase setzt und was nicht

Firebase Hosting liefert automatisches TLS, ein CDN und die Weiterleitung auf HTTPS. Sicherheits-Header setzt es nicht: Die kommen in die firebase.json. Und es liefert alles aus dem öffentlichen Ordner aus, auch eine versehentlich dorthin kopierte .env.

Teil 2: Was die KI mit Firebase falsch macht

  • Regeln im Testmodus, danach if true. Die KI lässt die Regeln stehen, die dreißig Tage lang alles öffnen; beim Ablauf bricht die App, und die schnelle Lösung ist, sie für immer zu öffnen.
  • request.auth != null als einzige Bedingung. Jeder registrierte Nutzer liest die Daten aller anderen.
  • Unvalidierte Schreibzugriffe. Das Profil hat role oder credits, und die Update-Regel schließt diese Felder nicht aus.
  • Andere Schlüssel im Bundle. Neben der Firebase-Konfiguration tauchen der geheime Stripe-Schlüssel, der OpenAI-Schlüssel oder der eines E-Mail-Dienstes auf. Details in Geheimnisse, die deine App im Browser preisgibt.
  • HTTP-Functions, die den Nutzer nicht prüfen. Die Function, die abrechnet, E-Mails sendet oder ein Modell aufruft, antwortet jedem, der die URL kennt.
  • Storage mit aus Firestore kopierten Regeln. allow read, write: if request.auth != null in storage.rules: Jeder Nutzer liest die Dateien der anderen und lädt hoch, was er will.
  • Kein App Check, keine Header, keine Alarme. Drei Häkchen, die niemand setzt, weil die App „ja schon läuft".

Ein Block zum Einfügen in dein Projekt

Sicherheits-Header in der firebase.json (die Content-Security-Policy kommt separat, weil sie von deinen Skripten abhängt):

{
  "hosting": {
    "public": "dist",
    "headers": [
      {
        "source": "**",
        "headers": [
          { "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains; preload" },
          { "key": "X-Content-Type-Options", "value": "nosniff" },
          { "key": "X-Frame-Options", "value": "DENY" },
          { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
          { "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
        ]
      }
    ]
  }
}

Und ein Ausgangspunkt für firestore.rules: standardmäßig alles geschlossen, jeder Nutzer sein eigenes Dokument und geschützte Privilegfelder.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read: if request.auth != null && request.auth.uid == userId;
      allow create: if request.auth != null && request.auth.uid == userId
        && !request.resource.data.keys().hasAny(['role', 'isAdmin', 'plan', 'credits']);
      allow update: if request.auth != null && request.auth.uid == userId
        && !request.resource.data.diff(resource.data).affectedKeys()
           .hasAny(['role', 'isAdmin', 'plan', 'credits']);
    }
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Ergänze danach eine explizite Regel pro Collection; die letzte mit if false garantiert, dass jede neue Collection geschlossen zur Welt kommt.

Ein Review-Prompt vor dem Veröffentlichen

Prüfe die Sicherheit dieser Firebase-App und ändere noch nichts. Antworte mit einer Liste:
1. Firestore-, Realtime-Database- und Storage-Regeln, die jedem Zugriff erlauben, mit Testmodus-Datum oder mit request.auth != null als einziger Bedingung.
2. Schreibregeln, die Felder nicht validieren, besonders role, isAdmin, plan oder credits.
3. Schlüssel außer der Firebase-Konfiguration im Browser-Code, mit Datei und Zeile.
4. HTTP-Cloud-Functions, die das Token des Nutzers nicht prüfen, und Functions, die Geheimnisse aus dem Code statt aus dem Secret Manager lesen.
5. Ob App Check aktiviert ist und ob der API-Schlüssel per Domain eingeschränkt ist.
6. Sicherheits-Header in firebase.json und Dateien im öffentlichen Ordner, die dort nicht hingehören.
Schlag für jeden Punkt die exakte Regel oder Änderung vor und warte auf meine Bestätigung.

Prüf das Ergebnis von außen

Deine projectId steht im Bundle, also kann das jeder tun. Die REST-API von Firestore ohne Token:

curl -s "https://firestore.googleapis.com/v1/projects/DEIN_PROJEKT/databases/(default)/documents/users" | head -c 400
curl -sI https://deinedomain.com | grep -iE "strict-transport|x-frame|x-content-type"

Richtig ist ein Rechtefehler beim ersten (liefert es Dokumente, ist die Collection offen) und die Header beim zweiten. Wiederhole den ersten für jede Collection und für Storage. Scanaris führt diese Prüfungen und rund vierzig weitere in 30 Sekunden aus: Es erkennt die Firebase-Konfiguration in deinem Bundle, testet die üblichen Collections ohne Authentifizierung, sucht andere Schlüssel im JavaScript, prüft Header, CORS, Cookies und offengelegte Dateien und gibt dir für jeden Fund einen Fix-Prompt zum Einfügen in Lovable, Bolt oder Cursor. Nutzt deine App Supabase statt Firebase, ist der Supabase-Guide das Gegenstück.

Häufige Fragen

Muss ich den Firebase-apiKey verstecken?

Nein. Er ist absichtlich öffentlich und identifiziert das Projekt. Die Daten schützen die Regeln und App Check. Sinnvoll ist, ihn in Google Cloud auf deine Domains zu beschränken.

Sind Cloud Functions privat?

Eine HTTP-Function ist eine öffentliche URL. Prüf das Token des Nutzers innerhalb der Function oder nutz callable Functions mit App Check. Functions, die auf Ereignisse reagieren (ein erstelltes Dokument, eine hochgeladene Datei), haben keine URL und sind tatsächlich intern.

Wie teste ich die Regeln, ohne die App kaputtzumachen?

Mit dem Simulator der Konsole (Tab Regeln) für konkrete Lesezugriffe und mit dem lokalen Emulator für automatisierte Tests. Ändere die Regeln mit der App in einem anderen Tab geöffnet und prüf, ob das, was funktionieren soll, weiter funktioniert.

Verwandte Checks

Besteht deine Firebase-App diese Checks?

Scanne sie kostenlos und erhalte einen Fix-Prompt für jedes Problem, das wir finden.

Meine Website kostenlos scannen