ascertify/learn/exposed

Firestore rules: allow read, write: if true

This rule makes your entire database public: anyone on the internet can read, overwrite, or delete every document without logging in. The fix is to replace it with rules that check who is asking, collection by collection, and then confirm the app still works through them.

Applies to Firebase + Firestore, all platformsSeverity CriticalDetected by static scan, no code execution

What this rule actually does

Firestore security rules are the only thing standing between the internet and your data, because Firestore is queried directly from the browser. There is no backend of yours in the middle. The /{document=**} wildcard matches every document in every collection, including ones you add later. read covers both fetching single documents and listing whole collections. write covers create, update, and delete. And if true means the answer is yes for every request, from anyone, forever.

Obscurity doesn't help. Your project ID ships inside the config block of every copy of your app, and Firestore's endpoints follow a predictable pattern built from it. Finding an open database takes a curious person minutes with standard tooling, and automated scanners sweep for exactly this misconfiguration.

How it ends up in production

The test mode timer

New Firestore databases created in test mode start with an allow-all rule capped by a date, roughly 30 days out:

4allow read, write: if request.time < timestamp.date(2026, 9, 3);

When the date passes, every client request starts failing, and the app breaks all at once. Under deadline pressure, the fastest way to make the errors disappear is to push the date out or swap the condition to true. The app comes back to life, and the database stays open for good.

The prompt loop

A query fails with Missing or insufficient permissions. The builder pastes the error into the AI chat. The fastest path to a green result is a rule that permits everything, so that's what gets written. The query works, the chat moves on, and the lock is gone. It's the same failure shape as pasting the Supabase service role key into the frontend: the tool optimized for making the error stop, not for keeping the data safe.

How to fix it

1

Decide what, if anything, is truly public

Most apps have at most one or two collections that should be readable by everyone, like published posts or a product catalog. Everything else, especially anything with user data, is private by default. Write that split down before touching the rules file.

2

Write ownership rules, collection by collection

Tie access to who owns the data, not just to being signed in. The standard pattern scopes each user to their own documents:

Not enough:request.auth != null only requires a login. With open sign-up, that's the same as public.

3

Test the rules before publishing

Use the Rules Playground in the Firebase console, or the local emulator, to check both directions: the owner can reach their data, and a different signed-in user cannot. Rules have unit tests for a reason; a rules file that was never tested is a guess.

4

Publish, then check your other Firebase doors

The same allow-all pattern ships in Realtime Database rules and Storage rules, and projects that had one open door often have two. Check all three in the Firebase console, not just the one that got flagged.

The ownership pattern from step 2, concretely:

3 match /users/{userId}/{document=**} {
4 allow read, write: if request.auth.uid == userId;
5 }

How to verify the fix

An anonymous request is rejectedIn the Rules Playground, simulate a get on a private document with authentication off. It should be denied. The same request succeeded before the fix.
A different user's request is rejectedSimulate a signed-in user reading another user's document. Denied. This is the case that request.auth != null alone gets wrong.
No allow-all survives anywhereSearch the published rules for if true and for date-capped conditions left over from test mode. Public read access should exist only on collections you deliberately chose in step 1, and never for writes.
The app still works signed inLog in as a normal user and use every feature. Anything that breaks was depending on the open door, and each failure points at the exact collection that still needs a real rule.

If features break after locking the rules, that's information, not regression. Every Missing or insufficient permissions error after the fix marks a code path that was silently relying on your database being public. Fixing those paths with real rules is the actual work; the allow-all rule was just hiding it.

Fair questions

Is allow read, write: if true ever OK?

Almost never as written. If some data is genuinely public, like a blog's posts, scope a read-only rule to that one collection. What's practically never OK is allow write: if true anywhere, or any allow-all under document=**, because that covers every collection you have now and every one you add later.

My app says 'Missing or insufficient permissions' after I fixed the rules. What now?

That error is your new rules working. Some part of the app is making a request your policies don't allow yet. Find the query, decide who should legitimately make it, and write a rule for that path. Don't put the allow-all back; that trades a visible error for an invisible breach.

Firebase emailed me that client access to my database is expiring. What does that mean?

Your project was created in test mode, which starts with an allow-all rule that shuts off after about 30 days, and Firebase mails you before the deadline. When it expires, requests are denied and the app breaks. The right response is writing real rules before the date, not extending the timestamp or switching to if true, both of which just re-open the database.

Isn't my database URL secret? Nobody knows where it is.

No. Your project ID ships inside the config block of every copy of your app, and Firestore's endpoints follow a predictable pattern built from it. Anyone who opens your site can read the project ID from the bundle and query the database directly. With allow-all rules, that query succeeds without any login.

Does allow read, write: if request.auth != null fix it?

It's a floor, not a fix. It only requires that the caller is signed in to your project. With open sign-up, anyone can create an account in seconds and then read and write every user's data exactly as before. Real rules tie access to ownership: request.auth.uid == userId on the document path.

Ascertify is a static code audit for AI-built and agency-delivered apps. It reads your code without running it and reports what's exposed, what's missing, and what to fix first, in plain English, pinned to the exact file and line. Open database rules are one of the launch-blocking issues it looks for; the free preview tells you how many your code has.

Read-only access. Your code is sandboxed, never executed, and deleted after the scan.

related