Insecure Design in Firestore

How Insecure Design Manifests in Firestore

Insecure Design in Firestore occurs when the database's security model, data schema, or access patterns are architected in a way that inherently enables unauthorized data access or manipulation, regardless of correct implementation. Unlike simple misconfigurations, these are fundamental flaws in how the Firestore database and its client interactions are designed. Firestore's NoSQL, document-based model and its security rules language create unique attack surfaces.

1. Overly Permissive Security Rules as Default Architecture: A common design flaw is using rules that grant broad access based on collection paths without sufficient context. For example, rules that allow read/write to any document in a users collection if request.auth.uid == resource.data.ownerId are vulnerable if the ownerId field is not strictly enforced at write time or if queries can bypass this check.

// VULNERABLE: Allows any authenticated user to read any user document if they can guess the ID
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth != null;
    }
  }
}

This design assumes client-side enforcement of ownership, which is easily bypassed. An attacker can directly query /users/<victimId>.

2. Query-Based Access Control Bypass (BOLA/IDOR via Queries): Firestore rules evaluate per-document, but queries execute against entire collections. A flawed design uses rules that work for single-document get() calls but fail for queries. If a rule only checks resource.data.ownerId (which is null for non-existent docs in a query), it may inadvertently allow listing all documents.

// VULNERABLE: Query returns all documents because rule passes for each doc where ownerId is not set in the request?
service cloud.firestore {
  match /databases/{database}/documents {
    match /projects/{projectId} {
      // Flaw: 'resource.data.ownerId' exists in stored doc, but query doesn't filter by it
      allow read: if request.auth.uid == resource.data.ownerId;
    }
  }
}

An attacker can call db.collection('projects').get() and receive all projects where the rule condition is false? Actually, Firestore rules for queries require that the rule condition be true for every document returned. If the rule uses a field not constrained by the query, the query fails. However, a design flaw occurs when the rule logic is incorrectly assumed to filter query results server-side. The secure design requires queries to include a filter matching the rule's condition, e.g., where('ownerId', '==', userId). If the application logic doesn't enforce this, but the rule is written as above, queries without the filter will be rejected by Firestore. The insecure design is when developers rely on rules to implicitly filter queries without ensuring client queries are properly constrained, leading to either rejected legitimate queries or, if rules are miswritten, unintended data exposure.

3. Data Modeling That Enforces No Authorization: Designing a flat data structure where sensitive data (e.g., apiKeys, ssn) is stored in a globally readable collection because the application expects all clients to need it. This violates the principle of least privilege at the schema level.

4. Missing Field-Level Security in Rules: Firestore rules operate at the document level. A design that stores multiple sensitivity levels in the same document (e.g., a userProfile doc containing both publicBio and privateMedicalHistory) without granular field-level checks in rules can leak data through queries that retrieve entire documents. While Firestore rules cannot block specific fields in a document response, a secure design would separate highly sensitive data into subcollections with stricter rules.

5. Insecure Use of Server Timestamps and Autogenerated IDs: Using ServerValue.TIMESTAMP or autogenerated document IDs as the sole security mechanism (e.g., allow read: if request.time < resource.data.expiresAt) is risky if the application logic that sets these values is client-controlled. An attacker could write a document with a far-future expiration if write rules are permissive.

Firestore-Specific Detection

Detecting insecure design in Firestore requires analyzing both the security rules configuration and the runtime behavior of API endpoints that interact with Firestore. middleBrick's black-box scanning approach tests the unauthenticated and authenticated attack surface by sending crafted requests to the API layer that ultimately accesses Firestore.

1. Rule Analysis via OpenAPI/Swagger Spec: If the API provides an OpenAPI spec, middleBrick cross-references endpoint paths and parameters with Firestore collection/document patterns. It looks for endpoints that likely map to Firestore operations (e.g., GET /users/{id}, POST /projects) and infers potential resource ownership parameters (like userId, ownerId). The scanner then attempts to manipulate these parameters to access unauthorized resources (BOLA/IDOR testing).

2. Active Probing for Query-Based Access Control Bypass: middleBrick tests if an API endpoint that should return a filtered list (e.g., GET /api/v1/projects expecting only the caller's projects) can be manipulated to return all projects. This is done by removing expected query parameters (like userId) or replacing them with another user's identifier. A successful response with data belonging to others indicates a broken authorization design.

3. Detection of Data Exposure via Overly Permissive Endpoints: The scanner probes endpoints for unauthenticated access or authentication bypass. If an endpoint that should require authentication returns sensitive document structures (e.g., containing fields like email, apiKey), it suggests the underlying Firestore rules or API logic is designed too permissively.

4. Property Authorization Testing: middleBrick tests if an API allows updating fields that should be immutable or restricted. For example, a PATCH /users/{id} endpoint that accepts a role or isAdmin parameter without proper server-side validation indicates an insecure design where client-controlled data can escalate privileges in Firestore documents.

Example Scan with middleBrick CLI:

middlebrick scan https://api.example.com
The resulting report will highlight findings like:

  • BOLA/IDOR: