https://blog.flatt.tech/entry/firebase_authentication_security
こんにちは、株式会社 Flatt Security セキュリティエンジニアのぴざきゃっと (@pizzacat83) です。
認証機構を自作せずに導入できる Firebase Authentication は様々なアプリケーションにて利用されていますが、その特性を十分に理解せずに導入すると、実は不具合や脆弱性が生じることがあります。そこで本稿では Firebase Authentication を利用するうえで、注意しなければ不具合や脆弱性に繋がりうる 7 個の「落とし穴」について解説します。
多くの 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 は他の IDaaS と比べて設定項目が少ないという特徴があります。一見「設定項目が少ないため設定ミスが起きにくく安全」と思われるかもしれませんが、設定項目がないということは、自作した認証機構や他の IDaaS であれば自分のアプリケーションの仕様に合わせてカスタマイズできるのに、Firebase Authentication では自分のアプリケーションをよく知らない Firebase 側が勝手に決めた設定値で固定されていると解釈できます。また設定項目が少ないことにより、Firebase Authentication においてユーザーにどんな操作ができるのかを、開発者がよく理解しないまま導入してしまう可能性が高いです。例えば「自己サインアップ (後述) を許可しますか?」という設定項目があれば、開発者は自己サインアップという機能の存在を認識し、アプリケーションに自己サインアップ機能が必要か判断して設定をするでしょうが、設定項目がない Firebase Authentication では開発者が自己サインアップという機能の存在に気づくきっかけがありません。リファレンスを隅々まで、自分のアプリケーションに無関係な部分を含めて読まない限り、開発者はユーザーに何ができるかを把握しきれないのです。Firebase Authentication は設定項目が少ないことにより、見えないところにいくつものリスクが隠れています。本稿ではそういった「見えない落とし穴」7 つに光を当て、その穴を塞ぐ対処方法について解説していきます。
なお他に知られた IDaaS としては Amazon Cognito や Auth0 などが挙げられます。Cognito をセキュアに使うための注意点については以下のブログで解説しておりますので、こちらもぜひご一読ください。
ユーザーの新規作成を利用者自身が行うのではなく、管理者がユーザーを発行するようなアプリケーションにおいて Firebase Authentication を導入する場合は、自己サインアップの対策が必要です。
Firebase Authentication では、たとえユーザー登録画面を実装していなかったとしても、signInWithEmailAndPassword
関数1 などを用いて誰でも勝手にユーザーを作成できます。このことを本稿では自己サインアップ2と呼びます。
ユーザー登録画面が実装されていないアプリケーションにおいて、勝手にユーザーを作成できることは意外に思われるかもしれません。「アプリケーションの仕様に適さない操作をユーザーが勝手に実行できる」という IDaaS の落とし穴の理解を助けるため、その方法を簡単にご説明します。
例として、ログイン画面はあるがユーザー登録画面がない社内システムのようなアプリケーションを考えます。
ユーザー登録に用いる signInWithEmailAndPassword
関数は Identity Toolkit API における /identitytoolkit/v3/relyingparty/signupNewUser
API に対応しており、この API に直接 HTTP リクエストを送信することでユーザーを作成します。リクエストには API キーを付与する必要がありますが、この API キーは例えば次のようにして取得できます。
まずログイン画面を開きます。ここで開発者ツールのネットワークタブを開いたうえで、適当な認証情報を入力して送信します。