Ist es sicher, Firebase apiKey der Öffentlichkeit zugänglich zu machen?

432

Im Firebase Web-App-Handbuch heißt es, dass ich das apiKeyFolgende in mein HTML einfügen sollte, um Firebase zu initialisieren:

// TODO: Replace with your project's customized code snippet
<script src="https://www.gstatic.com/firebasejs/3.0.2/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: '<your-api-key>',
    authDomain: '<your-auth-domain>',
    databaseURL: '<your-database-url>',
    storageBucket: '<your-storage-bucket>'
  };
  firebase.initializeApp(config);
</script>

Auf diese Weise ist das apiKeyjedem Besucher ausgesetzt. Was ist der Zweck dieses Schlüssels und soll er wirklich öffentlich sein?

farmio
quelle
1
Ich denke, solange Sie Firebase Auth- und Firebase-Datenbankregeln einrichten , können Sie diese Informationen öffentlich geben.
Abbaf33f
Benutzer Christophe Quintard hat einen Link zu einem sehr nützlichen Artikel mit zusätzlichen Informationen zur Sicherheit von Firebase-APIs hinzugefügt. Daher reposte ich ihn hier: javebratt.com/hide-firebase-api (Der Kommentar wird verschwinden, da er an den eines anderen Benutzers angehängt ist Antwort, die wegen schlechter Qualität zum Löschen markiert ist)
Oliver Schafeld
Ich möchte nur darauf hinweisen, dass nur, weil dieses spezielle Framework die API offen legt, dies nicht bedeutet, dass andere Frameworks damit einverstanden sind. Ich möchte nicht, dass jemand diesen Beitrag mit der Idee verlässt, dass "Es ist in Ordnung, API-Schlüssel verfügbar zu machen" im Allgemeinen.
YungGun
Sie legen Schlüssel ohne Probleme frei. Um die Sicherheit zu gewährleisten, können Sie sie auf eine bestimmte Domäne in der Produktion beschränken, sodass niemand sonst eine Aufruf-API von einem beliebigen Domänennamen aus aufrufen kann. Um es sicherer zu machen, entfernen Sie localhost aus der Produktions-App.
BL Λ CK
1
Ich glaube nicht, dass das Entfernen von localhost aus der Whitelist Ihrer Referrer etwas anderes bewirken wird, als das Testen zu erschweren. Diese Konfiguration ähnelt keiner IP-Whitelist. Stellen Sie sich das eher wie eine CORS-Konfiguration vor. Firebase funktioniert so, dass diese API-Routen direkt von Clients aufgerufen werden und nicht als Proxy fungieren. Deshalb benötigt Ihre Webseite den API-Schlüssel. Wenn ein schlechter Schauspieler Ihre API-Routen von Postman aus aufrufen möchte, wird Ihre Whitelist für Referrer sie nicht stoppen. Dies ist nur nützlich, um zu verhindern, dass andere öffentliche Websites Ihre Server verlassen.
Forresthopkinsa

Antworten:

448

Der apiKey in diesem Konfigurations-Snippet identifiziert lediglich Ihr Firebase-Projekt auf den Google-Servern. Es ist kein Sicherheitsrisiko für jemanden, es zu wissen. Tatsächlich müssen sie es wissen, damit sie mit Ihrem Firebase-Projekt interagieren können. Dieselben Konfigurationsdaten sind auch in jeder iOS- und Android-App enthalten, die Firebase als Backend verwendet.

In diesem Sinne ist es der Datenbank-URL sehr ähnlich, die die mit Ihrem Projekt verknüpfte Back-End-Datenbank in demselben Snippet identifiziert : https://<app-id>.firebaseio.com. In dieser Frage erfahren Sie, warum dies kein Sicherheitsrisiko darstellt: Wie kann die Änderung von Firebase-Daten eingeschränkt werden? , einschließlich der Verwendung der serverseitigen Sicherheitsregeln von Firebase, um sicherzustellen, dass nur autorisierte Benutzer auf die Backend-Dienste zugreifen können.

Wenn Sie erfahren möchten, wie der gesamte Datenzugriff auf Ihre Firebase-Backend-Dienste autorisiert wird, lesen Sie die Dokumentation zu den Firebase-Sicherheitsregeln .


Wenn Sie das Risiko verringern möchten, diese Konfigurationsdaten für die Versionskontrolle zu übernehmen, sollten Sie die automatische SDK-Konfiguration von Firebase Hosting verwenden . Während die Schlüssel immer noch im selben Format im Browser landen, werden sie damit nicht mehr fest in Ihren Code codiert.

