[{"data":1,"prerenderedAt":422},["ShallowReactive",2],{"blog-is-safe/supabase":3},{"id":4,"title":5,"body":6,"category":402,"date":403,"dateModified":403,"description":404,"draft":405,"extension":406,"faq":407,"featured":405,"headerVariant":408,"image":407,"keywords":407,"meta":409,"navigation":410,"ogDescription":411,"ogTitle":407,"path":412,"readTime":413,"schemaOrg":414,"schemaType":415,"seo":416,"sitemap":417,"stem":418,"tags":419,"twitterCard":420,"__hash__":421},"blog/blog/is-safe/supabase.md","Is Supabase Safe? Security Analysis",{"type":7,"value":8,"toc":381},"minimark",[9,16,21,24,28,76,80,83,93,98,112,116,131,135,211,215,224,228,231,245,249,263,267,271,294,322,326,329,350,369],[10,11,12],"tldr",{},[13,14,15],"p",{},"Supabase itself is secure and SOC 2 certified, but many Supabase projects are vulnerable because of misconfiguration. The #1 issue is missing Row Level Security (RLS) policies. Without RLS, anyone with your public anon key can read and modify all your data. Supabase is safe when configured correctly, but the defaults don't protect you.",[17,18,20],"h2",{"id":19},"what-is-supabase","What is Supabase?",[13,22,23],{},"Supabase is an open-source Firebase alternative providing a PostgreSQL database, authentication, realtime subscriptions, storage, and edge functions. It's popular for full-stack apps and is the default backend for many AI app builders like Lovable and Bolt.",[17,25,27],{"id":26},"our-verdict","Our Verdict",[29,30,31,36,55,59],"pros-cons",{},[32,33,35],"h4",{"id":34},"whats-good","What's Good",[37,38,39,43,46,49,52],"ul",{},[40,41,42],"li",{},"PostgreSQL's mature security",[40,44,45],{},"Built-in Row Level Security",[40,47,48],{},"SOC 2 Type II certified",[40,50,51],{},"Auth with JWT tokens",[40,53,54],{},"Self-hosted option",[32,56,58],{"id":57},"what-to-watch","What to Watch",[37,60,61,64,67,70,73],{},[40,62,63],{},"RLS disabled by default",[40,65,66],{},"Public anon key exposed",[40,68,69],{},"AI tools often skip RLS",[40,71,72],{},"Complex policy writing",[40,74,75],{},"Easy to misconfigure",[17,77,79],{"id":78},"the-rls-problem","The RLS Problem",[13,81,82],{},"Row Level Security (RLS) is Supabase's key security feature, but it's not enabled by default on new tables:",[84,85,86],"danger-box",{},[13,87,88,92],{},[89,90,91],"strong",{},"Critical:"," Without RLS enabled, anyone who knows your Supabase URL and anon key (which are public in your frontend) can read, modify, and delete all data in that table. This is the most common security issue we see in Supabase projects.",[94,95,97],"h3",{"id":96},"why-this-happens","Why This Happens",[37,99,100,103,106,109],{},[40,101,102],{},"AI app builders often create tables without enabling RLS",[40,104,105],{},"Quick prototypes skip security configuration",[40,107,108],{},"Developers may not understand the anon key exposure",[40,110,111],{},"Testing with RLS off and forgetting to enable it",[94,113,115],{"id":114},"how-to-check","How to Check",[117,118,119,122,125,128],"ol",{},[40,120,121],{},"Go to your Supabase dashboard",[40,123,124],{},"Navigate to Database → Tables",[40,126,127],{},"Check the shield icon next to each table",[40,129,130],{},"If the shield has a warning, RLS is disabled",[17,132,134],{"id":133},"common-supabase-vulnerabilities","Common Supabase Vulnerabilities",[136,137,138,154],"table",{},[139,140,141],"thead",{},[142,143,144,148,151],"tr",{},[145,146,147],"th",{},"Issue",[145,149,150],{},"Risk",[145,152,153],{},"Fix",[155,156,157,169,180,190,200],"tbody",{},[142,158,159,163,166],{},[160,161,162],"td",{},"RLS not enabled",[160,164,165],{},"Critical",[160,167,168],{},"Enable RLS on all tables",[142,170,171,174,177],{},[160,172,173],{},"Permissive RLS policies",[160,175,176],{},"High",[160,178,179],{},"Review and restrict policies",[142,181,182,185,187],{},[160,183,184],{},"Service key in frontend",[160,186,165],{},[160,188,189],{},"Only use in server-side code",[142,191,192,195,197],{},[160,193,194],{},"Missing auth checks",[160,196,176],{},[160,198,199],{},"Require auth in policies",[142,201,202,205,208],{},[160,203,204],{},"Overly broad storage policies",[160,206,207],{},"Medium",[160,209,210],{},"Restrict bucket access",[17,212,214],{"id":213},"service-key-vs-anon-key","Service Key vs Anon Key",[216,217,218],"warning-box",{},[13,219,220,223],{},[89,221,222],{},"Never expose the service_role key in frontend code."," The anon key is meant to be public and works with RLS. The service key bypasses all security and should only be used server-side.",[17,225,227],{"id":226},"supabase-auth-security","Supabase Auth Security",[13,229,230],{},"Supabase Auth is generally secure when used correctly:",[37,232,233,236,239,242],{},[40,234,235],{},"JWT tokens with short expiration",[40,237,238],{},"Secure password hashing (bcrypt)",[40,240,241],{},"Built-in MFA support",[40,243,244],{},"OAuth provider integration",[94,246,248],{"id":247},"common-auth-mistakes","Common Auth Mistakes",[37,250,251,254,257,260],{},[40,252,253],{},"Not verifying email before allowing access",[40,255,256],{},"Weak password requirements",[40,258,259],{},"Missing rate limiting on auth endpoints",[40,261,262],{},"Not using HTTPS for redirects",[17,264,266],{"id":265},"security-checklist","Security Checklist",[94,268,270],{"id":269},"before-going-live","Before Going Live",[37,272,273,276,279,282,285,288,291],{},[40,274,275],{},"Enable RLS on every table with data",[40,277,278],{},"Write restrictive RLS policies (deny by default)",[40,280,281],{},"Test policies from the browser (not admin)",[40,283,284],{},"Verify service key is not in frontend code",[40,286,287],{},"Configure storage bucket policies",[40,289,290],{},"Enable email verification",[40,292,293],{},"Set up rate limiting for functions",[295,296,297,304,310,316],"faq-section",{},[298,299,301],"faq-item",{"question":300},"Is Supabase safe for production?",[13,302,303],{},"Yes, when properly configured. Supabase itself is SOC 2 certified and uses PostgreSQL's mature security model. The platform is safe; the risk is misconfiguration, especially missing RLS policies.",[298,305,307],{"question":306},"Why is my anon key public?",[13,308,309],{},"The anon key is designed to be public. It's meant for client-side use and works with RLS to control access. The key itself doesn't grant access to data; your RLS policies determine what's accessible.",[298,311,313],{"question":312},"Can I use Supabase without RLS?",[13,314,315],{},"For development, yes, but never for production with real user data. Without RLS, any authenticated user can access all data. Even for internal tools, RLS is recommended.",[298,317,319],{"question":318},"How do I write secure RLS policies?",[13,320,321],{},"Start with a deny-all approach and explicitly allow what's needed. The most common pattern is \"users can only access their own data\" using auth.uid() = user_id. Test policies by querying as a regular user, not admin.",[17,323,325],{"id":324},"further-reading","Further Reading",[13,327,328],{},"Ready to secure your setup? Check out our hands-on guides.",[37,330,331,338,344],{},[40,332,333],{},[334,335,337],"a",{"href":336},"/blog/checklists/pre-deployment-security-checklist","Pre-deployment security checklist",[40,339,340],{},[334,341,343],{"href":342},"/blog/getting-started/first-scan","Run your first security scan",[40,345,346],{},[334,347,349],{"href":348},"/blog/best-practices/environment-variables","Environment variable best practices",[351,352,353,359,364],"related-articles",{},[354,355],"related-card",{"description":356,"href":357,"title":358},"Complete RLS setup","/blog/guides/supabase","Supabase Security Guide",[354,360],{"description":361,"href":362,"title":363},"Step-by-step tutorial","/blog/how-to/setup-supabase-rls","How to Set Up RLS",[354,365],{"description":366,"href":367,"title":368},"Compare alternatives","/blog/is-safe/firebase","Is Firebase Safe?",[370,371,374,378],"cta-box",{"href":372,"label":373},"/","Start Free Scan",[17,375,377],{"id":376},"using-supabase","Using Supabase?",[13,379,380],{},"Scan your project for missing RLS and other security issues.",{"title":382,"searchDepth":383,"depth":383,"links":384},"",2,[385,386,387,392,393,394,397,400,401],{"id":19,"depth":383,"text":20},{"id":26,"depth":383,"text":27},{"id":78,"depth":383,"text":79,"children":388},[389,391],{"id":96,"depth":390,"text":97},3,{"id":114,"depth":390,"text":115},{"id":133,"depth":383,"text":134},{"id":213,"depth":383,"text":214},{"id":226,"depth":383,"text":227,"children":395},[396],{"id":247,"depth":390,"text":248},{"id":265,"depth":383,"text":266,"children":398},[399],{"id":269,"depth":390,"text":270},{"id":324,"depth":383,"text":325},{"id":376,"depth":383,"text":377},"is-safe","2026-02-19","Is Supabase safe for production? Security analysis covering Row Level Security, authentication, and common misconfigurations in Supabase projects.",false,"md",null,"amber",{},true,"Security analysis of Supabase. Learn about RLS, auth, and common security issues.","/blog/is-safe/supabase","8 min read","[object Object]","Article",{"title":5,"description":404},{"loc":412},"blog/is-safe/supabase",[],"summary_large_image","hvAzIT8UCbri25Bam2pyg2Qywg0VD3zFJANGVvEKmgM",1775843918547]