# How apps with privacy rules can still leak data

**URL:** <https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799>\
**Category:** Tips\
**Created:** [November 18, 2024, 10:55am UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799 "2024-11-18T10:55:24Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![georgecollier](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/georgecollier/32/182327_2.png) [@georgecollier](https://forum.bubble.io/u/georgecollier)\
**Post date:** [November 18, 2024, 10:55am UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/1 "2024-11-18T10:55:24Z")

</div>

## 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:

```auto
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:

```auto
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:

 ![Xnapper-2024-11-18-10.40.05](https://us1.discourse-cdn.com/bubble/original/3X/f/1/f1e237a7b2b53e4ae7e0799e9dec266853b96398.jpeg)

Then, just configure the search:

 ![image](https://us1.discourse-cdn.com/bubble/original/3X/5/3/531ec9006a2b2256306d063cb95dd867a8837172.jpeg)

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](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.

---

<div class="post-metadata">

**Author:** ![senecadatabase](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/senecadatabase/32/260991_2.png) [@senecadatabase](https://forum.bubble.io/u/senecadatabase)\
**Post date:** [November 18, 2024, 11:14am UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/2 "2024-11-18T11:14:56Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![AndyMountHood](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/andymounthood/32/221851_2.png) [@AndyMountHood](https://forum.bubble.io/u/AndyMountHood)\
**Post date:** [November 18, 2024, 3:30pm UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/3 "2024-11-18T15:30:35Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![boston85719](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/boston85719/32/77286_2.png) [@boston85719](https://forum.bubble.io/u/boston85719)\
**Post date:** [November 18, 2024, 6:02pm UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/4 "2024-11-18T18:02:07Z")

</div>

> [@georgecollier](#):
>
> I hope Bubble would integrate something like this directly into the editor.

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.

 ![Screen Shot 2024-11-19 at 12.49.50 AM](https://us1.discourse-cdn.com/bubble/original/3X/c/c/cc4ff470357a70c53abad92a736cdf8d9e22b3ca.png)

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.

 ![Screen Shot 2024-11-19 at 12.52.47 AM](https://us1.discourse-cdn.com/bubble/original/3X/e/c/ecaaa93db928e3f7b318f27b8916b5f18690ad6f.png)

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](https://bubble.io/ideaboard?idea=1731952764458x845386205020028900) 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.

---

<div class="post-metadata">

**Author:** ![georgecollier](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/georgecollier/32/182327_2.png) [@georgecollier](https://forum.bubble.io/u/georgecollier)\
**Post date:** [November 18, 2024, 6:12pm UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/5 "2024-11-18T18:12:03Z")

</div>

> [@boston85719](#):
>
> forgotten constraint on a search that helps prevent leaked data.

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

> [@AndyMountHood](#):
>
> “This Team’s Company is Current User’s Company and Current User is logged in” work just as well?

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.

---

<div class="post-metadata">

**Author:** ![AndyMountHood](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/andymounthood/32/221851_2.png) [@AndyMountHood](https://forum.bubble.io/u/AndyMountHood)\
**Post date:** [November 21, 2024, 3:09pm UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/6 "2024-11-21T15:09:38Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![rico.trevisan](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/rico.trevisan/32/170176_2.png) [@rico.trevisan](https://forum.bubble.io/u/rico.trevisan)\
**Post date:** [November 21, 2024, 3:16pm UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/7 "2024-11-21T15:16:32Z")

</div>

Bubble acquisition incoming!

---

<div class="post-metadata">

**Author:** ![rico.trevisan](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/rico.trevisan/32/170176_2.png) [@rico.trevisan](https://forum.bubble.io/u/rico.trevisan)\
**Post date:** [November 21, 2024, 3:36pm UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/8 "2024-11-21T15:36:59Z")

</div>

Just ran the audit tool again and…

 ![image](https://us1.discourse-cdn.com/bubble/original/3X/0/c/0c187e654c5e1b27446c52a4088b6bdfa3d6bde8.jpeg)

… I got a lot of work to do.

Thanks, @georgecollier for all the work.

---

<div class="post-metadata">

**Author:** ![ihsanzainal84](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/ihsanzainal84/32/245932_2.png) [@ihsanzainal84](https://forum.bubble.io/u/ihsanzainal84)\
**Post date:** [November 22, 2024, 12:53am UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/9 "2024-11-22T00:53:00Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![georgecollier](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/georgecollier/32/182327_2.png) [@georgecollier](https://forum.bubble.io/u/georgecollier)\
**Post date:** [November 22, 2024, 1:02am UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/10 "2024-11-22T01:02:57Z")

</div>

> [@ihsanzainal84](#):
>
> I usually just have another user field to check for edge cases like this.

How do you mean?

---

<div class="post-metadata">

**Author:** ![ranjit](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/ranjit/32/254854_2.png) [@ranjit](https://forum.bubble.io/u/ranjit)\
**Post date:** [November 22, 2024, 4:51am UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/11 "2024-11-22T04:51:19Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![petter](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/petter/32/98626_2.png) [@petter](https://forum.bubble.io/u/petter)\
**Post date:** [November 22, 2024, 10:35am UTC](https://forum.bubble.io/t/how-apps-with-privacy-rules-can-still-leak-data/348799/12 "2024-11-22T10:35:10Z")

</div>

Definitely! Thanks for suggesting it @AndyMountHood
