Home › Blog › Checklist

Before You Launch a Lovable, Bolt or Cursor App: 7 Security Checks

Key takeaway: Seven practical security checks to run on an app built with Lovable, Bolt, Cursor or Replit before real users and real data arrive.

Seven practical security checks to run on an app built with Lovable, Bolt, Cursor or Replit before real users and real data arrive.

1. Verify Row‑Level Security on every table

Open the database console and list all tables in the public schema. For each table, confirm that a Row‑Level Security (RLS) policy exists for select, insert, update and delete operations.

To fix the issue, enable RLS on the table and write explicit policies that tie each operation to the current user's identifier. Test the policies by attempting to read a row owned by another user; the query should be denied. When the policies are correctly applied, only the owner’s data will be returned, and attempts to act on other users’ rows will be blocked.

2. Scan client‑side code for secret keys

Build the front‑end bundle and search the resulting JavaScript for strings that look like service‑role keys, live secret keys, or any provider‑specific secret‑key prefix. Also open the browser’s Network tab while the app runs and look for requests that include such values in headers or query parameters.

If a secret appears, move it to a server‑side environment variable and expose only a limited token to the client. After removal, rebuild the bundle and repeat the search to ensure no secret strings remain. This step prevents attackers from harvesting credentials that could be used to read or write data directly in external services.

3. Test data exposure for anonymous visitors

Log out of the application, clear cookies, and open a private browsing window. Try to load pages, API endpoints, or data files that are meant for logged‑in users. If the response includes private records, user profiles, or configuration details, the endpoint is not properly protected and can be scraped by anyone on the internet.

Secure the endpoint by adding authentication checks that return a generic “unauthorized” response for anonymous requests. Verify the fix by repeating the anonymous test; the response should contain only public information or an error indicating the need to log in.

4. Check cross‑user data access with test accounts

Create two separate user accounts, A and B. While logged in as B, manually change identifiers in API calls or URL parameters to reference A’s records. If B can read, edit, or delete A’s data, the application is missing proper ownership checks, allowing one user to manipulate another’s information.

Implement ownership validation in the backend, ensuring that every request compares the resource’s owner ID with the authenticated user’s ID. After adding the checks, repeat the test; B should receive an error or empty result when trying to act on A’s data.

5. Review storage bucket permissions

Open the cloud storage console and examine each bucket used by the app. Look for settings that mark a bucket as public or that generate unsigned URLs for uploaded files. Public buckets that store private documents, images, or logs expose that content to anyone who discovers the URL.

Change the bucket to private and configure signed URLs for any files that need temporary access. Test the change by attempting to fetch a private file without a signed URL; the request should be denied. This ensures that confidential assets remain hidden unless a time‑limited, authenticated link is provided.

6. Confirm secrets are kept out of the repository

Search the codebase for .env files, configuration files, and any committed secret strings. Verify that .env is listed in .gitignore so it never gets added to version control. Also scan the repository’s history for accidental secret commits that might still be reachable through older commits.

If secrets are found, remove them from the current code, rewrite history to purge them from past commits, and regenerate new credentials. Store the fresh secrets only in server‑side environment variables that are not part of the source tree. This prevents attackers from mining the public repository for usable keys.

7. Add rate limiting and hide internal errors

Configure the authentication endpoints—login, signup, and password‑reset—to limit the number of attempts per IP address or per user within a short time window. Without rate limiting, automated bots can brute‑force credentials or flood the service with requests. Also audit error handling to ensure that stack traces or database errors are not sent back to the client.

After enabling rate limiting, test by sending rapid repeated requests and verify that the server returns a generic throttling message after the limit is reached. Check error responses by deliberately causing a failure; the response should contain only a user‑friendly message, not internal details. This reduces the information available to attackers while protecting legitimate users from abuse.

What the documented sources report

Security researcher Matt Palmer's scan, completed on March 21, 2025, identified 303 endpoints across 170 of 1,645 analyzed Lovable projects (about 10.3%) with inadequate Row Level Security (RLS) settings. Depending on the app, exposed data could include personal information from users tables, API keys and access tokens for third-party services, and financial data such as transaction and subscription details, including the ability to modify payment status. The root cause, in the researcher's words, is the failure to enforce or maintain secure default RLS configurations for user projects. Timeline: discovered March 20, 2025; vendor notified March 21; vendor acknowledged March 24; CVE-2025-48757 published and publicly disclosed May 29, 2025.

Source: Matt Palmer, “Statement on CVE-2025-48757”

Escape.tech, a security vendor, analyzed over 5,600 publicly available applications built on platforms including Lovable (about 4,000 of them), Base44, Create.xyz, Vibe Studio and Bolt.new, and reported more than 2,000 vulnerabilities, 400+ exposed secrets and 175 instances of personal data, including medical records, IBANs, phone numbers and emails. Most of the critical weaknesses, such as exposed Supabase tokens, misconfigured APIs and missing row-level security, were reachable through public endpoints without authentication. The research is dated October 29, 2025.

Source: Escape.tech, “Methodology: 2k+ Vulnerabilities in Vibe-Coded Apps” (Oct 29, 2025)

Common questions

What if I cannot change the database schema to add RLS policies?

Consider adding an application‑level filter that enforces ownership before any query runs. While not as robust as native RLS, it still blocks unauthorized row access.

Can I use a public bucket for files that contain no sensitive data?

Accidental inclusion of private data in a public bucket can still result in exposure.

How often should I repeat these checks?

Run the checklist before every major release and after any change to authentication, storage, or secret management. Regular verification keeps new regressions from slipping into production.

Sources