firebase security rule to allow admin users to read/write all other users creates a security breach?

泪湿孤枕 提交于 2021-02-11 05:55:40

问题


I am using cloud Firestore database and I have 'users' collection on my root database and in it there are all the users documents (named as the uid) and inside it the data I collect. I wanted to allow users to only read/write to their own collections so I started my security rules with

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
    }
  }
}

then I realized that the users don't have permission to create their own main document (it created it as a 'ghost' document). I also want to add data to it such as display name and email, so I added

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

all works well but now I want to allow admin users to read/write to all user's collections and documents. firebase's documentations suggests adding a key-value to the user's document such as (admin:true), so editing my security rules like so should do the trick:

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?
}

but doesn't it creates a security breach where a user can technically update his own document with (admin:true) and gain admin privilege? if so, i'm guessing my approach should be creating a separate admins collection and add my admins there and then do something in the lines of

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

? or is there something prettier I can use?


回答1:


This rule is indeed going to allow anyone to mark themselves as an Admin, defeating the whole purpose of your rules:

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

What you'll want to do is:

  • Either give the admin users a custom admin: true claim, which you can then check in your rules with: allow read, write: if auth.token.admin === true;
  • Keep an explicit list of UIDs for your admins in your security rules, and then check that in each rule. So: allow read, write: if isAdmin(); and then function isAdmin(request) { return request.auth.uid == "KqEizsqUQ6XMkUgLUpNxFnzLm4F3" }.
  • Keep a list of admin UIDs in another (not normally writeable) collection in Firestore, and check against that. That's pretty much what you've described, and is the most common approach if you want to be add/remove admins quickly and easily.



回答2:


Just to clarify, if you're going to use get() you need to put the full path. So in your case, it will be:

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

You can read more about it here



来源:https://stackoverflow.com/questions/60179115/firebase-security-rule-to-allow-admin-users-to-read-write-all-other-users-create

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!