Apakah aman untuk mengekspos Firebase apiKey kepada publik?

439

The Firebase Web-App panduan menyatakan saya harus meletakkan diberikan apiKeydalam Html saya untuk menginisialisasi 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>

Dengan begitu, apiKeysemua pengunjung akan terpapar. Apa tujuan dari kunci itu dan apakah itu benar-benar dimaksudkan untuk umum?

farmio
sumber
1
Saya pikir selama Anda mengatur aturan Firebase Auth dan basis data Firebase Anda dapat memberikan info itu secara publik.
abbaf33f
Pengguna Christophe Quintard telah menambahkan tautan ke artikel yang sangat berguna dengan informasi tambahan mengenai keamanan API Firebase, jadi saya mengepos ulang di sini: javebratt.com/hide-firebase-api (Komentar akan menghilang karena dilampirkan ke pengguna lain jawaban yang ditandai untuk dihapus karena kualitas buruk)
Oliver Schafeld
Saya hanya ingin menunjukkan bahwa hanya karena kerangka kerja khusus ini baik-baik saja dengan mengekspos API itu, itu tidak berarti bahwa kerangka kerja lain tidak masalah dengan itu. Tidak ingin siapa pun meninggalkan pos ini dengan gagasan bahwa "Tidak apa-apa untuk mengekspos Kunci API" secara umum.
YungGun
Anda membuka kunci tanpa masalah. Untuk membuatnya aman, Anda dapat membatasi dengan domain tertentu dalam produksi sehingga tidak ada orang lain yang dapat membuat panggilan API dari nama domain acak. Agar lebih aman hapus localhost dari aplikasi produksi.
BL Λ CK
1
Saya tidak berpikir menghapus localhost dari daftar putih referer Anda akan melakukan apa pun kecuali mempersulit pengujian. Konfigurasi itu tidak seperti daftar putih IP; pikirkan lebih seperti konfigurasi CORS. Cara Firebase bekerja adalah bahwa rute API tersebut dipanggil langsung dari klien, mereka tidak diproksi. Itu sebabnya halaman web Anda membutuhkan kunci API. Jika aktor yang buruk ingin memanggil rute API Anda dari Postman, daftar putih pengarah Anda tidak akan menghentikannya. Ini hanya berguna untuk mencegah situs publik lain dari merobohkan server Anda.
forresthopkinsa

Jawaban:

452

ApiKey dalam cuplikan konfigurasi ini hanya mengidentifikasi proyek Firebase Anda di server Google. Ini bukan risiko keamanan bagi seseorang untuk mengetahuinya. Bahkan, mereka perlu mengetahuinya, agar mereka dapat berinteraksi dengan proyek Firebase Anda. Data konfigurasi yang sama ini juga termasuk dalam setiap aplikasi iOS dan Android yang menggunakan Firebase sebagai pendukungnya.

Dalam arti bahwa sangat mirip dengan URL database yang mengidentifikasi database back-end yang terkait dengan proyek Anda dalam potongan yang sama: https://<app-id>.firebaseio.com. Lihat pertanyaan ini tentang mengapa ini bukan risiko keamanan: Bagaimana cara membatasi modifikasi data Firebase? , termasuk penggunaan aturan keamanan sisi server Firebase untuk memastikan hanya pengguna yang berwenang yang dapat mengakses layanan backend.

Jika Anda ingin mempelajari cara mengamankan semua akses data ke layanan backend Firebase Anda diotorisasi, bacalah dokumentasi tentang aturan keamanan Firebase .


Jika Anda ingin mengurangi risiko melakukan data konfigurasi ini ke kontrol versi, pertimbangkan untuk menggunakan konfigurasi otomatis SDK dari Firebase Hosting . Meskipun kunci masih akan berakhir di browser dalam format yang sama, mereka tidak akan dikodekan ke dalam kode Anda lagi dengan itu.

Frank van Puffelen
sumber
7
Jadi itu berarti orang lain dapat mengakses semua data di basis data firebase saya?
Emmanuel Campos
31
@EmmanuelCampos Jawabannya Ya dan Tidak. Ya, jika Anda mengizinkan atau ingin orang lain mengakses semua data dalam database. Dan Tidak, jika Anda tidak menginginkannya. Basis data Firebase memiliki aturan, aturan yang Anda kontrol
KhoPhi
5
Temukan jawaban saya di sini untuk pertanyaan terakhir saya support.google.com/firebase/answer/6400741 Terima kasih atas bantuannya. Tautan ini dapat membantu seseorang di masa depan.
Emmanuel Campos
7
@ m.rufca, data Anda harus tersedia untuk pengguna, yang diautentikasi. Dan inilah triknya. Secara default, dalam pengaturan firebase Anda hanya host lokal dan domain proyek Anda yang diotorisasi untuk melakukan otentikasi darinya. Jadi tidak ada orang lain yang bisa membuat aplikasi yang biasanya akan bekerja dengan firebase Anda.
Artem Arkhipov
15
bagaimana jika bot membuat pengguna tak terbatas di aplikasi saya. Bagaimana saya bisa memerlukan captcha.
Muhammad Umer
79

Membangun jawaban prufrofro dan Frank van Puffelen di sini , saya membuat pengaturan ini yang tidak mencegah pengikisan, tetapi dapat membuatnya sedikit lebih sulit untuk menggunakan kunci API Anda.

Peringatan: Untuk mendapatkan data Anda, bahkan dengan metode ini, misalnya, cukup buka konsol JS di Chrome dan ketik:

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

Hanya aturan keamanan basis data yang dapat melindungi data Anda.

