2

Upon login through firebase, I obtained the uid from firebase. With that uid, I go into my database and grab more information about the user

-user
    -9a0rzPh3g5bqclxsarzx6pvd03  <- this is the user id
        -name: John Doe
        -companyId: Microsoft
        -uid: 9a0rzPh3g5bqclxsarzx6pvd03
        -email: john.doe@mail.com
        -managerEmail: JamesBond@mail.com

Now my app has the detail of the user saved in a variable named currentUser.

As my app is a 'form' based app where user submits forms to manager for approval, when the user fills out a form, I save it to my firebase node based on the "companyId" The manager (James Bond) will then be able to query the pendingForms node to look for anything that is addressed to him

-forms
    -Microsoft
        -pendingForms
            -KdAh5CCsbxvc1EVcbau <- this is the time stamped ID generated by firebase
                -submissionDate: 72490175
                -submistionNote: Please take a look
                -managerEmail: JamesBond@mail.com
                -userEmail: JohnDoe@mail.com

Since my app is build on Angular 2 with Typescript, I believe my code is vulnerable to being modified. My concern is that once the user info is downloaded, the user is able to go into the code and change the "currentUser" variable's companyId to someone else's. Therefore, if he has access to the companyId and manager email of that other company, he would be able to submit the form to that manager just by manipulating the client side code.

I have been reading several firebase documentation in relation to the Security Rules API and User based security rule. The only way that I can see to resolve this is Custom Auth Token such as

".write": "auth.companyId === root.child('user/' + $companyId).child(auth.uid).child('managerEmail).val()"

However, I dont think this is is the best approach for me because I am not familar to creating extra servers for this. I was thinking if there is another approach such as adding the following logic to the security rule

  1. When firebase received the new date, firebase looks into the "managerEmail" field and get that value. -> newData.child('managerEmail')
  2. Firebase then use the auth.uid value to go into user/uid/managerEmail to see if this value matches the obtained managerEmail.
  3. If they are the same, that means the data has not been modifed at client side.
  4. If they dont match, that means the client has somehow modified the user variable
ErnieKev
  • 2,831
  • 5
  • 21
  • 35

1 Answers1

3

The user can indeed change the uid in the client.

But Firebase's security rules are automatically enforced on the Firebase servers. And there is no way for them to fake the value of auth.uid in the security rules, unless they know the credentials to sign in as that user.

In other words: I can easily determine that your Stack Overflow user id is 7528750. But unless I also know your credentials (e.g. email+password), there is no way I can sign in to Stack Overflow and start posting as you.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Hi Frank. I agree with for what you are saying. However, I am not sure if that provides a solution or guide to my question. My question is... as I am updating the nodes in firebase based on the user information that is stored in the real time database (CompanyId, Manager'sEmail), the user can easily modify that and start saving to another branch where he shouldn't be storing. Hence, I want to have a server side rule to verify that the user data (companyId and manager's email) has not been modified from client side. Cheers – ErnieKev Feb 18 '17 at 04:03
  • In the question, I have provide the logic that I think will work. However, I dont know if it is possible to implement that in the security rules in firebase? Would Custom Token be the only solution? – ErnieKev Feb 18 '17 at 04:08
  • No, custom tokens are not the only solution. You can secure your database with the exact security rules that you're asking about. That leads to a question: who determines that `JamesBond@mail.com` is a manager? You need to store the fact that he's a manager somewhere in your database and ensure that only that "who" person can change such a fact. – Frank van Puffelen Feb 18 '17 at 04:15
  • 1
    This turns into a role based security model, like the one Sara has in [this gist](https://gist.github.com/sararob/331760829a9dcb4be3e7), or the one from Jenny talks about in [this answer](http://stackoverflow.com/questions/25641184/firebase-set-security-rules-depending-on-user-roles) or hiattp [has here](http://stackoverflow.com/questions/19520615/how-do-i-implement-role-based-access-control-in-firebase)... and probably more from [this list](https://www.google.com/search?q=site:stackoverflow.com+trenches+firebase&oq=trenches+firebase). – Frank van Puffelen Feb 18 '17 at 04:22
  • This helps a lot. Thanks – ErnieKev Feb 18 '17 at 04:33