使用本指南了解 Firebase 安全規則配置中的常見漏洞,檢查並更好地保護您自己的規則,並在部署更改之前測試您的更改。
如果您收到數據未得到適當保護的警報,請查看這些常見錯誤並更新任何易受攻擊的規則。
訪問您的 Firebase 安全規則
要查看現有規則,請使用 Firebase CLI 或 Firebase 控制台。確保使用相同的方法一致地編輯規則,以避免錯誤地覆蓋更新。如果您不確定本地定義的規則是否反映最新更新,Firebase 控制台始終顯示 Firebase 安全規則的最新部署版本。
要從Firebase 控制台訪問您的規則,請選擇您的項目,然後導航到Realtime Database 、 Cloud Firestore或Storage 。進入正確的數據庫或存儲桶後,單擊規則。
要從 Firebase CLI 訪問您的規則,請轉到firebase.json 文件中記錄的規則文件。
了解 Firebase 安全規則
Firebase 安全規則可保護您的數據免受惡意用戶的侵害。當您在 Firebase 控制台中創建數據庫實例或 Cloud Storage 存儲分區時,您可以選擇拒絕所有用戶的訪問權限(鎖定模式)或授予所有用戶訪問權限(測試模式)。雖然您可能在開發過程中需要更開放的配置,但請確保在部署應用程序之前花時間正確配置規則並保護數據。
當您開發應用並測試規則的不同配置時,請使用本地 Firebase 模擬器之一在本地開發環境中運行您的應用。
規則不安全的常見場景
在部署應用程序之前,應檢查和更新您默認設置的規則或最初開發應用程序時設置的規則。通過避免以下常見陷阱,確保正確保護用戶數據。
開放獲取
在設置 Firebase 項目時,您可能已設置規則以允許在開發期間進行開放訪問。您可能認為您是唯一使用您的應用程序的人,但如果您部署了它,它就可以在互聯網上使用。如果您沒有對用戶進行身份驗證並配置安全規則,那麼任何猜測您的項目 ID 的人都可以竊取、修改或刪除數據。
不推薦:所有用戶都具有讀寫權限。雲Firestore
// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this ruleset in production; it allows
// anyone to overwrite your entire database.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
實時數據庫
{
// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this ruleset in production; it allows
// anyone to overwrite your entire database.
"rules": {
".read": true,
".write": true
}
}
雲儲存
// Anyone can read or write to the bucket, even non-users of your app.
// Because it is shared with App Engine, this will also make
// files uploaded via App Engine public.
// Warning: This rule makes every file in your Cloud Storage bucket accessible to any user.
// Apply caution before using it in production, since it means anyone
// can overwrite all your files.
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
|
解決方案:限制讀寫訪問的規則。 構建對您的數據層次結構有意義的規則。解決這種不安全問題的常見解決方案之一是使用 Firebase 身份驗證實現基於用戶的安全性。了解有關使用規則驗證用戶身份的更多信息。 雲Firestore 僅限內容所有者
service cloud.firestore {
match /databases/{database}/documents {
// Allow only authenticated content owners access
match /some_collection/{document} {
allow read, write: if request.auth != null && request.auth.uid == request.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 read: if true
allow write: if request.auth != null && request.auth.uid == request.resource.data.author_uid
}
}
}
實時數據庫僅限內容所有者
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
}
公共和私人混合訪問
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path/$uid": {
".read": true,
// or ".read": "auth.uid !== null" for only authenticated users
".write": "auth.uid === $uid"
}
}
}
雲儲存僅限內容所有者
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
公共和私人混合訪問
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
|
任何經過身份驗證的用戶都可以訪問
有時,規則會檢查用戶是否已登錄,但不會根據該身份驗證進一步限制訪問。如果您的規則之一包含auth != null
,請確認您希望任何登錄用戶都有權訪問數據。
不推薦:任何登錄用戶都具有對整個數據庫的讀寫訪問權限。雲Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /some_collection/{document} {
allow read, write: if request.auth.uid != null;
}
}
}
實時數據庫
{
"rules": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
雲儲存
// Only authenticated users can read or write to the bucket
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
|
解決方案:利用安全條件縮小訪問範圍。 當您檢查身份驗證時,您可能還希望使用身份驗證屬性之一來進一步限制特定用戶對特定數據集的訪問。了解有關不同身份驗證屬性的更多信息。 雲Firestore 基於角色的訪問
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 get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
allow write: if 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
}
}
}
實時數據庫僅限內容所有者
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
}
}
}
路徑描繪的訪問
{
"rules": {
"some_path/$uid": {
".write": "auth.uid === $uid",
// Create a "public" subpath in your dataset
"public": {
".read": true
// or ".read": "auth.uid !== null"
},
// Create a "private" subpath in your dataset
"private": {
".read": "auth.uid === $uid"
}
}
}
}
公共和私人混合訪問
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path/$uid": {
".read": true,
// or ".read": "auth.uid !== null" for only authenticated users
".write": "auth.uid === $uid"
}
}
}
雲儲存基於組的訪問
// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
allow read: if resource.metadata.owner == request.auth.token.groupId;
allow write: if request.auth.token.groupId == groupId;
}
僅限內容所有者
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
公共和私人混合訪問
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
|
(實時數據庫)繼承規則不當
實時數據庫安全規則級聯,較淺的父路徑中的規則覆蓋較深的子節點中的規則。當您在子節點編寫規則時,請記住它只能授予附加權限。您無法細化或撤銷對數據庫中更深路徑中的數據的訪問。
不推薦:在子路徑上細化規則
{
"rules": {
"foo": {
// allows read to /foo/*
".read": "data.child('baz').val() === true",
"bar": {
/* ignored, since read was allowed already */
".read": false
}
}
}
}
|
解決方案:在廣泛的父路徑中編寫規則,並在子路徑中授予更具體的權限如果您的數據訪問需要更細粒度,請保持規則的細粒度。在保護您的數據中了解有關級聯實時數據庫安全規則的更多信息。 |
封閉訪問
在開發應用程序時,另一種常見方法是鎖定數據。通常,這意味著您已關閉所有用戶的讀寫訪問權限,如下所示:
雲Firestore
// Deny read/write access to all users under any conditions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
實時數據庫
{
"rules": {
".read": false,
".write": false
}
}
雲儲存
// Access to files through Cloud Storage is completely disallowed.
// Files may still be accessible through App Engine or Google Cloud Storage APIs.
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if false;
}
}
}
Firebase Admin SDK 和 Cloud Functions 仍然可以訪問您的數據庫。當您打算將 Cloud Firestore 或實時數據庫與 Firebase Admin SDK 結合使用作為僅服務器後端時,請使用這些規則。雖然它是安全的,但您應該測試應用程序的客戶端是否可以正確檢索數據。
要詳細了解 Cloud Firestore 安全規則及其工作原理,請參閱 Cloud Firestore 安全規則入門。
測試您的 Cloud Firestore 安全規則
要檢查應用的行為並驗證 Cloud Firestore 安全規則配置,請使用Firebase 模擬器。在部署任何更改之前,使用 Cloud Firestore 模擬器在本地環境中運行和自動化單元測試。
要在 Firebase 控制台中快速驗證 Firebase 安全規則,請使用Firebase 規則模擬器。