HIGH injection flawssailsfirestore

Injection Flaws in Sails with Firestore

Injection Flaws in Sails with Firestore — how this specific combination creates or exposes the vulnerability

Injection flaws occur when untrusted data is interpreted as part of a command or query. In a Sails application using Cloud Firestore, the risk arises when user-controlled input is directly embedded into Firestore queries, aggregations, or document paths without proper validation or escaping. Because Firestore uses a structured query model, concatenating user input into query predicates or collection/document names can lead to unintended data access or execution of unintended operations.

Sails.js is a Node.js MVC framework that does not inherently sanitize inputs for NoSQL backends. When a controller action builds a Firestore query by injecting request parameters into where(), orderBy(), or document references, an attacker can manipulate these values to bypass intended filters. For example, an attacker might supply a crafted value to a where clause that always evaluates to true, effectively reading documents they should not see.

Firestore’s client SDK evaluates JavaScript expressions on the client or in Node.js, and if user input is used to construct field paths or collection identifiers, it may allow traversal outside the intended data scope. An attacker could provide a dot notation field path (e.g., __proto__.admin) to probe or modify object properties if the application performs insecure merging of objects. Additionally, Firestore allows querying array-contains; injecting array values could expose documents containing sensitive array entries.

Another scenario involves dynamic collection names. If a Sails controller uses user input to determine the Firestore collection to query (e.g., firestore.collection(req.body.entity)), an attacker could reference collections outside the application’s expected namespace, potentially accessing shared or administrative collections. Even with Firestore security rules, improperly structured queries can return more data than intended if rules are not aligned with query patterns.

Because middleBrick scans the unauthenticated attack surface and includes checks for Input Validation and Property Authorization across 12 parallel security checks, it can detect whether a Sails + Firestore endpoint allows injection-style manipulation. The scanner does not fix the code but provides prioritized findings with severity and remediation guidance, helping developers identify where query construction must be hardened.

Firestore-Specific Remediation in Sails — concrete code fixes

To prevent injection flaws when using Firestore with Sails, always treat user input as untrusted and avoid string concatenation or direct interpolation into queries. Use Firestore’s built-in query methods with typed parameters, and validate inputs against an allowlist before use.

1. Parameterized Queries and Field Path Validation

Instead of dynamically building field paths from user input, validate field names against a known set and use object properties safely. Never allow user input to directly become a field path string.

const allowedFields = ['email', 'status', 'createdAt'];

if (!allowedFields.includes(req.body.sortField)) {
  throw new Error('Invalid sort field');
}

const query = firestore.collection('users')
  .where('status', '==', req.body.statusValue)
  .orderBy(req.body.sortField, 'asc');

const snapshot = await query.get();

2. Safe Document References and Collection Names

Do not use user input to construct document references or collection names. If you must use dynamic collections, map input through a strict whitelist and use Firestore’s document ID validation rules.

const validCollections = { profiles: true, orders: true };
const collectionName = req.body.collection;

if (!validCollections[collectionName]) {
  throw new Error('Invalid collection');
}

const docRef = firestore.collection(collectionName).doc(req.params.docId);
const doc = await docRef.get();
if (!doc.exists) { return res.notFound(); }

3. Avoiding Prototype Pollution via Object Merging

When updating documents, prefer explicit field assignment over merging user-provided objects. If merging is necessary, use a library or manual filtering to strip dangerous keys like __proto__, constructor, and prototype.

const userInput = req.body.updateData;
const safeData = {};

// Explicitly pick expected fields
if (typeof userInput.displayName === 'string') {
  safeData.displayName = userInput.displayName;
}
if (typeof userInput.preferences === 'object' && userInput.preferences !== null) {
  safeData.preferences = userInput.preferences;
}

await firestore.collection('settings').doc(userId).update(safeData);

4. Using Firestore Security Rules as a Safety Net

While rules are not a substitute for secure coding, ensure rules restrict reads and writes to intended paths and validate data shapes. Combine rules with parameterized queries in Sails for defense in depth.

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 /publicItems/{itemId} {
      allow read: if true;
      allow write: if request.auth != null && request.auth.token.admin == true;
    }
  }
}

Frequently Asked Questions

Can middleBrick fix injection flaws in my Sails + Firestore API?
No. middleBrick detects and reports injection-related findings with severity and remediation guidance, but it does not fix, patch, or block vulnerabilities. Developers must apply the provided remediation steps.
Does middleBrick test for Firestore-specific query manipulation during scans?
Yes. As part of its Input Validation and Property Authorization checks, middleBrick tests the unauthenticated attack surface for query manipulation patterns that could indicate injection risks in APIs using Firestore.