Canvas Privacy Rules: How to Audit What Your App Exposes
A step-by-step audit of Canvas Bubble privacy rules. The common ways data leaks via the Bubble Data API, how to test for it, and how to lock down what should be private.
Most Canvas (Airdev) apps have privacy rules. Most also have data exposure their owners don't know about - because Bubble's data API lets anyone with the URL try to read data the UI never shows them, and privacy rules are the only thing standing in the way.
This article walks through the audit we run on every Canvas app to find what's actually exposed via the data API, the common patterns we see, and how to lock things down without breaking your app.
If this is the first time you've thought seriously about privacy rules: read it. The cost of finding a data leak through a customer complaint is much higher than the cost of finding one now.
What "exposed via the data API" actually means
Bubble's Data API is a REST endpoint that lets you list and read records of any Data Type in your app. It's enabled by default for some apps and configurable on a per-type basis.
Whether someone can read a given record via the data API depends on:
- Is the Data API enabled for this Data Type?
- What do the privacy rules say about the requester's identity?
If the API is enabled and the privacy rules don't constrain access, the records are public to anyone who knows the URL. The URL format is predictable. The URL is in your page's HTML.
This is not an obscure attack vector. It's the most common Bubble security finding.
The audit, step by step
Step 1: list every Data Type that has the Data API enabled
In Bubble's Settings → API tab, look at the list of Data Types with the API enabled. Note which ones.
Anything you don't actively need exposed should be turned off. The default should be "off" for every Data Type and "on" only for the ones with a real reason.
Step 2: identify your app's API root URL
The URL for the data API follows the pattern:
or with your custom domain:
You'll use this URL to test what an anonymous request returns.
Step 3: test each enabled Data Type anonymously
For each Data Type with the API enabled, open a private browser window (so you have no auth) and hit:
If you get a list of records back, the Data Type is publicly readable. Look at what fields come back - that's what an attacker could see.
If you get an empty list, the Data Type is API-enabled but privacy rules are blocking the request. Good.
If you get an error, the Data Type might still be exposed - try with parameters - but it's at least not trivial.
Step 4: test each Data Type as a logged-in user
Now log in as a regular user and try the same URLs. The data you get back is what a logged-in user can see.
The difference between logged-out and logged-in responses tells you:
- What's truly public (returned to both)
- What's protected (returned only to logged-in)
- What's not exposed at all (empty in both)
Note: if you only have admin accounts, create a regular-user test account specifically for this audit. The whole point is to test as a non-admin.
Step 5: try parameterised queries
The data API supports constraints. Try:
This lets an attacker filter for records matching specific criteria. The privacy rules may behave differently when constraints are present (sometimes they fail open).
Test the queries an attacker would actually try - e.g. "give me all Users where email contains my domain."
Step 6: try direct record lookups by ID
Each record has a unique _id. Try:
https://yourapp.com/api/1.1/obj/{datatype}/{some-id-you-know}
If you can read records by ID that you shouldn't be able to read, that's a privacy rule failure for direct lookups (sometimes different from list lookups).
The most common findings
When we run this audit, the patterns we see most often:
"Everyone else" rules with read access
Privacy rules with a fall-through "Everyone else (default)" allowing read access. Often this was set up early when the app didn't need restrictions, and never tightened later.
Fix: change the rule to deny by default. Add explicit rules for the roles that should have access.
Privacy rules that "work" because the UI doesn't expose the field
A privacy rule allowing access to a record, but the UI never displays sensitive fields. The data API returns ALL fields - the UI restriction doesn't apply.
Fix: privacy rules should be field-level, not type-level. Restrict the sensitive fields explicitly.
Conditions that reference deleted users
A privacy rule like "When This Booking's Host is Current User". If the Host field is empty or points at a deleted record, Bubble's behaviour can be inconsistent - sometimes the rule fails open.
Fix: make rule conditions defensive. Check for non-empty values explicitly: "When Current User is logged in and This Booking's Host is not empty and ...".
Lookups via related records
A Data Type that's locked down... but it has a relationship to another Data Type that's publicly readable, and the related record contains the same data. The attacker reads via the back door.
Fix: audit related records too. If Booking has a User reference, and User is publicly readable with email and phone exposed, then bookings effectively expose contact details.
The "auto-bind" trap
Bubble's "auto-bind" feature lets users edit fields directly without an explicit workflow. If a privacy rule allows "Auto-bind" on a field that wasn't intended to be user-editable, the user can edit it via crafted API calls.
Fix: explicitly remove auto-bind from any field that shouldn't be user-editable.
Common fixes
Disable the Data API entirely for types that don't need it
The simplest, most common fix. If your app's UI is the only thing that should read from a Data Type, turn the API off in Settings.
Done. Now the data is invisible to anyone who's not logged in via the UI.
Add "When Current User is logged in" as a base condition
For Data Types that legitimately need data API access (for mobile apps, integrations, etc.) but should only be accessible to logged-in users, add a base condition to every privacy rule requiring authentication.
Restrict fields, not just records
For each rule, explicitly list which fields can be read. Don't use "View all fields" unless you've consciously decided every field is OK to expose.
Add a "denied" privacy rule at the top
If you want belt-and-braces denial: add a rule at the top that matches a condition that's always false, with no field access. Below it, add the rules that should allow access.
The "denied" rule never matches, but it sets the default state. If the more specific rules below have a bug, you fall through to denied rather than to "Everyone else."
Testing the fixes
After fixing privacy rules:
- Re-run all the steps from the audit above
- Specifically check that valid use cases still work (your app's own data fetches)
- Use a test account in each role and confirm normal flows work
- Have someone else try to break it - fresh eyes catch what you'll miss
Don't deploy privacy rule changes to production without testing. Privacy rule edits are the most common cause of "the app suddenly doesn't work for half our users" incidents.
When the audit suggests deeper problems
If the audit finds widespread issues - privacy rules that nobody designed coherently, an authorisation model that doesn't have a clear shape - the fix isn't a one-off patch. It's a privacy-and-permissions refactor.
This is significant work (usually 4-8 weeks) but it's also one of the few investments in a Canvas app that doesn't depreciate - the rules you set up correctly now will continue working.
If the structural problems suggest the app has outgrown what Bubble + Canvas can express, it might be a sign the migration off Canvas is closer than you thought.
What to do next
If you'd like an external review of your privacy rules, request a free Bubble app audit - the Security section explicitly covers data API exposure.
If you'd prefer a senior engineer to walk through your specific privacy model, book a 30-minute discovery call.
Read next: The Canvas tech debt audit and Translating Bubble privacy rules to Postgres RLS.
Got a Bubble or Canvas app you’d like a second pair of eyes on?
30-minute discovery call. We’ll look at your app live and tell you honestly what we’d do next.
Or grab the Bubble migration playbook PDF.