Zum Inhalt springen

Leitfaden

Firebase Security Rules richtig schreiben

Von Lucas Weber, CyberSec42 · Stand 28.10.2026

CyberSec42

Bei Firebase steht der Konfigurationsschlüssel absichtlich im Frontend, er identifiziert nur Ihr Projekt und schützt keine Daten. Wer was in Cloud Firestore, der Realtime Database und Cloud Storage lesen und schreiben darf, entscheiden allein die Firebase Security Rules. Richtig geschrieben heißt: standardmäßig alles verbieten, je Dokument den Eigentümer prüfen, Felder bei jedem Schreibzugriff validieren und das Ergebnis mit dem Emulator und einem zweiten Konto testen.

Kurz gefasst.

Wie Firebase schützt

Öffentlicher Schlüssel, Rules, Admin SDK.

Zum Abschnitt

Typische Fehler

Vom Testmodus bis zum offenen Bucket.

Zum Abschnitt

Schnell gebaute Apps

Warum der Fehler unsichtbar bleibt.

Zum Abschnitt

Regel-Beispiele

Firestore, Storage, Realtime Database.

Zum Abschnitt

Testen

Emulator, Unit-Tests, zweites Konto.

Zum Abschnitt

Checkliste

Alle Punkte vor dem Livegang.

Zum Abschnitt

Wie Firebase Zugriffe schützt

Eine Firebase-App spricht Cloud Firestore, die Realtime Database und Cloud Storage direkt aus dem Browser oder der mobilen App an, ohne eigenen Server dazwischen. Dafür liefert sie ein Konfigurationsobjekt mit apiKey, projectId und weiteren Werten aus. Jeder, der Ihre App öffnet, kann diese Werte lesen.

Das ist gewollt. Die Firebase-Dokumentation zu API-Schlüsseln sagt, dass Schlüssel für Firebase-Dienste Ihr Projekt und Ihre App nur identifizieren. Sie müssen nicht als Geheimnis behandelt werden und dürfen im Code und in eingecheckten Konfigurationsdateien stehen. Zugleich stellt die Dokumentation klar, dass API-Schlüssel nicht dazu dienen, den Zugriff auf Daten zu steuern. Das geht nur mit Firebase Security Rules für Ihre Nutzer und mit App Check für Ihre Apps. Die Firebase-Sicherheitscheckliste sagt dasselbe. Zwei Einschränkungen nennt Firebase: Schränken Sie jeden Schlüssel auf die APIs ein, die die App tatsächlich nutzt, und verwenden Sie für andere Google-Dienste eigene Schlüssel.

Die Folge: Ein Angreifer braucht keinen gestohlenen Schlüssel, um Ihre Datenbank anzusprechen. Er nimmt die Konfiguration aus Ihrer App und stellt eigene Anfragen. Was er dabei sieht oder ändert, entscheiden ausschließlich die Rules.

Jeder der drei Dienste hat eigene Regeln. Firestore und Cloud Storage nutzen eine gemeinsame Regelsprache mit match- und allow-Anweisungen, die Realtime Database eine JSON-Struktur mit .read, .write und .validate. Drei Grundsätze gelten für alle:

Beim Anlegen einer Datenbank oder eines Storage-Buckets wählen Sie zwischen einem gesperrten Modus und dem Testmodus. Im gesperrten Modus verweigern Firestore und Realtime Database laut Dokumentation jeden Zugriff, Cloud Storage lässt alle angemeldeten Nutzer zu. Der Testmodus erlaubt jedem den Zugriff.

Die typischen Fehler

Die folgenden Fehler sind keine Schwächen von Firebase, sondern Regeln, die genau das tun, was in ihnen steht. Firebase beschreibt die meisten davon selbst auf der Seite „Avoid insecure rules“.

1. Regeln aus dem Testmodus bleiben stehen

Der Testmodus ist laut Firebase gut für den Einstieg, erlaubt aber jedem, Ihre Daten zu lesen und zu überschreiben. Ergebnis sind Regeln wie allow read, write: if true; oder eine Regel, die nur an ein Datum gebunden ist:

// NICHT verwenden: bis zum Datum darf jeder alles
match /{document=**} {
  allow read, write: if request.time < timestamp.date(2026, 12, 1);
}

Bis zu diesem Datum ist die Datenbank offen, für jeden, der die Projekt-ID kennt. Firebase warnt, dass dann jeder Ihre Daten stehlen, ändern oder löschen kann. Bei der Realtime Database endet der Testmodus laut Dokumentation nach einer Testphase: Sie werden per E-Mail benachrichtigt, danach verweigern die Regeln alle Anfragen. Die App funktioniert dann plötzlich nicht mehr. Wer in diesem Moment nur das Datum nach hinten schiebt, hält die Datenbank weiter offen.

2. Nur die Anmeldung wird geprüft

Eine Regel wie allow read, write: if request.auth != null; sieht nach Schutz aus. Firebase führt sie als „nicht empfohlen“: Jeder angemeldete Nutzer darf damit die gesamte Datenbank lesen und schreiben. Kann sich jeder in Ihrer App registrieren, ist das praktisch dasselbe wie öffentlich. Das gilt besonders, wenn die anonyme Anmeldung aktiv ist. Die Sicherheitscheckliste weist darauf hin, dass jeder anonyme Konten anlegen kann und nicht öffentliche Daten deshalb eine echte Anmeldung oder eine bestätigte E-Mail-Adresse voraussetzen sollten.

3. Der Eigentümer wird nicht geprüft

Für personenbezogene Daten gehört in jede Regel ein Vergleich mit der ID des angemeldeten Nutzers, request.auth.uid. Dabei gibt es zwei Muster: Der Eigentümer steht im Pfad, etwa /users/{userId}, oder in einem Feld im Dokument, etwa ownerId. Beim zweiten Muster wird oft nur das Lesen geschützt. Fehlt beim Anlegen die Prüfung, dass request.resource.data.ownerId der eigenen ID entspricht, kann ein Nutzer Dokumente im Namen eines anderen anlegen. Fehlt sie beim Ändern, kann er ein eigenes Dokument einem anderen Konto zuschieben.

4. Felder werden nicht validiert

Darf ein Nutzer sein Profil-Dokument schreiben, darf er ohne weitere Prüfung jedes Feld darin setzen, auch Felder wie role, isAdmin oder einen Tarif. Liest Ihre App oder Ihre Regel daraus später Rechte ab, kann sich jeder selbst befördern. Firestore bietet dafür Werkzeuge, die die Dokumentation zur Feldkontrolle beschreibt:

Für das Lesen gilt das nicht. Lesen wird in Firestore immer auf Dokumentebene entschieden. Laut Dokumentation ist es mit Rules allein unmöglich, einzelne Felder eines Dokuments vor dem Lesen zu schützen. Sensible Felder gehören deshalb in ein eigenes Dokument mit eigener Regel.

5. Regeln wirken anders als gedacht

Drei Eigenheiten der Regelsprache führen regelmäßig zu Lücken:

6. Cloud Storage ist zu weit offen

Die Standardregeln von Cloud Storage erlauben jedem angemeldeten Nutzer den Zugriff, nicht nur dem Eigentümer einer Datei. Für Rechnungen, Ausweise, Verträge oder private Fotos reicht das nicht. Storage-Regeln brauchen dieselbe Eigentümerprüfung wie die Datenbank, meist über einen Pfad mit der Nutzer-ID. Dazu kommen Grenzen beim Hochladen: Ohne Prüfung von Größe und Dateityp kann jeder Nutzer beliebige und beliebig große Dateien in Ihr Projekt laden, auf Ihre Kosten.

7. Admin-Zugangsdaten im Client

Das Admin SDK arbeitet laut Dokumentation aus privilegierten Umgebungen wie einem Server, mit vollen Administratorrechten, und umgeht die Rules. Es authentifiziert sich mit einem Dienstkonto, oft über eine JSON-Datei mit privatem Schlüssel. Die Sicherheitscheckliste nennt diese Schlüssel sensibel und geheim zu halten. Landet eine solche Datei in einer Web-App, einem App-Paket oder einem öffentlichen Repository, sind alle Rules wirkungslos. Ersetzen Sie einen solchen Schlüssel in diesem Fall sofort und löschen Sie den alten.

8. App Check gilt als Ersatz für Rules

App Check prüft, ob eine Anfrage von Ihrer echten App auf einem echten Gerät kommt. Die App-Check-Dokumentation beschreibt App Check und Firebase Authentication als einander ergänzend: Authentication schützt Ihre Nutzer, App Check schützt Sie als Entwickler vor Missbrauch Ihrer Backends. Zugleich hält Firebase fest, dass App Check nicht jeden Missbrauch verhindert. Ein angemeldeter Nutzer, der Ihre echte App verwendet, besteht die App-Check-Prüfung. Ob er fremde Daten lesen darf, entscheiden weiterhin nur die Rules. Firebase empfiehlt, App Check für alle unterstützten Dienste einzuschalten, als zusätzliche Schicht, nicht als Ersatz.

