安全でないルールを修正する

このガイドを使って、Cloud Firestore Security Rules 構成における一般的な脆弱性を理解し、独自のルールを確認してセキュリティを強化して、デプロイする前に変更内容をテストします。

Cloud Firestore データベースが適切に保護されていないという警告を受け取った場合は、Cloud Firestore Security Rules を変更してテストすることで脆弱性を解決できます。

既存のセキュリティ ルールを表示するには、Firebase コンソールの [ルール] タブに移動します。

Cloud Firestore Security Rules について理解する

Cloud Firestore Security Rules は悪意のあるユーザーからデータを保護します。Firebase コンソールで作成された Cloud Firestore インスタンスのデフォルトのルールでは、すべてのユーザーへのアクセスが拒否されます。アプリを開発してデータベースにアクセスするには、これらのルールを変更して、開発環境内のすべてのユーザーに包括的なアクセス権を付与することを検討する必要があります。ただし、アプリを本番環境にデプロイする前に、十分な時間をかけてルールを正しく構成し、データを保護してください。

アプリの開発過程において、さまざまな構成でルールをテストする際は、Cloud Firestore エミュレータを使用してローカルの開発環境でアプリを実行します。

安全でないルールに関する一般的なシナリオ

デフォルトで設定した、または Cloud Firestore でのアプリの開発で最初に操作した Cloud Firestore Security Rules は、アプリをデプロイする前に確認して更新する必要があります。以下に示すよくある誤りを回避して、ユーザーのデータを適切に保護してください。

オープン アクセス

Cloud Firestore を設定する際に、開発中にオープン アクセスを許可するようにルールを設定している場合があります。アプリのユーザーは自分だけだと思いがちですが、アプリをデプロイすると、そのアプリはインターネット上で利用可能な状態になります。ユーザー認証を行っていない場合や、セキュリティ ルールを構成していない場合は、誰でもプロジェクト ID を推測してデータにアクセスし、データを窃取、変更、削除できてしまいます。

非推奨事項: すべてのユーザーに対する読み取りと書き込みのアクセス権。
// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this rule set in production; it allows
// anyone to overwrite your entire database.

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}
解決策: 読み取りと書き込みのアクセス権を制限するルール。

データ階層に合ったルールを構築します。この非安全性に対する一般的な解決策の一つは、Firebase Authentication によるユーザー単位のセキュリティです。詳しくは、ルールを使用したユーザーの認証をご覧ください。

コンテンツ所有者のみ

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated content owners access
    match /some_collection/{document} {
      // Allow reads and deletion if the current user owns the existing document
      allow read, delete: if request.auth.uid == resource.data.author_uid;
      // Allow creation if the current user owns the new document
      allow create: if request.auth.uid == request.resource.data.author_uid;
      // Allow updates by the owner, and prevent change of ownership
      allow update: if request.auth.uid == request.resource.data.author_uid
                    && request.auth.uid == resource.data.author_uid;

    }
  }
}
  

公開アクセスと限定公開アクセスの混合

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      // Allow public reads
      allow read: if true
      // Allow creation if the current user owns the new document
      allow create: if request.auth.uid == request.resource.data.author_uid;
      // Allow updates by the owner, and prevent change of ownership
      allow update: if request.auth.uid == request.resource.data.author_uid
                    && request.auth.uid == resource.data.author_uid;
      // Allow deletion if the current user owns the existing document
      allow delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}
  

認証されたユーザーのアクセス

Cloud Firestore Security Rules によってユーザーがログイン済みであることが確認されますが、その認証に基づき、それ以上はアクセスが制限されないことがあります。いずれかのルールに auth != null が含まれている場合は、ログインしているユーザーがデータにアクセス可能にする必要があることを確認します。

非推奨事項: ログインしているすべてのユーザーが、データベース全体に対して読み取りと書き込みのアクセス権を持っている。
service cloud.firestore {
  match /databases/{database}/documents {
    match /some_collection/{document} {
      allow read, write: if request.auth != null;
    }
  }
}
解決策: セキュリティ条件を使用してアクセスを制限する。

認証を確認するときは、いずれかの認証プロパティを使用して、特定のユーザーによる特定のデータセットへのアクセスをさらに制限することもできます。詳しくは、セキュリティ ルールの条件を追加する方法ロールベースのアクセス権をご覧ください。

ロールベースのアクセス権

service cloud.firestore {
  match /databases/{database}/documents {
    // Assign roles to all users and refine access based on user roles
    match /some_collection/{document} {
     allow read: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
     allow write: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"

     // Note: Checking for roles in your database using `get` (as in the code
     // above) or `exists` carry standard charges for read operations.
    }
  }
}

属性ベースのアクセス権

// Give each user in your database a particular attribute
// and set it to true/false
// Then, use that attribute to grant access to subsets of data
// For example, an "admin" attribute set
// to "true" grants write access to data

service cloud.firestore {
  match /databases/{database}/documents {
    match /collection/{document} {
      allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
      allow read: true;
    }
  }
}
  

公開アクセスと限定公開アクセスの混合

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      allow read: if true
      allow write: if request.auth.uid == request.resource.data.author_uid
    }
  }
}
  

クローズド アクセス

アプリの開発中における一般的なアプローチとしては、データを遮断するという方法もあります。通常、これは以下のように、すべてのユーザーに対して読み取りと書き取りのアクセス権を拒否することを意味します。

// Deny read/write access to all users under any conditions
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Firebase Admin SDK と Cloud Functions は、引き続きデータベースにアクセスできます。Firebase Admin SDK と組み合わせ、サーバーのみのバックエンドとして Cloud Firestore を使用する場合は、これらのルールを使用します。これによってセキュリティは確保されますが、アプリのクライアントによって適切にデータが取得されることをテストする必要が生じます。

Cloud Firestore Security Rules とその仕組の詳細については、Cloud Firestore Security Rules を使ってみるをご覧ください。

Cloud Firestore Security Rules」を確認してください

アプリの動作確認と Cloud Firestore Security Rules 構成の検証を行うには、Cloud Firestore エミュレータを使用します。変更をデプロイする前に、Cloud Firestore エミュレータを使用して、ローカル環境で単体テストの実施と自動化を行います。

更新した Cloud Firestore Security Rules を Firebase コンソールですばやくテストするには、ルール プレイグラウンド ツールを使用します。

  1. ルール プレイグラウンドを開くには、[ルール] タブの [ルール プレイグラウンド] をクリックします。
  2. ルール プレイグラウンドの設定で、次のようなテストのオプションを選択します。
    • 読み取りまたは書き込みのテスト
    • データベース内の特定の場所(パスとして)
    • 認証タイプ - 未認証、認証された匿名ユーザー、または特定のユーザー ID
    • ルールで参照するドキュメントの固有のデータ(例: ルールで書き込みを許可する前に、特定のフィールドが存在している必要がある場合)
  3. [実行] をクリックして、ルール ウィンドウの上のバナーで結果を確認します。