Haris Bjelic
Haris Bjelic

Reputation: 117

Firebase 3.0 Security Rules - Don't allow to push anonymous children

I'm building an application that allows users to stamp their working times. On my application are 2 types of users. One of them are the 'employee' which has only read access and the other is the 'admin' that has read and write access. The employee are allowed to read their own worktimes and the admins are allowed to create new users or add worktimes for each user/employee.

The admin fills the form and push the Data. On firebase, I checked if the user is authenticated andalso runned a validation for each property of the user object. But I'm asking myself, what if somebody copy my firebase url (which are visible in the source code) and tries to push some anonymous objects or properties to my database?

For example, I've SignUp form which requires this fields:

{ 
   "users": {
      "-KInd4V0V9k5n6yhAETd": {
         "uid": "-KInd4V0V9k5n6yhAETd",
         "username": "Haris",
         "password": "HelloWolrd123",
         "age":      "21"
         }
    }
}

On the firebas side, I've checked with the newData method if the children are passed from the form:

".validate": "newData.hasChildren(['uid','username','password,'age'])"

I've ran already a validation for each property that checks if the data are valid like username.isString() etc.

So what if an admin pushes an user object with the developer-tools like this to my database (email property added)

 {
    "-KInd4V0VEEEEEEEE": {
         "uid": "-KInd4V0VEEEEEEEE",
         "username": "Haris",
         "password": "HelloWolrd123",
         "age":      "21",

         // anonymous Object pushed from n admin developer-console
          "email": "[email protected]"
         }
}

This will work because all required fields are valid and the validation passed on firebase. But how can I deny that an admin can't add and pass the 'email' property to my firebase database? Because my user object structure on the Database don't have an email property. I don't wanna allow that an user can push his own anonymous objects/data to my database. Do I need to validate each property or is there a method which I can validate the Object itself? Like newData('users').isValid()? And If a property is append then isValid returns false because the object are not the same like in the database structure?

Upvotes: 0

Views: 406

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

I'm not entirely sure, but think you are looking for a rule that rejects all other children. If that is indeed what you're looking for, then:

{
  "rules": {
    "users": {
      "$uid": {
        // Valid users have these properties
        ".validate": "newData.hasChildren(['uid','username','password,'age'])",
        // The uid property must be a string and refer to an existing noder under /users
        "uid": {
          ".validate": "newData.isString() && root.child('users').child(newData.val()).exists()"
        },
        // the user name must be a string
        "username: {
          ".validate": "newData.isString()"
        },
        "password: {
          // I really hope you're not storing a password
        },
        "age: {
          // TODO: you're storing age as a string now, might want to fix that
          ".validate": "newData.isNumber()"
        },
        // All other properties are rejected
        "$other": {
          ".validate": false
        }
      }
    }
  }
}

Upvotes: 2

Related Questions