本指南說明「Firebase Security Rules」的常見安全漏洞
自行設定規則,檢查並加強保護自己的規則。
並在部署變更前進行測試
如果系統通知您資料可能不安全,
查看這些常見錯誤,並更新任何有安全漏洞的規則。
存取 Firebase Security Rules
如要查看現有Rules,請使用 Firebase CLI 或
Firebase 控制台。請務必使用相同的方式編輯規則
以避免意外覆寫更新。如果您不確定在本機定義的規則是否反映最新更新,Firebase 控制台一律會顯示最近部署的 Firebase Security Rules 版本。
如要透過 Firebase 控制台存取規則,請選取專案,然後前往 Realtime Database、Cloud Firestore 或 Storage。進入正確的資料庫或儲存空間桶後,請按一下「規則」。
如要透過 Firebase CLI 存取規則,請前往
在 firebase.json 檔案中記下的規則。
瞭解 Firebase Security Rules
Firebase Security Rules 保護資料免受惡意使用者的侵擾。在 Firebase 控制台中建立資料庫執行個體或 Cloud Storage 儲存桶時,您可以選擇拒絕所有使用者的存取權 (鎖定模式),或授予所有使用者的存取權 (測試模式)。雖然您可能會在開發期間採用較開放的設定,但請務必先花時間妥善設定規則,並確保資料安全無虞,再部署應用程式。
在開發應用程式並測試規則的不同設定時,請使用其中一個本機 Firebase 模擬器,在本機開發環境中執行應用程式。
常見的安全性偏低規則情境
您可能會預設設定 Rules,或是在最初開發應用程式時設定。在部署應用程式前,請先檢查並更新 Rules。請務必避免下列常見陷阱,確實保護使用者的資料。
公開存取
設定 Firebase 專案時,您可能已將規則設為允許開啟
存取資源您可能會認為只有您在使用應用程式,但如果您已部署應用程式,那麼網路上就會提供該應用程式。如果您沒有驗證使用者身分,也沒有設定安全性規則,那麼任何猜測到專案 ID 的使用者都能竊取、修改或刪除資料。
不建議:以下項目的讀取及寫入權限:
所有使用者。
Cloud 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;
}
}
}
Realtime Database
{
// 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
}
}
Cloud Storage
// 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 Authentication 實施使用者層級安全性。瞭解詳情
瞭解如何使用規則驗證使用者。
Cloud Firestore
僅限內容擁有者
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;
}
}
}
Realtime Database
僅限內容擁有者
{
"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"
}
}
}
Cloud Storage
僅限內容擁有者
// 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 會檢查使用者是否已登入,但不會根據該驗證進一步限制存取權。如果其中一個規則包含 auth != null
,請確認您要讓所有已登入的使用者都能存取資料。
不建議:任何已登入的使用者都有讀取
並授予完整資料庫的寫入權限
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /some_collection/{document} {
allow read, write: if request.auth.uid != null;
}
}
}
Realtime Database
{
"rules": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
Cloud Storage
// 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;
}
}
}
|
解決方案:使用安全性條件限制存取權。 檢查驗證時,您可能也想使用其中一個驗證屬性,進一步限制特定資料集的特定使用者存取權。進一步瞭解
驗證屬性。
Cloud 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
}
}
}
Realtime Database
僅限內容擁有者
{
"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"
}
}
}
Cloud Storage
群組存取權
// 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;
}
}
}
|
(Realtime Database) 不當繼承的規則
Realtime Database Security Rules 串聯,且規則範圍是較淺的,父項路徑覆寫
可建立更深層的子節點在子節點寫入規則時
授予對方其他權限您無法修正或撤銷
可在資料庫中更深入的路徑存取資料。
不建議:在子項路徑中修改規則
{
"rules": {
"foo": {
// allows read to /foo/*
".read": "data.child('baz').val() === true",
"bar": {
/* ignored, since read was allowed already */
".read": false
}
}
}
}
|
封閉存取
開發應用程式時,另一種常見的做法是
資料就會遭到鎖定通常這表示您已經關閉讀取和寫入功能
並開放所有使用者使用,方法如下:
Cloud 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;
}
}
}
Realtime Database
{
"rules": {
".read": false,
".write": false
}
}
Cloud Storage
// 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 或 Realtime Database 做為僅限伺服器的後端,並搭配使用 Firebase Admin SDK,請使用這些規則。雖然安全無虞,但您應測試應用程式的用戶端
以便正確擷取資料
進一步瞭解 Cloud Firestore Security Rules 及其運作方式
開始使用 Cloud Firestore Security Rules。
測試 Cloud Firestore Security Rules
如要查看應用程式行為並驗證 Cloud Firestore Security Rules 設定,
請使用 Firebase 模擬器。使用「Cloud Firestore」
模擬器,在部署前先在本機環境中執行及自動化單元測試
任何變更
如要在 Firebase 控制台中快速驗證 Firebase Security Rules,請使用
Firebase 規則模擬工具。