É seguro expor o Firebase apiKey ao público?

439

O guia Firebase Web-App afirma que devo colocar o dado apiKeyno meu HTML para inicializar o 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>

Ao fazer isso, o apiKeyé exposto a todos os visitantes. Qual é o objetivo dessa chave e ela realmente deve ser pública?

farmio
fonte
1
Acho que, desde que você configure as regras de banco de dados Firebase Auth e Firebase, poderá fornecer essas informações publicamente.
Abbaf33f 12/03/19
O usuário Christophe Quintard havia adicionado um link a um artigo muito útil com informações adicionais sobre a segurança das APIs do Firebase, por isso estou publicando aqui: javebratt.com/hide-firebase-api (O comentário vai desaparecer porque está anexado ao outro usuário resposta que está marcada para eliminação devido à má qualidade)
Oliver Schafeld
Eu só quero salientar que, só porque essa estrutura em particular está boa em expor sua API, isso não significa que outras estruturas estejam bem com ela. Não gostaria que alguém se afastasse desta postagem com a idéia de que "está tudo bem expor as chaves da API" em geral.
YungGun
você expõe chaves sem nenhum problema. Para torná-lo seguro, você pode restringi-lo a um domínio específico em produção, para que ninguém mais possa fazer chamadas à API de chamada a partir de qualquer nome de domínio aleatório. Para torná-lo mais seguro, remova o host local do aplicativo de produção.
BL Λ CK
1
Eu não acho que a remoção do host local da lista de permissões de seus autores faça qualquer coisa, exceto tornar os testes mais difíceis. Essa configuração não é como uma lista de permissões de IP; pense nisso mais como uma configuração do CORS. A maneira como o Firebase funciona é que essas rotas de API são chamadas diretamente de clientes, não são enviadas por proxy. É por isso que sua página da web precisa da chave da API. Se um ator ruim quiser chamar suas rotas de API do Postman, sua lista de desbloqueio de referenciadores não os interromperá. Isso é útil apenas para impedir que outros sites públicos usem seus servidores.
forresthopkinsa

Respostas:

451

A apiKey neste snippet de configuração apenas identifica seu projeto Firebase nos servidores do Google. Não é um risco de segurança para alguém conhecê-lo. De fato, é necessário que eles saibam, para interagir com o seu projeto Firebase. Esses mesmos dados de configuração também estão incluídos em todos os aplicativos iOS e Android que usam o Firebase como back-end.

Nesse sentido, é muito parecido com o URL do banco de dados que identifica o banco de dados back-end associado ao seu projeto no mesmo trecho: https://<app-id>.firebaseio.com. Veja esta pergunta sobre por que isso não representa um risco à segurança: Como restringir a modificação de dados do Firebase? , incluindo o uso das regras de segurança do servidor do Firebase para garantir que apenas usuários autorizados possam acessar os serviços de back-end.

Se você quiser aprender como proteger todos os acessos de dados aos serviços de back-end do Firebase está autorizado, leia a documentação sobre as regras de segurança do Firebase .


Se você deseja reduzir o risco de confirmar esses dados de configuração no controle de versão, considere usar a configuração automática do SDK do Firebase Hosting . Embora as chaves ainda acabem no navegador no mesmo formato, elas não serão mais codificadas no seu código com isso.

Frank van Puffelen
fonte
7
Então isso significa que outras pessoas poderiam acessar todos os dados no meu banco de dados firebase?
Emmanuel Campos
31
A resposta @EmmanuelCampos é Sim e Não. Sim, se você permitir ou desejar que outras pessoas acessem todos os dados no banco de dados. E não, se você não quiser. Banco de dados Firebase tem regras, regras que você controla
KhoPhi
5
Encontrei minha resposta aqui para minha última pergunta support.google.com/firebase/answer/6400741 Obrigado pela ajuda. Este link pode ajudar alguém no futuro.
Emmanuel Campos
7
@ m.rufca, seus dados devem estar disponíveis para usuários autenticados. E aqui está o truque. Por padrão, nas configurações da sua base de firmas, apenas o host local e os domínios do seu projeto estão autorizados a executar autenticação a partir deles. Portanto, ninguém mais pode criar um aplicativo que normalmente funcione com sua base de firmas.
Artem Arkhipov
15
e se o bot estiver criando usuários ilimitados no meu aplicativo. Como posso exigir captcha.
Muhammad Umer
79

Com base nas respostas de prufrofro e Frank van Puffelen aqui , montei essa configuração que não impede a raspagem, mas pode tornar um pouco mais difícil o uso da chave da API.

