はじめに
こんにちは、株式会社 Flatt Security セキュリティエンジニアのぴざきゃっと (@pizzacat83) です。
認証機構を自作せずに導入できる Firebase Authentication は様々なアプリケーションにて利用されていますが、その特性を十分に理解せずに導入すると、実は不具合や脆弱性が生じることがあります。そこで本稿では Firebase Authentication を利用するうえで、注意しなければ不具合や脆弱性に繋がりうる 7 個の「落とし穴」について解説します。
- はじめに
- IDaaS の利点と欠点
- 落とし穴 1. 自己サインアップ
- 落とし穴 2. ユーザーが自身を削除できる
- 落とし穴 3. 他人のメールアドレスを用いたユーザー登録
- 落とし穴 4. メールアドレスに紐付くユーザーが存在するかどうか判定可能
- 落とし穴 5. メールアドレス / パスワード認証のブルートフォース
- 落とし穴 6. パスワードの脆弱な構成要件
- 落とし穴 7. 異なる目的で有効化された認証プロバイダーの区別
- ベストプラクティス
- おわりに
- 更新履歴
IDaaS の利点と欠点
多くの Web・スマホアプリはユーザーごとにサービスを提供するために認証機構を持っていますが、認証機構に不備があると個人情報の漏洩や不正な書き換えなど、重大なリスクに繋がる場合もあります。セキュアに認証機構を実装するための注意点は NIST SP 800-63B や OWASP ASVS V2 などで解説されているほか、本ブログでもログイン機能の仕様にまつわる観点について過去にご紹介しました。 しかしながらこれらの資料の膨大さから感じられるように、瑕疵なく認証機構を実装することは困難です。
IDaaS (Identity as a Service) は認証機構を API として提供するクラウドサービスで、開発者は IDaaS を利用することでアプリケーションに認証機構を容易に導入できます。一般の開発者が認証機構を自力で実装するよりも、認証機構に特化して作られた IDaaS を利用したほうが安全そうに思われるかもしれません。
ところが IDaaS を導入することにより、逆に脆弱性が生まれることもあります。というのも、IDaaS は特定のアプリケーションのために作られたものではなく、様々なアプリケーションで利用できる汎用的なサービスです。このため IDaaS の仕様や設定値次第では、アプリケーションの仕様に適さない操作をユーザーが勝手に実行できる場合があります。認証機構を自作する場合ではアプリケーションが要求する仕様に沿って認証機構を実装するため、このような問題は IDaaS を利用するアプリケーション特有のものと言えます。アプリケーションに IDaaS を導入する際は、IDaaS の仕様を十分に把握したうえで、アプリケーションに適した設定値を吟味したり、アプリケーションの仕様に適さない IDaaS の機能に関する対策を施したりする必要があります。
本稿では IDaaS の 1 つである Firebase Authentication を取り上げます。Firebase Authentication を認証に用いたアプリケーションでは、ユーザーはログイン等の操作をする際に、アプリケーション本体ではなく Firebase Authentication の API に直接アクセスします。アプリケーション本体を介さずに認証に関する操作ができるこのアーキテクチャでは、アプリケーションの意図から外れた操作をユーザーが実行できてしまうことがあり、時にはそれが脆弱性につながります。このような脆弱性を防ぐためには、Firebase Authentication においてユーザーが実行できる操作を理解したり、アプリケーションの仕様に合わせて設定を調整したりすることが重要です。そこで本稿では Firebase Authentication のデフォルト設定での挙動とアプリケーション仕様のミスマッチが起きやすい箇所に焦点を当て、そのリスクや対処方法について解説していきます。
なお他に知られた IDaaS としては Amazon Cognito や Auth0 などが挙げられます。Cognito をセキュアに使うための注意点については以下のブログで解説しておりますので、こちらもぜひご一読ください。
落とし穴 1. 自己サインアップ
ユーザーの新規作成を利用者自身が行うのではなく、管理者がユーザーを発行するようなアプリケーションにおいて Firebase Authentication を導入する場合は、デフォルトの設定では自己サインアップの対策が必要です。
Firebase Authentication のデフォルト設定では、たとえユーザー登録画面を実装していなかったとしても、createUserWithEmailAndPassword
関数1 などを用いて誰でも勝手にユーザーを作成できます。このことを本稿では自己サインアップ2と呼びます。
ユーザー登録画面が実装されていないアプリケーションにおいて、勝手にユーザーを作成できることは意外に思われるかもしれません。「アプリケーションの仕様に適さない操作をユーザーが勝手に実行できる」という IDaaS の落とし穴の理解を助けるため、その方法を簡単にご説明します。
例として、ログイン画面はあるがユーザー登録画面がない社内システムのようなアプリケーションを考えます。
ユーザー登録に用いる createUserWithEmailAndPassword
関数は Identity Toolkit API における /identitytoolkit/v3/relyingparty/signupNewUser
API に対応しており、この API に直接 HTTP リクエストを送信することでユーザーを作成します。リクエストには API キーを付与する必要がありますが、この API キーは例えば次のようにして取得できます。
まずログイン画面を開きます。ここで開発者ツールのネットワークタブを開いたうえで、適当な認証情報を入力して送信します。
ログイン試行によって Identity Toolkit API にリクエストが送信されます。開発者ツールでこのリクエストを確認すると、上図に示したように URL のクエリーに API キーが記載されています。
こうして取得した API キーを用いて次のようなリクエストを送信すればユーザーが作成され、リクエストで指定したメールアドレスとパスワードでログインが可能となります。
curl -X POST \ -H 'Content-Type: application/json' \ --data-binary '{ "email": "fuga@example.com", "password": "silly3demurrer6root2barkeep", "returnSecureToken": true }' \ 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key={API キーをここに書く}'
アプリケーション内で利用していない Firebase Authentication の機能であっても、API を直接呼び出すことで勝手に実行できる、ということはご理解いただけましたでしょうか。ユーザー登録だけでなく、Firebase Authentication の他の機能についても同様のことが可能です。
ここまで読んで「API キーを知られないようにするにはどうすれば良いか」とお考えかもしれませんが、Firebase において API キーは機密情報ではありません。API キーは単に「どの Firebase プロジェクトに関するリクエストなのか」を Firebase が判断するための識別符号に過ぎず、むしろフロントエンドから Firebase にアクセスするために必要不可欠なものです。したがって自己サインアップ等の対策は、API キーが攻撃者に知られていることを前提に行う必要があります。具体的な対策方法については、リスクの解説の後にご説明します。
リスク
「正当な管理者が正しいフローに沿って作成したユーザー」と「外部者が勝手に作成した不正なユーザー」を区別して処理しなければ、正当なユーザー登録フローを迂回してアプリケーションにアクセスされる可能性があります。例えば社内システムにおいて、「社内の誰でも閲覧可」を意図して「ログイン済みなら誰でも閲覧可」とアクセス制御を実装すると、社外の攻撃者は自己サインアップをすることでその情報を閲覧できてしまいます。他には有料会員制サービスにおいて、正当な登録フローを迂回することで、利用料を払わずにサービスを利用できてしまう可能性があります。
対策
Firebase Authenticaionの設定画面で、「作成(登録)を許可する」のチェックを外して保存することで自己サインアップを禁止することができます。
落とし穴 2. ユーザーが自身を削除できる
自己サインアップと同様の注意点ですが、デフォルトの設定ではユーザーは deleteUser
関数 を用いることで任意の時点で自身を削除できます。
対策
対策もまた、自己サインアップと同じくFirebase Authenticationの設定画面で「削除を許可する」のチェックを外して保存することが有効です。
落とし穴 3. 他人のメールアドレスを用いたユーザー登録
どのようなアプリケーションであれ、ユーザーに紐付くメールアドレスはそのユーザー自身のものであることが想定されているはずです。ユーザーに紐付くメールアドレスをそのユーザーが本当に所有しているかどうかを確認することを、メールアドレスの疎通確認と呼びます。Firebase Authentication ではユーザーに紐付くメールアドレスに確認用 URL を送信し、ユーザーはその URL を開くことでメールアドレスの所有を証明する、という機能が sendEmailVerification
関数などで提供されています。
Firebase Authentication のメールアドレス / パスワード認証では、メールアドレスの疎通確認をせずともユーザー登録やログインが可能です。つまり、他人のメールアドレスを用いてアプリケーションを利用できてしまいます。あるいはユーザー登録後に、メールアドレス変更機能を用いて他人のメールアドレスに変更することもできます。そして、疎通確認が完了していないユーザーのログインを禁止できるような設定項目はありません。
リスク
リスク 3-1. メールアドレス誤入力によるユーザー乗っ取り
A さんがユーザー登録時に、メールアドレスを誤入力してしまったとします (入力したメールアドレスを john@example.com
とします)。そして、 john@example.com
はたまたま B さんが所有していたとします。
Firebase Authentication ではメールアドレスの疎通確認をせずともユーザー登録ができるため、A さんはメールアドレスを誤入力したことに気づかないままアプリケーションを利用してしまうかもしれません。ここで B さんは自分のメールアドレス john@example.com
に対してパスワードリセットを行うことで、A さんが登録したユーザーとしてログインできます。すると、A さんがアプリケーションに入力した個人情報などを B さんが閲覧できてしまいます。もし A さんが決済情報を登録していたら、B さんは A さんの決済情報を用いて購入操作などをできてしまうかもしれません。
リスク 3-2. 他人にメールを送りつけさせる
もし他人のメールアドレス john@example.com
を用いてユーザー登録すると、アプリケーションがユーザーに送るメールは全て john@example.com
に届きます。この事象は大した問題ではないように思えるかもしれませんが、アプリケーションのメール送信関連の仕様によっては大きなリスクに繋がることもあります。
例 3-2-1. メール本文にユーザー入力が挿入されるアプリケーション
メール先頭に「(ユーザー名) 様」と記載したり、本文中に申し込み内容を挿入したりと、アプリケーションが送信するメールにユーザー入力が含まれることは珍しくありません。ここでメールに挿入されるユーザー入力の長さや文字種などの制約が不十分だと、攻撃者は実質的にメールの本文を偽装できる場合があります。
例えばアプリケーションがユーザー名の長さや文字種に制約を課していないとします。攻撃者はユーザー名を次のように設定します。
お客様\n以下の URL からログインしてください。\nhttps://phishing.example/signin\n\n\n... (以降大量の改行文字)
アプリケーションが送信するメールに「(ユーザー名) 様」という記載をする場合、ユーザーには次のようなメールが届くことになります。
アプリケーションが本来送信したかった内容は大量の改行によって画面外に押し出されてしまい、攻撃者が仕込んだ文字列だけが表示されてしまうのです。
このようにして、攻撃者は被害者にフィッシングメールを送信できます。ここでメールの差出人は本物のアプリケーションのメールアドレスであるため、通常のフィッシングメールと比べ騙されやすいでしょう。
今回は簡単のため、ユーザー名に改行文字を含められるというアプリケーションの不備3を仮定して説明しました。しかし改行文字が禁止されていても大量の空白文字を挿入したり、改行を使わずに自然なメッセージを埋め込んだりできるかもしれません。また、ユーザー名以外のユーザー入力では改行文字を許容せざるを得ないこともあるでしょう。
メールに自由に文字列を挿入できても疎通確認をきちんと行っていれば、攻撃者が文言を細工してもそのメールは攻撃者の元に届くため攻撃は成立しません。単体では無害な性質が、疎通確認の欠如と組み合わせられることで精巧なフィッシングという重大なリスクに発展しうるのです。
例 3-2-2. プロモーションメールを送るアプリケーション
ユーザーにプロモーションメールを送るアプリケーションでは、攻撃者は被害者のメールアドレスで勝手にユーザー登録することで、被害者に身に覚えのないプロモーションメールを送りつけることができます。これはアプリケーションのレピュテーションリスクに繋がります。
例 3-2-3. メール送信を伴う操作を短時間で大量に実行可能なアプリケーション
申し込み完了メールなど、ユーザーの操作に伴ってユーザーにメールを送信する機能があるとします。この操作を短時間で大量に実行できる場合、攻撃者は他人のメールアドレスでユーザー登録したのちメール送信操作を大量に実行することにより、他人に大量のメールを送りつけさせることができます。これもまたアプリケーションのレピュテーションリスクに繋がります。
リスク 3-3. メールアドレスに基づくアクセス制御の迂回
ユーザーのメールアドレスに基づいてアクセス制御を行っているアプリケーションでは、攻撃者が自分の所有していないメールアドレスを用いてユーザー登録することで、そのアクセス制御を迂回できる可能性があります。
例えば社内システムにおいて自社ドメインのメールアドレス *@company.example.com
に紐付くユーザーのみにシステム利用を許可しているとします。社外の攻撃者は john@company.example.com
としてユーザー登録することで、社内システムを不正に利用できてしまいます。
学生限定のサービスを提供するアプリケーションにおいて、メールアドレスのドメインが .ac.jp
で終わるかどうかをもって学生かどうかを判定するような場合でも、同様の不正利用が考えられるでしょう。
対策
先述した通り、Firebase Authentication において「メールアドレスの疎通確認を行っていないユーザーがログインできないようにする」という設定はできません。
ユーザーのメールアドレス情報を一切利用しないアプリケーションであれば、これまでに例示したリスクは発生しないでしょう。ユーザーのメールアドレスを利用するアプリケーションの場合は、疎通確認が完了していないユーザーがアプリケーションを利用できないようにアクセス制御を実装することが対策となります。
メールアドレスの疎通確認が完了しているかどうかは、Firebase セキュリティールールにおいては request.auth.token.email_verified
を用いて判定できます。各言語の Firebase SDK, Admin SDK においても、細かなプロパティー名は異なりますが同様の情報が提供されています。Firestore, Cloud Storage, Functions など全てのバックエンドにおいて email_verified
プロパティーをチェックすることで、メールアドレスの疎通確認が完了していないユーザーにアプリケーションを利用させないようにできます。先述した自己サインアップの対策と合わせると、セキュリティールールは次のようになります。
function userIsValid(auth) { return ( auth.token.createdByAdmin && // メールアドレスの疎通確認が完了していなければならない auth.token.email_verified && // ... // 今後もさらに条件を追加していきます ) }
OAuth 2.0 プロバイダーを利用している場合でも、email_verified
のチェックは必要です。というのも OAuth 2.0 プロバイダーを用いて登録したユーザーであっても、updateEmail
関数を用いてメールアドレスの変更ができるためです。疎通確認はメールアドレス / パスワード認証の場合と同様に、先に紹介した sendEmailVerification
関数を用いて行うことができます。
ところで、「リスク」において紹介した具体的な攻撃の例の中には、メールアドレスの疎通確認不足に加えて「アプリケーションが送信するメールに自由に文字列を挿入可能」「メール送信を伴う操作を短時間で大量に実行可能」という別の不備を利用したものがありました。先述したメールアドレスの疎通確認に関する対策に加えて、これらの不備に対策をしておくことももちろん大切です。
落とし穴 4. メールアドレスに紐付くユーザーが存在するかどうか判定可能
fetchSignInMethodsForEmail
関数は、与えたメールアドレスに紐付く認証プロバイダーの一覧を返します。返り値が非空ならば、そのメールアドレスに紐付くユーザーが存在することがわかります。この関数は未認証状態でも実行できるため、「あるメールアドレスに紐付くユーザーが存在するか調べる」ということが誰にでもできます。
リスク
マッチングアプリなどアプリケーションの内容によっては、利用者であることを他人に知られることがユーザーに不利益をもたらすかもしれません。利用状況を他人に知られても問題がないようなアプリケーションであっても、「アプリケーションの利用者である」という情報が標的型メールなどに悪用されるかもしれません。またブルートフォース攻撃において、アプリケーションで利用されているメールアドレスに絞り込んでからメールアドレスとパスワードの組を総当たりすることで、利用状況の情報がない場合と比べて試行回数を減らすことができます。
対策
メールアドレスと紐付けられない認証プロバイダーのみを利用することが、根本的な対策となります。そのような認証プロバイダーとしては匿名認証や電話番号ログインが挙げられますが、これらのプロバイダーには欠点4もあり、一概に推奨されるものではありません。OAuth 2.0 を利用した認証においてメールアドレスを取得するスコープを要求しないことでも、メールアドレスに紐付けられないユーザーを作成できます。しかし多くの OAuth 2.0 プロバイダーは、Firebase SDK をそのまま利用するとデフォルトでメールアドレスを閲覧できるスコープが要求されるため、これを回避するにはフローを自分で実装する必要があります。このように根本的な対策にはデメリットもあるため、先述したリスクをどこまで許容できるかを考慮して対策を検討することをお勧めします。場合によっては Firebase Authentication 以外の IDaaS を利用することも視野に入れると良いでしょう。
その他、大量のメールアドレスでログイン試行を繰り返すことで有効なメールアドレスを収集する行為に対しては、Firebase Authenticationの設定画面からメールの列挙保護機能を有効化することが対策となります。 詳細な仕様については以下のリンクから公式ドキュメントをご確認ください(リンク先はIdentity Platformのドキュメントですが、メールの列挙保護機能はIdentity Platformにアップグレードせずとも利用可能です)。
また、こちらの機能の有効化はセキュリティチェックリストの中にも項目として記述があります。
ただしこの対策は根本的なものではありません。前述したドキュメントの以下の記述に注目してください。
無効な登録のケースでは引き続き EMAIL_EXISTS エラーが返されます。
具体的には、アカウントの新規登録を利用すると「交際相手のメールアドレスを入力してマッチングアプリを利用しているか調べる」というような、特定のメールアドレスの利用状況を調べる攻撃が成立してしまうことがわかります。 以上から、メールアドレスの列挙保護機能は有効なメールアドレスの収集への対策にはなるが、「メールアドレスに紐付くユーザーが存在するかどうか判定可能」というリスクに対しては根本的対策でないと言えます。
落とし穴 5. メールアドレス / パスワード認証のブルートフォース
認証機構に対する基本的な攻撃の 1 つであるブルートフォース攻撃ですが、実は Firebase Authentication においてもブルートフォース攻撃の対策が必要です。
攻撃者が一定時間内に実行できるログイン試行の数は、Identity Toolkit API の割り当てによって制限されています。同一の IP アドレスから 1 分間あたりに実行できる Identity Toolkit API の回数は、次のコマンドで確認できます (リファレンス)。
gcloud alpha services quota list \ --service=identitytoolkit.googleapis.com \ --consumer=projects/プロジェクトID \ --flatten='consumerQuotaLimits' \ --filter='metric:"identitytoolkit.googleapis.com/default" AND consumerQuotaLimits.unit:"1/min/{project}/{user}"'
コマンドの出力例は以下の通りです。コマンド出力の effectiveLimit
の値が、同一の IP アドレスから 1 分間あたりに実行できる Identity Toolkit API の回数を表します。defaultLimit
の値は 2022/03 調査時点で 3 万回であり、ブルートフォース攻撃に対する他の防御機構がないと仮定すると、同一の IP アドレスから 1 分間あたりに 3 万回もログインを試行できる可能性があります。
consumerQuotaLimits: metric: identitytoolkit.googleapis.com/default quotaBuckets: - defaultLimit: '30000' effectiveLimit: '30000' unit: 1/min/{project}/{user} displayName: Queries metric: identitytoolkit.googleapis.com/default
なお、Google Cloud コンソールからも割り当ての値を確認できます。「Queries per minute per user」という行の上限値を参照してください。
ブルートフォース攻撃とその対策の必要性はほとんどの開発者が認識していることでしょう。しかし Firebase Authentication においてそれを防ぐための設定は Firebase コンソールから確認できるものではなく、Google Cloud のコンソールや CLI から変更する必要があるため、対策が漏れているアプリケーションは多いのではないでしょうか。
対策
メールアドレス / パスワード認証を利用しないことが根本的な対策となります。公式ドキュメント「Firebase のセキュリティチェックリスト」では OAuth 2.0 プロバイダーがもっとも安全な認証プロバイダーであるとして推奨されています。
どうしてもメールアドレス / パスワード認証を利用する必要がある場合は、根本的な対策とはなりませんが、ブルートフォース攻撃を緩和する次のような対策をお勧めします。
まず Identity Toolkit API の割り当てを小さくすることで、攻撃者が一定時間内に実行できるログイン試行の数を減らすことができます。このことは、公式ドキュメント「Firebase のセキュリティチェックリスト」でも推奨されています。ただし Identity Toolkit API の割り当てはログインだけでなく、ユーザー登録やパスワードリセットなど Firebase Authentication の他の機能と合算した回数に対する制限であるため、割り当てを過度に小さくするとアプリケーションの正常な利用に支障を来す可能性があります。アプリケーションの通常の使用方法における Identity Toolkit API の利用状況の測定や割り当て超過エラーの検知を行い、適切な割り当てを検討すると良いでしょう。
またパスワードの構成要件を堅牢にすることで、ブルートフォース攻撃を成功させにくくすることも緩和策となります。パスワードの構成要件については、次節で詳しく扱います。
ちなみに認証機構を自作する場合のブルートフォース攻撃対策については、以下のブログで解説しています。
落とし穴 6. パスワードの脆弱な構成要件
メールアドレス / パスワード認証を利用する場合、ユーザーが容易に推測可能なパスワードを設定できないようにして、アカウントの乗っ取りを防ぐことが重要です。Firebase Authentication のデフォルト設定では 6 文字未満のパスワードを設定しようとするとパスワードが弱すぎる旨のエラーが発生します (ドキュメント) が、6 文字以上であれば aaaaaa
のような単純なパスワードであっても設定できてしまいます。
対策
Firebase Authenticationではパスワードポリシーとして、最小文字数の制限や、使える文字種の制限が可能です。これにより、上の例にあげた同一文字だけのパスワードなどのような単純なパスワードの設定は防ぐことができます。
構成要件を設計するうえでは、NIST SP 800-63B 5.1.1 や OWASP ASVS V2.1 などのガイドラインが参考になります。
落とし穴 7. 異なる目的で有効化された認証プロバイダーの区別
本節の内容は気をつけるべき Firebase Authentication の仕様というよりは、開発者の不注意によって生まれやすい脆弱性です。
Firebase Authentication ではメール認証や Google ログインなど、複数の認証プロバイダーを併用できます。アプリケーションによっては、複数の認証プロバイダーを異なる目的で利用している場合があるでしょう。このようなアプリケーションではアクセス制御の際に「ユーザーがどの認証プロバイダーを利用しているか」を適切に検証しなければなりません。
このことは言葉にすると当たり前に聞こえますが、この点に注意せず認証プロバイダーを新たに有効化すると、アプリケーションに不具合が生じる可能性があります。例えば Google ログインだけを認証に用いているアプリケーションを考えます。ある日キャンペーンとしてアプリケーションにミニゲーム機能を追加することになり、アプリケーションに本登録しなくてもハイスコア情報を記録できるよう匿名認証を有効化したとします。このときもしアプリケーション本体が Google ログイン以外の認証プロバイダーを想定していない場合、匿名認証のユーザーを本登録ユーザーと同等に扱ってしまい、予期しない挙動に繋がる可能性があります。
対策
複数の認証プロバイダーを異なる目的で使い分けている場合は、アクセス制御において認証プロバイダーが仕様に沿ったものであるかどうかをホワイトリスト方式で検証しましょう。
現在単一の認証プロバイダーしか有効化していない場合は、現時点で「想定外の認証プロバイダーの利用」という事象は起き得ませんが、先述した例のように将来的な変更によって問題が生じる可能性はあります。認証プロバイダーを 1 つしか有効化していない場合であっても、予防的な対策として認証プロバイダーをホワイトリスト方式で検証することをお勧めします。
自己サインアップやメールアドレスの疎通確認チェックの対策と合わせると、Firestore セキュリティールールは次のようになります。例として、メールアドレス / パスワード認証と Google ログインだけを想定しているとします。
function userIsValid(auth) { return ( auth.token.createdByAdmin && auth.token.email_verified && // 認証プロバイダーをホワイトリスト方式で検証 auth.token.firebase.sign_in_provider in ['password', 'google.com'] && // ... // 本稿で推奨するチェックは以上です。 // アプリケーションの仕様上他に必要なチェックがあれば追加してください。 ) }
また認証プロバイダーの有効化や設定変更を行う際には、アプリケーションのあらゆる箇所に対してその変更が及ぼす影響を考えてから変更を実施することをお勧めします。
ベストプラクティス
Firebase Authentication をはじめとする様々な Firebase プロダクトを利用するうえでのベストプラクティスは、以下の資料などにまとめられています。本稿と重複する内容も含まれますが、是非ご参照ください。
おわりに
本稿では IDaaS の 1 つである Firebase Authentication について、アプリケーションによっては不具合や脆弱性のもととなる仕様とその対策をご紹介しました。
この記事の主旨は決して「Firebase Authentication は危険だから使うべきでない」ということではありません。どのような IDaaS であれ、IDaaS の仕様と自分のアプリケーションの仕様を考慮して、IDaaS や認証プロバイダーを選定し適切な設定を行いましょう。IDaaS とアプリケーションの仕様のミスマッチにより不具合が生じうる場合は、その対策を実装しましょう。
Firebase は簡単にアプリケーションを構築できる便利な mBaaS ですが、完成を急ぐあまりセキュリティー対策を疎かにしてしまうと、どれほど素晴らしいサービス内容であってもいつの日か脆弱性攻撃によって大きな被害を受ける可能性があります。Firebase を用いて開発をされている皆様が、自らのアプリケーションを脅威から守り、ユーザーに素晴らしいサービスを届けていくことに、本記事を一助としていただければ幸いです。
Flatt Security Blog では、これまでも Firebase をセキュアに利用するための情報を発信しております。Firestore セキュリティールールの実装など、Firebase Authentication 以外のプロダクトについても解説しておりますので、Firebase ユーザーの方はぜひこちらもご一読ください。
また、Flatt Security が提供するセキュリティ診断サービスでは、Firebase をセキュアに扱えているか専門家の視点でチェックする Firebase 診断というメニューも提供しています。
これまでの経験から正直に申し上げますと、Firebase を利用したアプリケーションには攻撃されるとサービスの継続が困難になるような深刻な脆弱性が見つかるケースが多いです。専門的な診断を行ったことがない場合は、ぜひ利用をお勧めします。
ご興味のある方向けに下記バナーよりセキュリティ診断の料金に関する資料もダウンロード可能です。Web アプリケーションの診断にどの程度費用が発生するかを、ご自身で計算できるようになっています。
Firebase 診断だけはどうしても個別のお見積りが必要ですので、ご自身での料金計算はできないのですが、Firebase Authentication, Firestore, Cloud Functions それぞれに対する診断の具体的な料金例も掲載されておりますので、参考にしていただけるかと思います。
また、Flatt Security はセキュリティーに関する様々な発信を行っています。最新情報を見逃さないよう、公式 X のフォローをぜひお願いします!
ここまでお読みいただきありがとうございました。
更新履歴
2022 年 4 月 21 日 「自己サインアップ」の対策において、Firebase Authentication から Google Identity Platform にアップグレードする方法を追記しました。この方法を発信してくださった Nil Hiiragi さんにこの場を借りて御礼申し上げます。
2022 年 5 月 2 日 「メールアドレス / パスワード認証のブルートフォース」において、可能なログイン試行の回数について断定的と解釈できてしまう表現を修正しました。
2022 年 6 月 30 日
「createUserWithEmailAndPassword
関数」と書くべきところを誤って「signInWithEmailAndPassword
関数」と記載していた箇所を修正しました。
2024 年 8 月 6 日 落とし穴1, 2, 4, 6の対策について更新しました。 これらの差分についての解説は以下リンクをご覧ください。
- 本稿で Firebase Authentication の API について述べる際は特記なき場合 JavaScript SDK (version 9) を例に説明します。ただしほとんどの議論は SDK の言語やプラットフォームの種別 (Web, iOS, Android 等) によらず同様です。↩
- Firebase Authentication のドキュメント等において、この行為を指す用語は特にないようです。同様の行為が Cognito において「自己サインアップ」と呼ばれていることから、本稿ではこの語を Firebase Authentication に流用しています。↩
-
ちなみに、Firebase Authentication においてユーザーの
displayName
には改行文字を含めることができます。↩ - 匿名認証はデバイスを喪失した場合に再ログインができないなどのデメリットがあることから、利用者が本登録するまでの一時的な利用にとどめることが推奨されています (ドキュメント)。電話番号ログインについては、機種変更などでユーザーが電話番号を手放し、他人がその電話番号を取得することで乗っ取りが発生しうるなどのリスクが指摘されています (ドキュメント)。↩