• トップ
  • ブログ一覧
  • Firestore セキュリティルール ~ テストのすすめ ~
  • Firestore セキュリティルール ~ テストのすすめ ~

    広告メディア事業部広告メディア事業部
    2020.04.17

    IT技術

    Firestore セキュリティルールをテストしよう

    Firestore(ファイアストア)」は、クライアントコードから、直接読み書きができるなどの機能を備えた、便利な NoSQL データベースです。

    ですが、アクセス制限の要となるセキュリティルールの設定を怠ると、悪意あるユーザによって「データの改変・削除」がされる可能性があります。

    本記事では、危険なセキュリティルールの例と共に、セキュリティルールをテストすることのメリットを紹介していきます。

    セキュリティルールの手抜きは危険!?

    Firestore では、クライアントコードから直接、データの取得・更新をリクエストできます

    Firestore を利用する上での大きなメリットの1つですが、その反面、クライアントコードに Firestore への接続情報を記述する必要があります。

    セキュリティルールの設定が必要!

    例えば、ウェブクライアントから Firestore を使用する場合、ユーザはクライアントコードから簡単に接続情報を確認できます。

    そのため、Firestore 側で適切なアクセス制限(=セキュリティルール)が設定がされていないと、ユーザが自由にデータを取得・更新できてしまいます

    つまり、ユーザが悪意のあるユーザであった場合、データを悪用または破壊される可能性があります。

    危険なセキュリティルールの例

    危険なセキュリティルールの例を、いくつか挙げていきたいと思います。

    【※注意※】
    それぞれの例について、危険なセキュリティルールとより好ましいセキュリティルールを例示していますが、より好ましいセキュリティルールについても完全なものではありません。
    解説のために簡略化したものとなりますので、実際に本番環境で使用する場合は、各環境に応じてルールを追加するなどの調整が必要となります

    なお、セキュリティルールの構成や設定の方法については、以下で解説していますので、ぜひ参考にしてください。

    featureImg2020.03.23Firestore セキュリティルール ~入門編~Firestore セキュリティルールなにかと便利な「Firestore(ファイアストア)」ですが、セキュリティルール...

    プロファイル NO.1 ~ ブログ記事 ~

    ブログ記事のデータについて、以下のようにセキュリティルールを設定してみます。

    1rules_version = '2';
    2service cloud.firestore {
    3  match /databases/{database}/documents {
    4    match /articles/{article} {
    5      // 全てのユーザの読み書きを許可
    6      allow read, write: if true;
    7    }
    8  }
    9}

    上記のルールでは、全ての訪問者のデータの「読み書き」が許可されています

    公開ブログであれば、「読み込み」についての許可設定は必要となります。

    しかし、「書き込み」については、誰でも記事の内容を変更・削除できる状態であり、適切なルールとは言えません。

    認証付きユーザのみ「書き込み」を許可

    「書き込み」については、以下のように認証付きのユーザのみが「書き込み」可能とするなどの調整が必要となります。

    1rules_version = '2';
    2service cloud.firestore {
    3  match /databases/{database}/documents {
    4    match /articles/{article} {
    5      // 全てのユーザの読み込みを許可
    6      allow read: if true;
    7      // 認証されたユーザのみ書き込みを許可
    8      allow write: if request.auth.uid != null;
    9    }
    10  }
    11}

    プロファイル NO.2 ~ ユーザ情報 ~

    ユーザ情報について、以下のようにセキュリティルールを設定してみます。

    1rules_version = '2';
    2service cloud.firestore {
    3  match /databases/{database}/documents {
    4    match /users/{userId} {
    5      // 認証されたユーザのみ読み書きを許可
    6      allow read, write: if request.auth.uid != null;
    7    }
    8  }
    9}

    一見、問題ないかのように見えますが、上記のルールでは、認証されているユーザであれば、ユーザ本人以外のユーザのデータの「読み書き」も可能な状態となっています

    認証されているユーザであれば誰でも、全てのユーザの情報を閲覧・変更・削除が可能であり、ユーザ情報の漏えいや改ざんにつながる可能性があります。

    対策の1つとして、ユーザ本人だけが情報を取得・更新できるようにルールを設定することが挙げられるでしょう。

    ユーザ本人だけ「読み書き」を許可

    以下のようにルールを調整することで、ユーザ本人だけが情報を取得・更新できるようになります

    1rules_version = '2';
    2service cloud.firestore {
    3  match /databases/{database}/documents {
    4    match /users/{userId} {
    5      // ユーザ本人の読み書きを許可
    6      allow read, write: if request.auth.uid == userId;
    7    }
    8  }
    9}

    プロファイル NO.3 ~ サーバプログラムのログ ~

    サーバプログラムのログを Firestore に保存する場合、どのようにセキュリティルールを設定すれば良いでしょうか。

    サーバからのアクセスのみで、ウェブ・モバイルクライアントからの「読み書き」は特に必要がない場合を考えます。

    サーバプログラムのログについてセキュリティルールを設定

    サーバプログラムのログについて、以下のようにセキュリティルールを設定してみます。

    1rules_version = '2';
    2service cloud.firestore {
    3  match /databases/{database}/documents {
    4    match /server_logs/{log} {
    5      // 全てのユーザの読み込みを許可
    6      allow read: if true;
    7    }
    8  }
    9}

    セキュリティルールは、ウェブ・モバイルクライアントからのアクセスに適用され、サーバからのアクセスには適用されません。

    悪意あるユーザに、サーバプログラムのログを取得された場合、そこからセキュリティホールを発見、または推測される可能性があります。

    そのため、クライアントで使用する事のないデータについては、不必要にアクセスを許可せずに、以下のように全てのアクセスを拒否してしまうのが安全です

    1rules_version = '2';
    2service cloud.firestore {
    3  match /databases/{database}/documents {
    4    match /server_logs/{log} {
    5      // 全てのユーザの読み書きを拒否
    6      allow read, write: if false;
    7    }
    8  }
    9}

    セキュリティルール ~ テストのすすめ ~

    以上のように、セキュリティルールが適切でない場合、意図しないユーザに情報が漏れてしまったり、データを改ざん・削除されてしまうといった事態が起こりえます。

    Firestore を活用する上で、継続的にセキュリティルールの動作をチェックし、ルールを適正な状態に保つことが重要となります

    Firebase コンソールには、ルールの動作確認用のシミュレータが用意されています。

    ですが、シミュレータを使うと、変更や調整のたびに毎回デプロイが必要だったり、設定の入力が必要だったりと手間がかかります。

    また、ステージング環境では、手動操作でルールの確認もできますが、同様に面倒です。

    そういった面倒や手間の回避する策として、テストによってセキュリティルールをチェックする事がおすすめです。

    セキュリティルールをテストするメリット

    セキュリティルールをテストするメリットをご紹介したいと思います!

    ルールの確認が楽!

    テストを用いたセキュリティルールのチェックでは、コマンドラインからテストを実行するだけで、セキュリティルールが適正な状態であるかどうかを確認することができます

    ファイルの監視機能があるテストツールであれば、ルールの変更に併せて自動でテストを再実施してくれるので、一段とスムーズにセキュリティルールの実装を進める事ができます。

    また、ルールに不備があった場合には、テストのエラーメッセージによって不備のある箇所の推測・特定の助けとなるでしょう。

    リグレッションテスト

    慎重な設定・取り扱いが必要なセキュリティルールですが、テストによる保護があれば、気楽に追加調整や変更を加える事ができます

    同様の理由で、ルールの見通しをよくするために「ネスト記述で書き換える」、「カスタム関数を導入する」といった具合に、ルールのリファクタリングも気楽にできるようになります。

    ルールのリファクタリングによってクリアなルールを維持することで、結果的にルールの設定漏れや設定ミスの防止につながります。

    安全な環境を維持

    「全てのアクセスを拒否する」ルールからスタートして、必要に合わせてアクセス許可のテストを追加していくことで、必要以上のアクセス許可が追加されることを継続的に防ぐことができます。

    まとめ

    以上、セキュリティルールの不備の危険性と、セキュリティルールをテストによって管理することのメリットを紹介しました。

    最後に、簡単に今回の内容をまとめてみたいと思います。

    1. セキュリティルールの手抜きは危険!
    2. テストでセキュリティルールをチェック
    3. リグレッションテストで安全性を維持
    4. テストを導入すれば、気楽に調整ができる!
    5. テストを導入すれば、気楽にリファクタリングができる!

    テストの導入は、多少の面倒はありますが、一度導入してしまえば、その後の開発の大きな助けとなります。

    セキュリティルールのテストの導入については、以下の記事で詳細に解説しています。

    興味がある方は、ぜひ読んでいただければ!

    こちらの記事もオススメ!

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    featureImg2020.08.04エンジニアの働き方 特集社員としての働き方社員としてのエンジニアの働き方とは?ライトコードのエンジニアはどんな働き方をしてるのか、まとめたいと...

    featureImg2020.07.27IT・コンピューターの歴史特集IT・コンピューターの歴史をまとめていきたいと思います!弊社ブログにある記事のみで構成しているため、まだ「未完成状態」...

    広告メディア事業部

    広告メディア事業部

    おすすめ記事