Безопасно ли выставлять apiKey Firebase широкой публике?


439

Руководство Firebase Web-App гласит, что я должен поместить данные apiKeyв мой HTML, чтобы инициализировать 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>

Таким образом, apiKeyон открыт для каждого посетителя. Какова цель этого ключа и действительно ли он должен быть публичным?


1
Я думаю, что пока вы настраиваете правила для баз данных Firebase Auth и Firebase, вы можете обнародовать эту информацию.
abbaf33f

Пользователь Christophe Quintard добавил ссылку на очень полезную статью с дополнительной информацией, касающейся безопасности API Firebase, поэтому я публикую его здесь: javebratt.com/hide-firebase-api (Комментарий исчезнет, ​​поскольку он прикреплен к другому пользователю ответ, помеченный для удаления из-за низкого качества)
Оливер Шафельд,

Я просто хочу отметить, что только потому, что этот конкретный фреймворк подходит для предоставления своего API, это не означает, что другие фреймворки в порядке с ним. Не хотелось бы, чтобы кто-нибудь уходил от этого поста с идеей, что «это нормально, выставлять ключи API» в целом.
ЮнгГун

Вы выставляете ключи без проблем. Чтобы сделать его безопасным, вы можете ограничить его конкретным доменом в производстве, чтобы никто другой не мог сделать вызов API-вызова из любого случайного доменного имени. Для большей безопасности удалите localhost из производственного приложения.
BL Λ CK

1
Я не думаю, что удаление localhost из белого списка рефералов сделает что-либо, кроме как усложнить тестирование. Эта конфигурация не похожа на белый список IP-адресов; думать об этом больше как конфиг CORS. Firebase работает так, что эти API-маршруты вызываются напрямую от клиентов, а не через прокси. Вот почему вашей веб-странице нужен ключ API. Если плохой актер хочет вызвать ваши API-маршруты из Почтальона, ваш белый список рекомендателей не остановит их. Это полезно только для предотвращения отключения других публичных сайтов от ваших серверов.
Форрестхопкинса

Ответы:


452

ApiKey в этом фрагменте конфигурации просто идентифицирует ваш проект Firebase на серверах Google. Это не риск для безопасности, чтобы кто-то это знал. На самом деле, им необходимо это знать, чтобы они могли взаимодействовать с вашим проектом Firebase. Эти же данные конфигурации также включены в каждое приложение для iOS и Android, которое использует Firebase в качестве своего бэкэнда.

В этом смысле он очень похож на URL базы данных , который идентифицирует серверную базу данных , связанных с вашим проектом в том же фрагменте кода: https://<app-id>.firebaseio.com. См. Этот вопрос о том, почему это не представляет угрозы для безопасности: как ограничить изменение данных Firebase? включая использование правил безопасности Firebase на стороне сервера, чтобы гарантировать, что только авторизованные пользователи могут получить доступ к внутренним службам.

Если вы хотите узнать, как обеспечить безопасный доступ ко всем данным к вашим внутренним службам Firebase, ознакомьтесь с документацией по правилам безопасности Firebase .


Если вы хотите снизить риск передачи этих данных конфигурации в систему управления версиями, рассмотрите возможность автоматической настройки SDK Firebase Hosting . Хотя ключи по-прежнему будут отображаться в браузере в том же формате, они больше не будут жестко закодированы в вашем коде.


7
Значит, другие люди смогут получить доступ ко всем данным в моей базе данных Firebase?
Эммануэль Кампос

31
@EmmanuelCampos Ответ - Да и Нет. Да, если вы разрешите или хотите, чтобы другие люди имели доступ ко всем данным в базе данных. И нет, если вы не хотите, чтобы они. База данных Firebase содержит правила, правила, которыми вы управляете
KhoPhi

5
Здесь я нашел ответ на мой последний вопрос support.google.com/firebase/answer/6400741 Спасибо за помощь. Эта ссылка может помочь кому-то в будущем.
Эммануэль Кампос

7
@ m.rufca, ваши данные должны быть доступны для пользователей, прошедших аутентификацию. А вот и хитрость. По умолчанию в ваших настройках firebase только localhost и домены вашего проекта имеют право выполнять аутентификацию на них. Так что никто другой не может создать приложение, которое будет нормально работать с вашей базой данных.
Артем Архипов

15
Что делать, если бот создает неограниченное количество пользователей в моем приложении. Как я могу потребовать капчу.
Мухаммед Умер