Warum schnell gebaute Apps besonders betroffen sein können

Mit KI-Werkzeugen, Vorlagen oder Baukästen entsteht eine Firebase-App in kurzer Zeit. Das Risiko liegt weniger im erzeugten Code als im Prüfvorgang danach, denn fehlerhafte Rules sind im normalen Gebrauch unsichtbar:

Firebase rät in seiner Sicherheitscheckliste deshalb, Rules nicht erst als Aufgabe kurz vor dem Start zu schreiben, sondern parallel zur App, wie ein Datenbankschema. Für die gleiche Fragestellung bei Supabase gibt es einen eigenen Leitfaden: Supabase Row Level Security richtig einsetzen.

Regel-Beispiele: minimal und korrekt

Das folgende Firestore-Beispiel deckt die zwei häufigsten Fälle ab: ein Profil-Dokument je Nutzer unter /users/{userId} und Notizen in /notes, deren Eigentümer im Feld ownerId steht. Alles, was nicht ausdrücklich erlaubt ist, bleibt verboten.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    function signedIn() {
      return request.auth != null;
    }
    function isUser(uid) {
      return signedIn() && request.auth.uid == uid;
    }
    function validNote(d) {
      return d.title is string && d.title.size() <= 200
          && d.body is string && d.body.size() <= 10000;
    }

    // Profil: nur der Nutzer selbst, nur erlaubte Felder
    match /users/{userId} {
      allow read: if isUser(userId);
      allow create: if isUser(userId)
        && request.resource.data.keys().hasOnly(['displayName'])
        && request.resource.data.displayName is string
        && request.resource.data.displayName.size() <= 80;
      allow update: if isUser(userId)
        && request.resource.data.diff(resource.data).affectedKeys().hasOnly(['displayName'])
        && request.resource.data.displayName is string
        && request.resource.data.displayName.size() <= 80;
      allow delete: if false;
    }

    // Notizen: Eigentümer steht im Dokument
    match /notes/{noteId} {
      allow read, delete: if isUser(resource.data.ownerId);
      allow create: if isUser(request.resource.data.ownerId)
        && request.resource.data.keys().hasOnly(['ownerId', 'title', 'body'])
        && validNote(request.resource.data);
      allow update: if isUser(resource.data.ownerId)
        && request.resource.data.diff(resource.data).affectedKeys().hasOnly(['title', 'body'])
        && validNote(request.resource.data);
    }
  }
}

Vier Details stecken darin. rules_version = '2'; muss die erste Zeile sein. Es gibt keine Regel auf {document=**}, also keinen Zugriff auf Kollektionen, die hier nicht genannt sind. Felder wie role oder isAdmin kann der Nutzer nicht setzen, weil hasOnly sie ausschließt; legen Sie solche Werte serverseitig an. Und bei der Änderung darf sich ownerId nicht ändern, weil das Feld nicht in der erlaubten Liste steht.

Weil Rules keine Filter sind, muss die App ihre Notizen so abfragen, dass die Regel jedes mögliche Ergebnis erlaubt, also mit einem Filter auf ownerId gleich der eigenen Nutzer-ID. Eine Abfrage auf die ganze Kollektion scheitert, und das ist richtig so.

Für Cloud Storage gilt dasselbe Prinzip. Dieses Beispiel erlaubt jedem Nutzer nur Dateien in seinem eigenen Ordner, beim Hochladen nur Bilder unter 5 MB. Die Grenzwerte folgen dem Beispiel der Storage-Dokumentation:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /users/{userId}/{fileName} {
      allow read, delete: if request.auth != null
        && request.auth.uid == userId;
      allow create, update: if request.auth != null
        && request.auth.uid == userId
        && request.resource.size < 5 * 1024 * 1024
        && request.resource.contentType.matches('image/.*');
    }
  }
}

Nutzen Sie noch die Realtime Database, sieht dieselbe Logik so aus. $uid ist der Platzhalter für die Nutzer-ID im Pfad, "$other" lehnt alle nicht genannten Felder ab:

{
  "rules": {
    "notes": {
      "$uid": {
        ".read": "auth !== null && auth.uid === $uid",
        ".write": "auth !== null && auth.uid === $uid",
        "$noteId": {
          ".validate": "newData.hasChildren(['title', 'body'])",
          "title": { ".validate": "newData.isString() && newData.val().length <= 200" },
          "body": { ".validate": "newData.isString() && newData.val().length <= 10000" },
          "$other": { ".validate": false }
        }
      }
    }
  }
}

