How apps with privacy rules can still leak data

The standard privacy rule approach is not robust

Most developers assume that a standard form privacy rule like “This Team’s Company is Current User’s Company” will effectively restrict access to only users within the same company. However, that assumption overlooks a common edge case that leads to data leaks.

After auditing many, many apps, after misconfigured/no privacy rules, this is the most common cause of data leaks for apps where the developer has attempted to set up privacy rules correctly…

Understanding the issue

  1. When a privacy rule’s reference field (like Company) is empty, Bubble evaluates it as matching an empty value
  2. For logged-out users, their Company field is naturally empty
  3. Therefore, if you have a Team whose Company field becomes empty (e.g., after company deletion), it will suddenly become visible to all logged out users!

Example case

Consider a team collaboration app where teams belong to companies. You might have a privacy rule:

This Team's Company is Current User's Company

If you delete a company but forget to clean up its associated teams:

  • The teams now have an empty Company field
  • These teams become publicly accessible
  • Any user (even logged out) can now view these “orphaned” teams

How to Fix It

The solution is straightforward - always add an “is not empty” condition to these types of privacy rules:

This Team's Company is Current User's Company
AND
This Team's Company is not empty

This ensures that items with empty reference fields remain private rather than becoming public by default.

How to Test Privacy Rules

To verify your application’s vulnerability to this issue:

  1. Create a test page with a repeating group for each data type in your app
  • Set each repeating group to Do a search for Datatype
  • Leave the constraint field empty to search all records
  • Add a text element for each field in that data type to display that field’s data
  1. Steps to test:
  • Log out of your application or log in as the user you want to test
  • Visit the test page
  • Any data visible in the repeating groups that should not be, represents a privacy vulnerability

Testing automatically

I think the method above is a pain in the ass, so I’ve developed a tool to test this auto-magically.

You can preset each user type:

Then, just configure the search:

Search and explore the data accessible to that user:

If you’d like to try it out, you can sign up for the waitlist @ https://secure.notquiteunicorns.xyz. It’s entirely free. I think this feature makes it the most powerful security analysis tool in the ecosystem (it is essentially a privacy rule debugger), and I hope Bubble would integrate something like this directly into the editor.

17 Likes

Hey George, this sounds like an awesome tool.

I signed up for the waitlist.

Don’t know why anyone that uses Bubble wouldn’t sign up for this.

1 Like

Would “This Team’s Company is Current User’s Company and Current User is logged in” work just as well?

That would be cool…they should also improve privacy rules so that empty fields are not an issue. I think it might be simple enough I believe since if we have a repeating group that has a constraint for company = user company, nothing would show up if the user company is empty. It is as if Bubble should make it so Privacy Rules do not have ‘ignore empty constraints’ checked.

This also brings up another important security point, I think often overlooked, is the use of constraints on searches and implementing those prior to privacy rules, since implementing privacy rules first can lead to a forgotten constraint on a search that helps prevent leaked data.

In the example above, with ignore empty constraints unchecked, any logged out user sees no teams at all, even when all 3 relevant data types (user, company and team) have no privacy rules set at all.

It is also automatically updates if a change is made to the database. For example, a logged in user with a company field that is not empty because the company data entry exists in database, can view the teams that are associated with the company, but if that company data entry is deleted while the user is logged in viewing teams, the RG is updated in real time and the RG no longer displays any teams.

With great privacy rules like what you suggest and proper use of constraints on searches, users can get pretty secure apps on Bubble…next step is for Bubble to fix these leaks. I added an idea to the idea board for Bubble to fix this. Follow this link to upvote the idea to help Bubble make our apps more secure. @fede.bubble could you follow up with the team about this? Definitely a security issue that should be addressed.

1 Like

If a forgotten constraint leaks data, then that data was leaking anyway :slight_smile:

In many apps it’d probably resolve the issue, but is not empty is more effective as it actually just tackles the root cause of the problem (a user having an empty team). If a logged in user has a Company and you delete their Company… then the other orphaned data will become visible to that user because even though they’re logged in, their Company is empty.

1 Like

Hey @petter , I wonder if you would consider adding a subsection about “and ___ is not empty” and/or “and ___ is logged in” to the privacy rules section of the next edition of your security book?

I’ve gone through the privacy rules of my app and added @georgecollier 's suggestion. For most situations, “and ___ is not empty” is what I added. There were some situations where “and ___ is logged in” still made more sense to me, although I could be wrong.

Thank you, George!

1 Like

Bubble acquisition incoming!

1 Like

Just ran the audit tool again and…

… I got a lot of work to do.

Thanks, @georgecollier for all the work.

3 Likes

I usually just have another user field to check for edge cases like this. Together with page level permission checks.

How do you mean?

:fire: Dude @georgecollier seems like you’re Flusking more than Flusk has Flusked in a while

1 Like

Definitely! Thanks for suggesting it @AndyMountHood