Aviso: para obter seus dados, mesmo com esse método, é possível, por exemplo, simplesmente abrir o console JS no Chrome e digitar:

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

Somente as regras de segurança do banco de dados podem proteger seus dados.

No entanto, restrinjai o uso da chave da API de produção ao meu nome de domínio da seguinte maneira:

  1. https://console.developers.google.com/apis
  2. Selecione seu projeto Firebase
  3. Credenciais
  4. Em chaves da API, escolha sua chave do navegador. Deve ter a seguinte aparência: " Chave do navegador (criada automaticamente pelo Serviço Google) "
  5. Em " Aceitar solicitações dessas referências HTTP (web sites) ", adicionar o URL do seu aplicativo (exemple: projectname.firebaseapp.com/*)

Agora, o aplicativo funcionará apenas nesse nome de domínio específico. Então, criei outra chave de API que será privada para o desenvolvimento do host local.

  1. Clique em Criar credenciais> Chave da API

Por padrão, como mencionado por Emmanuel Campos, o Firebase apenas lista de permissões localhoste o domínio de hospedagem do Firebase .


Para garantir que não publique a chave de API errada por engano, use um dos métodos a seguir para usar automaticamente a mais restrita na produção.

Configuração para Create-React-App

Em /env.development:

REACT_APP_API_KEY=###dev-key###

Em /env.production:

REACT_APP_API_KEY=###public-key###

No /src/index.js

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

Minha configuração anterior para o Webpack:

Eu uso o Webpack para criar meu aplicativo de produção e coloco minha chave de API de desenvolvimento dentro da minha, index.htmlexatamente como você faria normalmente. Em seguida, dentro do meu webpack.production.config.jsarquivo, substituo a chave toda vez que index.htmlé copiada para a compilação de produção:

plugins: [
    new CopyWebpackPlugin([
      {
        transform: function(content, path) {
          return content.toString().replace("###dev-key###", "###public-key###");
        },
        from: './index.html'
      }
    ])
  ]
agora
fonte
1
Isso está funcionando bem para você? Estava pensando em fazer o mesmo para um aplicativo Android. Eu me pergunto por que o Firebase não cobre isso na seção de segurança.
Steliosf
2
Até agora não tive nenhum problema, mas provavelmente também não houve ataques
agora
3
Isso não é mencionado no guia, porque não o protegerá da raspagem. Tudo isso garante que outra pessoa não possa criar um aplicativo Web que use sua base de firmas para ler (ou gravar) dados, se executados em um navegador normal e bem comportado.
Thoutbeckers 04/07
@thoutbeckers você está certo, obrigado. Editei a resposta, mas deixei o método, pois ainda pode ser útil.
agora
1
@FrankvanPuffelen Pelo que entendi, não faz muita diferença, mas pode tornar um pouco mais irritante abusar da sua cota, já que em um navegador bem comportado, a chave da API veiculada em HTML / JS funcionará apenas no objetivo domínio (s) e não localhost ou qualquer outra coisa. Mas concordo que a proteção adicional é marginal em comparação com o que o Firebase já oferece. Vou reformular a resposta para algo menos dramático.
agora
22

Não estou convencido de expor chaves de segurança / configuração ao cliente. Eu não chamaria isso de seguro, não porque alguém possa roubar todas as informações privadas desde o primeiro dia, porque alguém pode fazer solicitações excessivas, drenar sua cota e fazer com que você deva muito dinheiro ao Google.

Você precisa pensar em muitos conceitos, desde restringir as pessoas a não acessar onde elas não deveriam estar, ataques do DOS etc.

Eu preferiria que o cliente atingisse primeiro o seu servidor da Web, lá você coloca o que sempre é o firewall, captcha, cloudflare, segurança personalizada entre o cliente e o servidor ou entre o servidor e a base de firmas, e você está pronto para começar. Pelo menos você pode primeiro interromper a atividade suspeita antes que ela atinja a base do firebase. Você terá muito mais flexibilidade.

Eu vejo apenas um bom cenário de uso para usar a configuração baseada em cliente para usos internos. Por exemplo, você possui um domínio interno e tem certeza de que pessoas de fora não podem acessá-lo, portanto, pode configurar um ambiente como navegador -> tipo firebase.

Teoman shipahi
fonte
10
Mas não é o mesmo que "expor" qualquer outra API REST? Quero dizer, com a URL da API REST estão disponíveis para o usuário. Eles podem usar o URL para fazer as solicitações desejadas e drenar sua cota. O que o firebase faz é usar o config com chaves api para identificar sua parte do back-end, e é e deve estar disponível para o usuário fazer solicitações.
mbochynski
3
@mbochynski, mas você pode fazer solicitações diretas aos recursos que causam o pagamento da fatura. E no lado do Firebase, não há muito mecanismo de controle para impedir ataques DDoS, etc. Minha sugestão seria que o cliente chamasse sua API REST, mas que a API REST retenha as chaves da API em particular e, mesmo antes de você acessar os recursos do Firebase, valide-os se forem solicitações legítimas. (via Cloudflare etc). ou recuperar resultados do cache. Então você só atingirá os recursos do Firebase apenas se precisar. Isto é o que eu implementaria firebase.google.com/docs/admin/setup
Teoman shipahi
3
expor chaves no navegador é uma péssima idéia. para escrever todos esses guias / artigos, o que eles estavam pensando? referenciador http por segurança? que é facilmente falsificado
Nick Chan Abdullah
1
Vocês não estão pensando nisso direito. Não pense na chave da API como um segredo; não é uma chave privada, é apenas um ID para que a API do Firebase saiba quem está acessando qual projeto. Se você deseja muita flexibilidade e precisa controlar todas as etapas da interação servidor / cliente, não deve usar o Firebase, deve usar o GCP.
forresthopkinsa
@forresthopkinsa Tenho o link acima para comentar qual abordagem tomar. Ninguém aqui é ingênuo o suficiente para sugerir que é uma chave secreta.
Teoman shipahi 20/04
4

Acredito que, uma vez que as regras do banco de dados sejam escritas com precisão, será suficiente para proteger seus dados. Além disso, existem diretrizes que se pode seguir para estruturar seu banco de dados de acordo. Por exemplo, criando um nó UID sob usuários e colocando todas as informações sob ele. Depois disso, você precisará implementar uma regra de banco de dados simples, como abaixo

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

Nenhum outro usuário poderá ler os dados de outros usuários; além disso, a política de domínio restringirá as solicitações provenientes de outros domínios. Pode-se ler mais sobre isso nas regras de segurança do Firebase

Bhupiister singh
fonte
3

A exposição da chave da API cria uma vulnerabilidade quando a inscrição de usuário / senha está ativada. Há um ponto de extremidade da API aberto que pega a chave da API e permite que qualquer pessoa crie uma nova conta de usuário. Eles podem usar essa nova conta para fazer login no aplicativo protegido por autenticação do Firebase ou usar o SDK para autenticar com o usuário / passar e executar consultas.

Eu relatei isso ao Google, mas eles dizem que está funcionando conforme o esperado.

Se você não puder desativar as contas de usuário / senha, faça o seguinte: Crie uma função de nuvem para desativar automaticamente novos usuários noCriar e crie uma nova entrada de banco de dados para gerenciar seu acesso.

Por exemplo: Meus usuários / {userId} / Acesso: 0

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

Atualize suas regras para permitir apenas leituras para usuários com acesso> 1.

Na hipótese de a função de ouvinte não desabilitar a conta com rapidez suficiente, as regras de leitura os impedirão de ler quaisquer dados.

bzk
fonte
3

Depois de ler isso e depois de fazer algumas pesquisas sobre as possibilidades, criei uma abordagem um pouco diferente para restringir o uso de dados por usuários não autorizados:

Também salvo meus usuários no meu banco de dados (e também os dados do perfil). Então, eu apenas defino as regras de db assim:

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

Dessa maneira, apenas um usuário salvo anterior pode adicionar novos usuários ao banco de dados, de forma que ninguém sem uma conta possa executar operações no banco de dados. adicionar novos usuários também é possível apenas se o usuário tiver uma função especial e editar apenas pelo administrador ou pelo próprio usuário (algo como isto):

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

Você não deve expor essas informações. em público, especialmente chaves da API. Isso pode levar a um vazamento de privacidade.

Antes de tornar o site público, você deve ocultá-lo. Você pode fazer isso de 2 ou mais maneiras

  1. Codificação / ocultação complexa
  2. Basta colocar os códigos SDK do firebase na parte inferior do seu site ou aplicativo para que o firebase faça todos os trabalhos automaticamente. você não precisa colocar as chaves da API em qualquer lugar
user12449933
fonte
1
Cito o Firebase: "Copie e cole esses scripts na parte inferior da sua tag <body>, mas antes de usar qualquer serviço do Firebase", que inclui a chave da API
Luke-zhang-04