Frank van Puffelen
quelle
7
Das bedeutet also, dass andere Personen auf alle Daten in meiner Firebase-Datenbank zugreifen können?
Emmanuel Campos
31
@EmmanuelCampos Die Antwort lautet Ja und Nein. Ja, wenn Sie zulassen oder möchten, dass die anderen Personen auf alle Daten in der Datenbank zugreifen. Und nein, wenn du es nicht willst. Firebase-Datenbank hat Regeln, Regeln, die Sie kontrollieren
KhoPhi
5
Ich habe hier meine Antwort auf meine letzte Frage gefunden. Support.google.com/firebase/answer/6400741 Vielen Dank für die Hilfe. Dieser Link kann in Zukunft jemandem helfen.
Emmanuel Campos
7
@ m.rufca, Ihre Daten sollten für Benutzer verfügbar sein, die authentifiziert sind. Und hier ist der Trick. Standardmäßig sind in Ihren Firebase-Einstellungen nur localhost und Ihre Projektdomänen berechtigt, eine Authentifizierung von diesen durchzuführen. So kann niemand anderes eine App erstellen, die normalerweise mit Ihrer Firebase funktioniert.
Artem Arkhipov
15
Was ist, wenn Bot unbegrenzte Benutzer in meiner App erstellt? Wie kann ich Captcha benötigen?
Muhammad Umer
79

Aufbauend auf den Antworten von Prufrofro und Frank van Puffelen habe ich dieses Setup zusammengestellt, das das Scraping nicht verhindert, aber die Verwendung Ihres API-Schlüssels etwas erschweren kann.

Warnung: Um Ihre Daten auch mit dieser Methode abzurufen, können Sie beispielsweise einfach die JS-Konsole in Chrome öffnen und Folgendes eingeben:

firebase.database().ref("/get/all/the/data").once("value", function (data) {
    console.log(data.val());
});

Nur die Datenbanksicherheitsregeln können Ihre Daten schützen.

