Skip to content

Firebase Security Vulnerability: FBR-LOGIC-004

Name: Insecure Delete Operation Leading to Orphaned Data

Applicable Services: Cloud Firestore

Description

Note

This data integrity vulnerability occurs when security rules permit a delete operation on a document without ensuring that related, dependent data in other documents is also handled. - The Technical Flaw: The security rule allows a client-side delete on a document (e.g., /users/{userId}) without considering that other documents (e.g., in a posts collection) hold a reference to it. Firestore does not enforce referential integrity, so it won't automatically clean up these dependent references. - Intended Behavior: Deletions of documents that are referenced by other parts of the database should be handled by a trusted server process (like a Cloud Function) that can perform a "cascading delete," ensuring all related data is removed atomically. - The Risk: Allowing direct client-side deletes can lead to an inconsistent data state where some records point to non-existent documents. This "orphaned" data can cause application crashes, UI errors, and a poor user experience.

Impact

Potential Consequences

The severity of this vulnerability is a warning. Exploiting it can lead to: * Application Errors - The application may crash or enter an error state when it tries to look up an orphaned reference that no longer points to an existing document. * Data Inconsistency - The database is left in an inconsistent state, making data management and future development more difficult.
* Poor User Experience - Users may see broken UIs, error messages, or experience app crashes, leading to a loss of trust.

Example Attack Scenarios

Exploit Scenario: Deleting a User and Orphaning Their Posts

  • The Vulnerable Rule: The following Firestore rule allows a user to delete their own profile document, but there's no mechanism to clean up the posts they've created.
    // VULNERABLE: Allows a user to delete their own profile,
    // but does not handle the user's posts.
    service cloud.firestore {
      match /databases/{database}/documents {
        match /users/{userId} {
          allow delete: if request.auth.uid == userId;
        }
        match /posts/{postId} {
          // For this example, anyone can read posts
          allow read: if true;
        }
      }
    }
    
  • Attacker's Goal: This isn't a malicious attack, but a standard user action that reveals a flaw. A user wants to delete their account.
  • The Exploit: The user triggers a delete operation from the client-side application. Their profile document at /users/user-abc is successfully deleted.
    // A standard client-side operation that triggers the vulnerability.
    // A user with UID "user-abc" deletes their own profile.
    db.collection("users").doc("user-abc").delete
      .then(() => {
        console.log("User profile successfully deleted!");
      })
      .catch((error) => {
        console.error("Error removing document: ", error);
      });
    
  • Outcome: The user's profile is gone, but all their documents in the posts collection, which contain authorId: "user-abc", remain. When the application tries to load one of these posts and fetch the author's details, the lookup for /users/user-abc fails, leading to application errors or a broken UI.

Mitigation

The vulnerability is resolved by disallowing direct client-side deletes on documents with dependencies. Instead, deletions should be handled by a trusted server process, like a Cloud Function, which can perform a cascading delete.

// VULNERABLE: Allows direct client-side deletes.
match /users/{userId} {
  allow delete: if request.auth.uid == userId;
}
// SECURE: Blocks direct client-side deletes, forcing them
// to be handled by a trusted server process.
match /users/{userId} {
  // Create, read, and update might be allowed.
  allow create, read, update: if request.auth.uid == userId;
  // Direct deletes are explicitly forbidden.
  allow delete: if false;
}

Best Practice

The most robust solution is to handle deletions via a server-side environment (like a Cloud Function) that performs atomic, cascading deletes using a batched write. With the secure rule in place, the client application would call a Cloud Function (e.g., deleteUserAccount). This function would then use the Firebase Admin SDK to perform a batched write that deletes the user's profile document and all their posts in a single, atomic operation, preventing any data from being orphaned.

References