Supabase fraud prevention

12 min read

Let's be real…

Supabase fraud prevention
SS

Simul Sarker

CEO of DataCops

Last Updated

May 10, 2026

Supabase fraud prevention in 2026: the consolidated signup defense playbook

Let's be real. The fraud prevention story in Supabase is fragmented. The official docs cover CAPTCHA. The rate-limit page covers fail2ban and IP throttles. A separate community PG TLE called email_guard handles disposable-email blocklists. Auth hooks have their own page. Anonymous sign-ins have a third page where the Supabase team itself admits they are easier to abuse than OAuth.

Nobody has put the whole picture together. This is that page.

The pain is concrete. 47 percent of SaaS platforms cite fake accounts as their top security concern. The average annual cost per company from fake registrations is around 127,000 dollars. Real-time validation against known temporary email domains blocks roughly 73 percent of fake registrations on its own, but it is a layer most Supabase devs only add after they get burned. Cloudflare Turnstile, which is Supabase's officially supported invisible CAPTCHA, hits about 33 percent detection accuracy against advanced bots in independent testing. Residential-proxy headless browsers walk through it. The October 2025 Hacker News thread "Ask HN: What in the world is going on at Supabase?" surfaced practitioners getting hit by fake-trial signup abuse against their domains and unable to find a turnkey answer.

Meanwhile the Pro plan includes 100,000 MAUs and overage is 0.00325 dollars per MAU. Anonymous sign-ins are rate-limited at 30 requests per hour per IP, which residential proxy pools clear with one finger. Every bot-driven anonymous signup is a row you pay for, and the is_anonymous JWT claim has to gate features you do not want exposed.

This post is the consolidated playbook. What Supabase actually ships natively. What it explicitly does not. The Postgres functions and HTTP hooks that close the gaps. And where DataCops fits if you do not want to maintain six layers yourself.


Quick stuff people keep asking

Does Supabase have built-in fraud detection?

Partly. Supabase ships CAPTCHA via Cloudflare Turnstile or hCaptcha, fail2ban-style brute-force protection on auth, configurable IP rate limits, and the before_user_created hook. It does not natively block disposable email domains, normalize Gmail dot or plus subaddresses, score device or IP risk, or detect behavioral bot patterns. Those gaps are explicitly out of scope per Supabase's own docs.

Are anonymous sign-ins safe?

They are useful. They are also the new attack surface. The Supabase team's own words: "Anonymous sign-ins can be slightly easier to abuse with bots and scripts than OAuth sign-in methods." Default rate limit is 30 requests per hour per IP. Residential proxy pools defeat that trivially. Every anonymous user is a row you pay for under the 0.00325 dollar per MAU overage.

Is the before_user_created hook reliable?

Mostly, with one caveat. Late 2025 reports show the hook returning "Invalid payload sent to hook" when rejecting signup with HTTP 400, blocking the documented fraud-rejection pattern. The hook is the right integration point for pre-insert rejection. Just expect to handle the bug and have an external retry-safe scorer behind it.

Is Turnstile enough?

No. Independent testing puts Turnstile at around 33 percent detection vs advanced bots. No escalation challenge for stealth headless browsers on residential proxies. Turnstile is necessary as a friction layer, not sufficient as a defense. The hCaptcha team makes the same point in their 2025 engineering writeup: "Selective humanity verification remains the single best tool to detect and prevent automated attacks."

What about RLS, does that protect against fraud?

Different layer. RLS protects data access. It does not protect signup. Pomerium's analysis of the 2025 Supabase MCP "lethal trifecta" incident put it cleanly: "RLS can protect your data from honest users, but it cannot protect against a confused, overly-privileged AI agent." CVE-2025-48757 exposed 170 plus Lovable-on-Supabase apps because RLS is opt-in. Both layers matter.


The five-layer defense Supabase devs should actually run

This is the consolidated stack. Five layers, ordered from cheapest to most defensible.

Layer 1: Turnstile or hCaptcha at the form

The Good: Officially supported by Supabase. Drop the captchaToken into the auth call and you are done. Free up to generous limits. Deflects script kiddies and the simplest bot waves.

Frustrations: Around 33 percent detection vs advanced bots per independent 2025 testing. No escalation step. Stealth headless browsers on residential proxies pass cleanly. Single-layer defense is not a defense.

Wish List: Native escalation challenge for borderline scores. A risk-score field returned to the server so you can chain it into the next layer.

Value for Money: 6.5/10. Necessary baseline, never sufficient.

Pricing: Turnstile free, hCaptcha free with paid Pro and Enterprise tiers.


Layer 2: configurable rate limits and fail2ban brute-force protection

The Good: Supabase ships fail2ban-style brute-force protection on the auth endpoints. IP rate limits are configurable. Anonymous sign-ins default to 30 per hour per IP.