Trotzdem habe ich die Verwendung meines Produktions-API-Schlüssels wie folgt auf meinen Domain-Namen beschränkt:

  1. https://console.developers.google.com/apis
  2. Wählen Sie Ihr Firebase-Projekt aus
  3. Referenzen
  4. Wählen Sie unter API-Schlüssel Ihren Browser-Schlüssel aus. Es sollte folgendermaßen aussehen: " Browser-Schlüssel (automatisch von Google Service erstellt) "
  5. In " Accept - Anfragen von diesen HTTP - Referrer (Websites) ", fügen Sie die URL Ihrer App (exemple: projectname.firebaseapp.com/*)

Jetzt funktioniert die App nur noch mit diesem bestimmten Domainnamen. Also habe ich einen weiteren API-Schlüssel erstellt, der für die Entwicklung von localhost privat ist.

  1. Klicken Sie auf Anmeldeinformationen erstellen> API-Schlüssel

Wie von Emmanuel Campos erwähnt, sind Firebaselocalhost standardmäßig nur Whitelists und Ihre Firebase-Hosting-Domain .


Um sicherzustellen, dass ich nicht versehentlich den falschen API-Schlüssel veröffentliche, verwende ich eine der folgenden Methoden, um automatisch den eingeschränkteren in der Produktion zu verwenden.

Setup für Create-React-App

In /env.development:

REACT_APP_API_KEY=###dev-key###

In /env.production:

REACT_APP_API_KEY=###public-key###

Im /src/index.js

const firebaseConfig = {
  apiKey: process.env.REACT_APP_API_KEY,
  // ... 
};

Mein vorheriges Setup für Webpack:

Ich verwende Webpack, um meine Produktions-App zu erstellen, und stecke meinen Dev-API-Schlüssel index.htmlwie gewohnt in meinen . Dann webpack.production.config.jsersetze ich in meiner Datei den Schlüssel jedes Mal, wenn er index.htmlin den Produktionsbuild kopiert wird:

plugins: [
    new CopyWebpackPlugin([
      {
        transform: function(content, path) {
          return content.toString().replace("###dev-key###", "###public-key###");
        },
        from: './index.html'
      }
    ])
  ]
jetzt
quelle
1
Funktioniert das gut für dich? Ich dachte daran, dasselbe für eine Android-App zu tun. Ich frage mich, warum Firebase dies im Sicherheitsbereich nicht behandelt.
Steliosf
2
Ich hatte bisher kein Problem, aber wahrscheinlich auch keine Angriffe
jetzt
3
Dies wird in ihrem Handbuch nicht erwähnt, da es Sie nicht vor dem Schaben schützt. Dies stellt nur sicher, dass jemand anderes keine Web-App erstellen kann, die Ihre Firebase zum Lesen (oder Schreiben) von Daten verwendet, wenn sie in einem normalen, gut erzogenen Browser ausgeführt wird.
Thoutbecker
@thoutbeckers du hast recht, danke. Ich habe die Antwort bearbeitet, aber die Methode verlassen, da sie möglicherweise noch nützlich ist.
Jetzt
1
@FrankvanPuffelen Soweit ich weiß, macht es keinen großen Unterschied, kann es jedoch etwas ärgerlicher machen, Ihr Kontingent zu missbrauchen, da in einem gut erzogenen Browser der mit HTML / JS bereitgestellte API-Schlüssel nur für den beabsichtigten Zweck funktioniert Domain (s) und nicht localhost oder irgendetwas anderes. Ich stimme jedoch zu, dass der zusätzliche Schutz im Vergleich zu dem, was Firebase bereits bietet, marginal ist. Ich werde die Antwort auf etwas weniger Dramatisches umformulieren.
jetzt
22

Ich bin nicht davon überzeugt, Sicherheits- / Konfigurationsschlüssel dem Client zur Verfügung zu stellen. Ich würde es nicht als sicher bezeichnen, nicht weil jemand vom ersten Tag an alle privaten Informationen stehlen kann, weil jemand übermäßige Anfragen stellen und Ihr Kontingent belasten und Sie Google viel Geld schulden lassen kann.

Sie müssen über viele Konzepte nachdenken, von der Beschränkung des Zugriffs auf Personen, auf die sie nicht zugreifen sollen, DOS-Angriffe usw.

Ich würde es vorziehen, wenn der Client zuerst auf Ihren Webserver gelangt. Dort setzen Sie Firewall, Captcha, Cloudflare und benutzerdefinierte Sicherheit aus erster Hand zwischen Client und Server oder zwischen Server und Firebase und los geht's. Zumindest können Sie verdächtige Aktivitäten zuerst stoppen, bevor sie die Feuerbasis erreichen. Sie haben viel mehr Flexibilität.

Ich sehe nur ein gutes Verwendungsszenario für die Verwendung der clientbasierten Konfiguration für interne Verwendungen. Sie haben beispielsweise eine interne Domäne und sind sich ziemlich sicher, dass Außenstehende dort nicht darauf zugreifen können, sodass Sie eine Umgebung wie Browser -> Firebase-Typ einrichten können.

Teoman Shipahi
quelle
10
Aber ist es nicht dasselbe wie das "Offenlegen" einer anderen REST-API? Ich meine mit REST API URL stehen dem Benutzer zur Verfügung. Sie können die URL verwenden, um beliebige Anfragen zu stellen und Ihr Kontingent zu belasten. Firebase verwendet die Konfiguration mit API-Schlüsseln, um Ihren Teil des Backends zu identifizieren. Dies ist der Fall und muss für den Benutzer verfügbar sein, um Anforderungen zu stellen.
mbochynski
3
@mbochynski, aber Sie können etwas direkte Anfragen an Ressourcen stellen, die dazu führen, dass Sie die Rechnung bezahlen. Und auf der Firebase-Seite gibt es nicht so viele Kontrollmechanismen, um DDoS-Angriffe usw. zu verhindern. Mein Vorschlag wäre, dass Ihr Client Ihre REST-API aufruft, aber dass die REST-API API-Schlüssel privat enthält und diese noch vor dem Zugriff auf Firebase-Ressourcen validiert wenn es sich um legitime Anfragen handelt. (über Cloudflare usw.). oder Ergebnisse aus dem Cache abrufen. Dann werden Sie Ihre Firebase-Ressourcen nur dann erreichen, wenn Sie dies benötigen. Dies ist , was ich würde implementieren firebase.google.com/docs/admin/setup
Teoman shipahi
3
Das Freilegen von Schlüsseln im Browser ist eine ernsthafte Idee. Diejenigen, die all diese Leitfäden / Artikel geschrieben haben, was dachten sie? http Referrer für die Sicherheit? das ist leicht
Nick Chan Abdullah
1
Ihr denkt nicht richtig darüber nach. Betrachten Sie den API-Schlüssel nicht als Geheimnis. Es ist kein privater Schlüssel, sondern nur eine ID, damit die Firebase-API weiß, wer auf welches Projekt zugreift. Wenn Sie viel Flexibilität wünschen und jeden Schritt der Server / Client-Interaktion steuern müssen, sollten Sie Firebase nicht verwenden, sondern GCP.
Forresthopkinsa
@forresthopkinsa Ich habe den Link oben Kommentar, welchen Ansatz zu nehmen. Niemand hier ist naiv genug, um zu behaupten, dass es sich überhaupt um einen geheimen Schlüssel handelt.
Teoman Shipahi
4

Ich glaube, sobald die Datenbankregeln korrekt geschrieben sind, reicht es aus, Ihre Daten zu schützen. Darüber hinaus gibt es Richtlinien, nach denen Sie Ihre Datenbank entsprechend strukturieren können. Erstellen Sie beispielsweise einen UID-Knoten unter Benutzern und fügen Sie alle unter Informationen darunter ein. Danach müssen Sie eine einfache Datenbankregel wie folgt implementieren

  "rules": {
    "users": {
      "$uid": {
        ".read": "auth != null && auth.uid == $uid",
        ".write": "auth != null && auth.uid == $uid"
      }
    }
  }
}

Kein anderer Benutzer kann die Daten anderer Benutzer lesen. Darüber hinaus schränkt die Domänenrichtlinie Anforderungen von anderen Domänen ein. Weitere Informationen finden Sie in den Firebase-Sicherheitsregeln

Bhupiister singh
quelle
3

Die API-Schlüsselbelichtung verursacht eine Sicherheitsanfälligkeit, wenn die Benutzer- / Kennwortanmeldung aktiviert ist. Es gibt einen offenen API-Endpunkt, der den API-Schlüssel verwendet und es jedem ermöglicht, ein neues Benutzerkonto zu erstellen. Sie können sich dann mit diesem neuen Konto bei Ihrer Firebase Auth-geschützten App anmelden oder das SDK verwenden, um sich mit Benutzer / Pass zu authentifizieren und Abfragen auszuführen.

Ich habe dies Google gemeldet, aber sie sagen, dass es wie beabsichtigt funktioniert.

Wenn Sie Benutzer- / Kennwortkonten nicht deaktivieren können, sollten Sie folgende Schritte ausführen: Erstellen Sie eine Cloud-Funktion, um neue Benutzer bei Erstellen automatisch zu deaktivieren, und erstellen Sie einen neuen DB-Eintrag, um deren Zugriff zu verwalten.

Beispiel: MyUsers / {userId} / Access: 0

exports.addUser = functions.auth.user().onCreate(onAddUser);
exports.deleteUser = functions.auth.user().onDelete(onDeleteUser);

Aktualisieren Sie Ihre Regeln, um nur Lesevorgänge für Benutzer mit Zugriff> 1 zuzulassen.

Wenn die Listener-Funktion das Konto nicht schnell genug deaktiviert, verhindern die Leseregeln, dass Daten gelesen werden.

bzk
quelle
3

Nachdem ich dies gelesen und einige Nachforschungen über die Möglichkeiten angestellt hatte, kam ich auf einen etwas anderen Ansatz, um die Datennutzung durch nicht autorisierte Benutzer einzuschränken:

Ich speichere meine Benutzer auch in meiner Datenbank (und speichere dort die Profildaten). Also habe ich die DB-Regeln einfach so eingestellt:

".read": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()",
".write": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()"

Auf diese Weise kann nur ein zuvor gespeicherter Benutzer neue Benutzer zur Datenbank hinzufügen, sodass niemand ohne Konto Vorgänge für die Datenbank ausführen kann. Das Hinzufügen neuer Benutzer ist nur möglich, wenn der Benutzer eine spezielle Rolle hat und nur vom Administrator oder von diesem Benutzer selbst bearbeitet wird (so ähnlich):

"userdata": {
  "$userId": {
    ".write": "$userId === auth.uid || root.child('/userdata/'+auth.uid+'/userRole').val() === 'superadmin'",
   ...
Berci
quelle
-2

Sie sollten diese Informationen nicht verfügbar machen. in der Öffentlichkeit speziell API-Schlüssel. Dies kann zu einem Datenschutzleck führen.

Bevor Sie die Website veröffentlichen, sollten Sie sie ausblenden. Sie können dies auf zwei oder mehr Arten tun

  1. Komplexes Codieren / Verstecken
  2. Fügen Sie einfach Firebase-SDK-Codes am Ende Ihrer Website oder App ein, damit Firebase automatisch alle Funktionen ausführt. Sie müssen keine API-Schlüssel irgendwo ablegen
user12449933
quelle
Ich zitiere aus Firebase: "Kopieren Sie diese Skripte und fügen Sie sie unten in Ihr <body> -Tag ein, aber bevor Sie Firebase-Dienste verwenden", einschließlich des API-Schlüssels
Luke-zhang-04,