最近Compass漁ってNuxt+Firebase とかReactNative(Expo)+FirebaseとかのHands-onに色々と参加していました。
フレームワークで生成した静的ファイル(HTML+CSS+JavaScript)をFirebaseやNetlifyにデプロイすれば簡単にFirebaseと連動したWEBサービス・アプリがが作れてマジヤバイ (語彙力 という感じです。
しかしながら僕のような古(いにしえ)のほうむぺぃじ作ってきたマンとしては、firebaseとか従量課金だと設定漏れて悪用されたらパケ死しない???という不安もあり、生成されたものがブラックボックスなままでは
- 静的ファイルならどうやってFirebaseと接続してるの?
- 接続に必要な設定ファイルはどういう扱いになっているんだろう?
- JavaScriptで読み込むとローカル側に設定ファイルDLするよね?
というような疑問が残ったままになっていました。
Nuxt generate で生成された静的ファイルの中身
Nuxtが吐き出した静的ファイルのディレクトリdist
内でagコマンド(The Silver Searcher)を使ってfirebase apiKeyを検索。
-l
オプションを付けるとマッチしたファイル名だけ返してくれます。
$ cd dist $ ag -l <firebase apiKey> _nuxt/cf55170e35703f7a131c.js
nuxt generate
で生成されたJavaScriptファイルに.env
に書いてたFirebaseの接続情報がバンドルされているようです。
firebase serve
コマンドを実行すると、Firebaseのdeploy先に指定していたディレクトリをルートにしたローカルサーバーで確認ができるようです。
これで先程のfirebase apiKey
が含まれているファイルが使用されているか見てみます。
$ firebase serve
i hosting: Serving hosting files from: dist
✔ hosting: Local server: http://localhost:5000
ブラウザhttp://localhost:5000
にアクセスして、devtoolを開いて確認します。
読み込まれていました。
やはり静的化されたものでは直接設定ファイルを読み込んでFirebaseにアクセスしているようです。
Firebase Hosting だと接続情報はそもそも見ることが出来る
Firebase Hostingを使っているとhttps://{Hosting Domain}/__/firebase/init.json
で接続情報が見れるみたいです。
Firebase Hosting は、
/__
で始まるサイトの URL を予約します。この予約された名前空間により、Firebase Hosting と他の Firebase 機能を簡単に同時利用できます。予約済みの URL は、デプロイ時だけでなく、firebase serve をローカルで実行したときにも利用されます。
SDK の自動構成
SDK 自体をホスティングするだけでなく、予約済みの名前空間では、Firebase Hosting サイトに関連するプロジェクトの SDK の初期化に必要な構成も提供されます。これは、直接追加できるスクリプトとして提供されます。
<!-- load Firebase SDK before loading this file --> <script src="/__/firebase/init.js"></script>
アプリケーション側からCloud Firestoreに新しいコレクションを作成することが出来るのか?
接続情報は誰でも見れる状態なので、テストモードの誰でも読み書きできるデータベース設定・ドメインのホワイトリストを設定していない状態で、アプリケーション側からCloud Firestoreに新しいコレクションを作成できるのか調べてみました。
https://{Hosting Domain}/__/firebase/init.json
で取得できた接続情報を元に次のような存在しないコレクションevil-table
にデータを追加しようとするスクリプトのあるHTMLを作成しました。
<html> <body> <script src="https://www.gstatic.com/firebasejs/5.8.0/firebase.js"></script> <script src="https://www.gstatic.com/firebasejs/4.12.1/firebase-firestore.js"></script> <script> // Initialize Firebase var config = { apiKey: "<init.jsonにあるapiKey>", databaseURL: "<init.jsonにあるdatabaseURL>", storageBucket: "<init.jsonにあるstorageBucket>", authDomain: "<init.jsonにあるauthDomain>", messagingSenderId: "<init.jsonにあるmessagingSenderId>", projectId: "<init.jsonにあるprojectId>" }; firebase.initializeApp(config); const db = firebase.firestore(); // 存在しないコレクションにデータを追加してみる db.collection("evil-table").add({ name: 'new item' }) .then((res) => console.log("Document written with ID: ", res.id)) .catch((err) => console.error("Error adding document: ", err)) </script> </body> </html>
これを適当なドメインを割り当てているサーバにおいてアクセスしてみます。
コンソールをみてみると...
> Document written with ID: QHHn09EqgvNvZxSifBdU
データ作れてるっぽい。
FirebaseコンソールにアクセスしてDatabaseの項目を見てみます。
データ作られちゃってますね... (゚∀゚)アヒャャャャャャ
だでれも読み書きできるテストモードのままだと、誰でも新しいDBのテーブルが作れるちゃうので他人のFirebaseアカウントに寄生したアプリとか作れちゃうのでは🤔
Firebase の接続情報より権限設定の方が重要っぽい
Firebase リリース チェックリスト
WEB: 不正使用を防ぐためのドメインのホワイトリストを追加します。 - Google Developer Console のブラウザ API キーとクライアント ID の運用環境ドメインをホワイトリストに登録 - Firebase コンソール パネルの [Auth] タブにある運用環境ドメインをホワイトリストに登録
Cloud Firestore
意図しないデータアクセスを防ぐためにセキュリティ ルールを構成します。
出典: Firebase Launch Checklist | Firebase
cf.
The apiKey essentially just identifies your Firebase project on the Google servers. It is not a security risk for someone to know it. In fact, it is necessary for them to know it, in order for them to interact with your Firebase project.
In that sense it is very similar to the database URL that Firebase has historically been used to identify the back-end:https://<app-id>.firebaseio.com
. See this question on why this is not a security risk: How to restrict Firebase data modification?, including the use of Firebase's server side security rules to ensure only authorized users can access the backend services.
出典: javascript - Is it safe to expose Firebase apiKey to the public? - Stack Overflow
まとめ
Hands-onで静的ファイルの場合は設定ファイルをサーバーに上げて直接アクセスはできなくする。FirebaseにHostingする場合はFirebase側に設定があるから不要。Nuxtの場合はプロジェクト生成時に.env
やdist/*
が自動的に.gitignore
されるのでFirebaseの設定ファイルがGitHubに上がったりすることはないので安心と聞いていたのですが、そもそもFirebaseの設定は見れても問題がなくて、むしろCloud Firestoreのルール設定や不正使用を防ぐためのドメインのホワイトリストの設定の方が重要な印象を受けました。接続情報のモーダルがそもそも、scriptタグに囲まれたのをHTMLに貼り付けてくださいって出てきてますものね...
なのでHands-onなどでDatabaseはテストモードのままサクッと作ったアプリを雑に公開していていたり、接続情報が入ったファイルをGitHubにpushしていたりして、悪意のある誰かに見つかってしまうと接続情報からDBに寄生したアプリに利用されたり、遊び半分に大量のデータを投稿するボット作られちゃったりで、パケ死する可能性がなくもないのでは?と感じました。
サクッとアプリが作れるのはすごいのですが、Cloud Firestoreのルール設定やFirebaseの請求のアラート設定などは、公開をゴールにするHands-onならしっかり説明しておいて欲しいなって思いました。
Firebaseセキュリティ設定のHands-onぜひ開催してください!!
[参考]
firebaseの設定関連の参考サイト
- 予約された URL | Firebase
- Firebaseの小ネタ集 - Qiita
- javascript - Is it safe to expose Firebase apiKey to the public? - Stack Overflow
- security - How to restrict Firebase data modification? - Stack Overflow
- Firebase Launch Checklist | Firebase
- Understand Firebase Security Rules for Cloud Storage | Firebase
他
- connpass - エンジニアをつなぐIT勉強会支援プラットフォーム
- Firebase
- Netlify: All-in-one platform for automating modern web projects.
- The Silver Searcher のススメ - Qiita
- 作者: 小笠原みつき,西村公宏,柳佳音,志甫侑紀,池田友洋,木村涼平,?橋優介,大塚雅和,飯塚直,吉川竜太,末永恭正,久保田祐史,浜田真成,穴井宏幸,大島一将,桑原仁雄,牧大輔,池田拓司,はまちや2,竹原,WEB+DB PRESS編集部
- 出版社/メーカー: 技術評論社
- 発売日: 2018/06/23
- メディア: 単行本
- この商品を含むブログを見る
実践Expo React NativeとFirebaseで、SNSアプリを最速ストアリリース! (NextPublishing)
- 作者: 前田翼,渡邊雄,中川幸哉
- 出版社/メーカー: インプレスR&D
- 発売日: 2018/12/14
- メディア: オンデマンド (ペーパーバック)
- この商品を含むブログを見る
プログラマのためのGoogle Cloud Platform入門 サービスの全体像からクラウドネイティブアプリケーション構築まで
- 作者: 阿佐志保,中井悦司
- 出版社/メーカー: 翔泳社
- 発売日: 2017/06/02
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る