79

Основываясь на ответах prufrofro и Франк ван Puffelen здесь , я соединял эту установку , которая не мешает выскабливание, но может сделать это немного сложнее использовать ключ API.

Предупреждение. Чтобы получить данные, даже с помощью этого метода, можно, например, просто открыть консоль JS в Chrome и ввести:

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

Только правила безопасности базы данных могут защитить ваши данные.

Тем не менее, я ограничил использование моего производственного API-ключа для моего доменного имени следующим образом:

  1. https://console.developers.google.com/apis
  2. Выберите свой проект Firebase
  3. полномочия
  4. В разделе «Ключи API» выберите ключ браузера. Это должно выглядеть так: « Ключ браузера (автоматически создается сервисом Google) »
  5. В « Принимать запросы от этого HTTP рекомендателей (веб - сайты) », добавьте URL вашего приложения (Exemple: projectname.firebaseapp.com/*)

Теперь приложение будет работать только на этом конкретном доменном имени. Поэтому я создал еще один API-ключ, который будет закрыт для разработки на локальном хосте.

  1. Нажмите Создать учетные данные> Ключ API

По умолчанию, как отметил Эммануэль Кампос, Firebase только белые списки localhostи ваш хостинг домен Firebase .


Чтобы убедиться, что я не опубликую неправильный ключ API по ошибке, я использую один из следующих методов, чтобы автоматически использовать более ограниченный в работе.

Настройка для Create-React-App

В /env.development:

REACT_APP_API_KEY=###dev-key###

В /env.production:

REACT_APP_API_KEY=###public-key###

В /src/index.js

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

Моя предыдущая настройка для Webpack:

Я использую Webpack для создания своего производственного приложения и помещаю свой ключ dev API в свой, index.htmlкак вы это обычно делаете. Затем внутри моего webpack.production.config.jsфайла я заменяю ключ каждый раз, когда index.htmlкопируюсь в рабочую сборку:

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

1
Это работает хорошо для вас? Думал сделать то же самое для приложения для Android. Интересно, почему Firebase не освещает это в разделе о безопасности.
steliosf

2
У меня не было никаких проблем до сих пор, но , вероятно , не нападения либо
настоящее время

3
Это не упоминается в их руководстве, потому что это не защитит вас от соскабливания. Все это гарантирует, что кто-то другой не сможет создать веб-приложение, которое использует вашу базу данных для чтения (или записи) данных, если оно запущено в обычном браузере с хорошим поведением.
thoutbeckers

@ thoutbeckers ты прав, спасибо. Я отредактировал ответ, но оставил метод, поскольку он все еще может быть полезен.
сейчас

1
@FrankvanPuffelen Из того, что я понимаю, это не имеет большого значения, но может немного усложнить злоупотребление вашей квотой, так как в браузере с хорошим поведением ключ API, предоставляемый с HTML / JS, будет работать только по назначению домен (ы), а не localhost или что-нибудь еще. Но я согласен, что дополнительная защита является незначительной по сравнению с тем, что уже обеспечивает Firebase. Я перефразирую ответ на что-то менее драматичное.
сейчас

22

Я не убежден, чтобы выставить ключи безопасности / конфигурации клиенту. Я бы не назвал это безопасным, не потому, что кто-то может украсть всю личную информацию с первого дня, потому что кто-то может сделать чрезмерный запрос, истощить вашу квоту и заставить вас задолжать Google много денег.

Вам нужно подумать о многих концепциях: от ограничения доступа людей к месту, где они не должны быть, до DOS-атак и т. Д.

Я бы предпочел, чтобы клиент сначала попадал на ваш веб-сервер. Там вы устанавливаете межсетевой экран, капчу, облачный флаг, настраиваемую безопасность между клиентом и сервером или между сервером и базой данных, и вы готовы к работе. По крайней мере, вы можете сначала остановить подозрительную активность, прежде чем она достигнет базы огня. У вас будет гораздо больше гибкости.

Я вижу только один хороший сценарий использования клиентского конфига для внутреннего использования. Например, у вас есть внутренний домен, и вы почти уверены, что посторонние не могут получить к нему доступ, поэтому вы можете настроить среду, такую ​​как browser -> firebase type.


10
Но разве это не то же самое, что «разоблачение» любого другого REST API? Я имею в виду с REST API URL доступны для пользователя. Они могут использовать URL-адрес для выполнения любых запросов и истощать вашу квоту. Что делает Firebase, так это использует config с ключами api для идентификации вашей части бэкэнда, и он должен быть доступен пользователю для отправки запросов.
Мбочинский

3
@mbochynski, но вы можете сделать несколько прямых запросов к ресурсам, которые заставляют вас платить по счетам. А на стороне Firebase не так уж много механизма контроля для предотвращения DDoS-атак и т. Д. Я бы предложил, чтобы ваш клиент вызывал ваш REST API, но чтобы REST API содержал ключи API в частном порядке, и даже до того, как вы нажмете ресурсы Firebase, проверьте их. если они законные запросы. (через Cloudflare и т. д.). или получить результаты из кеша. Тогда вы будете использовать только ресурсы Firebase, только если вам это нужно. Это то, что я хотел бы реализовать firebase.google.com/docs/admin/setup
Теоман Шипахи

3
разоблачение ключей в браузере - очень плохая идея. те, кто пишет все эти руководства / статьи, что они думают? http реферер для безопасности? это легко подделать
Ник Чан Абдулла

1
Вы, ребята, не думаете об этом правильно. Не думайте, что ключ API является секретом; это не закрытый ключ, это просто идентификатор, поэтому API Firebase знает, кто имеет доступ к какому проекту. Если вам нужна большая гибкость и вам нужно контролировать каждый шаг взаимодействия сервер / клиент, то вам не следует использовать Firebase, вы должны использовать GCP.
Форрестхопкинса

@forresthopkinsa У меня есть ссылка выше, комментарий, какой подход выбрать. Никто здесь не настолько наивен, чтобы предположить, что это вообще секретный ключ.
Теоман Шипахи

4

Я верю, что если правила базы данных написаны правильно, этого будет достаточно для защиты ваших данных. Кроме того, есть рекомендации, которым можно следовать, чтобы соответствующим образом структурировать вашу базу данных. Например, создание узла UID под пользователями и размещение всех под информацией. После этого вам нужно будет реализовать простое правило базы данных, как показано ниже

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

Ни один другой пользователь не сможет читать данные других пользователей, более того, политика домена будет ограничивать запросы, поступающие из других доменов. Подробнее об этом можно прочитать в правилах Firebase Security.


3

Использование ключа API создает уязвимость при включении регистрации пользователя / пароля. Существует открытая конечная точка API, которая принимает ключ API и позволяет любому пользователю создавать новую учетную запись пользователя. Затем они могут использовать эту новую учетную запись для входа в приложение, защищенное аутентификацией Firebase, или использовать SDK для авторизации с запросами user / pass и run.

Я сообщил об этом в Google, но они говорят, что он работает как задумано.

Если вы не можете отключить учетные записи пользователей и паролей, вы должны сделать следующее: Создать облачную функцию для автоматического отключения новых пользователей onCreate и создать новую запись в БД для управления их доступом.

Пример: MyUsers / {userId} / Доступ: 0

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

Обновите свои правила, чтобы разрешить чтение только пользователям с доступом> 1.

При случайном отключении функция слушателя не отключает учетную запись достаточно быстро, тогда правила чтения не позволят им прочитать какие-либо данные.


3

Прочитав это и после того, как я провел небольшое исследование о возможностях, я предложил немного другой подход к ограничению использования данных неавторизованными пользователями:

Я также сохраняю своих пользователей в своей БД (и сохраняю там данные профиля). Поэтому я просто установил правила БД следующим образом:

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

Таким образом, только предыдущий сохраненный пользователь может добавлять новых пользователей в БД, так что никто без учетной записи не может выполнять операции с БД. добавление новых пользователей также возможно только в том случае, если пользователь имеет особую роль и редактирует только администратор или сам этот пользователь (что-то вроде этого):

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

-2

Вы не должны раскрывать эту информацию. публично, особенно API-ключи. Это может привести к утечке конфиденциальности.

Перед тем как сделать сайт общедоступным, вы должны его скрыть. Вы можете сделать это 2 или более способами

  1. Комплексное кодирование / сокрытие
  2. Просто поместите коды SDK Firebase в нижней части вашего веб-сайта или приложения, таким образом, Firebase автоматически сделает все работы. вам не нужно никуда класть ключи API

1
Я цитирую из Firebase: «Скопируйте и вставьте эти сценарии в конец тега <body>, но перед тем, как использовать какие-либо службы Firebase», который включает в себя ключ API
Luke-zhang-04
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.