What happened, in the order it was reported
On July 25, 2025, 404 Media reported that users on 4chan claimed to have found an exposed database, hosted on Google's Firebase platform, belonging to the Tea app, and were rifling through people's driver's licences and selfies. The 4chan post describing the flaw said there was no authentication at all and called it a public bucket. Tea verifies that new users are women by asking them to upload a selfie, and at the time claimed more than 1.6 million users.
Tea confirmed the incident the same day. In its statement to 404 Media, reproduced by Engadget, Tea said it had identified unauthorized access to one of its systems and immediately launched a full investigation. It said the exposed set included 72,000 images, including selfies, photo IDs and pictures from app posts and DMs, and that the data was from over two years ago. TechCrunch's July 26 report broke the figure down as 13,000 selfies and photo IDs submitted for verification and 59,000 images from posts, comments and direct messages, and said Tea stated that no emails or phone numbers were exposed and only users who signed up before February 2024 were affected.
On July 29, TechCrunch and 404 Media reported a second, separate issue found by security researcher Kasra Rahjerdi: more than 1.1 million direct messages, from early 2023 up to that week, were accessible. Tea announced on Instagram that it had temporarily disabled direct messaging. CBS News reported on July 30 that Tea said the attackers accessed a data storage system containing information members had uploaded prior to February 2024, and that Tea had taken the affected system offline out of an abundance of caution.
The mechanism: a bucket anyone could read
Firebase Cloud Storage is a Google Cloud Storage bucket with a Firebase rules layer in front of it. Client apps read and write files directly, and the rules decide who may do what. Firebase's own guidance is that these rules are the only safeguard blocking access for malicious users, because there is no server in the middle.
For Tea's older files there was no effective safeguard. Engadget reported that 404 Media verified the exposed storage bucket URL matched one found in Tea's Android app, so the location was not secret, and the 4chan post said no authentication was required. Once a bucket is publicly readable and its URL is inside a shipped app, anyone can list or download files at scale, and copies spread faster than a company can revoke access.
This is the same class of mistake covered in our guide to Firebase security rules mistakes: a Storage rule that allows read without checking request.auth, or a bucket whose access was set by a different mechanism entirely and never reviewed. The details of how Tea's bucket was configured have not been published, so we describe the class, not a specific rule.
Why old data was still there
Tea's statements point to an older system. The company said the exposed system held information members uploaded before February 2024, that the data was from over two years ago, and that it was originally stored in compliance with law enforcement requirements related to cyber-bullying prevention. In plain terms, a set of files from the app's earlier period stayed in the earlier storage location after newer users were being handled differently.
That pattern is common in fast-growing apps, including ones built with AI tools. A team moves to a new backend, new buckets and new rules, and the migration is judged done when the current app works against the new system. The previous bucket still exists, still holds every file that was ever put in it, and is now maintained by nobody. Its rules are whatever they were on the last day anyone looked, and its URL is still embedded in every old build of the app that users have not updated.
The lesson is that "we migrated" is not a security control. Migration changes where new data goes. It does nothing to the old location unless someone deliberately locks it down, exports what must legally be kept to a private place, and deletes the rest.
The second exposure was a different failure
The direct-message exposure was not the same open bucket. In an August 2025 piece, 404 Media described it as any Tea user being able to use their own API key to access sensitive parts of the Tea app's backend, including a database of private messages, and reported that Rahjerdi found evidence others had also used the same flaw. TechCrunch noted that Tea's first statement said only pre-February 2024 users were affected, while the messages Rahjerdi found ran up to the week of the report.
For builders, the distinction matters. The first problem was a storage location open to everyone with no login. The second was a logged-in user being able to reach data belonging to other users, which is the "signed in is not the same as authorised" mistake. Fixing one does not fix the other. A bucket locked to authenticated users still leaks everything if the rule stops at request.auth != null and never checks ownership.
Lesson 1: storage rules that check ownership
Every Firebase Storage bucket your app can reach needs rules that deny by default and grant access per user. Firebase's Storage rules documentation shows the shape: a path segment for the user ID, a write rule of request.auth.uid == userId, and a read rule that is either the same ownership check or, for genuinely shared files, request.auth != null. For an unauthenticated request, request.auth is null and the check fails.
Files that hold identity documents should be readable by nobody on the client at all. Verification is something your server or a Cloud Function does with the Admin SDK, which bypasses rules; the client only needs to upload. A rule of allow read: if false on the verification folder, with allow write limited to the owner and validated for size and content type, means even a bug in the app cannot expose the images to another user.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /verification/{userId}/{fileName} {
allow read: if false;
allow write: if request.auth != null
&& request.auth.uid == userId
&& request.resource.size < 10 * 1024 * 1024
&& request.resource.contentType.matches('image/.*');
}
match /{allPaths=**} {
allow read, write: if false;
}
}
}Lesson 2: retention and deletion are security features
A file that no longer exists cannot leak. Tea said the exposed images were from over two years ago, and that they were kept for law-enforcement related reasons. Whatever your own obligations are, the question to ask is which specific files must be retained, for how long, under which rule, and where. Everything outside that answer should have a deletion date.
For an AI-built app the practical version is a scheduled job that runs with the Admin SDK, lists objects older than the retention period, and deletes them, plus a record of what was deleted and when. For verification selfies and IDs, the retention period is usually the time it takes to verify the account. Keep the outcome, delete the evidence, and if a rule requires you to keep the evidence, keep it somewhere the client SDK cannot reach.
Retention also applies to the systems you stopped using. A migration plan should end with a line that says the old bucket was emptied and deleted, or moved to private storage with a named owner, and that line should be checked by someone other than the person who wrote it.
- List every bucket, database and table the app has ever used, including ones from earlier versions and prototypes.
- For each, write down who can read it today, tested from a logged-out client.
- Set a retention period per data type and automate deletion with the Admin SDK.
- Delete identity documents as soon as verification completes unless a specific rule requires otherwise.
- Remove old bucket URLs and config from the app and confirm old builds cannot reach live data.
Lesson 3: identity documents are not ordinary uploads
The images that made the Tea breach severe were the ones users had the least choice about: the selfie and the government ID the app required to prove they were women. A driver's licence exposed alongside a face photo is enough for identity fraud and, for an app built around dating safety, for physical harm. Treat the verification step as a separate system with tighter rules than the rest of the product.
That means a separate storage path with client reads denied, server-side processing with the Admin SDK, a short retention window, and no copies in logs, error trackers or analytics. It also means asking whether you need the document at all. If a third-party verification provider can return a yes or no without you storing the image, storing the image is a liability you chose.
| What was exposed | Reported cause | Control that addresses it |
|---|---|---|
| 13,000 verification selfies and photo IDs, 59,000 post, comment and DM images | Publicly accessible Firebase storage bucket, URL present in the Android app, holding pre-February 2024 uploads | Deny-by-default Storage rules with per-user ownership, no client reads on ID images, deletion after verification, and an inventory of every historical bucket |
| More than 1.1 million direct messages, early 2023 to July 2025 | Any Tea user could use their own API key to reach backend data including a messages database, per 404 Media | Authorization that checks the requester owns the conversation, not just that they are logged in; tests where user B requests user A's data |
Lesson 4: the app is not the attack surface, the account is
When founders say "the app is secure", they usually mean the current build against the current backend. Attackers do not evaluate the current build. They enumerate everything the project owns: old buckets, old Firebase projects, staging databases, exported backups and API endpoints an old client version still calls. The Tea reporting is a clean example: the current system may well have been fine, and it did not matter.
So the audit question is not "is my app secure?" but "is every storage location this app has ever written to secure or deleted?". Answer it with a list, not a feeling. A read-only external scan such as VibeSecurity can check whether a bucket or database endpoint is publicly readable from outside, but the list of what to check has to come from you, because only you know what the app used to use.
Then test the two failure modes separately, as covered in our Firebase rules guide: a logged-out request to every bucket and collection should fail, and a logged-in request for another user's data should also fail. If both are true for every location on the list, you have covered what went wrong at Tea.
Frequently asked questions
What caused the Tea app breach?
Per 404 Media's July 25, 2025 reporting, a Firebase storage bucket belonging to Tea could be read without any authentication, and its URL was in the Android app. Tea said the exposed system held images uploaded before February 2024, including about 13,000 verification selfies and IDs and 59,000 other images. A separate flaw, reported days later, exposed over 1.1 million direct messages.
Was the Tea breach a hack or a misconfiguration?
The reporting describes the first exposure as a publicly accessible storage bucket, which is a configuration failure rather than a break-in: 4chan users found it and downloaded from it without credentials. Tea's own statement referred to unauthorized access. The later message exposure was described by 404 Media as any user being able to use their own API key to reach backend data.
Why did old user data leak if Tea had moved to a new system?
Tea said the exposed system held uploads from before February 2024 and that the data was over two years old. Moving new data to a new system does nothing to an old bucket unless it is locked down or deleted. Old buckets keep their old permissions, and their URLs remain in older app builds, so they stay reachable long after the team stops thinking about them.
How do I stop a Firebase Storage bucket being public?
Open Storage rules in the Firebase console and make sure every path requires request.auth != null plus an ownership check such as request.auth.uid == userId, with a final match /{allPaths=**} that denies everything. Test a download while logged out; it should fail. Then check any other buckets or projects the app has ever used, because rules are per bucket.
Should my app store photo IDs for verification?
Only if you have a specific reason and a deletion date. If you must, keep them in a separate storage path with client reads denied, process them server-side with the Admin SDK, delete them as soon as verification completes, and keep them out of logs and analytics. If a verification provider can return a result without you storing the image, prefer that.
Put it into practice
Sources
- 1.404 Media: Women Dating Safety App 'Tea' Breached, Users' IDs Posted to 4chan (July 25, 2025)
- 2.Engadget: Tea app suffers breach, exposing thousands of user images (Tea statement)
- 3.TechCrunch: Dating safety app Tea breached, exposing 72,000 user images (July 26, 2025)
- 4.TechCrunch: Tea app disables DMs after second data breach exposed over a million private messages (July 29, 2025)
- 5.CBS News: Tea dating app disables direct messaging as it investigates data breach (July 30, 2025)
- 6.404 Media: How Tea's Founder Convinced Millions of Women to Spill Their Secrets, Then Exposed Them to the World (August 19, 2025)