Безопасно ли публиковать Firebase apiKey?

руководство Firebase Web-App утверждает, что я должен поместить данный apiKey в свой Html для инициализации firebase:

// TODO: Replace with your project 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

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

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

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

Ответ 2

Опираясь на ответы Пруфрофро и Фрэнка ван Пуффелена здесь, я собрал это решение, которое не предотвращает очистку, но может затруднить использование вашего ключа 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 своего приложения (пример: 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'
      }
    ])
  ]

Ответ 3

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

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

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

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

Ответ 4

Использование ключа 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.

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