HIGH pii leakagegrapefirestore

Pii Leakage in Grape with Firestore

Pii Leakage in Grape with Firestore — how this specific combination creates or exposes the vulnerability

Grape is a Ruby API micro-framework commonly used to build RESTful endpoints. When a Grape API uses Google Cloud Firestore as a backend data store, PII leakage can occur if endpoint responses include sensitive document fields and security rules or runtime controls are insufficient. Firestore stores documents in collections; if a query returns entire documents or subcollections that contain fields such as email, phone, national ID, or health information, and the API does not explicitly project or filter those fields, the data is exposed in HTTP responses.

The risk is compounded when Firestore security rules are misconfigured—for example, allowing read access based only on authentication state without validating ownership or context—or when the API directly forwards Firestore query results to clients. Sensitive data may also be exposed through error messages if Firestore exceptions reveal document paths or internal structures. Because Grape endpoints often map resources 1:1 to Firestore documents, missing field-level filtering means any over-permissive rule effectively becomes a data leak. Common root causes include:

  • Reading full documents without field selection, so PII such as emails or addresses is returned verbatim.
  • Using broad Firestore rules like allow read: if request.auth != null; without additional constraints per user or per resource.
  • Pass-through APIs that proxy Firestore responses without normalization or redaction, inadvertently leaking nested fields or metadata.

An attacker who compromises authentication or exploits a logic flaw may enumerate accessible document IDs and retrieve PII directly through the Grape endpoint. MiddleBrick’s scans detect such leakage by correlating OpenAPI paths that expose user data with Firestore access patterns, highlighting endpoints that return sensitive fields without masking or authorization checks at the field level.

Firestore-Specific Remediation in Grape — concrete code fixes

Remediation focuses on minimizing data exposure in both Firestore rules and Grape response construction. Use Firestore queries that explicitly select only required fields and enforce ownership-based rules. In Grape, transform Firestore documents before serialization to strip or mask PII.

Firestore security rules

Rules should scope reads to the requesting user and avoid broad public access. For a users collection where each document ID matches the user’s UID:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
    match /profiles/{profileId} {
      allow read, write: if request.auth != null && request.auth.uid == profileId;
    }
  }
}

Avoid rules that allow reading all documents in a collection, and prefer granular matches that also validate request resource data when needed.

Grape endpoint with field-level filtering

Use select in Firestore queries to limit returned fields, and remove PII before sending the response.

require 'google/cloud/firestore'

class EntitiesResource
  include Grape::API
  format :json

  helpers do
    def firestore
      @firestore ||= Google::Cloud::Firestore.new
    end

    def current_user_id
      # derive from auth token in real use
      env['current_user_id']
    end
  end

  desc 'Get public profile data only'
  params do
    requires :profile_id, type: String, desc: 'Profile document ID'
  end
  get '/profiles/:profile_id' do
    profile_ref = firestore.col('profiles').doc(params[:profile_id])
    # Select only non-sensitive fields
    snapshot = profile_ref.get(fields: [:display_name, :avatar_url])
    not_found! unless snapshot.exists?

    {
      display_name: snapshot[:display_name],
      avatar_url: snapshot[:avatar_url]
    }
  end

  desc 'Get user data with PII masked'
  params do
    requires :user_id, type: String, desc: 'User document ID'
  end
  get '/users/:user_id' do
    user_ref = firestore.col('users').doc(params[:user_id])
    snapshot = user_ref.get
    forbidden! unless snapshot.exists? && snapshot[:owner_uid] == current_user_id

    {
      user_id: snapshot[:user_id],
      display_name: snapshot[:display_name],
      # PII fields are omitted; if needed, apply controlled transformation
      email: nil # do not forward raw email
    }
  end
end

Additional practices

  • Prefer read-time field selection over write-time redaction; less data traverses your API.
  • Validate and sanitize inputs to prevent IDOR and ensure Firestore path correctness.
  • Audit logs and monitoring can help detect anomalous access patterns that suggest enumeration attempts.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Does middleBrick fix PII leakage in Grape-Firestore APIs?
middleBrick detects and reports PII leakage findings with remediation guidance; it does not fix or block data exposure. Apply the suggested field filtering and rule changes to reduce risk.
Can continuous monitoring prevent PII leakage over time?
The Pro plan supports continuous monitoring for registered APIs, enabling scheduled scans and alerts when new endpoints or permissive rules increase exposure risk.