HIGH integrity failuresfirestore

Integrity Failures in Firestore

How Integrity Failures Manifests in Firestore

Integrity failures in Firestore occur when attackers manipulate data through unauthorized modifications, bypassing business logic controls. These failures typically manifest through four primary attack vectors specific to Firestore's architecture.

The most common pattern involves client-side data manipulation. Since Firestore allows direct client access to documents and collections, malicious users can modify request payloads before they reach the database. An attacker might intercept a legitimate request to update their user profile, then modify the JSON payload to escalate privileges or alter unrelated user data:

const updateProfile = async (userId, profileData) => {
  const userDoc = db.collection('users').doc(userId);
  await userDoc.update(profileData);
  
  // Integrity failure: client can modify any field
  // Attacker could add: { role: 'admin', balance: 9999 }
}

Another critical manifestation is collection traversal attacks. Firestore's hierarchical structure allows navigation from one collection to another if path traversal isn't properly validated. An attacker might exploit this to access documents outside their authorized scope:

// Vulnerable: No validation of collection path
const getDocument = async (collectionPath, docId) => {
  const docRef = db.doc(`${collectionPath}/${docId}`);
  return await docRef.get();
}

// Attacker could call: getDocument('users/../admin', 'config')
// This might access: /admin/config instead of /users/config

Batch operation abuse represents another integrity failure vector. Firestore's batch writes allow multiple operations in a single transaction, but if the batch includes operations the user shouldn't perform, integrity is compromised:

// Vulnerable batch operation
const processOrder = async (userId, orderId) => {
  const batch = db.batch();
  
  // User should only update their own order
  batch.update(db.collection('orders').doc(orderId), { status: 'processing' });
  
  // Attacker adds: batch.update(db.collection('inventory').doc('all'), { stock: 0 })
  
  await batch.commit();
}

Finally, security rule bypasses through complex document structures can lead to integrity failures. When documents contain arrays or nested objects that aren't properly validated, attackers can inject malicious data structures:

// Vulnerable: No validation of array contents
const addPermission = async (userId, permission) => {
  const userDoc = db.collection('users').doc(userId);
  await userDoc.update({
    permissions: admin.firestore.FieldValue.arrayUnion(permission)
  });
  
  // Attacker could add: { admin: true, deleteAll: true }
}

Firestore-Specific Detection

Detecting integrity failures in Firestore requires examining both your security rules and application code. Start by analyzing your Firestore security rules for overly permissive patterns that could allow unauthorized data manipulation.

Security Rule Analysis should focus on identifying rules that grant excessive write permissions. Look for patterns like:

match /databases/{database}/documents {
  match /users/{userId}/orders/{orderId} {
    // Vulnerable: allows any authenticated user to write any order
    allow write: if request.auth != null;
  }
  
  match /{document=**} {
    // Vulnerable: allows any authenticated user to write anywhere
    allow write: if request.auth != null;
  }
}

middleBrick's Firestore scanner specifically tests for these integrity failure patterns by attempting to modify data across different user contexts. The scanner simulates authenticated users with varying privilege levels to identify where data can be manipulated beyond authorized boundaries.

Code Review Patterns should examine how your application validates and processes Firestore operations. Key areas to investigate:

// What to look for:
- Direct client writes without server validation
- Missing field-level authorization checks
- Unvalidated batch operations
- Insecure collection path construction

// middleBrick scans for these patterns automatically:
- Attempts to write to collections the user shouldn't access
- Modification of document fields outside the intended scope
- BOLA (Broken Object Level Authorization) vulnerabilities
- Privilege escalation through data manipulation

Runtime Detection involves monitoring for suspicious patterns in your Firestore operations. Look for:

  • Unexpected field modifications in audit logs
  • Batch operations containing unauthorized document references
  • Collection path traversal attempts
  • Mass data modifications from single requests

The middleBrick CLI tool can scan your Firestore endpoints and provide detailed reports on integrity failure risks:

npx middlebrick scan https://firestore.googleapis.com/

# Output includes:
# - Integrity failure risk score
# - Specific vulnerable endpoints
# - Severity levels for each finding
# - Remediation guidance for Firestore-specific issues

Firestore-Specific Remediation

Remediating integrity failures in Firestore requires a defense-in-depth approach combining security rules, server-side validation, and proper data modeling. The most effective strategy starts with granular security rules that enforce field-level authorization:

