使用本指南了解 Firebase 安全规则配置中的常见漏洞,审查并更好地保护您自己的规则,并在部署之前测试您的更改。
如果您收到有关您的数据未得到妥善保护的警报,请查看这些常见错误并更新任何易受攻击的规则。
访问您的 Firebase 安全规则
要查看现有规则,请使用 Firebase CLI 或 Firebase 控制台。确保使用相同的方法一致地编辑规则,以避免错误地覆盖更新。如果您不确定本地定义的规则是否反映了最新更新,Firebase 控制台始终会显示最新部署的 Firebase 安全规则版本。
要从Firebase 控制台访问您的规则,请选择您的项目,然后导航到实时数据库、 Cloud Firestore或存储。进入正确的数据库或存储桶后,单击规则。
要从 Firebase CLI 访问您的规则,请转到您的firebase.json 文件中记录的规则文件。
了解 Firebase 安全规则
Firebase 安全规则保护您的数据免受恶意用户的侵害。在 Firebase 控制台中创建数据库实例或 Cloud Storage 存储桶时,您可以选择拒绝所有用户访问(锁定模式)或授予所有用户访问权限(测试模式)。虽然在开发过程中您可能需要更开放的配置,但请确保在部署应用程序之前花时间正确配置规则并保护数据。
当您开发应用程序并测试规则的不同配置时,请使用本地 Firebase 模拟器之一在本地开发环境中运行您的应用程序。
具有不安全规则的常见场景
在部署应用程序之前,应检查和更新您可能默认设置的规则或您最初开发应用程序时设置的规则。通过避免以下常见陷阱,确保您正确保护用户数据。
开放获取
在设置 Firebase 项目时,您可能已设置规则以允许在开发期间进行开放访问。您可能认为您是唯一使用您的应用程序的人,但如果您部署了它,它就可以在 Internet 上使用。如果您不对用户进行身份验证和配置安全规则,那么任何猜测您的项目 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 规则模拟器。