修正不安全的規則

您可以參考本指南,瞭解 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 Security Rules,或第一次使用 Cloud Firestore 開發應用程式時。

公開存取

設定 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 仍可存取您的資料庫。如要將 Cloud Firestore 用於僅限伺服器的後端,並搭配使用 Firebase Admin SDK,請使用這些規則。雖然這項做法安全無虞,但您仍應測試應用程式的用戶端是否能正確擷取資料。

如要進一步瞭解 Cloud Firestore Security Rules 及其運作方式,請參閱「Cloud Firestore Security Rules 入門」。

請查看「Cloud Firestore Security Rules

如要檢查應用程式的行為並驗證 Cloud Firestore Security Rules 設定,請使用 Cloud Firestore 模擬器。部署任何變更之前,請先使用 Cloud Firestore 模擬器,在本機環境中執行及自動化單元測試。

如要在 Firebase 控制台中快速測試更新後的 Cloud Firestore Security Rules,請使用 Rules Playground 工具。

  1. 如要開啟「Rule Playground」,請按一下「Rules」分頁中的「Rules Playground」
  2. 在「Rules Playground」設定中,選取測試選項,包括:
    • 測試讀取或寫入
    • 資料庫中的特定「位置」,以路徑表示
    • 驗證類型:未驗證、已驗證的匿名使用者,或特定使用者 ID
    • 規則特別參照的文件專屬資料 (例如,如果規則要求在允許寫入前必須有特定欄位)
  3. 按一下「執行」,然後在規則視窗上方的橫幅中查看結果。