Lovable App Security: 7 Fixes Before Production
Seven Lovable app security gaps show up on almost every audit Cardinal Stacks runs: weak auth defaults, missing Supabase Row Level Security, API keys in git, no spend ceiling on LLM endpoints, console-only error handling, manual deploys with no rollback, and PII flowing to LLMs unredacted. This is the CTO's read on what to find and how to fix each one before you onboard paying users.
01 · Auth: bcrypt cost factor and session expiry
The risk. Default Lovable auth scaffolds often ship with low password-hash work factors and sessions that never expire. A stolen laptop or a leaked database dump becomes a long-lived account takeover instead of a window that closes on its own.
What to look for. Open your auth config and find the bcrypt cost factor. If it is below 10, or if the value is not set at all and the library default applies, that is the gap. Then check your session table or JWT payload. If you see a session created six months ago that is still valid, expiry was never configured.
How to fix it. Set bcrypt to a cost factor of 12 in 2026: high enough to slow offline cracking, low enough to keep login latency under 200ms on commodity hardware. Set session idle expiry to 14 days and absolute expiry to 30 days for a consumer app. For anything touching payment or PII, drop those to 24 hours idle and 7 days absolute. Add a server-side revocation table so a password reset or a logout actually kills active sessions.
02 · Row Level Security on every Supabase table
The risk. Supabase is the default backend on most Lovable builds, and Row Level Security is off by default on every table you create. Any user with a valid anon key (which ships in your client bundle) can read and often write every row in every public table. This is the single most common path to PII exposure we see.
What to look for. Open the Supabase dashboard, go to Authentication then Policies, and scan the table list. If RLS is disabled on any table that holds user data, billing records, or messages, that is a bug. Then check the policies that do exist.
A policy of
truewith noauth.uid()filter is the same as no policy at all.
How to fix it. Enable RLS on every table without exception. Write per-table policies that filter on auth.uid() = user_id for owner-scoped tables, and explicit role checks for admin surfaces. Test with the Supabase SQL editor under the anon role before you trust the result. Audits of vibe-coded apps routinely find significant data-exposure vulnerabilities shipping before there are any real users on the system — RLS misconfiguration is the bulk of that number.
03 · API keys and secrets committed to git
The risk. Lovable scaffolds frequently inline API keys directly into source files: OpenAI, Stripe, Supabase service role, SendGrid. Once a secret is in git history, rotating it later does not undo the leak. Public repos get scraped within minutes; private repos get exposed the day they go public, or the day a contractor forks them.
What to look for. Run git log -p | grep -iE "sk-|api_key|secret|service_role" against your repo. Any match is a problem, even if the key looks rotated. Then check your client bundle: curl your production JS bundle and grep for the same patterns. Secrets baked into the build are visible to every visitor.
How to fix it. Move every secret to environment variables, scoped per environment (preview, staging, production). Rotate every key that ever touched git, even briefly. Add a pre-commit hook with gitleaks or trufflehog so a new secret cannot get committed by accident. For keys that need to reach the browser, use a server-side proxy. Never ship a write-capable key in client code.
04 · No spend ceiling on OpenAI or LLM endpoints
The risk. A chat endpoint or generation feature with no spend cap is a four-figure invoice waiting for a bad weekend. One scraper, one adversarial user with a script, one viral post: any of them can run your monthly OpenAI bill into five figures before you notice on Monday morning.
What to look for. Open the OpenAI dashboard and check Usage limits. If the hard cap is not set, or is set at the default account ceiling, you have no spend ceiling. Then audit your own code: any LLM call triggered by user input without a per-user rate limit, a per-request token cap, or input length validation is a cost vector.
How to fix it. Set a hard monthly spend cap in the OpenAI dashboard at a number that would hurt but not bankrupt you. For most early-stage apps that is $200 to $500. Add a per-user daily rate limit at the application layer (10 to 50 requests is a reasonable ceiling for a free tier). Cap max_tokens on every call. Validate input length before it hits the API. Log token usage per user so you can detect abuse before the bill arrives.
05 · No error monitoring beyond console.log
The risk. If your only error reporting is console.log, you learn about outages from customer email. By the time the third user has written in, the bug has been in production for hours, the data is already wrong, and you have no stack trace to work from.
What to look for. Search your codebase for console.log and console.error calls in catch blocks. If that is the only thing happening there, the error never leaves the browser. Then check your alerting: do you have any channel (email, Slack, phone) that pings you when production throws an unhandled exception? If the answer is no, your monitoring is your users.
How to fix it. Wire Sentry into both the client and the server with environment-scoped DSNs. Configure release tracking so a stack trace ties back to the exact deploy. Set up alerts on new issue types and on error rate spikes, not on every exception, which trains you to ignore the channel. Send alerts to a channel you already read, not a dashboard you have to remember to open.
06 · Manual deploys with no rollback
The risk. A manual deploy with no preview environment, no CI gate, and no rollback button means every push to production is a coin flip. A bad merge takes the site down with no fast path back to the last working version. This compounds the moment you have paying users: the same outage now costs revenue and trust.
What to look for. Check your deploy history. If you cannot point at a specific commit hash for the version currently in production, deploys are not reproducible. Check your CI: does the main branch require tests to pass before merge? Check your hosting platform: is there a rollback button, and have you ever used it? A button you have never tested is a button that does not exist.
How to fix it. Set up a CI gate on the main branch: at minimum a typecheck and a build step. Configure preview environments on every pull request so you can click around the change before merging. Use a host with one-click rollback (Vercel, Netlify, Railway all support this) and rehearse the rollback once on a Friday afternoon so it is muscle memory the day you need it. If this is the gap that worries you most, the full Vibe Rescue deploy surface covers the deploy pipeline end-to-end as one of its seven audited surfaces.
07 · PII flowing to LLMs unredacted
The risk. When a user types their name, email, phone, address, or medical detail into a chat interface and that text goes straight to OpenAI or Anthropic, you have just sent regulated data to a third party, often without a Business Associate Agreement, often without a data processing addendum, and often without your user knowing. In healthcare or financial apps this is a direct compliance failure. In any app it is a privacy gap your users will not appreciate when they find out.
What to look for. Trace any user-input field that feeds an LLM call. If the raw input string hits the OpenAI or Anthropic API without a redaction step in between, PII is leaving your perimeter. Check your logs too: prompt logs that store raw user input become a secondary PII store with the same exposure surface as your database.
How to fix it. Run user input through a redaction step before it reaches any external LLM. Cardinal uses Redactor, our in-house privacy guard, on every engagement that touches user data. It tokenizes names, emails, phone numbers, addresses, account numbers, and clinical identifiers before the prompt leaves your infrastructure, then re-hydrates the response on the way back. Whatever you use, the principle is the same: PII never reaches the third party, and your prompt logs never store the raw input. For apps under HIPAA, see our HIPAA software development notes. The BAA gap is not optional there.
What to do next
The seven items above are the recurring Lovable app security set. They are not theoretical and they are not exotic. These same gaps show up on almost every Lovable audit Cardinal runs, on apps whose screens and product logic are otherwise fine. The order roughly tracks blast radius: auth and RLS first because they expose user data directly, secrets and LLM spend next because they leak money fast, observability and deploys after that, PII redaction last because it sits on top of the rest. Work through all seven and you have a secure Lovable app at the layer underneath the screens.
If you want a second set of eyes on your own build, you can Get a free written audit of your Lovable app. Cardinal returns a written intake within two business days with a flat number and a list of must-fix items, no obligation to proceed. If the audit comes back clean, you keep the report at no cost and we tell you so.
Frequently asked questions
Is Lovable secure by default?
Can I keep using Lovable after fixing these issues?
How long does it take to fix all 7?
What's the most common Lovable security gap Cardinal sees?
Free 48-hr audit. Written quote in two business days.
Same team, same flat-fee posture, same operating stack on every engagement. Email the repo or zip the project and the written audit lands in your inbox inside two business days.