Database security

So how exacly are we supposed to control who adds what to the database?

If we remove all the permissions by default:


Users can’t sign up.

I don’t want them to be able to write in the “e-mail” field again after signing up. But If they have permission to write once they can re-write again.

I also want usernames to be readable by the public but not e-mails.
Users being able to add random fields is also quite annoying.

Thanks in advance!

You can add a validation before data is added to the database, or add more columns, rename, remove fields. Here is an example from another thread: Sign Up (Cloud functions field validation)
The idea is that you can use beforeSave trigger: https://docs.moralis.io/moralis-server/cloud-code/triggers#beforesave

1 Like

My app might have 1000 fields, am I supposed to validate all 1000 fields in the same function every time someone tries to save something?

You make a validation function per table/class, you can validate how many fields you want in that function.

1 Like

So every query triggers the “beforeSafe”.
Sign up is basically a query then right?

And I guess CLP is really broad… I will still use CLP in each class but where I really want to make more detailed verifications is with the ACL.

You make a validation function per table/class, you can validate how many fields you want in that function.

Is this ACL? How exacly do I check the table the user is trying to edit?
Does all ACL code goes inside “beforeSave”?

beforeSave is called whenever something changes in the database


Moralis is built on open source software called parse and inherits the security system from Parse.
To learn more about ACL and CLP check this: https://blog.back4app.com/parse-server-security/.
Especially see the security checklist at the bottom.

CLP is used to protect the whole class
ACL is used if you want to protects a specific row in a class


You can use Roles in order to give users different CLP and ACL permissions

Note: Moralis doesn’t support column level permission access meaning you can’t expose some columns while hiding the rest (like hiding email but showing username in the same Class).

To achieve this you need to split up data into different Classes


1 Like

How can I split username to be public and email to be private?

Like we describe in our docs https://docs.moralis.io/moralis-server/database/security#access-control-lists

You need to create 2 Classes

1 for public data

1 for private (User Class can be used for private as its protected by default)

1 Like

How can I know if a class is protected? And what does “Security->Protected Fields” do then, if not to hide columns from the public?

From Parse:

The Parse.User class is secured by default. Data stored in a Parse.User can only be modified by that user. By default, the data can still be read by any client.

Aka: emails are public

And also: Where should I configure the ACL objects? In the cloud outside any function?

But somehow if I run this query in the browser:

let query = new Moralis.Query("User");
result = await query.find()

I get the information only for current user and not for any other user.

1 Like

Ok cool I assume you guys dealt with that problem, what does “Security->Protected Fields” do tho?
And “where should I configure the ACL objects? In the cloud outside any function?”

Sorry If I’m being annoying I just really want to understand everything at 100%

In dashboard, in the ACL column, you can double click on that entry to get to a new interface for a particular row in that table. This way you will see that there is an ACL already present for every user row in User table.

1 Like

Ok got it.
What about “Security->Protected Fields” in the moralis dashboard in each class?

For protected fields, for example for

    let query = new Moralis.Query("EthBalance");
    result = await query.find()

If you run this query in a browser without any protected fields, then you will get the data for all the entries and for all the fields. If you add specific fields as protected fields to EthBalance class/table then those protected fields will not appear any more as the result of that query, and only the rest of the fields.

1 Like

Couldn’t we say that field is private then? Or is it still possible to read that field?

From a cloud function with master key you can read everything.
In particular it looks like protected fields don’t work on User class (maybe this class is special).

1 Like

I understand that with a master key you can still read anything and that makes sense.

The thing is, why would I want to make a “privateData” class if I can just mark the fields I want to hide as protected? If I want a “phone number” field to be private but the rest of the fields to be readable by the public, why should I use a different class to store that value instead of using the same class and mark that field as protected?

My assumption: if you want to add that “phone number” field directly to User class, and if the User class is special and it doesn’t work with protected fields, then you would have to move that field to another class.

1 Like

protected fields don’t work only with public access, they can work with restricted access too, and in that case you may not want to hide the phone number field from current user because it is his phone number anyway.

1 Like

We will soon record a video explaining everything in detail thanks for great questions

1 Like