# Sign-up without email confirmation: is it a risk?

Checked on 1 November 2026

It is a real risk when a new account gets something that costs you money or reaches other people, such as free credits, AI calls or the right to post: without email confirmation, a bot can create accounts with made-up addresses as fast as your sign-up limits allow.

Turn on email confirmation (“Confirm email” in Supabase, or switch off “Auto-confirm email” in Lovable Cloud) once you are sure the confirmation emails reach your users, and add CAPTCHA if new accounts get anything of value.

LidTight’s free check reads this setting from your database’s public sign-up settings, without creating an account. On Tidybook, our demo app built with Lovable, it reported the problem as high on 1 November 2026.

## What sign-up without email confirmation means

At sign-up, your app can send a link to the new address and let the person in only after they click it. That is email confirmation. Without it, the person gets in at once, with no proof that they own the address.

In [Supabase](https://supabase.com/docs/guides/auth/general-configuration), a database with a built-in sign-in service, this is one switch called “Confirm email”. With it on, users must confirm their address before they sign in for the first time. With it off, Supabase marks every new address as confirmed without checking it. A second switch, “Allow new users to sign up”, decides whether strangers can create accounts at all. “Open sign-up” means that switch is on.

Lovable Cloud, Lovable’s built-in backend, is [built on Supabase’s open-source foundation](https://docs.lovable.dev/features/cloud). There the same choice is called [“Auto-confirm email”](https://docs.lovable.dev/features/email-auth), under More → Users → Settings → Email. The meaning is reversed: auto-confirm on means no confirmation.

## When it is a real risk

Without confirmation, a bot (a program that acts like a user) can sign up again and again with new made-up addresses, and each account works at once. How much this hurts depends on what a new account gets.

- **Free credits, trials or a free plan.** Each new account gets a fresh allowance. A bot that keeps signing up gets free use without end. See [Can users get your paid features for free?](https://lidtight.com/guides/paid-features-for-free)
- **AI features.** If signed-in users can ask an AI model, every fake account spends your money with OpenAI, Anthropic or your other AI provider. See [Someone is running up your AI bill](https://lidtight.com/guides/ai-bill-abuse).
- **Content that other people see.** Reviews, comments, messages and public profiles become a path for spam.
- **Emails your app sends.** An account can carry an address that belongs to someone else. [Lovable’s docs](https://docs.lovable.dev/features/email-auth) say it plainly: without confirmation, “anyone can sign up with an address they don’t own.” Your welcome emails and receipts then go to a person who never signed up.

### When it matters less

- A new account gets nothing of value: no credits, no AI calls, nothing that other people see, and each user can read only their own rows.
- Sign-up is closed, for example in an internal tool where you add each user yourself.
- Email sign-up is off, and users sign in only with Google or another social sign-in. Then this setting does not apply.

Even then, a fake account is a signed-in user: whatever your database rules let signed-in users read or change, a bot can too. Check that with [Can one customer see another customer’s data?](https://lidtight.com/guides/one-customer-sees-another)

## What LidTight found on Tidybook

Tidybook is our own demo app, built with Lovable on Lovable Cloud. On 1 November 2026, our free check reported this finding:

| Severity | Finding | Evidence |
| --- | --- | --- |
| High | Anyone can create accounts without confirming an email | Sign-up is open and email confirmation is off (the database’s public sign-up settings) |

The check explains: “A bot can sign up thousands of fake accounts with made-up emails. Each one can use your app, and your free limits, as a real user.”

The deep checks, which run only with the owner’s permission, showed the same thing that day. They signed up two test users with made-up addresses at example.com, a domain [kept for documentation](https://www.iana.org/help/example-domains) that no one can register. No one clicked a confirmation link, and both test users could use the app at once.

### How the free check sees this without creating an account

It reads only what any visitor’s browser can reach, in four steps:

- It downloads the code your app sends to every visitor. On Tidybook, that was 27 files, 738 KB.
- It finds your database address and public key in that code. This key is public by design. See [My Supabase public key is visible. Is that a problem?](https://lidtight.com/guides/supabase-public-key)
- It asks the sign-in service for its public settings. Supabase’s sign-in service [returns these “publicly available settings”](https://github.com/supabase/auth/blob/master/README.md) to anyone who asks.
- It reads three values: is sign-up open (disable_signup), is email sign-up on (external.email), and are new addresses confirmed automatically (mailer_autoconfirm). When all three answers are yes, it reports the problem as high.

The free check never sends a sign-up request, so it creates no account in your app. CAPTCHA and rate limits are [not part of the public settings](https://github.com/supabase/auth/blob/master/internal/api/settings.go), so the finding can show even when CAPTCHA is on. The check cannot know what a new account gets in your app. It does not check sign-up on Base44 or Firebase apps yet.

## How to check your own app

1. Open your sign-in settings. In Supabase, go to Authentication → Sign In / Providers → Email and look at “Confirm email”. In Lovable Cloud, go to More → Users → Settings → Email and look at “Auto-confirm email”. Also check whether sign-up is open at all: “Allow new users to sign up” in Supabase, [“Disable sign-up”](https://docs.lovable.dev/features/authentication) in Lovable Cloud.
2. Test your live app. Sign up with a new address that you own, and do not open the email. If the app lets you in, confirmation is off.
3. List what a new account gets: free credits, AI calls, a trial, or the right to post. That list tells you what a fake account costs you.

You can also ask your project for its public settings, as the free check does, with your database address and public key:

```
curl "https://YOUR-DATABASE-ADDRESS/auth/v1/settings" \
  -H "apikey: YOUR_PUBLIC_KEY"
```

In the answer, **disable_signup: false** means anyone can sign up, and **mailer_autoconfirm: true** means no email confirmation. Or paste your app link into [our free check](https://lidtight.com/#check-now), which reads these settings in seconds.

## How to fix it

### First, make sure confirmation emails arrive

Confirmation works only if the email reaches the user. Supabase’s built-in email service is [not meant for production](https://supabase.com/docs/guides/auth/auth-smtp): it sends only to members of your project’s team, and currently at most 2 emails per hour. Before you turn on confirmation in your own Supabase project, set up custom SMTP (an outside email sending service, such as Resend or Amazon SES) in the Authentication settings.

In Lovable Cloud, an [hourly email limit](https://docs.lovable.dev/features/email-auth) applies too. To raise “Rate limit for sending emails”, first set up managed email or a verified custom domain under More → Emails.

### Turn on email confirmation

1. In Supabase: go to Authentication → Sign In / Providers → Email and turn on “Confirm email”.
2. In Lovable Cloud: go to More → Users → Settings → Email and turn off “Auto-confirm email”.
3. If your app does not need public sign-up, close it instead: turn off “Allow new users to sign up” in Supabase, or turn on “Disable sign-up” in Lovable Cloud. Existing users can still sign in.
4. Sign up once more with a new address that you own. Check that the email arrives and that the app waits for the click.

Then ask your AI builder to update the sign-up page. Paste this prompt into Lovable, Bolt or the builder you use:

```
Turn on email confirmation for sign-up: a new user must confirm their email before they can sign in. After sign-up, ask the user to check their inbox, with a button to resend the email. Add Cloudflare Turnstile CAPTCHA to the sign-up, sign-in and password reset forms. Give no free credits, trials or AI calls before the email is confirmed. Tell me which dashboard settings I must change myself.
```

### Add CAPTCHA to the sign-up form

A CAPTCHA is a short test that is easy for a person and hard for a program. Supabase supports [hCaptcha and Cloudflare Turnstile](https://supabase.com/docs/guides/auth/auth-captcha) on sign-up, sign-in and password reset forms. It has two parts. You turn it on in the Supabase dashboard (Authentication → Attack Protection → Enable CAPTCHA protection) with the secret key from the CAPTCHA provider. Your sign-up page must also show the CAPTCHA and send its token with each sign-up. Make both changes together: a CAPTCHA on the page alone does not stop a bot that calls Supabase directly.

Lovable’s pages on users and email sign-in do not mention CAPTCHA, so on Lovable Cloud ask Lovable in the project chat whether your backend supports it.

### Check your rate limits

A rate limit caps how many requests the sign-in service accepts in a period of time. By default, Supabase [accepts 30 sign-up and sign-in requests per 5 minutes](https://supabase.com/docs/guides/auth/rate-limits) from one IP address (the network address a request comes from), with bursts of up to 30. Change it under Authentication → Rate Limits only if real users hit it. The limit counts per IP address, so it slows a bot down. It does not prove that a person is behind each sign-up.

> Email confirmation proves that someone can read the inbox, not that a person made the account. Use it together with CAPTCHA, rate limits and limits that your server checks, such as one free trial per confirmed address. For the rest of your checks before launch, see [Before you go live: a security checklist](https://lidtight.com/guides/launch-security-checklist).

## Sources

1. [Supabase: General configuration (Confirm email, Allow new users to sign up)](https://supabase.com/docs/guides/auth/general-configuration)
2. [Supabase: Send emails with custom SMTP](https://supabase.com/docs/guides/auth/auth-smtp)
3. [Supabase: Enable CAPTCHA protection](https://supabase.com/docs/guides/auth/auth-captcha)
4. [Supabase: Rate limits](https://supabase.com/docs/guides/auth/rate-limits)
5. [Supabase Auth on GitHub: README, GET /settings](https://github.com/supabase/auth/blob/master/README.md)
6. [Supabase Auth on GitHub: the public settings (settings.go)](https://github.com/supabase/auth/blob/master/internal/api/settings.go)
7. [Lovable: Built-in backend](https://docs.lovable.dev/features/cloud)
8. [Lovable: Email authentication for your app](https://docs.lovable.dev/features/email-auth)
9. [Lovable: Users and authentication](https://docs.lovable.dev/features/authentication)
10. [IANA: Example domains](https://www.iana.org/help/example-domains)
