How I dumped 4,500 users and 5,000 GPS-tagged confessions from a feelings app
How I dumped 4,500 users and 5,000 GPS-tagged confessions from a feelings app
Embers is one of those apps where you drop anonymous thoughts on a map, tagged with how you're feeling. Hope, heartbreak, venting, ghosts. Other people walk by the same spot and find what someone left behind. Location-based emotional graffiti.
The entire database was open to the internet. No authentication needed beyond a key sitting in the frontend JavaScript.
Finding the key
The site runs at embers.jayrb.dev. It's a web app backed by Supabase, which is a hosted Postgres service that gives you a REST API out of the box. Supabase projects ship with two API keys: an anon (public) key meant for client-side use, and a service_role key that bypasses all security rules. The anon key is expected to be in the frontend. That's fine, as long as you've set up Row Level Security (RLS) to control what it can actually read.
The key was in the page source:
sb_publishable_7yA0vgieRQYCTStFPAQcaQ_6gCoSU93
Project URL: https://bglibqmhuyvonncknltj.supabase.co
Again, finding the key in the frontend is normal. The problem is what happened next.
No RLS, no rules
I pointed the key at the Supabase REST API and asked for everything.
GET /rest/v1/profiles?select=*&limit=1000&offset=0
GET /rest/v1/embers?select=*&limit=1000&offset=0
Both returned full results. No restrictions, no filtering, no "you can only see your own rows." Just the whole table, paginated in batches of 1,000.
Three tables existed:
| Table | Records | What's in it |
|---|---|---|
| profiles | 4,503 | User IDs, usernames, account creation dates |
| embers | 5,167 | Thoughts, GPS coordinates, ember type, username, TikTok links |
| notifications | 0 | Empty |
I downloaded every record in both tables. Took about 30 seconds.
What the data looks like
The profiles table is straightforward. UUID, username, timestamps. No passwords or emails. Supabase stores authentication data (password hashes, email addresses) in an internal auth.users table that wasn't accessible with the anon key. I checked. The auth admin endpoints returned 401, and trying to select password/email columns from the public tables returned "column does not exist." So at least the auth layer held up.

The embers table is where it gets uncomfortable.
Each record is a message someone left on the map, with their exact latitude and longitude. Here's the kind of stuff in there:
A user named "J.D" posted from coordinates 6.688, 124.678 (that's southern Philippines), with a TikTok link and a long message about lying to their partner for 10 years to hide that their parents disapproved of the relationship. "I fought for our relationship alone for 10 years. I was alone fighting the battle that I've been hiding from you."
Another user, "jea_jingjing," posted from 8.484, 124.651: "Just tell me po if you don't want me anymore ying." Also with a TikTok link attached.
People are using this app to say things they can't say out loud. Love confessions, breakup grief, venting about family. The ember types tell you the mood: "hearts" for love, "hope" for optimism, "vents" for frustration, "echoes" and "ghost" for the heavier stuff.
Every one of these messages has GPS coordinates accurate to about a meter. Combined with the username and the TikTok links some people attached, you can tie real identities to real locations to very personal thoughts.
The actual risk
No passwords leaked. No emails. If this were just a list of usernames and UUIDs, it'd barely be worth writing up.
But 5,167 geo-tagged personal messages, a lot of them raw and emotional, some with TikTok links that point straight to a real person? That's a problem. You could map out where someone lives or works based on where they post. You could read their private thoughts and know exactly who wrote them.
The vulnerability is a Supabase misconfiguration that comes up constantly. RLS was either never enabled or was enabled but had no policies restricting reads. The anon key, which is supposed to be scoped down to only what's appropriate for unauthenticated users, had full SELECT access to every row in every public table.
Fix
Enable RLS on all tables. Add policies so users can only read their own profiles and only see embers within some geographic radius, or whatever the app's design requires. The Supabase docs have a whole section on this. It takes maybe 20 minutes.
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE embers ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can read own profile"
ON profiles FOR SELECT
USING (auth.uid() = id);
CREATE POLICY "Users can read nearby embers"
ON embers FOR SELECT
USING (true); -- replace with actual proximity logic
The anon key stays in the frontend. That's fine. RLS is what keeps it safe.
Timeline
- February 18, 2026: Discovered exposed Supabase key, confirmed full read access, dumped 4,503 profiles and 5,167 embers
- February 21, 2026: Verified no password or email exposure through auth endpoints
- Disclosure: Pending