Wichtig: Auf höherer Ebene, etwa direkt unter "rules" oder "notes", darf kein ".read": true stehen, sonst gilt es wegen der Kaskade für alles darunter.

So testen Sie Ihre Rules

Prüfen Sie nur Projekte, die Ihnen gehören oder für die Sie eine schriftliche Erlaubnis haben. Firebase stellt für das Testen eigene Werkzeuge bereit.

Schritt 1: Rules Playground für den schnellen Check

Im Regeleditor der Firebase-Konsole finden Sie für Firestore, Realtime Database und Storage den Rules Playground. Dort simulieren Sie einen Lese- oder Schreibzugriff auf einen Pfad, ohne Anmeldung, als anonymer Nutzer oder mit einer bestimmten Nutzer-ID, und sehen, ob die Regel ihn erlaubt. Firebase selbst nennt den Playground ein Werkzeug für schnelle Prüfungen und verweist für vollständige Tests auf den Emulator.

Schritt 2: Rules-Unit-Tests mit dem Emulator

Mit der Firebase Local Emulator Suite laufen Firestore, Realtime Database und Storage lokal, zum Beispiel mit firebase emulators:start --only firestore. Für automatisierte Tests gibt es die Bibliothek @firebase/rules-unit-testing. Sie simuliert angemeldete und nicht angemeldete Nutzer und prüft mit assertSucceeds und assertFails, ob ein Zugriff erlaubt oder abgelehnt wird. Ein Test für die Notizen-Regel oben, in der Form der Dokumentation:

import { readFileSync } from 'node:fs';
import {
  initializeTestEnvironment, assertSucceeds, assertFails,
} from '@firebase/rules-unit-testing';

const env = await initializeTestEnvironment({
  projectId: 'demo-rules-test',
  firestore: { rules: readFileSync('firestore.rules', 'utf8') },
});

// Testdaten ohne Rules anlegen
await env.withSecurityRulesDisabled(async (ctx) => {
  await ctx.firestore().doc('notes/n1')
    .set({ ownerId: 'alice', title: 'A', body: '' });
});

const alice = env.authenticatedContext('alice').firestore();
const bob   = env.authenticatedContext('bob').firestore();
const guest = env.unauthenticatedContext().firestore();

await assertSucceeds(alice.doc('notes/n1').get());
await assertFails(bob.doc('notes/n1').get());      // fremde Notiz
await assertFails(guest.doc('notes/n1').get());    // ohne Anmeldung
await assertFails(bob.doc('notes/n2')              // im Namen von alice
  .set({ ownerId: 'alice', title: 'x', body: '' }));
await assertFails(alice.doc('notes/n1')            // Eigentümer wechseln
  .update({ ownerId: 'bob' }));

await env.cleanup();

Für die kontinuierliche Integration empfiehlt Firebase firebase emulators:exec: Der Befehl startet die Emulatoren, führt Ihr Testskript aus, etwa firebase emulators:exec --only firestore "npm test", und beendet sie danach wieder. Die Sicherheitscheckliste rät, diese Tests in die CI-Pipeline aufzunehmen. So fällt auf, wenn eine spätere Änderung eine Regel aufweicht.

Schritt 3: Selbsttest mit einem zweiten Konto

Der letzte Test findet gegen Ihr echtes Projekt statt. Legen Sie zwei Testkonten an, A und B, und erzeugen Sie mit A einige Datensätze und eine Datei. Melden Sie sich dann als B an und versuchen Sie, über Ihre App oder ein kleines Testskript mit dem Firebase-Client:

Jeder dieser Versuche muss mit einem Berechtigungsfehler scheitern. Wiederholen Sie die Tests ohne Anmeldung. Denken Sie daran, dass Änderungen an Firestore-Rules laut Dokumentation bis zu einer Minute brauchen, bis sie für neue Abfragen gelten, und bis zu zehn Minuten, bis sie auch aktive Listener erfassen. Testen Sie nach dem Deployment also nicht sofort.

Checkliste vor dem Livegang