match /databases/{database}/documents {
  match /users/{userId}/orders/{orderId} {
    // Only allow users to modify their own orders, and only specific fields
    allow read, update: if request.auth.uid == userId && 
                        isValidOrderUpdate(request.resource.data);
    allow create: if request.auth.uid == userId && 
                  isValidNewOrder(request.resource.data);
    allow delete: if request.auth.uid == userId && 
                  isOrderDeletable(request.time, request.resource.data);
  }
  
  // Helper functions for field-level validation
  function isValidOrderUpdate(data) {
    return data.keys().hasOnly(['status', 'shippingAddress', 'items']) &&
           data.isString('status') &&
           data.isBoolean('isShipped') == false; // Prevent status override
  }
}

Server-side validation provides an additional layer of protection by validating all data before it reaches Firestore. Use Cloud Functions or your backend to enforce business logic:

const admin = require('firebase-admin');
const db = admin.firestore();

// Server-side validation middleware
const validateAndUpdateUser = async (userId, updateData) => {
  const userDoc = db.collection('users').doc(userId);
  const userSnap = await userDoc.get();
  
  if (!userSnap.exists) {
    throw new Error('User not found');
  }
  
  const userData = userSnap.data();
  
  // Validate each field against business rules
  const validatedData = validateUserData(updateData, userData);
  
  // Only allow specific fields to be updated
  const allowedFields = ['email', 'displayName', 'preferences'];
  const filteredData = Object.fromEntries(
    Object.entries(validatedData).filter(([key]) => allowedFields.includes(key))
  );
  
  await userDoc.update(filteredData);
  return filteredData;
};

function validateUserData(updateData, existingData) {
  const result = {};
  
  // Email validation
  if (updateData.email) {
    if (!isValidEmail(updateData.email)) {
      throw new Error('Invalid email format');
    }
    result.email = updateData.email;
  }
  
  // Role escalation prevention
  if (updateData.role && updateData.role !== existingData.role) {
    throw new Error('Role modification not allowed');
  }
  
  // Other field validations...
  return result;
}

Transaction-based operations ensure atomicity and prevent partial updates that could lead to inconsistent state:

const processPaymentTransaction = async (orderId, paymentData) => {
  const transaction = db.transaction();
  
  return transaction.get(db.collection('orders').doc(orderId))
    .then(orderSnap => {
      const orderData = orderSnap.data();
      
      // Validate payment amount matches order total
      if (paymentData.amount !== orderData.total) {
        throw new Error('Payment amount mismatch');
      }
      
      // Check order status
      if (orderData.status !== 'pending') {
        throw new Error('Order already processed');
      }
      
      // Update order and create payment record atomically
      transaction.update(orderSnap.ref, { status: 'paid' });
      transaction.set(db.collection('payments').doc(), {
        orderId: orderId,
        amount: paymentData.amount,
        method: paymentData.method,
        timestamp: admin.firestore.Timestamp.now()
      });
    })
    .then(() => transaction.commit())
    .catch(error => {
      console.error('Transaction failed:', error);
      throw error;
    });
};

Audit logging helps detect and respond to integrity failures by tracking all data modifications:

const logDataChange = async (userId, documentPath, oldData, newData, operation) => {
  const auditLog = db.collection('audit_logs').doc();
  
  await auditLog.set({
    userId: userId,
    documentPath: documentPath,
    oldData: oldData,
    newData: newData,
    operation: operation,
    timestamp: admin.firestore.Timestamp.now(),
    ipAddress: getClientIP(), // Implement your own IP detection
    userAgent: getClientUserAgent()
  });
  
  // Alert on suspicious patterns
  if (shouldAlert(operation, oldData, newData)) {
    await sendAlertEmail('Integrity alert', generateAlertMessage(...));
  }
};

function shouldAlert(operation, oldData, newData) {
  // Alert on privilege escalation attempts
  if (operation === 'update' && 
      newData.role && 
      newData.role !== oldData.role && 
      newData.role === 'admin') {
    return true;
  }
  
  // Alert on mass data modifications
  if (operation === 'update' && 
      Object.keys(newData).length > 10) {
    return true;
  }
  
  return false;
}

Frequently Asked Questions

How does Firestore's security rules engine prevent integrity failures?
Firestore security rules prevent integrity failures by enforcing field-level authorization and validating data before it's written to the database. Rules can restrict which users can modify specific fields, validate data types and formats, and prevent unauthorized operations like privilege escalation. For example, rules can ensure users can only update their own documents and only modify specific fields like 'displayName' or 'preferences', while blocking attempts to change 'role' or 'permissions' fields.
Can middleBrick scan my Firestore security rules for integrity failures?
Yes, middleBrick can analyze your Firestore security rules and identify potential integrity failure vulnerabilities. The scanner tests your rules by attempting to perform operations that should be blocked, such as modifying documents outside a user's authorized scope, escalating privileges, or accessing collections the user shouldn't have permission to write to. It provides a security risk score with specific findings about rule weaknesses and suggests remediation steps based on the detected vulnerabilities.