TL;DR
Moltbook launched in late January 2026 with Row Level Security switched off, which in Supabase terms means the front door was never fitted. Security researcher Jamieson O'Reilly found it within days: the anon key in the site's own JavaScript returned nearly 1.5 million agent records, API keys included. Two SQL statements would have closed it.
What Is Moltbook?
Moltbook is a social network where AI agents interact with each other. Users create AI agents that post, interact, and build relationships with other agents. It launched in late January 2026 and grew fast. By the time of the incident it carried 1.5 million registered agents, with about 17,000 human owners behind them.
"A lot of these vibe coders and new developers, even some big companies, are using Supabase. The reason a lot of vibe coders like to use it is because it's all GUI driven, so you don't need to connect to a database and run SQL commands."
- Jamieson O'Reilly, security researcherWhat Went Wrong
On January 31, 2026, days after launch, Jamieson O'Reilly went looking and found the whole database sitting in the open. Not a stray table. All of it.
The Technical Details
Moltbook runs on Supabase, the backend-as-a-service that's become the default pick for indie developers and vibe coders. Supabase exposes REST APIs by default. That's fine, as long as you've told it who may read what.
Moltbook shipped without enabling Row Level Security or writing a single access policy. With RLS off, the "anon" key, the one that is supposed to live in public client-side code, isn't a limited key at all. It reads everything.
What was exposed: O'Reilly found the Supabase anon key sitting in client-side JavaScript. That one key opened the production database with full read and write access to every table, including the API keys for every account on the platform.
In practice, anyone who knew where to look could take over any account on Moltbook and post as that person.
How Bad Was It?
Let's put some numbers on this:
- ~1.5 million agent records with exposed API keys
- 35,000+ email addresses exposed
- 17,000 human users whose credentials were compromised
- Full read/write access to the entire database
- Exposed from day one: the flaw shipped with the product
404 Media, which broke the story, confirmed they viewed both the exposed database URL in Moltbook's code and the list of API keys.
A Trivial Fix That Should Have Happened Before Launch
Here's the frustrating part. Two SQL statements would have shut this down:
-- Enable Row Level Security on the agents table
ALTER TABLE agents ENABLE ROW LEVEL SECURITY;
-- Create a policy so users can only access their own data
CREATE POLICY "Users can only access own data"
ON agents FOR ALL
USING (auth.uid() = owner_id);
Thirty seconds of typing.
Nobody attacked Moltbook. There was no exploit chain and no zero-day, just a configuration that was never switched on, sitting in plain sight in the client-side bundle. We flag this exact shape constantly in scans: the key isn't the finding, the missing policy behind it is.
Why This Keeps Happening
The Supabase Mental Model Problem
Supabase is genuinely excellent for building fast, and that's the trap. When the app works on the first try, it's easy to read that as "configured correctly."
When you create a Supabase project, you get two keys:
- anon key: designed for client-side use. Not a secret.
- service_role key: admin access, bypasses RLS. Never ships to the browser.
Plenty of developers treat the anon key like a password and assume hiding it is the protection. It isn't, and it was never meant to be. The anon key is public by design. Your policies are the security.
The misconception: "My API key is in client-side code, but that's fine because nobody will find it."
The reality: Every security researcher, and plenty of malicious actors, know exactly where to look for exposed database credentials. It takes about 30 seconds to find them.
The "Ship Now, Secure Later" Trap
Moltbook isn't alone. This pattern shows up constantly in vibe-coded apps:
- Build fast with AI tools
- Get it working
- Ship it
- Plan to add security "later"
- "Later" never comes
- Security researcher (or worse, attacker) finds the flaw
As AI researcher Mark Riedl observed about the Moltbook incident: "AI community relearning past 20 years of cybersecurity courses in hardest way possible."
The Aftermath
After O'Reilly's disclosure:
- The platform was temporarily taken offline to patch the breach
- All API keys were force-reset
- Moltbook's founder reached out to O'Reilly for help securing the platform
- The exposed database was closed
O'Reilly reported it rather than using it. Plenty of people who find these don't. Someone less scrupulous could have:
- Posted malicious content as any user
- Extracted all user data
- Deleted or corrupted the entire database
- Used the compromised accounts for spam or scams
The Case for Scanning Before You Ship
None of this needed security expertise to find. The URL and the anon key were in the shipped JavaScript, where any automated scanner reads them in seconds.
A single pre-launch security scan would have caught:
- The exposed database credentials in client-side code
- The missing RLS configuration that left all data accessible
- The full read/write access available to unauthenticated users
This is the floor, not the ceiling. No pen test, no audit, just an automated pass for obvious misconfiguration before you go live.
What About After Launch?
Pre-launch scanning catches the obvious things. The awkward ones show up later:
- New code introduces new risks. A feature that was secure yesterday might not be secure after today's update.
- Configuration drift happens. Someone disables RLS "temporarily" for debugging and forgets to re-enable it.
- Dependencies change. A library update might expose something that was previously protected.
Scanning on a schedule means you find these, rather than a researcher finding them for you.
Is my Supabase database at risk?
If you haven't enabled Row Level Security and created appropriate policies for all tables, then yes. Test by trying to query your database with just the anon key and no user authentication. If you can access data that should be protected, you have a problem.
What's the difference between the anon key and service_role key?
The anon key is meant to be used in client-side code and is not secret. Security comes from RLS policies. The service_role key bypasses RLS entirely and belongs on the server, never in client code.
How do I know if my RLS is configured correctly?
The best test is to try to access data you shouldn't be able to access. Sign in as User A and try to query User B's data. If you can see it, your policies are wrong. Also test unauthenticated access: with proper RLS, a query with no auth should return nothing, or only what you meant to make public.
Could this happen with Firebase too?
Absolutely. Firebase has similar security rules that need to be configured properly. Firebase's default "test mode" is wide open by design and meant to expire, but plenty of apps ship with it left on. The same principles apply: never trust that your configuration is secure without testing it.
Is Your Database Exposed?
Run a free scan to check for exposed API keys, missing RLS, and other common vulnerabilities before you launch.