È sicuro esporre Firebase apiKey al pubblico?


439

La guida dell'app Web Firebase afferma che dovrei inserire il dato apiKeynel mio HTML per inizializzare Firebase:

// 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>

In questo modo, apiKeyviene esposto a tutti i visitatori. Qual è lo scopo di quella chiave ed è davvero destinato a essere pubblico?


1
Penso che fino a quando imposti le regole del database di Firebase Auth e Firebase puoi fornire tali informazioni pubblicamente.
abbaf33f,

L'utente Christophe Quintard ha aggiunto un collegamento a un articolo molto utile con informazioni aggiuntive sulla sicurezza delle API di Firebase, quindi lo ripubblico qui: javebratt.com/hide-firebase-api (Il commento sparirà perché è allegato a un altro utente risposta contrassegnata per l'eliminazione a causa della scarsa qualità)
Oliver Schafeld,

Voglio solo sottolineare che solo perché questo particolare framework sembra andare bene con l'esposizione delle sue API, ciò non significa che altri framework siano d'accordo con esso. Non vorrei che nessuno si allontanasse da questo post con l'idea che "Va bene esporre le chiavi API" in generale.
YungGun,

esponi le chiavi senza problemi. Per renderlo sicuro, puoi limitarlo con un dominio specifico in produzione in modo che nessun altro possa effettuare chiamate API di chiamata da qualsiasi nome di dominio casuale. Per renderlo più sicuro, rimuovere localhost dall'app di produzione.
BL Λ CK

1
Non credo che la rimozione di localhost dalla whitelist dei referrer farà altro che rendere più difficile il test. Tale configurazione non è come una whitelist IP; pensalo più come una configurazione CORS. Il modo in cui Firebase funziona è che quelle rotte API sono chiamate direttamente dai client, non sono sottoposte a proxy. Ecco perché la tua pagina web richiede la chiave API. Se un cattivo attore vuole chiamare i tuoi percorsi API da Postman, la tua whitelist referrer non li fermerà. È utile solo per impedire ad altri siti pubblici di spostarsi dai server.
forresthopkinsa

Risposte:


452

L'apiKey in questo frammento di configurazione identifica semplicemente il tuo progetto Firebase sui server di Google. Non è un rischio per la sicurezza che qualcuno lo sappia. In effetti, è necessario che lo sappiano, per poter interagire con il tuo progetto Firebase. Questi stessi dati di configurazione sono inclusi anche in ogni app iOS e Android che utilizza Firebase come backend.

In questo senso è molto simile all'URL database che identifica il database back-end associato al tuo progetto nella stessa frammento di: https://<app-id>.firebaseio.com. Vedi questa domanda sul perché questo non rappresenta un rischio per la sicurezza: come limitare la modifica dei dati di Firebase? , incluso l'uso delle regole di sicurezza lato server di Firebase per garantire che solo gli utenti autorizzati possano accedere ai servizi di back-end.

Se vuoi sapere come proteggere l'accesso ai dati ai tuoi servizi di back-end di Firebase è autorizzato, leggi la documentazione sulle regole di sicurezza di Firebase .


Se desideri ridurre il rischio di eseguire il commit di questi dati di configurazione nel controllo versione, prendi in considerazione l'utilizzo della configurazione automatica dell'SDK di Firebase Hosting . Mentre le chiavi finiranno comunque nel browser nello stesso formato, non saranno più codificate nel codice con quello.


7
Quindi significa che altre persone sarebbero in grado di accedere a tutti i dati nel mio database Firebase?
Emmanuel Campos,

31
@EmmanuelCampos La risposta è Sì e No. Sì, se si consente o si desidera che le altre persone accedano a tutti i dati nel database. E no, se non vuoi che lo facciano. Il database di Firebase ha regole, regole che controlli
KhoPhi,

5
Ho trovato la mia risposta qui per la mia ultima domanda support.google.com/firebase/answer/6400741 Grazie per l'aiuto. Questo link potrebbe aiutare qualcuno in futuro.
Emmanuel Campos,

7
@ m.rufca, i tuoi dati dovrebbero essere disponibili per gli utenti autenticati. Ed ecco il trucco. Per impostazione predefinita, nelle impostazioni del Firebase solo localhost e i domini del progetto sono autorizzati a eseguire l'autenticazione da essi. Quindi nessun altro può creare un'app che normalmente funzionerà con il tuo Firebase.
Artem Arkhipov,

15
cosa succede se il bot sta creando un numero illimitato di utenti sulla mia app. Come posso richiedere captcha.
Muhammad Umer,

79

