HIGH hallucination attacksfeathersjsfirestore

Hallucination Attacks in Feathersjs with Firestore

Hallucination Attacks in Feathersjs with Firestore — how this specific combination creates or exposes the vulnerability

FeathersJS is a framework for real-time APIs that typically sits on top of databases such as Google Cloud Firestore. When FeathersJS services are configured to pass user-supplied query parameters or dynamic lookups directly to Firestore without strict validation, an attacker can manipulate inputs to trigger inconsistent or fabricated responses—a behavior commonly described as hallucination in the context of generative systems or loosely controlled data services. In this setup, hallucination is not about the model producing false content, but about the service returning data that does not correspond to the intended or authorized dataset due to injection or insecure query construction.

Consider a FeathersJS service that builds Firestore queries from user-supplied filters. If the service dynamically adds fields like where clauses based on unvalidated keys or operators, an attacker can supply crafted parameters that cause Firestore to match unintended documents or produce empty results that the service misinterprets as valid data. Because Firestore does not inherently understand application-level authorization, the service must enforce ownership and scope. If the service incorrectly assumes Firestore responses are authoritative without cross-checking the requesting user’s permissions, the mismatch between expected and actual data can be exploited to infer the existence of records or to extract information across tenant boundaries.

Another vector involves Firestore’s handling of array-contains and inequality filters. An attacker can probe acceptable query patterns by submitting values that trigger different Firestore behaviors, such as using an array field that does not contain the supplied value, leading to empty result sets. If the service treats empty results as an error condition or a cache miss and falls back to a default or cached response, it may inadvertently reveal whether a specific resource exists or expose default data that should remain hidden. In multi-tenant applications, missing tenant identifiers in Firestore queries due to incomplete parameter validation can cause the service to read documents from other tenants, effectively turning a logic flaw into a data exposure path.

The combination of FeathersJS’s dynamic service layer and Firestore’s flexible query syntax amplifies the risk when input validation is weak. Attackers can use deeply nested objects or special Firestore operators such as array-contains-any or in to probe for field existence or trigger errors that expose stack traces or internal field names. These errors can be interpreted by the service as partial matches or fallback paths, generating responses that appear coherent but are misaligned with the user’s authorization context. Without strict schema checks and explicit tenant scoping, the service may construct queries that reference incorrect document paths, causing Firestore to return documents it would not normally return under properly constrained conditions.

LLM/AI Security checks are particularly valuable in this context because they can detect prompt injection patterns that might be used to coax a service into returning hallucinated data through indirect prompts or injected instructions. For example, an attacker could embed instructions in API payloads that manipulate the service’s query-building logic if the service improperly trusts user input. middleBrick’s LLM/AI Security module includes system prompt leakage detection and active prompt injection testing, which can uncover weaknesses where improperly handled inputs lead to unintended data exposure or inconsistent behavior across API calls.

To mitigate these risks, developers should treat all inputs that influence Firestore queries as hostile and validate them against strict allowlists. Field names, operators, and values must be checked against known safe sets before being incorporated into query objects. Tenant identifiers should be injected at the service layer based on authentication context rather than derived from user input. By combining rigorous input validation, explicit tenant scoping, and runtime monitoring, teams can reduce the likelihood of hallucination-style attacks that exploit the interaction between FeathersJS and Firestore.

Firestore-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on hardening how FeathersJS builds and executes Firestore queries. The service should avoid dynamically injecting user-controlled keys or operators into query constraints. Instead, use enumerated operator mappings and strict schema validation before constructing queries. Tenant context must be derived from authentication metadata, not from request parameters.

Example of a vulnerable FeathersJS service that builds Firestore queries from raw user input:

// Vulnerable: dynamic operator and field names
app.service('items').find({
  query: {
    field: req.query.field,
    operator: req.query.operator,
    value: req.query.value
  }
});

Safer approach using an allowlist for operators and predefined field mappings:

const ALLOWED_FIELDS = new Set(['status', 'ownerId', 'category']);
const ALLOWED_OPERATORS = new Set(['==', 'array-contains', 'in']);

function buildFirestoreQuery(userQuery, authTenantId) {
  const queryConstraints = [];

  if (ALLOWED_FIELDS.has(userQuery.field) && ALLOWED_OPERATORS.has(userQuery.operator)) {
    if (userQuery.operator === 'in' && Array.isArray(userQuery.value)) {
      queryConstraints.push({ [userQuery.field]: { 'in': userQuery.value } });
    } else if (userQuery.operator === 'array-contains') {
      queryConstraints.push({ [userQuery.field]: { 'array-contains': userQuery.value } });
    } else {
      queryConstraints.push({ [userQuery.field]: { '==': userQuery.value } });
    }
  }

  // Always enforce tenant scope from server-side identity
  queryConstraints.push({ tenantId: { '==': authTenantId } });

  return queryConstraints;
}

app.service('items').find({
  query: {
    constraints: buildFirestoreQuery(req.query, req.identity.tenantId)
  }
});

For services using FeathersJS hooks, validate and sanitize within the before hook to ensure no malicious fields reach Firestore:

const { iff, isProvider } = require('feathers-hooks-common');

function validateFirestoreQuery() {
  return iff(isProvider('external'), context => {
    const { field, operator, value } = context.data || {};
    const safeFields = ['status', 'priority', 'region'];
    const safeOperators = ['==', '!=', 'array-contains'];

    if (!safeFields.includes(field) || !safeOperators.includes(operator)) {
      throw new Error('Invalid query parameters');
    }

    // Ensure tenant scoping
    context.data.tenantId = context.params.authTenantId;
  });
}

app.service('records').hooks({
  before: [validateFirestoreQuery()]
});

When using Firestore’s REST or SDK directly, ensure reference paths are static where possible. Avoid concatenating user input into document paths. Instead, resolve identifiers against a trusted map:

const ALLOWED_COLLECTIONS = new Set(['publicProfiles', 'sharedResources']);

function getDocumentRef(collectionName, documentId, tenantId) {
  if (!ALLOWED_COLLECTIONS.has(collectionName)) {
    throw new Error('Unsupported collection');
  }
  return firestore.collection(`${tenantId}/${collectionName}`).doc(documentId);
}

These patterns reduce the attack surface by limiting dynamic query construction and enforcing tenant boundaries. They align with the principle that services should not reflect user input directly into database operations without rigorous validation and transformation.

Related CWEs: llmSecurity

CWE IDNameSeverity
CWE-754Improper Check for Unusual or Exceptional Conditions MEDIUM

Frequently Asked Questions

Can hallucination attacks in FeathersJS with Firestore lead to unauthorized data access?
Yes. If user input is used to dynamically construct Firestore queries without strict validation and tenant scoping, attackers can manipulate queries to access data outside their authorization context, leading to unauthorized data exposure.
How does middleBrick help detect risks related to FeathersJS and Firestore integrations?