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

Joe*_*Joe 3 firebase firebase-security firebase-authentication google-cloud-firestore

我正在使用云 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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

// Allow users to read/write their own main user object
match /users/{userId} {
  allow read, write: if request.auth.uid == userId
}
Run Code Online (Sandbox Code Playgroud)

一切正常,但现在我想允许管理员用户读取/写入所有用户的集合和文档。 firebase 的文档建议向用户文档添加一个键值,例如(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?
}
Run Code Online (Sandbox Code Playgroud)

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

allow read, write: if get(/admins/$(request.auth.uid)) != null
Run Code Online (Sandbox Code Playgroud)

?或者有什么更漂亮的东西我可以使用?

Fra*_*len 6

该规则确实允许任何人将自己标记为管理员,从而​​违背了规则的全部目的(不要这样做):

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

你更想做的是:

  • 要么为管理员用户提供自定义admin: true声明,然后您可以使用以下方式检查您的规则:allow read, write: if auth.token.admin === true;
  • 在安全规则中保留管理员的明确 UID 列表,然后在每个规则中进行检查。所以:allow read, write: if isAdmin();然后function isAdmin(request) { return request.auth.uid == "KqEizsqUQ6XMkUgLUpNxFnzLm4F3" }
  • 将管理员 UID 列表保留在 Firestore 中的另一个(通常不可写)集合中,并进行检查。这几乎就是您所描述的,如果您想快速轻松地添加/删除管理员,这是最常见的方法。