Sulla base delle risposte di prufrofro e Frank van Puffelen qui , ho messo insieme questa configurazione che non impedisce raschiando, ma può rendere leggermente più difficile da usare la tua chiave API.

Attenzione: per ottenere i tuoi dati, anche con questo metodo, puoi ad esempio semplicemente aprire la console JS in Chrome e digitare:

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

Solo le regole di sicurezza del database possono proteggere i tuoi dati.

Tuttavia, ho limitato l'uso della mia chiave API di produzione al mio nome di dominio in questo modo:

  1. https://console.developers.google.com/apis
  2. Seleziona il tuo progetto Firebase
  3. Credenziali
  4. Sotto Chiavi API, seleziona la tua chiave del browser. Dovrebbe apparire così: " Chiave del browser (creata automaticamente dal servizio Google) "
  5. In " Accetta le richieste da questi referrer HTTP (siti web) ", aggiungere l'URL della tua app (Esempio: projectname.firebaseapp.com/*)

Ora l'app funzionerà solo su questo nome di dominio specifico. Quindi ho creato un'altra chiave API che sarà privata per lo sviluppo di localhost.

  1. Fai clic su Crea credenziali> Chiave API

Per impostazione predefinita, come menzionato da Emmanuel Campos, Firebase solo le whitelist localhoste il dominio di hosting Firebase .


Per essere sicuro di non pubblicare la chiave API errata per errore, utilizzo uno dei seguenti metodi per utilizzare automaticamente quello più limitato in produzione.

Impostazione per Create-React-App

In /env.development:

REACT_APP_API_KEY=###dev-key###

In /env.production:

REACT_APP_API_KEY=###public-key###

In /src/index.js

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

La mia configurazione precedente per Webpack:

Uso Webpack per creare la mia app di produzione e inserisco la mia chiave API dev all'interno della mia index.htmlesattamente come faresti normalmente. Quindi, all'interno del mio webpack.production.config.jsfile, sostituisco la chiave ogni volta che index.htmlviene copiata nella build di produzione:

plugins: [
    new CopyWebpackPlugin([
      {
        transform: function(content, path) {
          return content.toString().replace("###dev-key###", "###public-key###");
        },
        from: './index.html'
      }
    ])
  ]

1
Funziona bene per te? Stavo pensando di fare la stessa cosa per un'app Android. Mi chiedo perché Firebase non lo copra nella sezione sulla sicurezza.
steliosf,

2
Finora non ho avuto alcun problema, ma probabilmente nemmeno attacchi
ora il

3
Questo non è menzionato nella loro guida perché non ti proteggerà dai graffi. Tutto ciò garantisce che qualcun altro non possa creare un'app Web che utilizza la base di fuoco per leggere (o scrivere) i dati, se viene eseguita in un normale browser ben educato.
thoutbeckers il

@thoutbeckers hai ragione, grazie. Ho modificato la risposta, ma ho lasciato il metodo in quanto potrebbe essere ancora utile.
ora il

1
@FrankvanPuffelen Da quanto ho capito, non fa una grande differenza, ma può rendere leggermente più fastidioso abusare della tua quota, poiché in un browser ben educato, la chiave API fornita con HTML / JS funzionerà solo sull'inteso domini e non localhost o qualsiasi altra cosa. Ma concordo sul fatto che la protezione aggiunta è marginale rispetto a quanto già prevede Firebase. Riformulerò la risposta a qualcosa di meno drammatico.
ora il

22

Non sono convinto di esporre le chiavi di sicurezza / configurazione al client. Non lo definirei sicuro, non perché qualcuno possa rubare tutte le informazioni private dal primo giorno, perché qualcuno può fare richieste eccessive, scaricare la tua quota e farti pagare un sacco di soldi a Google.

Devi pensare a molti concetti che impediscono alle persone di non accedere dove non dovrebbero essere, attacchi DOS ecc.

Preferirei di più che il client colpisse prima il tuo server web, lì metterai quello che mai prima mano firewall, captcha, cloudflare, sicurezza personalizzata tra client e server, o tra server e firebase e sei a posto. Almeno puoi prima fermare l'attività sospetta prima che raggiunga la base del fuoco. Avrai molta più flessibilità.

Vedo solo un buon scenario di utilizzo per l'utilizzo della configurazione basata su client per usi interni. Ad esempio, hai un dominio interno e sei abbastanza sicuro che gli estranei non possano accedervi, quindi puoi configurare un ambiente come browser -> tipo firebase.


10
Ma non è lo stesso che "esporre" qualsiasi altra API REST? Voglio dire, con REST API URL sono disponibili per l'utente. Possono utilizzare l'URL per effettuare le richieste desiderate e scaricare la quota. Ciò che Firebase fa è usare la configurazione con i tasti API per identificare la tua parte di back-end ed è e deve essere disponibile affinché l'utente possa effettuare richieste.
mbochynski,