Frustrations: Rate limits are per IP. Residential proxy pools rotate IPs at scale. The defense is real against single-source brute-force, weak against distributed signup floods. The 30 per hour anonymous default is too low for real product flows and too high for serious attackers.

Wish List: Per-fingerprint rate limits in addition to per-IP. A reputation field on the IP that decays.

Value for Money: 6/10. Useful against amateurs. The professional bot pools have already moved past it.

Pricing: Included in every Supabase tier.


Layer 3: the before_user_created hook plus an external scorer

This is the linchpin. The hook fires before the user row hits auth.users, which means you can reject without paying for the MAU and without leaving an is_anonymous shell behind.

The Good: Supported HTTP and Postgres-function variants. Signed via the Standard Webhooks spec (webhook-id, webhook-timestamp, webhook-signature). Right integration point for pre-insert rejection.

Frustrations: Late 2025 bug returning "Invalid payload sent to hook" when rejecting signup with HTTP 400. Reliability dip on the very pattern Supabase docs recommend. You need the external scorer to be retry-safe and idempotent because the hook can re-fire.

Wish List: Stable HTTP 400 rejection without the payload-error bug. A built-in scorer SDK that wraps the signed-webhook plumbing.

Value for Money: 7/10. The right architecture, with one bug to design around.

Pricing: Hooks free on Pro and above.

The hook contract, in code:

typescript
// /functions/v1/before-user-created handler
import { Webhook } from 'standardwebhooks';
export async function handler(req: Request) {
const wh = new Webhook(SUPABASE_HOOK_SECRET);
const payload = await wh.verify(await req.text(), Object.fromEntries(req.headers));
const { user } = payload;
// call your fraud scorer here
const score = await scoreSignup({
email: user.email,
ip: user.raw_user_meta_data?.ip,
fingerprint: user.raw_user_meta_data?.fingerprint,
});
if (score.risk > 0.8) {
return new Response(JSON.stringify({ error: { http_code: 400, message: 'rejected' } }), { status: 200 });
}
return new Response('{}', { status: 200 });
}

Layer 4: a daily-refreshed disposable-domain table plus subaddress normalization

Supabase does not block disposable emails out of the box. The community PG TLE called email_guard ships a blocklist of 20,000 plus disposable email domains, refreshed weekly, plugged in via auth hooks. It is the de facto disposable-domain solution in the Supabase ecosystem.

The Good: Real-time validation against known temporary email domains blocks roughly 73 percent of fake registrations. PG TLE means it lives inside Postgres, no extra service to run. Weekly refresh catches new disposable domains as they spin up.

Frustrations: Maintained by the community, not by Supabase. The refresh cadence is weekly, which is fine for established disposables and behind for fresh-spun domains attackers actually use. Does not handle Gmail dot tricks or plus-subaddress duplicates on its own.

Wish List: A daily refresh feed. Built-in subaddress normalization helper.

Value for Money: 7.5/10. The single highest-leverage layer for the work involved.

The Postgres normalization function:

sql
create or replace function normalize_email(email text)
returns text language sql immutable as $$
select lower(
case
when split_part(email, '@', 2) = 'gmail.com'
then replace(split_part(split_part(email, '@', 1), '+', 1), '.', '')
else split_part(split_part(email, '@', 1), '+', 1)
end
|| '@' || split_part(email, '@', 2)
);
$$;
-- in your fraud scorer, dedupe on normalize_email(user.email) before allowing signup

This catches the multi-account abuse where attackers register [email protected], [email protected], and [email protected] as three separate users on a free trial.


Layer 5: behavioral and device-risk scoring via webhook to an external scorer

This is the layer Supabase explicitly does not ship. Browser fingerprinting (canvas, WebGL, audio, screen, fonts), IP intelligence (residential vs datacenter vs VPN vs proxy vs Tor), behavioral patterns (form-fill velocity, mouse movement entropy), and email-domain risk all live outside the platform.

You have three options:

