允许管理员用户读取/写入所有其他用户的firebase安全规则会造成安全漏洞?

时间:2020-02-11 23:55:22

标签: firebase google-cloud-firestore firebase-authentication firebase-security

我正在使用Cloud Firestore数据库,并且我的根数据库上有“用户”集合,并且其中包含所有用户文档(称为uid),并且其中包含我收集的数据。 我希望只允许用户对自己的集合进行读/写操作,因此我从

开始了我的安全规则。
service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated content owners access
    match /users/{userId}/{documents=**} {
      allow read, write: if request.auth.uid == userId
    }
  }
}

然后我意识到用户没有创建自己的主文档的权限(将其创建为“幽灵”文档)。我还想向其中添加数据,例如显示名称和电子邮件,所以我添加了

// Allow users to read/write their own main user object
match /users/{userId} {
  allow read, write: if request.auth.uid == userId
}

一切正常,但现在我想允许管理员用户读取/写入所有用户的收藏夹和文档。 firebase's documentations suggests向用户文档(例如(admin:true))添加键值,因此像这样编辑我的安全规则应该可以解决问题:

match /users/{userId}/{documents=**} {
  allow read, write: if request.auth.uid == userId
  allow read, write: if get(/users/$(request.auth.uid)).data.admin == true; //-security breach?
}

但这是否会造成安全漏洞,用户可以使用(admin:true)从技术上更新自己的文档并获得管理员特权? 如果是这样,我想我的方法应该是创建一个单独的admins集合并在其中添加我的管理员,然后执行以下操作

allow read, write: if get(/admins/$(request.auth.uid)) != null

?还是我可以使用更漂亮的东西?

2 个答案:

答案 0 :(得分:3)

此规则确实将允许任何人将自己标记为管理员,从而​​破坏了规则的全部目的:

allow read, write: if get(/users/$(request.auth.uid)).data.admin == true;

您想要做的是:

  • give the admin users a custom admin: true claim之一,然后您可以使用以下命令检入规则:allow read, write: if auth.token.admin === true;
  • 在安全规则中为管理员保留明确的UID列表,然后在每个规则中进行检查。因此:allow read, write: if isAdmin();,然后function isAdmin(request) { return request.auth.uid == "KqEizsqUQ6XMkUgLUpNxFnzLm4F3" }
  • 在Firestore中的另一个(通常不可写)集合中保留管理员UID列表,并进行检查。这几乎就是您所描述的,并且是想要快速轻松地添加/删除管理员的最常用方法。

答案 1 :(得分:0)

只需澄清一下,如果要使用get(),则需要输入完整路径。因此,在您的情况下,它将是:

allow read: if get(/databases/$(database)/documents/admins/$(request.auth.uid)).data.admin == true

您可以详细了解here