3
@mbochynski ma puoi in qualche modo fare richieste dirette alle risorse che ti fanno pagare la bolletta. E sul lato Firebase non ci sono molti meccanismi di controllo per prevenire gli attacchi DDoS ecc. Il mio suggerimento sarebbe quello di consentire al tuo client di chiamare l'API REST, ma che l'API REST dovrebbe contenere le chiavi API in privato, e anche prima di colpire le risorse di Firebase, convalidarle se sono richieste legittime. (tramite Cloudflare ecc.). o recuperare i risultati dalla cache. Quindi colpirai le tue risorse Firebase solo se necessario. Questo è ciò che implementerei firebase.google.com/docs/admin/setup
Teoman shipahi

3
esporre le chiavi al browser è davvero una cattiva idea. quelli per scrivere tutte queste guide / articoli, cosa stavano pensando? referrer http per sicurezza? che è facilmente falsificato
Nick Chan Abdullah,

1
Ragazzi, non state pensando a questo diritto. Non pensare alla chiave API come un segreto; non è una chiave privata, è solo un ID, quindi l'API Firebase sa chi sta accedendo a quale progetto. Se vuoi molta flessibilità e devi controllare ogni fase dell'interazione server / client, allora non dovresti usare Firebase, dovresti usare GCP.
forresthopkinsa,

@forresthopkinsa Ho il link sopra per commentare quale approccio adottare. Nessuno qui abbastanza ingenuo da suggerire che sia una chiave segreta.
Teoman Shipahi,

4

Credo che una volta che le regole del database saranno scritte in modo accurato, sarà sufficiente per proteggere i tuoi dati. Inoltre, ci sono linee guida che si possono seguire per strutturare il database di conseguenza. Ad esempio, creando un nodo UID sotto gli utenti e inserendo tutte le informazioni sotto di esso. Successivamente, sarà necessario implementare una semplice regola del database come di seguito

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

Nessun altro utente sarà in grado di leggere i dati di altri utenti, inoltre la politica del dominio limiterà le richieste provenienti da altri domini. Si può leggere di più al riguardo sulle regole di Firebase Security


3

L'esposizione della chiave API crea una vulnerabilità quando è abilitata la registrazione utente / password. Esiste un endpoint API aperto che accetta la chiave API e consente a chiunque di creare un nuovo account utente. Possono quindi utilizzare questo nuovo account per accedere all'app protetta da Firebase Auth o utilizzare l'SDK per eseguire l'autenticazione con l'utente / passare ed eseguire query.

L'ho segnalato a Google ma dicono che funziona come previsto.

Se non è possibile disabilitare gli account utente / password, è necessario effettuare le seguenti operazioni: Creare una funzione cloud per disabilitare automaticamente i nuovi utenti su Crea e creare una nuova voce DB per gestirne l'accesso.

Es .: MyUsers / {userId} / Accesso: 0

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

Aggiorna le tue regole per consentire solo letture per gli utenti con accesso> 1.

In caso contrario la funzione di ascolto non disabilita l'account abbastanza velocemente, quindi le regole di lettura impediranno loro di leggere i dati.


3

Dopo aver letto questo e dopo aver fatto qualche ricerca sulle possibilità, ho trovato un approccio leggermente diverso per limitare l'utilizzo dei dati da parte di utenti non autorizzati:

Salvo anche i miei utenti nel mio DB (e salviamo i dati del profilo lì). Quindi ho appena impostato le regole del db in questo modo:

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

In questo modo solo un utente salvato in precedenza può aggiungere nuovi utenti nel DB, quindi non è possibile che nessuno senza un account possa eseguire operazioni sul DB. anche l'aggiunta di nuovi utenti è possibile solo se l'utente ha un ruolo speciale e modifica solo dall'amministratore o dallo stesso utente (qualcosa del genere):

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

-2

Non dovresti esporre queste informazioni. in pubblico, in particolare le chiavi API. Potrebbe causare una perdita di privacy.

Prima di rendere pubblico il sito Web, è necessario nasconderlo. Puoi farlo in 2 o più modi

  1. Codifica / nascondimento complessi
  2. Inserisci semplicemente i codici SDK di firebase nella parte inferiore del tuo sito web o della tua app in modo che firebase funzioni automaticamente. non è necessario posizionare le chiavi API da nessuna parte

1
Cito da Firebase, "Copia e incolla questi script nella parte inferiore del tag <body>, ma prima di utilizzare qualsiasi servizio Firebase", che include la chiave API
Luke-zhang-04
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.