Option A. Build it yourself. Maintain a fingerprint library (FingerprintJS open source or Castle's free tier), an IP reputation feed, a behavioral signal collector, and the scoring service. Real engineering investment. Six to twelve weeks for a credible v1, ongoing maintenance forever.

Option B. Use a dedicated signup-fraud vendor. SEON, Sift, Verisoul, Castle. Each scores well on accuracy. Each costs 500 to 5000 dollars per month at SMB scale. Each integrates via a webhook into the before_user_created hook. None of them also covers your ad-attribution stitching, your CAPI, your consent banner, or your traffic-side bot filter.

Option C. Use a stack that bundles signup fraud with the rest of the trust layer.


DataCops as the trust-infrastructure layer underneath Supabase

The Good: SignUp Cops scores the signup form via webhook into the before_user_created hook. IP intelligence (residential vs datacenter vs VPN vs proxy vs Tor). Browser fingerprinting (canvas, WebGL, audio, screen, fonts). Email validation including disposable domain detection, fresh domain heuristics, and alias technique recognition. Real-time risk scoring at the form. 361 billion plus IPs and network ranges in the reputation database. 160K plus fraud email domains. 620 million proxy and anonymizer IPs. CNAME on your own subdomain so the fingerprint script survives uBlock and ITP. Same pipeline carries the consent state into Meta CAPI and Google Ads CAPI for the conversion side.

Frustrations: Newer brand than SEON or Sift. SOC 2 Type II in progress, not yet active. ISO 27001 planned. Smaller community than the email_guard PG TLE for sheer Supabase-specific tutorials, though the integration is straightforward.

Wish List: SOC 2 Type II shipping. A native Supabase template repo for the before_user_created handler. SSO and SAML on standard plans.

Value for Money: 8.5/10. The bundling matters. Signup fraud, traffic fraud, CAPI, consent, and first-party analytics under one bill instead of five vendors stitched together.

Pricing: Basic free, 2,000 sessions per month, 500 signup verifications. Growth 7.99 dollars per month, 5,000 sessions. Business 49 dollars per month, 50,000 sessions. Organization 299 dollars per month, 300,000 sessions. Enterprise: dedicated runtime, dedicated IP reputation database, custom DPA. Signup verification overage is 0.019 dollars per 500.


What Supabase fixed in 2025 (and what it did not)

The Supabase Security Retro 2025 was substantive. New publishable plus secret API key model. Asymmetric JWTs. Auto-revocation of leaked keys detected via GitHub. RLS-on-by-default for dashboard tables. Email alerts when RLS-disabled tables are created. A Splinter security advisor inside the dashboard. IP allowlists. Column-level security.

Note what is not on that list: identity fraud scoring, disposable-email blocking, device fingerprinting, behavioral signals. The 2025 retro was about safer defaults at the data layer, not about closing the signup-fraud gap. That gap is still there in mid-2026.

Two other 2025 incidents worth knowing because they shape the threat model:

The MCP "lethal trifecta" attack. A prompt-injected support ticket caused a Cursor agent running with service_role to exfiltrate the integration_tokens table, bypassing RLS. The Pomerium analysis: RLS protects data from honest users, not from confused over-privileged AI agents. Fraud and abuse vectors now include AI-agent actions, not just bot signups.

CVE-2025-48757. 170 plus Lovable-on-Supabase apps exposed because Supabase auto-generates REST APIs from schema and RLS is opt-in. One researcher's tool found a leak exposing 13,000 users. Secure-by-default is still maturing.


So what should you actually build?

Brand new project, indie scale, want the cheapest credible defense? Turnstile plus the email_guard PG TLE plus the subaddress normalization function. Free. About 73 percent of fake signups blocked.

Funded SaaS hitting MAU overages from anonymous-signup abuse? Add a before_user_created hook with an external fraud scorer. SEON, Sift, Verisoul, Castle, or DataCops SignUp Cops. The scorer pays for itself in MAU savings before the bot pool finds you.

Need to stop multi-account abuse on a free trial? The Postgres normalize_email function on every signup, plus the disposable-domain table. Normalizing alone catches Gmail dot and plus-subaddress dupes. Disposable list catches the rest.

Want one bill covering signup fraud, traffic fraud, CAPI, and consent on top of Supabase? DataCops. Free tier covers 500 signup verifications per month.

Worried about the AI-agent attack surface? Lock the service_role key, audit which tools have it, and add an IP allowlist on the management API. The 2025 MCP incident is a warning, not a one-off.


The mistake we see people make

Devs ship Turnstile, watch the dashboard show 90 percent of signups as "verified human", and assume the job is done. Then the bot pool starts using residential proxies, Turnstile detection drops to its real 33 percent rate, and the signup floods get through. Six weeks later the MAU bill is up 40 percent, the conversion data is poisoned, and the postmortem blames Supabase for not flagging it.

Supabase did not promise device fingerprinting. The docs explicitly say anonymous sign-ins are easier to abuse than OAuth. The fraud layer is on you. The question is whether you build it, buy it from one of the dedicated signup-fraud vendors, or buy it from a stack that also covers the conversion side.


Now your turn

What is your Supabase fraud stack? Drop the layers in the comments. If it stops at Turnstile, tell us what your MAU graph looks like.


Live traffic quality

Updated just now

Visits · last 24h

487
Real users
35873.5%
Bots · auto-filtered
12926.5%

Without filtering, 26.5% of your reported traffic is bot noise inflating dashboards and draining ad spend.

Don't trust your analytics!

Make confident, data-driven decisions withactionable ad spend insights.

Setup in 2 minutes
No credit card