Чи безпечно експонувати Firebase apiKey перед громадськістю?


438

Посібник для веб-додатків Firebase зазначає, що я повинен вкласти дані 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

Користувач Крістоф Квінтар додав посилання на дуже корисну статтю з додатковою інформацією щодо безпеки API Firebase, тому я репостую тут: javebratt.com/hide-firebase-api (коментар зникне, оскільки він додається до іншого користувача відповідь, яка позначена для видалення через низьку якість)
Олівер Шафельд

Я просто хочу зазначити, що лише тому, що ця конкретна рамка виявляється чудовою, коли виставляти API, це не означає, що інші рамки з нею в порядку. Не хотілося б, щоб хтось відходив від цієї публікації з думкою про те, що "Непогано викрити ключі API" взагалі.
YungGun

ви виставляєте ключі без проблем. Щоб зробити це безпечним, ви можете обмежити його певним доменом у виробництві, так що ніхто інший не може здійснювати дзвінки API з будь-якого випадкового доменного імені. Щоб зробити це більш безпечним, видаліть localhost з виробничого додатку.
BL Λ CK

1
Я не думаю, що видалення localhost з білого списку рефератів не буде робити нічого, крім того, щоб зробити складніше тестування. Ця конфігурація не схожа на білий список IP-адрес; думайте про це більше, як конфігурацію CORS. Те, як працює Firebase, полягає в тому, що ті маршрути API викликаються безпосередньо від клієнтів, вони не мають проксі-сервера. Ось чому для вашої веб-сторінки потрібен ключ API. Якщо поганий актор хоче зателефонувати на ваші маршрути API від Postman, ваш список рефералів не зупинить їх. Це корисно лише для того, щоб інші загальнодоступні веб-сайти не могли перебирати ваші сервери.
forresthopkinsa

Відповіді:


451

ApiKey у цьому фрагменті конфігурації просто ідентифікує ваш Firebase проект на серверах Google. Для когось це не є ризиком для безпеки. Насправді їм потрібно це знати, щоб вони взаємоділи з вашим проектом Firebase. Ці ж дані конфігурації також містяться у кожному додатку для iOS та Android, який використовує Firebase як резервний.

У цьому сенсі він дуже схожий на URL бази даних , який ідентифікує серверну базу даних , пов'язаних з вашим проектом в тому ж фрагменті коду: https://<app-id>.firebaseio.com. Дивіться це питання про те, чому це не є ризиком безпеки: як обмежити зміну даних Firebase? , включаючи використання правил безпеки серверної бази Firebase, щоб забезпечити доступ до сервісів сервера лише авторизованим користувачам.

Якщо ви хочете дізнатися, як забезпечити доступ до всіх даних до ваших серверних сервісів Firebase, ознайомтеся з документацією щодо правил безпеки Firebase .


Якщо ви хочете зменшити ризик здійснення цих даних конфігурації для контролю версій, подумайте про використання автоматичної конфігурації SDK хостингу Firebase . Хоча ключі все ще залишатимуться в браузері в тому самому форматі, з цим вони вже не будуть жорстко закодовані у ваш код.


7
Отже, це означає, що інші люди зможуть отримати доступ до всіх даних у моїй базі даних firebase?
Еммануель Кампос

31
@EmmanuelCampos Відповідь - так і ні. Так, якщо ви дозволяєте або хочете, щоб інші люди отримували доступ до всіх даних у базі даних. І ні, якщо ви цього не хочете. У базі даних Firebase є правила, якими ви керуєте
KhoPhi

5
Тут я знайшов свою відповідь на останнє запитання support.google.com/firebase/answer/6400741 Дякую за допомогу. Це посилання може допомогти комусь у майбутньому.
Еммануель Кампос

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

15
що робити, якщо бот створює необмежену кількість користувачів у моїй програмі. Як я можу вимагати капчу.
Мухаммед Умер

79

Спираючись на відповіді пруфрофро та Френка ван Пуффелена тут , я зібрав цю програму, яка не запобігає вискоблюванню, але може трохи ускладнити використання вашого ключа 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, який буде приватним для розробки localhost.

  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 для створення свого виробничого додатка, і я кладу свій ключ розробки 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 тощо.

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

Я бачу лише один хороший сценарій використання для використання конфігурації клієнта для внутрішніх звичаїв. Наприклад, у вас є внутрішній домен, і ви впевнені, що сторонні люди не можуть отримати доступ туди, тому ви можете налаштувати середовище, наприклад тип браузера -> firebase.


10
Але хіба це не те саме, що "виставляти" будь-який інший API REST? Я маю на увазі, що URL-адреса REST API доступна користувачеві. Вони можуть скористатися URL-адресою, щоб зробити будь-які запити та зцілити вашу квоту. Що потрібно зробити, це використовувати config з клавішами api для ідентифікації вашої частини бекенда, і це має бути доступне для користувача, щоб робити запити.
mbochynski

3
@mbochynski, але ви можете дещо робити прямі запити до ресурсів, які викликають оплату рахунку. І з боку Firebase існує не так багато механізму управління для запобігання DDoS-атак тощо. Моя пропозиція полягає в тому, щоб дозволити вашому клієнту зателефонувати на ваш REST API, але цей REST API повинен мати приватні ключі API, і навіть до того, як ви натиснете ресурси Firebase, валідайте їх якщо вони є законними проханнями. (через Cloudflare тощо). або отримати результати з кешу. Тоді ви будете потрапляти лише на свої ресурси Firebase, лише якщо вам буде потрібно. Це те, що я б реалізував firebase.google.com/docs/admin/setup
Теоман шипахі

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

1
Ви, хлопці, не думаєте про це правильно. Не думайте про ключ API як секрет; це не приватний ключ, це лише ідентифікатор, тому Firebase API знає, хто має доступ до якого проекту. Якщо ви хочете отримати велику гнучкість і вам потрібно контролювати кожен крок взаємодії сервер / клієнт, тоді ви не повинні використовувати Firebase, ви повинні використовувати GCP.
forresthopkinsa

@forresthopkinsa У мене є посилання вище, коментуючи, який підхід слід використовувати. Тут ніхто не є наївним, щоб припустити, що це секретний ключ.
Теоман шипахі

4

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

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

Жоден інший користувач не зможе читати дані інших користувачів, крім того, політика домену обмежує запити, що надходять з інших доменів. Більше про це можна прочитати в правилах безпеки Firebase


3

Експозиція ключа API створює вразливість, коли ввімкнено реєстрацію користувача / пароля. Існує відкрита кінцева точка API, яка бере ключ API і дозволяє будь-кому створити новий обліковий запис користувача. Потім вони можуть використовувати цей новий обліковий запис для входу у вашу захищену програму Firebase Auth або використовувати SDK для авторизації з користувачем / проходом та запуском запитів.

Я повідомив про це в Google, але вони кажуть, що це працює за призначенням.

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

Наприклад: MyUsers / {userId} / Доступ: 0

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

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

Випадково функція слухача не вимикає обліковий запис досить швидко, тоді правила читання не дозволять їм читати будь-які дані.


3

Прочитавши це, і після того, як я провів кілька досліджень щодо можливостей, я придумав дещо інший підхід до обмеження використання даних сторонніми користувачами:

Я також зберігаю своїх користувачів у своїй БД (і зберігаю там дані профілю). Тому я просто встановив правила db таким чином:

".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. Це може призвести до витоку конфіденційності.

Перш ніж оприлюднити веб-сайт, його слід приховати. Зробити це можна двома або більше способами

  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.