Security Risk with Recommended Data Rules!

For everyone that is depending on the default privacy security on data: Creator is Current User

There is a big hole there. It should be Current User Is Logged In AND Creator is Current User

Why?

  1. If a User is deleted THEN Creator on all records created by that user become empty AND i can see your data by actually not logging in. Try it on the data APIs, use an anonymous browser window.
  2. If you created a record through a backend workflow, then creator could be empty anyways and same problem.

Seems someone should have caught this… Including myself since i have been using bubble for 7 years.

Oh Well.

6 Likes
  1. Just don’t use Creator in general because it can’t be manually set - use a User field
  2. use This Thing’s X is Current User’s X and This Thing’s X is not empty
8 Likes

You have to be careful with “logged in” because you may need users to have access to data pre-signup. I’m actually not sure what the purpose of sending a data request with correct authentication while not being logged in would be from the perspective of a malicious actor.

You can fix this by including This Thing’s Creator is not empty or do as @georgecollier recommended. I prefer using Creator for data types where I know the user will never need to be changed because it means that it’s 100% secure to be overwritten. You can’t change that field even if you wanted to. On the contrary it is possible to write to fields even if privacy rules don’t give you access to read those fields. So the choice is between 100% security and 100% modularity.

Yes I’m with George on this. If you are doing data recovery, relying on the Creator field is problematic. Good enough to get your MVP running, but operationally it’s a problem.

6 Likes

Whether or not you use the Creator or another field is a separate issue from what the OP is talking about.

When you say “data recovery” do you mean a database merge?

Not really. I mean restoring external backups, manual database interventions to correct issues, those kinds of things. When things have gone wrong.

And @notorioustech makes a good point also. :slightly_smiling_face:

I’m in the process of trying to think up new exam questions - this is food for thought. :thinking:

1 Like

@randomanon
So current user is only empty when using the data APIs or a bit of hacking.

Is Logged In covers for that, but you are right if you want to have security with anonymous users you have do creator is not empty.

This won’t work for any kind of data manipulation for logged out users.

Yes. updated my reply.

While we are discussing security…

The ability for a hacker to run a workflow even with a condition on it by overriding the variables passed back. i.e… CurentUser.is_admin flag you may have.

Has anyone figured out how to block that?

Do you mean like, if you have a Role option set? If it’s a field on your Current User, that’s gonna be checked serverside.

Assuming the data is only meant for logged in users, I suppose it wouldn’t hurt to use all three rules just in case for maximum security. It’s not like it adds any performance overhead. At worse it might be redundant compared to Current User + Current User is logged in. Knowing how sloppy Bubble can be I just feel like there might be some weird edge cases where somehow the “Creator/User is not empty” might also help.

Data expressions like Current user’s X or Do a search for Y are secure. However, referencing group variables / states allows the user to inject values.

On critical workflows, have a condition on the workflow that checks the user’s role/permissions and that resolves it. If you use group data variables, use a custom event to display data in them and then reference them in the same workflow. That’ll ensure they use the correct values.

this is what i was referring to: Workflow security concern

1 Like

I don’t know what that user is describing because the post isn’t very clear, but you cannot bypass privacy rules with any injection methods (that’s the expected behaviour at least). Privacy rules are always evaluated server side and you can’t ‘pretend’ to have permission. Changing the API call response to include ‘admin = true’ doesn’t all of a sudden permit me to access data that requires me to be an admin - all I’ve done is change the client side representation of that API call.

2 Likes

Let me explain.

The other day, as I was going through @petter 's excellent work in the Bubble manual, I noticed the following:

This made me wonder if using “Current user’s Role” was secure, so I actually messaged Petter to ask, and his answer was that the check would be performed server-side. But this user has demonstrated that this is not the case, with one very specific caveat. He says:

This implies that, at the very least, if you’re not logged in/authenticated, then the server will just “trust” the client-side cookie version of Current User instead of retrieving it from the server. Note that even guest users technically have a temporary “Current user,” created in the DB, so it should still be possible to check against the database, but this doesn’t happen. If this only applies to logged out users, then the condition “Current user is logged in AND Current User’s Role is Admin” should be fine. That is, “if.”

More worryingly, however, it may be the case that Current User is always retrieved from the client, even when you are logged in. This would represent a massive data security problem for Bubble apps, the majority of which use “Current’s User’s Role is X” to authenticate their workflows.

In light of this, without being too alarmist, I think it would be prudent for @petter and @fede.bubble to escalate this directly to the engineering team, and get the following answers to these questions immediately:

Is “Current user’s X” evaluated using the client or the server when:

  1. Current user is logged in and the condition is placed on a normal clientside workflow
  2. Current user is logged out and the condition is placed on a normal clientside workflow
  3. Current user is logged in and the condition is placed on a backend workflow
  4. Current user is logged out and the condition is placed on a backend workflow

My assumption is that Current User’s Role is always a safe condition on a backend workflow because the whole thing is server-side, it wouldn’t make sense to pass it from the client as a variable. So I am not as worried about #3 and #4, but we should get a final answer regardless from the engineering team. This is important enough that it needs to be escalated directly, last time I reported a security bug using security@bubble.io, one of the techs kept asking me for my app id (???) and basically ignored it despite me describing it fully, the second tech actually escalated it and it was fixed in a week. This can’t wait.

That is a very detailed response.
Thank you.
I tend to just assume everyone understands what is in my head when i write these short posts.

1 Like

This wasn’t a fear of people accessing the data but executing clientside workflows i thought were protected by my CurrentUser.is_admin flag check.

1 Like

So, not quite.

Let’s take a workflow with the condition ‘Current User’s fullName’. Suppose my name is not John Smith, but I trick the client into thinking I am.

Workflow with only one client side action
I place a client side workflow action inside of it:

This will run, even though I’m not actually John Smith. This is because the workflow is run entirely on the client, and does not touch the server.

Workflow with at least one server side action

Now, let’s add a Create a new Thing action. It is self-evident that this is a server-side action.

If I attempt to run the workflow now, the alert will show, but the thing will not be created. The data associated with Step 2 is sent to Bubble’s server, where it presumably checks the workflow’s condition against the User in the database, not the client, and doesn’t create the Thing. Bubble will return an ‘event failed’ error for the workflow run.

In the logs, that looks like this:

The logs show the event didn’t run because the condition was not passed. In fact, step 1 did run, but the server side actions did not run because the condition was once again checked on the server.

So, the answer appears to be that one can inject values into a wholly client side workflow (as you’d be able to do on any site on any platform), but for workflows that hit the server, the condition will be correctly evaluated (though note that Current User’s X is not the same as var - (group)'s X).

Did you replicate the exact method in that post? Did you try as a logged out user? It shows you’re logged in.

He also used “Make changes” instead of “Create” although that shouldn’t matter.