Guides

Is my Bubble app secure?

Bubble writes the JavaScript for you. The data stays safe when privacy rules are tight and when API keys never land in the files a visitor downloads. A public scan can help with the second part. The rules are still your job.

Free check

Check the live app

Paste the public Bubble URL. The check reads what a visitor's browser can already see, then gives you a private report with a fix prompt for each issue.

Free, one time, and limited to what a stranger can already see. No account required.

What Bubble actually ships

Bubble hosts the app and generates the page's JavaScript and JSON. Bubble's docs say those files contain the page's elements, workflows, and other static details, and that a person can read them. Privacy rules decide which data a visitor can find and which fields they can see. The API Connector can keep a key on the server when the parameter is marked private. The Data API follows privacy rules for a normal user, and Bubble's docs say an API token ignores those rules and acts as an admin. There is no single React or Supabase stack underneath a typical Bubble app.

Mistakes worth checking

These are the ones that show up in apps built with Bubble. Each step is something you can do in the browser or in the product dashboard.

  1. High

    Privacy rules that let everyone find private things

    Each data type has privacy rules. The role "Everyone else" with "Find this in searches" and "View all fields" on a User type, an order, or a message is how a customer list becomes public. The free check does not evaluate these rules.

    Check it yourself

    In Data, then Privacy, open every type that holds personal data. For Everyone else, turn off finding it in searches unless the type is public on purpose, and expose only the fields a stranger should see. Repeat for any logged-in role that should not see other people's rows.

  2. Critical

    An API key stored on the page

    Bubble's docs say not to put API keys in option sets, on-page workflows, elements, dynamic expressions, app texts, custom states, or URL parameters. Those can show up in the downloaded files. In the API Connector, mark sensitive parameters as private so Bubble sends them from the server.

    Check it yourself

    Load the live app, open developer tools, and search the downloaded files for the key. In the editor, search option sets and on-page workflows for the same value. Move it to a private API Connector parameter.

  3. High

    A Data API admin token in the client

    Enabling the Data API exposes the types you check, still filtered by privacy rules when the caller is a user. Bubble's docs say an API token skips privacy rules and has admin access. That token is a password. It does not belong in a page, a plugin, or a public workflow.

    Check it yourself

    Under Settings, then API, enable only the types you mean to share. Search the live files for the token. Prefer a signed-in user when another app needs the data. If the token has already been in a page, generate a new one.

  4. Medium

    An HTML element that embeds another backend

    Some Bubble pages include an HTML element that loads Supabase, Firebase, or a script with a hard-coded key. That snippet is part of the page a visitor downloads. Supabase still needs row-level security. Firebase still needs rules that are not test mode.

    Check it yourself

    Search HTML elements for supabase, firebase, sk-, and sk_live. If a supabase.co address and anon key are there, confirm row-level security in Supabase. If a Firebase config is there, confirm the rules require a signed-in user.

  5. Low

    Browser headers, after the data leaks are closed

    Missing headers such as Content-Security-Policy are worth adding, and they are much less urgent than an open privacy rule or a key in the page. Bubble's hosting sends the headers it sends. You may not control all of them.

    Check it yourself

    Run the free check and read the header note if one appears. Fix a leaked key or an open privacy rule first. Add headers when the host lets you, without blocking the app's own scripts by accident.

A prompt you can paste

Paste this into Bubble, publish again, and run the check a second time. If a key was already on the live site, rotate it in the vendor dashboard. The prompt cannot do that part.

Review this Bubble app's security settings and page content. Do not weaken a privacy rule to make a repeating group show data.

1. For every data type that holds private information, set privacy rules. For the role Everyone else, turn off "Find this in searches" unless the type is public on purpose, and expose only fields that strangers should see. Do the same for signed-in users so they cannot read other people's rows.
2. Remove API keys from elements, workflows, option sets, custom states, app texts, and URL parameters. Store them as private parameters on the API Connector so the call runs on the server.
3. If the Data API is enabled, expose only the types that need it. Remove any admin API token from pages and plugins. If one was exposed, regenerate it. Prefer user authentication over the admin token.
4. Search HTML elements for third-party keys and for Supabase or Firebase clients. Keep Supabase row-level security on, and do not leave Firebase in test mode.
5. Tell me which keys were visible in the app so I can rotate them. Do not print the secret values.

What the check looks at

  • The public page and the JavaScript it loads, for common leaked secret keys: a Supabase service role key, OpenAI, Anthropic, Stripe secret keys, AWS, GitHub, Slack, private keys, and database URLs that include a password. A Supabase anon key is called out as expected in the browser.
  • A short list of public paths: /.env, /.env.local, /.env.production, /.git/config, /.git/HEAD, and /.npmrc.
  • A source map, only when a script on the page already points at one, and only when that map includes original source.
  • Supabase tables, only when the page already includes a supabase.co address and the public anon key. It asks for one row per table, then drops that row.
  • Firebase Realtime Database and Firestore, only when the public config is already in the page. It uses that public config and does not sign in.
  • A few browser safety headers on the main response. Missing headers are noted when two or more of the watched ones are absent. They are less urgent than a leaked key.

What stays outside it

  • It reads. It does not log in, submit forms, or change data.
  • It does not guess passwords, fuzz inputs, or hunt through hidden paths.
  • It does not use any secret it finds, including a service role key.
  • It does not open your builder's dashboard. A rule that lives only there can stay invisible.
  • A clear result describes this public look. It is not a certificate that the whole app is safe.
  • Bubble privacy rules and the Data API are not tested. A key inside the downloaded page can still be found. Public .env and .git files are uncommon on Bubble's own hosting, and the check still requests those paths.

Questions

Free check

Run it on the published URL

Use the address a customer would type. The report stays private, and the shareable scorecard hides the details.

Free, one time, and limited to what a stranger can already see. No account required.

Other builders

Vibe-coded app security checklist · All guides