ゼスト Tech Blog

ゼストは「護りたい。その想いを護る。」をミッションに、在宅医療・介護業界向けのSaaSを開発しています。

Firebaseのセキュリティについて - そのAPI キー本当に公開しても大丈夫ですか?

Firebaseは多機能かつ使い勝手も良いため、mBaaSやFirebase Authentication/Identity PlatformをIDaaSとして利用している方も多いのではないでしょうか。
ただし便利な反面、考慮が不足していると、意図しないセキュリティの穴を招いてしまうことがあります。

Firebaseを安全に利用するため、考慮すべき観点について下記にまとめます。

Firebase セキュリティチェックシート

Firebase側で考慮すべき点について、セキュリティチェックシートとして既にまとめてくれているので、プロダクションで公開する前にこちらは必ず確認しましょう。

firebase.google.com

また脆弱性診断サービスを提供している Flatt Security社でも利用時のよくある脆弱性とその対策について、記事をまとめてくださっているので、こちらも参照しておくとよいかもしれません。

blog.flatt.tech

Firebase API キーの公開について

これまで何万回も同様のことについて語っている記事が存在しているように、基本的には公開しても問題ないです。
上記のセキュリティチェックシートでも

Firebase は、アプリの Firebase プロジェクトを Firebase サービスに対して識別する目的でのみ API キーを使用します。(中略) このため、Firebase サービスの API キーをシークレットとして扱う必要はなく、クライアント コードに安全に埋め込むことができます。

として問題ない旨を記載しています。

ただし、同じプロジェクトで他の従量課金系APIを有効化 している場合には注意が必要です。

例として、Firebaseを有効化しているGCPプロジェクトでGoogle Maps Platformも有効化しているケースを紹介します。

Google Maps Platformの管理画面で 「鍵と認証情報」 を確認してみましょう。 API キーとして Browser key (auto created by Firebase) が存在しています。

鍵と認証情報

このAPI キーは制限がかかっておらず、注意マークが表示されています。また鍵を表示するとFirebaseのAPI キーと同一であることが確認できると思います。
このAPIキーを利用してGeocoding APIを呼んでみましょう。

import { Client } from "@googlemaps/google-maps-services-js";

const client = new Client({});
const key = process.env.GOOGLE_MAPS_API_KEY as string;

async function main() {
  const response = await client.geocode({
    params: {
      address: "東京都千代田区内幸町2丁目1番地6号 日比谷パークフロント19階",
      key: key,
    },
  });
  const result = JSON.stringify(response.data.results[0].geometry.location);
  console.log(result);
}

main();
$ export GOOGLE_MAPS_API_KEY=xxxxxxxxxxxxxxxxx
$ ts-node main.ts | jq.
{
  "lat": 35.6708752,
  "lng": 139.7536284
}

Google Maps PlatformのAPIキーとして登録されているので、当たり前ですが、FirebaseのAPIキーでもGoogle Maps PlatformのAPIをコールすることができました。

このようにFirebaseのAPIキーとして公開したつもりでも、公開したキーを用いて他の従量課金系サービスに利用される可能性 があります。
上記の考慮が不足していると、他者に従量課金サービスを不正に利用され、自分/自社では利用していないにも関わらず、多額の請求を受け取るリスクが存在します。

どのようにすればよいか?

実はこちらもFirebaseのドキュメントに記載されています。

firebase.google.com

Firebase サービスの API キーをコードに含めることは安全ですが、API キーに関して制限を適用しなければならない特定のケースもあります。たとえば、Firebase ML を使用している場合や、メールアドレスとパスワードによるログイン手法で Firebase Authentication を使用している場合、または課金対象の Google Cloud APIs を使用している場合などがこれに該当します。

ドキュメントの通り、APIキーに関して制限を設定することで、上記で挙げたリスクを回避することができます。

APIキーに制限を設定

API キーの詳細画面でAPIに制限を設定することができます。

APIキーの詳細画面

アプリケーション用の制限を設定することはもちろん、利用するAPIについても制限することが望ましいです。*1 Firebase Authentication/Identity Platformを利用する場合は、Identity Toolkit APIToken Service API のみに制限を許可すれば良いでしょう。検証をしながら、必要なAPIのみ許可を設定する必要があります。

APIの制限

より厳密に許可されたクライアントだけ許可したい場合は Firebase App Checkの利用も検討してください。

firebase.google.com

許可したAPIについてquotaを設定する

GCPでは各APIについてquotaを設定することができます。許可したAPIについて、不必要に多くAPIをコールされないようquotaを設定しましょう。
APIのquotaの設定は、GCPの管理コンソールの「APIとサービス」-> 「有効なAPIとサービス」の各APIの詳細から設定できます。

APIのquota設定

またアラートも同画面にて設定することができるので、同様に設定して監視しましょう。
最初は余裕を持って設定し、利用状況を監視しながら、徐々に適正な値を設定していくのが良いと思います。監視の設定については下記のドキュメントが参考になります。

cloud.google.com

Firestore、Realtime DatabaseやCloud Storageのセキュリティルール

こちらは既にご存知の方も多いと思います。セキュリティチェックシートからの再掲になりますが

Firebase は、アプリの Firebase プロジェクトを Firebase サービスに対して識別する目的でのみ API キーを使用します。データベースまたは Cloud Storage データへのアクセスを制御する目的では使用しません。このためには Firebase セキュリティ ルールが使用されます。

の通り、Firestore等へのアクセス制御には別途セキュリティルールを設定する必要があります。
もしセキュリティルールを設定しない場合、公開したAPIキーを用いて、Firestoreにアクセスすることが可能です。そのため本来該当のユーザ以外には公開しない想定の情報に第三者がアクセスすることができ、場合によっては個人情報の漏洩などのセキュリティインシデントが発生するリスクがあります。

各種セキュリティルールの設定方法については、下記のドキュメント等が参考になります。

firebase.google.com

firebase.google.com

firebase.google.com

最後に

Firebaseのセキュリティについて考慮すべき点について、簡単に紹介しました。
セキュリティルールについては言及している記事が多いものの、特にAPIキーの公開については、他のAPIにも利用可能な点について、言及している記事が少なかったため、改めて記事として取り上げてみました。
上記で挙げた点以外にも参照先として挙げたドキュメントに他にも考慮すべきことが記載されているので、ぜひご確認頂ければと思います。

*1:リファラー制限の場合は、リファラーを偽装することもできるため