Enable Access Control in Realm

Hi there. I’m using the mongodb Realm and Atlas web UIs to manage my database serverlessly.

Now I’m having a big problem. I accidentally found out (because there are no warnings or hints except well hidden in the documentary…!) that even when I have enabled and set up authentication and thoroughly configured role restrictions that still anyone on the whole planet can access and read all of my database data.

WHY on earth would a company even default that?! This is so careless and dangerous, I almost can not believe that. I have sensible data (steam codes) in the database and thought having user authentication and role restrictions is enough to protect them. Nooooo because the mongo developers seem to not value security at all. By default everyone on the internet is invited to steal my data.

And there is no option that I can change that in the mongodb Realm web dashboard.

So for a basic security feature, where it should be very plausible to lock and close all virtual doors by default, I need to download stuff and learn how to use some 1980’s command shell stuff. Great.

Please imagine this: I was able to create, manage, update, delete, read a database and what not without touching a single command shell. But for making it secure I need to do that? Sorry that doesn’t look like a very reputable practice to bait novice people into using your, as so easy to use and fast to setup, product and then not protect these users by default.

I hope the development team will show mercy and implement these 4 lines of code asap, so that normal people who are not programmers can also have security. That’s one of the purposes of Realm I guessed.

Hi @Nilom_N_A,

Without revealing details to your cluster/project, could you elaborate which part of Realm does this involve ? i.e. Realm Sync, Webhooks, Functions, GraphQL, etc ? Could you provide the link to the hidden warnings in the documentation as well for better context ?

You need to create Realm Rules to allow access to a collection, and by default there are no rules set; which means there is no access. Would you be able to share which Realm Authentication Providers and what kind of role restrictions do you use ?

Are you referring to realm-cli ? and what did you need to do via the command line ?

Regards,
Wan.

3 Likes

Hello @wan ,

I use the Mongodb Realm Web SDK version 1.3.

I did already setup the rules as follows:

{
  "roles": [
    {
      "name": "owner",
      "apply_when": {
        "id": "%%user.id"
      },
      "insert": true,
      "delete": true,
      "search": true,
      "read": true,
      "write": true,
      "fields": {},
      "additional_fields": {}
    }
  ],
  "filters": [],
  "schema": {}
}

This is the collection where the useraccounts are saved. Users should only be able to read their own data.

My first attempt was to store the sensible data in another collection. The rules where the same. Users are able to only read own data. But that didn’t work either.

This is the code I use to sign the user in:

const id = "mongodb-notmyreal-id";
const config = {
  id,
};
globalThis.app = new Realm.App(config);


async function loginEmailPassword(email, password) {
  // Create an anonymous credential
  const credentials = Realm.Credentials.emailPassword(email, password);
  try {
    // Authenticate the user
    const user = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id)
    return user
  } catch(err) {
    console.error("Failed to log in", err);
  }
}
await loginEmailPassword(localVars.username, localVars.password).then(user => {
  console.log("Successfully logged in!", user);
})

What is strange about this is that even when I put wrong login data the console.error(“Failed to log in”, err); part will not be triggered. Instead it still will say “Successfully logged in!” but without a user id mentioned after that. Even though there will be a 401 error in the console. So even with wrong credentials a user can sign in via web sdk and email/password authentication? This is so strange because the Web SDK paired with the rules should only return the own custom_data because the collection is filtered by the users id? When not signed in, how can it return another users custom_data? Is this completely bugged?

Even though it is the email/password authentication I use it as username/password. It shouldn’t make a difference though? Just wanted to mention that if there is a bug or something.

Here is the link from the documentation. I’m pretty sure the “security is not enabled by default”-thing was not mentioned even once in the complete setup documentation of mongodb realm. And even it was, really this should not be default.

If you have any further questions please feel free to ask. I’m glad that you want to help.
Thank you!

Hi @Nilom_N_A ,

Do you mean for users should be able to read and write their own data ?

This is more about JS instead of Realm, but assert does not throw. You would need to add extra error handling in that code snippet to ensure that the user.id matches.

If you are using username instead of email, does that mean that you enable Automatically Confirm Users setting ? I would recommend to stick with email with confirmation.

Regards,
Wan.

1 Like

From my understanding of software security is that no matter what I do on client side, never should be any data readable that is not supposed to be readable from the database.

The code is 1/1 copied from the official mongodb documentation. If there is something wrong with it then it should be updated on the documentation aswell.

I know. For I full product I should use email so that lost passwords can be reset. But for now I sticked with username/password because it is just a christmas calendar for a friend.

Okay I see no one will be able to really help me on this. So I need to get rid of mongodb and just make the data locally.

Edit:

Turns out I failed. The issue was about sessions automatically managed by the Web SDK. So when I “logged out”, in reality I was still logged in to mongodb because the Web SDK still had a refresh token on the clients browser saved.

I forgot to do:

await app.currentUser.logOut();

Then again I wonder why the documentation says that Access Control is not enabled by default when it in fact is.