Namun demikian, saya membatasi penggunaan kunci API produksi saya untuk nama domain saya seperti ini:

  1. https://console.developers.google.com/apis
  2. Pilih proyek Firebase Anda
  3. Kredensial
  4. Di bawah kunci API, pilih kunci Browser Anda. Seharusnya terlihat seperti ini: " Kunci browser (otomatis dibuat oleh Layanan Google) "
  5. Dalam " Terima permintaan dari referer HTTP ini (situs web) ", tambahkan URL dari aplikasi Anda (contoh: projectname.firebaseapp.com/*)

Sekarang aplikasi hanya akan bekerja pada nama domain spesifik ini. Jadi saya membuat Kunci API lain yang akan bersifat pribadi untuk pengembangan localhost.

  1. Klik Buat kredensial> Kunci API

Secara default, seperti yang disebutkan oleh Emmanuel Campos, daftar putih hanya Firebase localhostdan domain hosting Firebase Anda .


Untuk memastikan saya tidak mempublikasikan kunci API yang salah secara tidak sengaja, saya menggunakan salah satu metode berikut untuk secara otomatis menggunakan yang lebih terbatas dalam produksi.

Pengaturan untuk Buat-Bereaksi-Aplikasi

Dalam /env.development:

REACT_APP_API_KEY=###dev-key###

Dalam /env.production:

REACT_APP_API_KEY=###public-key###

Di /src/index.js

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

Pengaturan saya sebelumnya untuk Webpack:

Saya menggunakan Webpack untuk membangun aplikasi produksi saya dan saya meletakkan kunci API dev saya di dalam saya index.htmlseperti yang biasa Anda lakukan. Kemudian, di dalam webpack.production.config.jsfile saya , saya mengganti kunci setiap kali index.htmldisalin ke build produksi:

plugins: [
    new CopyWebpackPlugin([
      {
        transform: function(content, path) {
          return content.toString().replace("###dev-key###", "###public-key###");
        },
        from: './index.html'
      }
    ])
  ]
sekarang
sumber
1
Apakah itu baik untuk Anda? Sedang berpikir untuk melakukan hal yang sama untuk aplikasi Android. Saya ingin tahu mengapa Firebase tidak membahasnya di bagian keamanan.
steliosf
2
Sejauh ini saya tidak punya masalah, tapi mungkin juga tidak ada serangan
sekarang
3
Ini tidak disebutkan dalam panduan mereka karena itu tidak akan melindungi Anda dari goresan. Semua ini memastikan bahwa orang lain tidak dapat membuat aplikasi web yang menggunakan firebase Anda untuk membaca (atau menulis) data, jika itu dijalankan di peramban berperilaku normal.
thoutbeckers
@thoutbeckers Anda benar, terima kasih. Saya mengedit jawabannya, tetapi meninggalkan metode karena mungkin masih berguna.
sekarang
1
@FrankvanPuffelen Dari apa yang saya pahami, itu tidak membuat perbedaan besar, tetapi dapat membuatnya sedikit lebih mengganggu untuk menyalahgunakan kuota Anda, karena di browser yang berperilaku baik, kunci API yang disajikan dengan HTML / JS hanya akan berfungsi pada yang dimaksudkan domain dan bukan localhost atau yang lainnya. Tetapi saya setuju bahwa perlindungan tambahan itu marjinal dibandingkan dengan apa yang sudah disediakan Firebase. Saya akan menulis ulang jawaban untuk sesuatu yang kurang dramatis.
sekarang
22

Saya tidak yakin untuk mengekspos kunci keamanan / konfigurasi ke klien. Saya tidak akan menyebutnya aman, bukan karena seseorang dapat mencuri semua informasi pribadi sejak hari pertama, karena seseorang dapat membuat permintaan berlebihan, dan mengeringkan kuota Anda dan membuat Anda berutang ke Google banyak uang.

Anda perlu memikirkan banyak konsep dari membatasi orang untuk tidak mengakses di tempat yang seharusnya, serangan DOS dll.

Saya lebih suka klien pertama kali akan menekan ke server web Anda, di sana Anda meletakkan apa firewall tangan pertama, captcha, cloudflare, keamanan kustom di antara klien dan server, atau antara server dan firebase dan Anda baik untuk pergi. Setidaknya Anda dapat menghentikan aktivitas yang dicurigai sebelum mencapai firebase. Anda akan memiliki lebih banyak fleksibilitas.

Saya hanya melihat satu skenario penggunaan yang baik untuk menggunakan konfigurasi berbasis klien untuk penggunaan internal. Misalnya, Anda memiliki domain internal, dan Anda cukup yakin bahwa orang luar tidak dapat mengaksesnya, sehingga Anda dapat mengatur lingkungan seperti browser -> tipe firebase.

Teoman shipahi
sumber
10
Tapi bukankah itu sama dengan "mengekspos" API REST lainnya? Maksud saya dengan REST API URL tersedia untuk pengguna. Mereka dapat menggunakan URL untuk membuat permintaan apa pun yang mereka inginkan dan mengeringkan kuota Anda. Apa yang dilakukan firebase adalah menggunakan konfigurasi dengan kunci api untuk mengidentifikasi bagian Anda dari backend dan itu dan itu harus tersedia bagi pengguna untuk membuat permintaan.
mbochynski
3
@ mbochynski tetapi Anda dapat membuat permintaan langsung ke sumber daya yang menyebabkan Anda membayar tagihan. Dan di sisi Firebase tidak ada banyak mekanisme kontrol untuk mencegah serangan DDoS dll. Saran saya adalah membiarkan klien Anda memanggil REST API Anda, tetapi REST API harus menahan Kunci API secara pribadi, dan bahkan sebelum Anda menekan sumber daya Firebase, validasi mereka jika itu adalah permintaan yang sah. (via Cloudflare dll). atau mengambil hasil dari cache. Maka Anda hanya akan menekan sumber daya Firebase Anda hanya jika perlu. Inilah yang akan saya terapkan firebase.google.com/docs/admin/setup
Teoman shipahi
3
mengekspos kunci di browser adalah ide yang buruk. mereka yang menulis semua panduan / artikel ini, apa yang mereka pikirkan? pengarah http untuk keamanan? yang mudah dipalsukan
Nick Chan Abdullah
1
Kalian tidak memikirkan hal ini dengan benar. Jangan menganggap Kunci API sebagai rahasia; itu bukan kunci pribadi, itu hanya sebuah ID sehingga API Firebase tahu siapa yang mengakses proyek apa. Jika Anda ingin banyak fleksibilitas dan Anda perlu mengontrol setiap langkah interaksi server / klien maka Anda seharusnya tidak menggunakan Firebase, Anda harus menggunakan GCP.
forresthopkinsa
@ forresthopkinsa saya memiliki tautan di atas komentar pendekatan apa yang harus diambil. Tidak seorang pun di sini yang cukup naif untuk menyarankan itu adalah kunci rahasia sama sekali.
Teoman shipahi
4

Saya percaya begitu aturan basis data ditulis secara akurat, itu akan cukup untuk melindungi data Anda. Selain itu, ada pedoman yang bisa diikuti untuk menyusun database Anda sesuai. Misalnya, membuat simpul UID di bawah pengguna, dan meletakkan semua informasi di bawahnya. Setelah itu, Anda perlu menerapkan aturan basis data sederhana seperti di bawah ini

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

Tidak ada pengguna lain yang dapat membaca data pengguna lain, apalagi, kebijakan domain akan membatasi permintaan yang datang dari domain lain. Seseorang dapat membaca lebih lanjut tentang itu pada aturan Firebase Security

Bhupiister singh
sumber
3

Eksposur kunci API menciptakan kerentanan saat pendaftaran pengguna / kata sandi diaktifkan. Ada titik akhir API terbuka yang mengambil kunci API dan memungkinkan siapa pun untuk membuat akun pengguna baru. Mereka kemudian dapat menggunakan akun baru ini untuk masuk ke aplikasi Firebase Auth yang Anda lindungi atau menggunakan SDK untuk auth dengan pengguna / pass dan menjalankan kueri.

Saya sudah melaporkan ini ke Google tetapi mereka mengatakan itu berfungsi sebagaimana mestinya.

Jika Anda tidak dapat menonaktifkan akun pengguna / kata sandi Anda harus melakukan yang berikut: Membuat fungsi cloud untuk secara otomatis menonaktifkan pengguna baru diCreate dan membuat entri DB baru untuk mengelola akses mereka.

Contoh: MyUsers / {userId} / Akses: 0

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

Perbarui aturan Anda untuk hanya mengizinkan bacaan untuk pengguna dengan akses> 1.

Jika fungsi pendengar tidak menonaktifkan akun dengan cukup cepat maka aturan baca akan mencegah mereka membaca data apa pun.

bzk
sumber
3

Setelah membaca ini dan setelah saya melakukan riset tentang kemungkinan, saya datang dengan pendekatan yang sedikit berbeda untuk membatasi penggunaan data oleh pengguna yang tidak sah:

Saya menyimpan pengguna saya di DB saya juga (dan menyimpan data profil di sana). Jadi saya hanya mengatur aturan db seperti ini:

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

Dengan cara ini hanya pengguna yang disimpan sebelumnya dapat menambahkan pengguna baru di DB sehingga tidak ada cara siapa pun tanpa akun dapat melakukan operasi pada DB. juga menambahkan pengguna baru hanya mungkin jika pengguna memiliki peran khusus dan hanya mengedit oleh admin atau oleh pengguna itu sendiri (seperti ini):

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

Anda tidak boleh mengekspos info ini. di depan umum, khususnya kunci api. Ini dapat menyebabkan kebocoran privasi.

Sebelum membuat situs web menjadi publik, Anda harus menyembunyikannya. Anda dapat melakukannya dengan 2 cara atau lebih

  1. Pengodean / persembunyian yang kompleks
  2. Cukup letakkan kode SDK firebase di bagian bawah situs web atau aplikasi Anda sehingga firebase secara otomatis berfungsi. Anda tidak perlu meletakkan kunci API di mana pun
pengguna12449933
sumber
1
Saya mengutip dari Firebase, "Salin dan rekatkan skrip ini ke bagian bawah tag <body> Anda, tetapi sebelum Anda menggunakan layanan Firebase apa pun," yang mencakup kunci API
Luke-zhang-04