BereichMaßnahme
TestmodusKeine Regel mit if true oder nur mit Datum mehr aktiv, in Firestore, Realtime Database und Storage
GrundhaltungAlles verboten, was nicht ausdrücklich erlaubt ist; keine weite Regel auf {document=**}
EigentümerJede Regel für personenbezogene Daten vergleicht mit request.auth.uid, auch beim Anlegen und Ändern
FelderErlaubte Felder mit hasOnly, Änderungen mit affectedKeys(), Typen und Längen geprüft; Rollen und Tarife nicht vom Nutzer änderbar
Sensible FelderIn eigenen Dokumenten mit eigener Regel, weil Lesen nur je Dokument geregelt werden kann
UnterkollektionenJede Unterkollektion mit eigener Regel
Realtime DatabaseKein .read oder .write auf hoher Ebene, das tiefer liegende Regeln aushebelt
StorageEigentümerprüfung je Pfad, Größe und Dateityp beim Hochladen begrenzt
SchlüsselIm Client nur die Firebase-Konfiguration, API-Schlüssel eingeschränkt; Dienstkonto-Schlüssel nur auf dem Server
AnmeldungAnonyme Konten bekommen keinen Zugriff auf nicht öffentliche Daten
App CheckFür alle unterstützten Dienste eingeschaltet, zusätzlich zu den Rules
TestsRules-Unit-Tests im Emulator in der CI, Selbsttest mit zweitem Konto und ohne Anmeldung bestanden

Was Tests der eigenen Regeln nicht abdecken

Unit-Tests prüfen genau die Fälle, an die Sie gedacht haben. Ob eine Cloud Function mit dem Admin SDK eine Prüfung überspringt, ob ein Team-Mitglied Rechnungen eines anderen Teams sieht oder ob sich über eine Kombination aus erlaubten Schritten doch fremde Daten erreichen lassen, zeigt sich oft erst, wenn jemand die App gezielt mit mehreren Rollen angreift. Werden personenbezogene Daten dabei tatsächlich abgerufen, kann das eine Meldepflicht nach Art. 33 DSGVO auslösen. Ob das im Einzelfall zutrifft, ist eine Rechtsfrage. Dieser Artikel ist keine Rechtsberatung.

Halten Ihre Firebase Rules einem echten Angriff stand?

Wir prüfen Apps auf Firebase, auch mit KI-Werkzeugen gebaute, im schriftlich vereinbarten Umfang: Rules für Firestore, Realtime Database und Storage, Schreibrechte und Felder mit Berechtigungsfolgen, Schlüssel im Client, Anmeldung und Cloud Functions, jeweils mit mehreren Testkonten und ohne Anmeldung. Jeder Befund kommt mit einem nachvollziehbaren Nachweis und einem konkreten Korrekturvorschlag. Mehr dazu unter KI-App-Sicherheitscheck.

App-Sicherheitscheck anfragen

CyberSec42 ist eine unabhängige technische Sicherheitsprüfung, keine akkreditierte Zertifizierungsstelle und keine Rechtsberatung. CyberSec42 steht in keiner Verbindung zu Google oder Firebase.

Häufige Fragen

Darf der Firebase-API-Schlüssel im Frontend stehen?

Ja. Laut Firebase-Dokumentation identifizieren Schlüssel für Firebase-Dienste nur Ihr Projekt und Ihre App und müssen nicht geheim gehalten werden. Schränken Sie den Schlüssel auf die benötigten APIs ein. Der Schutz Ihrer Daten hängt an den Security Rules.

Reicht request.auth != null als Regel?

Nein, nicht für Daten einzelner Nutzer. Damit darf jeder angemeldete Nutzer alle Daten lesen und schreiben. Firebase führt diese Regel als nicht empfohlen. Vergleichen Sie zusätzlich request.auth.uid mit dem Eigentümer des Dokuments oder der Datei.

Was passiert, wenn die Testmodus-Regeln ablaufen?

Bei der Realtime Database werden Sie laut Dokumentation per E-Mail benachrichtigt, danach verweigern die Regeln alle Anfragen. Ersetzen Sie die Regeln dann durch echte Zugriffsregeln, statt das Ablaufdatum zu verschieben. Ein verschobenes Datum hält die Datenbank für jeden offen.

Ersetzt App Check die Security Rules?

Nein. App Check prüft, ob eine Anfrage aus Ihrer echten App kommt. Welcher Nutzer welche Daten lesen oder ändern darf, regeln weiterhin die Rules. Firebase empfiehlt App Check als zusätzliche Schicht.

Gelten die Rules auch für das Admin SDK und Cloud Functions?

Nein. Server-Bibliotheken und das Admin SDK umgehen die Security Rules. Prüfungen in Cloud Functions müssen Sie deshalb selbst im Code schreiben, und Dienstkonto-Schlüssel gehören nur auf den Server.

Wie teste ich Firebase Security Rules automatisiert?

Mit der Firebase Local Emulator Suite und der Bibliothek @firebase/rules-unit-testing. Sie simuliert angemeldete und nicht angemeldete Nutzer, und firebase emulators:exec führt die Tests in der CI aus.

Weiterlesen

Quellen