Skip to main content
Application & APICritical

Publicly Writable Firebase Database

A publicly writable Firebase database is a Firebase Realtime Database or Cloud Firestore whose Security Rules permit unauthenticated read and write access, so anyone who learns the project ID can read, modify, or delete the entire dataset over a simple HTTPS request.

Firebase backends are convenient precisely because the mobile or web client talks to the database directly, with no server in between. That same architecture means the database's Security Rules are the only thing standing between your data and the public internet. When those rules are left at the permissive defaults a developer used during a weekend prototype, the database stops being a private store and becomes a publicly addressable API that returns its contents to a curl command.

Reviewed by Aakash Harish

Security Research Contributor, Legba

Reviewed 2026-05-28 · Updated 2026-05-28

What it is

Firebase exposes two client-facing data stores: the Realtime Database (a JSON tree reachable at https://<project-id>.firebaseio.com) and Cloud Firestore (a document store reached through the project's REST or SDK endpoints). Because clients connect to these stores directly, Firebase Security Rules act as the authorization layer. A publicly writable database is one whose rules evaluate to allow access regardless of the caller's identity, for example a Realtime Database rule of {".read": true, ".write": true} or a Firestore rule of allow read, write: if true. These are the rules Firebase itself uses for test mode, a 30-day open window meant only for local prototyping. When that window is forgotten, extended, or copied into production, the store grants full read and write to any anonymous caller on the internet.

When the only gate on your database is a rule that says yes to everyone, you are not exposed to a future risk, you have already published a live, editable copy of your data. An attacker can exfiltrate every record (user emails, password hashes, chat history, payment tokens, location coordinates), silently alter balances or order records, or wipe the entire tree in one DELETE call. Public read leaks regulated personal data and breaches GDPR, CCPA, and contractual obligations; public write lets an adversary plant malicious content, escalate privileges by editing their own role document, or hold the database for ransom. Google's own Firebase documentation states that with open rules anyone who guesses your project ID can steal, modify, or delete the data, and the OWASP API Security Top 10 classifies this kind of broken authorization configuration as API8:2023 Security Misconfiguration. The job a security team actually wants done here is not another scanner alert that says a Firebase endpoint exists, but a confirmed, evidenced answer to a single question: can an anonymous request actually write to this store right now.

At a glance

Typepublic-firebase-database
Ports443
ProtocolsHTTPS, REST
Seen onFirebase Realtime Database, Cloud Firestore, Google Cloud Platform, Firebase Web SDK, Firebase Android SDK, Firebase iOS SDK
SeverityCritical
Updated2026-05-28

How attackers find and exploit it

  • Harvest Firebase project IDs at scale by extracting the apiKey, projectId, databaseURL, and storageBucket fields from public JavaScript bundles, mobile app APK/IPA strings, and the firebaseConfig object embedded in deployed front ends.
  • Resolve each project ID to its Realtime Database root by requesting https://<project-id>.firebaseio.com/.json, which returns the full JSON tree as plain HTTP when read rules are open.
  • For Cloud Firestore, enumerate collection and document paths through the public REST API at firestore.googleapis.com/v1/projects/<project-id>/databases/(default)/documents to test for unauthenticated read access.
  • Confirm write access by issuing a benign PUT or PATCH to a throwaway path (for example /pentest_marker.json) and checking whether the value persists, demonstrating that the rules accept anonymous mutations.
  • Escalate from a confirmed write primitive: overwrite role or isAdmin fields in a user record, inject malicious payloads into fields rendered by other clients, or issue a DELETE against the database root to destroy or ransom all data.
  • Automate the entire chain across thousands of harvested project IDs using published tooling that reads APKs and probes the .json endpoint, turning opportunistic discovery into bulk compromise.

How to detect it on your surface

  • Inventory every Firebase project your organization owns by reviewing the Firebase and Google Cloud consoles, then list each project's databaseURL and Firestore database for both Realtime Database and Firestore.
  • For every Realtime Database, send an unauthenticated GET to https://<project-id>.firebaseio.com/.json from outside your network and confirm whether it returns data or a Permission denied error.
  • Open the Rules tab for each database in the Firebase console and search for the literal patterns ".read": true, ".write": true, and allow read, write: if true that grant unconditional access.
  • Use the Firebase Security Rules unit-testing library and the local emulator to replay representative read and write operations as an unauthenticated principal and observe which ones the rules permit.
  • Cross-reference your client bundles and mobile binaries for leaked firebaseConfig values so you can detect Firebase projects that were spun up outside the central GCP organization and never reviewed.

Detection signals

  • An unauthenticated GET to https://<project-id>.firebaseio.com/.json returns HTTP 200 with a JSON body instead of HTTP 401 and the string {"error":"Permission denied"}.
  • Realtime Database rules contain {".read": true} or {".write": true} at or near the root, or Firestore rules contain match /{document=**} { allow read, write: if true; }.
  • The Firebase console shows a banner warning that your security rules are insecure or that test-mode rules expire in N days.
  • A Firestore REST query to the documents endpoint succeeds with no Authorization header and returns document data rather than a PERMISSION_DENIED gRPC status.
  • A test PUT to a unique path is reflected back on a subsequent GET, proving the store accepted an anonymous write.

Validate before you report

  • Reproduce read exposure with a single unauthenticated request, capturing the full response headers and a redacted sample of the returned JSON or documents as evidence rather than relying on the rule text alone.
  • Reproduce write exposure non-destructively by creating a clearly labeled marker key (for example /_recon_validation/<timestamp>) with a benign value, confirming it persists on read-back, then deleting only that key.
  • Distinguish Realtime Database from Firestore exposure, since the two use different endpoints and rule syntaxes and a project can have one secured while the other is wide open.
  • Record the exact project ID, endpoint, rule snippet, request, and response so the finding is independently verifiable and the owner can confirm it without re-running the test themselves.
  • Verify that the access is genuinely anonymous by repeating the request from a clean client with no cached Firebase auth token or session cookie.

What looks like this but isn't

  • A database that returns data to a GET but rejects writes is read-only-public, not writable; confirm the write primitive separately before assigning a writable-database finding.
  • Some apps intentionally publish a small public collection (for example feature flags or public content) while protecting the rest with path-scoped rules, so an open response on one path does not mean the whole store is exposed.
  • Firebase App Check or per-path conditional rules can cause a request to succeed only with a valid app token; a 200 from an instrumented client may not reproduce from an anonymous one, so re-test without any token.

Remediation

  • Immediately replace any open rule with a default-deny baseline: set Realtime Database rules to {".read": false, ".write": false} or Firestore to allow read, write: if false, then re-enable access path by path.
  • Require authentication for every privileged path by gating rules on request.auth != null and scope ownership with checks such as request.auth.uid == resource.data.ownerId or $uid == auth.uid.
  • Never ship test-mode rules to production; treat the 30-day test window as local-only and configure production rules before the first public deployment.
  • Validate field-level writes in the rules themselves (data types, allowed keys, immutability of role and balance fields) so an authenticated user cannot escalate by editing fields they should not control.
  • Adopt Firebase App Check to attest that requests originate from your genuine app, reducing automated abuse of the client endpoints as a defense-in-depth layer on top of authorization rules.
  • Add Security Rules unit tests to CI using the emulator so that any future change which would re-open the database fails the build before it deploys.

Operational checklist

  • Maintain a central inventory of all Firebase and GCP projects, including shadow projects discovered from leaked client config, and assign each an owner.
  • Enforce default-deny Security Rules as the baseline template for every new database and require explicit review to widen them.
  • Run automated, authentication-aware checks against every Realtime Database and Firestore endpoint on a recurring schedule, not just at launch.
  • Block deployment of rules containing if true, .read: true, or .write: true through a pre-deploy lint or policy check in CI.
  • Enable Firebase App Check and monitor Firebase usage and security alerts for unexpected spikes in reads, writes, or egress.
  • Review rules whenever data models change, since a new collection added under an open match block silently inherits the open access.

What to do next

An open Firebase database is not a hypothetical weakness; it is a live, anonymously editable copy of your data sitting one HTTPS request away from anyone who reads your app's JavaScript. The first action is concrete and takes minutes: pull each project's rules, send one unauthenticated read and one marker write, and if either succeeds, set the rules to default-deny today and rebuild access behind request.auth checks. Confirm the fix the same way you found the problem, by proving the anonymous request now fails.

Methodology

Each finding-type guide is built from Legba Recon's real detection and validation logic, reviewed by a named security contributor, and cited against primary sources such as OWASP, CISA, NIST, and MITRE. We update pages when the underlying guidance changes. See our contributors and company.

FAQs.

References.

Weakness references (CWE)

Keep exploring

Your agent needs its Legba.

Read the docs