Firebaseリソースとユーザーのデータを安全に保つには、次のガイドラインに従ってください。すべての項目が必ずしも要件に当てはまるわけではありませんが、アプリを開発する際にはそれらを念頭に置いてください。
乱暴な交通を避ける
バックエンドサービスの監視とアラートを設定する
サービス拒否(DOS)攻撃などの不正なトラフィックを検出するには、 Cloud Firestore 、 Realtime Database 、 Cloud Storage 、およびHostingの監視とアラートを設定します
アプリケーションへの攻撃が疑われる場合は、できるだけ早くサポートに連絡して、何が起こっているかを知らせてください。
アプリチェックを有効にする
アプリのみがバックエンドサービスにアクセスできるようにするには、それをサポートするすべてのサービスに対してアプリチェックを有効にします。
通常のトラフィックに合わせてスケーリングするようにCloudFunctionsを構成します
Cloud Functionsは、アプリの要求に合わせて自動的にスケーリングしますが、攻撃が発生した場合、これは多額の費用を意味する可能性があります。これを防ぐために、アプリの通常のトラフィックに基づいて、関数の同時インスタンスの数を制限できます。
制限に近づいたときに通知されるようにアラートを設定します
サービスにリクエストの急増がある場合、多くの場合、クォータが開始され、アプリケーションへのトラフィックが自動的に抑制されます。使用量と請求のダッシュボードを必ず監視してください。ただし、リソースの使用量が予想を超えたときに通知されるように、プロジェクトに予算アラートを設定することもできます。
自己DOSの防止:エミュレーターを使用してローカルで機能をテストします
クラウド関数の開発中に誤ってDOSを実行するのは簡単です。たとえば、無限のトリガーと書き込みのループを作成します。 Firebaseエミュレータスイートを使用して開発を行うことで、これらの間違いがライブサービスに影響を与えるのを防ぐことができます。
(誤って自分でDOSを実行した場合は、 index.js
から関数を削除してから、
を実行して関数をデプロイ解除してください。)
リアルタイムの応答性がそれほど重要でない場合、構造は防御的に機能します
関数の結果をリアルタイムで表示する必要がない場合は、結果をバッチで処理することで、不正なトラフィックを軽減できます。結果をPub / Subトピックにパブリッシュし、スケジュールされた関数を使用して定期的に結果を処理します。 。
APIキーを理解する
FirebaseサービスのAPIキーは秘密ではありません
FirebaseはAPIキーを使用して、Firebaseサービスに対するアプリのFirebaseプロジェクトを識別し、 Firebaseセキュリティルールを使用して行われるデータベースやクラウドストレージデータへのアクセスを制御しません。このため、FirebaseサービスのAPIキーをシークレットとして扱う必要はなく、クライアントコードに安全に埋め込むことができます。 FirebaseのAPIキーの詳細をご覧ください。
APIキースコープを設定する
APIキーを使用してリクエストをスプーフィングしようとする攻撃者に対する追加の抑止力として、アプリクライアントを対象とするAPIキーを作成できます。
FCMサーバーのキーを秘密にしておく
FirebaseサービスのAPIキーとは異なり、FCMサーバーキー(従来のFCM HTTP APIで使用)は機密性が高く、秘密にしておく必要があります。
サービスアカウントキーを秘密にしておく
また、FirebaseサービスのAPIキーとは異なり、サービスアカウントの秘密キー( Admin SDKで使用される)は機密性が高く、秘密にしておく必要があります。
セキュリティルール
本番モードまたはロックモードでルールを初期化します
Cloud Firestore、Realtime Database、およびCloud Storageをセットアップするときは、セキュリティルールを初期化してデフォルトですべてのアクセスを拒否し、アプリの開発時に特定のリソースへのアクセスを許可するルールを追加します。
これは、Cloud Firestore(本番モード)およびRealtime Database(ロックモード)の新しいインスタンスのデフォルト設定の1つです。新しいデータベースインスタンスを設定するときにこのオプションを選択します。
Cloud Storageの場合、次のようなセキュリティルールの構成から始めます。
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if false;
}
}
}
セキュリティルールはスキーマです。ドキュメントを追加するときにルールを追加する
起動前のタスクの一種として、アプリを作成した後にセキュリティルールを作成しないでください。代わりに、アプリを作成するときにセキュリティルールを作成し、データベーススキーマのように扱います。新しいドキュメントタイプまたはパス構造を使用する必要がある場合は、最初にセキュリティルールを作成します。
EmulatorSuiteを使用したユニットテストのセキュリティルール。 CIに追加する
セキュリティルールがアプリの開発に対応していることを確認するには、 Firebaseエミュレータスイートを使用してルールを単体テストし、これらのテストをCIパイプラインに追加します。 CloudFirestoreとRealtimeDatabaseについては、これらのガイドを参照してください。
認証
カスタム認証:信頼できる(サーバー側の)環境からのミントJWT
カスタムシステムであれサードパーティサービスであれ、安全なサインインシステムがすでにある場合は、既存のシステムを使用してFirebaseサービスで認証できます。信頼できる環境からカスタムJWTを作成し、トークンをクライアントに渡します。クライアントは、トークンを使用して認証します( iOS + 、 Android 、 Web 、 Unity 、 C ++ )。
サードパーティプロバイダーでカスタム認証を使用する例については、ブログ投稿「 Oktaを使用してFirebaseで認証する」を参照してください。
管理された認証:OAuth2.0プロバイダーが最も安全です
Firebaseのマネージド認証機能を使用する場合、OAuth 2.0 / OpenID Connectプロバイダーオプション(Google、Facebookなど)が最も安全です。可能であれば、これらのプロバイダーの1つ以上をサポートする必要があります(ユーザーベースによって異なります)。
電子メールパスワード認証:ブルートフォース攻撃を防ぐために、サインインエンドポイントに厳しい割り当てを設定します
Firebaseのマネージドメールパスワード認証サービスを使用する場合は、ブルートフォース攻撃を防ぐために、 identitytoolkit.googleapis.com
エンドポイントのデフォルトの割り当てを厳しくしてください。これは、Google CloudConsoleのAPIのページから行うことができます。
多要素認証のためにCloudIdentityPlatformにアップグレードする
サインイン時のセキュリティを強化するために、 Cloud IdentityPlatformにアップグレードして多要素認証のサポートを追加できます。アップグレード後も、既存のFirebase認証コードは引き続き機能します。
匿名認証
ウォームオンボーディングには匿名認証のみを使用してください
ユーザーが実際にサインインする前に、匿名認証のみを使用してユーザーの基本状態を保存します。匿名認証は、ユーザーサインインの代わりにはなりません。
スマートフォンを紛失したときにデータが必要な場合は、ユーザーを別のログイン方法に変換します
ユーザーがローカルストレージをクリアするか、デバイスを切り替えると、匿名認証データは保持されません。単一のデバイスでアプリの再起動を超えてデータを保持する必要がある場合は、ユーザーを永続アカウントに変換します。
ユーザーがサインインプロバイダーに変換するか、電子メールを確認することを要求するセキュリティルールを使用します
誰でもプロジェクトに匿名アカウントを作成できます。そのことを念頭に置いて、特定のサインイン方法または確認済みの電子メールアドレスを必要とするセキュリティルールを使用して、すべての非公開データを保護してください。
例えば:
allow write: if request.auth.token.firebase.sign_in_provider != "anonymous";
allow write: if request.auth.token.email_verified = true;
環境マネジメント
開発およびステージングプロジェクトを設定する
開発、ステージング、本番用に個別のFirebaseプロジェクトを設定します。ステージングプロジェクトに対してテストされるまで、クライアントコードを本番環境にマージしないでください。
チームによる本番データへのアクセスを制限する
大規模なチームで作業する場合は、事前定義された役割またはカスタムIAM役割のいずれかを使用して本番データへのアクセスを制限することにより、ミスや違反の結果を軽減できます。
チームが開発にエミュレータスイートを使用している場合は、本番プロジェクトへのより広いアクセスを許可する必要がない場合があります。
図書館管理
ライブラリのスペルミスや新しいメンテナに注意してください
プロジェクトにライブラリを追加するときは、ライブラリとそのメンテナの名前に細心の注意を払ってください。インストールしようとしているライブラリと同じ名前のライブラリに、悪意のあるコードが含まれている可能性があります。
変更を理解せずにライブラリを更新しないでください
アップグレードする前に、使用しているライブラリの変更ログを確認してください。アップグレードが付加価値をもたらすことを確認し、メンテナがまだ信頼できる当事者であることを確認してください。
ウォッチドッグライブラリを開発またはテストの依存関係としてインストールします
Snykなどのライブラリを使用して、安全でない依存関係がないかプロジェクトをスキャンします。
機能の監視を設定します。ライブラリの更新後に確認してください
Cloud FunctionsロガーSDKを使用すると、ライブラリの更新によって引き起こされる動作など、異常な動作を監視してアラートを受け取ることができます。
クラウド機能の安全性
CloudFunctionの環境変数に機密情報を入れないでください
多くの場合、自己ホスト型のNode.jsアプリでは、環境変数を使用して秘密鍵などの機密情報を含めます。 CloudFunctionsではこれを行わないでください。 Cloud Functionsは関数の呼び出し間で環境を再利用するため、機密情報を環境に保存しないでください。
- 秘密ではないFirebaseAPIキーを保存するには、コードに埋め込むだけです。
- CloudFunctionでFirebaseAdmin SDKを使用している場合、SDKは初期化中にサービスアカウントのクレデンシャルを自動的に取得できるため、サービスアカウントのクレデンシャルを明示的に提供する必要はありません。
- サービスアカウントの資格情報を必要とするGoogleおよびGoogleCloud APIを呼び出す場合、Node.jsのGoogle Authライブラリは、CloudFunctionsに自動的に入力されるアプリケーションのデフォルトの資格情報からこれらの資格情報を取得できます。
- Google以外のサービスの秘密鍵とクレデンシャルをCloudFunctionsで利用できるようにするには、Cloud SecretManagerを使用します。
機密情報を暗号化する
機密情報をCloudFunctionに渡すことを避けられない場合は、情報を暗号化するための独自のカスタムソリューションを考え出す必要があります。
単純な関数の方が安全です。複雑さが必要な場合は、CloudRunを検討してください
CloudFunctionsをできるだけシンプルで理解しやすいものに保つようにしてください。関数の複雑さは、多くの場合、見つけにくいバグや予期しない動作につながる可能性があります。
複雑なロジックまたは環境構成が必要な場合は、 CloudFunctionsの代わりにCloudRunを使用することを検討してください。