I'm trying to find the best way to design security for our app that uses firebase
Basic problem
We want our users' data to be secure. We don't want a malicious agent to be able to access other users' private data on the Firebase db. It seems that there should be a solution for this via firebaseSimpleLogin, but despite scouring the documentation, we haven't seen one.
Problem specifics
Solutions we've considered
1. Store a user_secret to ensure user has legitimate access
Problems with #1
2. Temporarily Store User Secret
Problem with #2 - The issue with this method is the user is vulnerable while they're logged in, as their security information would be present.
3. Use built in Firebase Security Rules
We are hoping someone can help shed light on the best approach here, either using our ideas or another route. Thanks so much for your help.
You've essentially asked for someone to write an entire security schema for your app. It would be better if you understood security rules thoroughly before attempting to apply them to a complex structure like this. A good study of the docs from start to end would take you a long way to a fully functional solution.
Let's just focus on what seems to be the core problem, which is that you aren't sure how to make invites work securely with a client-only solution. (The node.js solution should also be obvious with this understanding, given the additional firepower provided by being able to create our own tokens) I'll make a lot of assumptions here; just apply these ideas to your current use case as you see fit.
A data structure:
/invites/$game_id/$uuid/true (a place to store invited users)
/accepted_invites/$gameid/$userid/$uuid/true (a place to store accepted invites)
/games/$game_id (the place we want to invite users into)
/users/$user_id (a place where we put profiles for existing users)
1) When a new user creates an account in the app, write their profile into /users. Secure users/ as follows:
"users": {
"$userid": {
".write": "auth.uid === $userid"
}
}
2) To invite a user, create a uuid , which represents an unguessable id, and store it in invites/$game_id. Note that nobody should be able to read this path.
"invites": {
"$game_id": {
"$invite_id": {
// I can only create an invite for groups I'm a member of
".write": "root.child('games/'+$game_id+'/members/'+auth.uid).exists()",
".validate": "newData.val() === true"
}
}
}
3) To join a game, a user must first accept the access token, which proves that they know the token (since they can't read the invites path) and links the token to their account id. The value of this entry is the uuid of the invite.
"accepted_invites": {
"$game_id": {
"$user_id": {
".write": "auth.uid === $user_id",
".validate": "root.child('invites/'+$game_id+'/'+newData.val()).exists()"
}
}
}
4) A user can write themselves into a game if they have accepted an invite or when it is initially created and there are no members yet (the !data.parent().exists()
rule)
"game": {
"$gid": {
"members": {
"$uid": {
".write": "auth.uid === $uid",
// I can join a group if a) I'm creating it or b) I have accepted an invite
".validate": "!data.parent().exists() || root.child('accepted_invites/'+$gid+'/'+auth.uid).exists()"
}
}
}
}
Another enhancement to our client-side solution would be to assign the invites a priority, which represents when they expire, and then reference that priority in the security rules to control how long the token is valid.
I ended up going with idea #3, thanks to the help of @Kato's suggestions. The solution of using the built in rules and designing a schema allowed us to avoid needing a 3rd party auth server, so far. Some example of the schema was as follows:
"game_detail" : {
"$game_detail" : {
".read" : "data.child('owner').val() === auth.email || root.child('admins').val() === auth.email",
".write" : "newData.child('owner').val() === auth.email || root.child('admins').val() === auth.email"
}
},
Then, the additional key that made #3 possible was that, in addition to having a schema of security rules, we also created a generic admin credential that can be used by anonymous users when they are logged in to access a subset of the DB and perform necessary cross account operations.
Thanks all for the input here.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.