Skip to content

Firebase Security Vulnerability: FBR-AUTHZ-002

Name: Access Based on Unverified Attribute

Applicable Services: Cloud Firestore, Firebase Realtime Database, Cloud Storage

Description

Note

This vulnerability occurs when security rules grant access based on user attributes from Firebase Authentication (like an email address or phone number) without also checking if that attribute has been verified.

  • The Technical Flaw: The security rule checks for the presence of an attribute (e.g., request.auth.token.email) but omits the corresponding verification check (e.g., request.auth.token.email_verified).
  • Intended Behavior: Firebase Authentication provides flags like email_verified and phone_number_verified that are meant to be used in security rules to confirm that a user has proven they control the associated email or phone number.
  • The Risk: Without the verification check, a user can create an account with an email address they don't own. The system would temporarily trust the unverified email, granting the user access based on that attribute until the legitimate owner claims it or the account is removed.

Impact

Potential Consequences

The severity of this vulnerability is a warning. Exploiting it can lead to: * Temporary Unauthorized Access: An attacker can gain short-term access to data or resources that should be protected. For example, they could access a private document repository reserved for employees of a specific company by signing up with a fake @company.com email address. * Information Disclosure: Sensitive information could be exposed to unauthorized individuals during the window of unverified access.

Example Attack Scenarios

Exploit Scenario: Gaining Access with an Unverified Email

  • The Vulnerable Rule: The following Firestore rule grants read access to any document in the company_secrets collection to any authenticated user whose email address ends with @company.com. However, it fails to check if the email has been verified.
    // VULNERABLE: grants access based on email domain without checking email_verified
    match /company_secrets/{docId} {
      allow read: if request.auth != null && request.auth.token.email.matches(".*@company.com");
    }
    
  • Attacker's Goal: To read documents from the company_secrets collection, which they are not authorized to view.
  • The Exploit: An attacker creates a new Firebase account using the email ceo@company.com, an address they do not own. Since Firebase allows account creation without immediate email verification, the attacker is now authenticated and has an auth token where request.auth.token.email is ceo@company.com. The attacker then uses a simple client-side script to query the protected collection.
    // Attacker signs up with "ceo@company.com" and runs this code
    // before their session expires or email verification is required.
    db.collection("company_secrets").get()
      .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
          console.log("Successfully read secret document:", doc.id, "=>", doc.data());
        });
      })
      .catch((error) => {
        console.error("Error reading documents: ", error);
      });
    
  • Outcome: The insecure rule allows the request because the attacker's unverified email matches the required pattern. The attacker successfully reads and exfiltrates sensitive documents from the company_secrets collection.

Mitigation

The vulnerability is resolved by adding a check to ensure the user's email has been verified by Firebase Authentication. This confirms that the user actually controls the email address they claim to have.

// VULNERABLE: Only checks the email domain.
match /company_secrets/{docId} {
  allow read: if request.auth != null && request.auth.token.email.matches(".*@company.com");
}
// SECURE: Checks both the email domain AND that the email is verified.
match /company_secrets/{docId} {
  allow read: if request.auth != null &&
                 request.auth.token.email.matches(".*@company.com") &&
                 request.auth.token.email_verified == true;
}

Best Practice

Always couple an attribute check with its corresponding verification check. For any user attribute that can be verified (e.g., email, phone_number), your security rules should enforce that the _verified flag is true before granting access based on that attribute.

References