tag:crieit.net,2005:https://crieit.net/tags/Authentication/feed 「Authentication」の記事 - Crieit Crieitでタグ「Authentication」に投稿された最近の記事 2019-12-18T16:11:20+09:00 https://crieit.net/tags/Authentication/feed tag:crieit.net,2005:PublicArticle/14572 2018-10-19T20:52:47+09:00 2019-12-18T16:11:20+09:00 https://crieit.net/posts/Firebase Firebaseの匿名認証はなんのためにあるのか - セキュリティ編 <p>FirebaseのAuthenticationはGoogleログインやTwitterログインが簡単にできる便利なものですが、その中には匿名認証というものもあります。これが一体何のためにあるのか、セキュリティの観点から見てみます。今回はブラウザ上で動くWebアプリケーションの話です。</p> <h2 id="そもそも匿名認証とは?"><a href="#%E3%81%9D%E3%82%82%E3%81%9D%E3%82%82%E5%8C%BF%E5%90%8D%E8%AA%8D%E8%A8%BC%E3%81%A8%E3%81%AF%EF%BC%9F">そもそも匿名認証とは?</a></h2> <p>匿名認証というのは、ユーザーが何も操作などをしなくても、内部で勝手にログインする機能です。</p> <h2 id="何のためにあるのか?"><a href="#%E4%BD%95%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AB%E3%81%82%E3%82%8B%E3%81%AE%E3%81%8B%EF%BC%9F">何のためにあるのか?</a></h2> <p>基本的には公式の説明にいきなり書かれています。</p> <p><a target="_blank" rel="nofollow noopener" href="https://firebase.google.com/docs/auth/web/anonymous-auth?hl=ja">JavaScript を使用して Firebase 匿名認証を行う  |  Firebase</a></p> <blockquote> <p>アプリに登録していないユーザーが、セキュリティ ルールで保護されているデータを使用できるようになります。</p> </blockquote> <h2 id="セキュリティとは?"><a href="#%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%81%A8%E3%81%AF%EF%BC%9F">セキュリティとは?</a></h2> <p>Firebaseは便利ですが、怖いところがあります。Webアプリケーションの場合、JavaScriptを使うためFirebaseアプリケーションを初期化するための設定情報が丸見えになってしまいます。そのため、何のセキュリティも導入していないとその設定情報を使って誰でも勝手にそのアプリケーションの情報を読み書きできてしまいます。</p> <p>それを制限する方法として、ForestoreやStorageにはセキュリティルールがあります。例えば以下のようなことが設定できます。</p> <ul> <li>あるデータは誰でも閲覧できる</li> <li>あるデータはログインしたユーザーしか書き込みできない</li> </ul> <p>等。</p> <h3 id="セキュリティルールを設定しないとどうなるのか?"><a href="#%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%83%AB%E3%83%BC%E3%83%AB%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%AA%E3%81%84%E3%81%A8%E3%81%A9%E3%81%86%E3%81%AA%E3%82%8B%E3%81%AE%E3%81%8B%EF%BC%9F">セキュリティルールを設定しないとどうなるのか?</a></h3> <p>前述の通り設定情報が丸見えですので、それをコピーして誰かが自分のプログラムに組み込めば、他人のFirebaseのアカウントで自由にデータなどを扱えるようになってしまいます。</p> <p>見られてはいけないデータが見られてしまいますし、そもそも利用量によって金額も増えてしまう恐れがありとても危険です。</p> <h2 id="匿名認証を使ったセキュリティ設定の一例"><a href="#%E5%8C%BF%E5%90%8D%E8%AA%8D%E8%A8%BC%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E8%A8%AD%E5%AE%9A%E3%81%AE%E4%B8%80%E4%BE%8B">匿名認証を使ったセキュリティ設定の一例</a></h2> <p>セキュリティ上問題ないと思われる、匿名認証を使ったシンプルな例をあげてみます。(一部誤りと追記修正を含んでいます)</p> <h3 id="全てのデータの読み書きを認証済みの場合のみ許可する"><a href="#%E5%85%A8%E3%81%A6%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E8%AA%AD%E3%81%BF%E6%9B%B8%E3%81%8D%E3%82%92%E8%AA%8D%E8%A8%BC%E6%B8%88%E3%81%BF%E3%81%AE%E5%A0%B4%E5%90%88%E3%81%AE%E3%81%BF%E8%A8%B1%E5%8F%AF%E3%81%99%E3%82%8B">全てのデータの読み書きを認証済みの場合のみ許可する</a></h3> <p>認証していない場合はあらゆるデータの読み書きを不可能にします。</p> <h3 id="匿名認証で誰もが必ず認証している状態にする"><a href="#%E5%8C%BF%E5%90%8D%E8%AA%8D%E8%A8%BC%E3%81%A7%E8%AA%B0%E3%82%82%E3%81%8C%E5%BF%85%E3%81%9A%E8%AA%8D%E8%A8%BC%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E7%8A%B6%E6%85%8B%E3%81%AB%E3%81%99%E3%82%8B">匿名認証で誰もが必ず認証している状態にする</a></h3> <p>これで、ログイン機能がなかったり、手動でログインしたりしなくても全てのユーザーが読み書きできるようになります。</p> <h3 id="ログイン可能なホスト名を本番環境のみにする"><a href="#%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E5%8F%AF%E8%83%BD%E3%81%AA%E3%83%9B%E3%82%B9%E3%83%88%E5%90%8D%E3%82%92%E6%9C%AC%E7%95%AA%E7%92%B0%E5%A2%83%E3%81%AE%E3%81%BF%E3%81%AB%E3%81%99%E3%82%8B">ログイン可能なホスト名を本番環境のみにする</a></h3> <p>Firebase ConsoleのAuthenticationの設定でログインできるホスト名を設定することができます。ここで本番のホスト名だけを認証可能にします。こうすることで、Firebaseの設定情報を使われてもデータにアクセスすることなどは不可能となります。</p> <p>localhost等も当然消しておきましょう。開発時には別途開発用のFirebaseアプリケーションを用意し、そちらの設定を使ってください。ビルド時にはcross-envを使うと良いと思います。(誤りがあるので追記をご覧ください)</p> <p>追記)<br /> このホスト設定はリダイレクト用のため、匿名認証には利用できないようです。今のところ簡単に制限する方法はなさそうです。適切なセキュリティルールを設定してください。ルールの制限がないデータは今のところ他者に自由遊ばれる事ができてしまうのかもしれません…。良い情報があればぜひ提供をお願いします。</p> <h2 id="APIキーを制限する"><a href="#API%E3%82%AD%E3%83%BC%E3%82%92%E5%88%B6%E9%99%90%E3%81%99%E3%82%8B">APIキーを制限する</a></h2> <p>Firebaseのコンソールでなく、GCPコンソールの方で制限が必要そうです。詳しくは下記に書きました。</p> <p><a href="https://crieit.net/posts/Google-API">GoogleからAPIキーが公開されているよとアラートが来た</a></p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>このように、匿名認証を入れることで本番でしかデータを扱うことができなくなり、セキュリティのベース部分の強化を行うことができます。(追記:前述の理由から、リダイレクトがないので本番以外でも扱うことはできるため、正しいセキュリティルール設定が必要です)</p> <p>とにかく、設定情報が丸見えというのは非常に恐ろしい話です。当記事の話も鵜呑みにせず、しっかりと色々なパターンを考えセキュリティを強化しておきましょう。(むしろ間違っている話があればご指摘をお願いします)</p> <p>Firebaseと連携するあらゆる処理をfunctionsに実装して設定情報は公開しないようにする、くらいの強固さで考えるくらいでも良いかもしれません。(認証の連携ができないので厳しいかもしれませんが)</p> だら@Crieit開発者