HIGH prototype pollutionadonisjsfirestore

Prototype Pollution in Adonisjs with Firestore

Prototype Pollution in Adonisjs with Firestore — how this specific combination creates or exposes the vulnerability

Prototype pollution in AdonisJS when interacting with Google Cloud Firestore occurs when untrusted input modifies JavaScript object prototypes that are later used to construct Firestore document references, queries, or update payloads. Because Firestore client libraries accept plain JavaScript objects for document paths, field values, and query constraints, objects that reach Firestore operations may carry poisoned properties introduced through deep merge patterns or unsafe object extension.

AdonisJS applications commonly use helper libraries to merge configuration or request payloads into query or document models. If these merges are not constrained, an attacker-supplied property such as __proto__, constructor.prototype, or a custom prototype key can propagate into objects passed to Firestore. Once polluted objects are used to build document paths or update maps, the pollution can affect object behavior in unpredictable ways during serialization, validation, or path resolution. For example, a merge that extends a Firestore document map with user input may inadvertently add or override properties on shared prototypes, changing how document data is interpreted or serialized when read back or used in security-sensitive contexts like policy checks.

Consider an endpoint that builds a Firestore document update from request body using object spread or lodash merge. An attacker sending { "__proto__": { isAdmin: true } } can cause the resulting object to carry poisoned properties. When this object is passed to docRef.set(), the polluted fields may bypass expected validation logic or interact unexpectedly with application-level guards that rely on prototype checks. Firestore itself does not execute JavaScript, but the client-side objects used to construct queries and updates can become unsafe if they inherit unexpected properties, potentially leading to privilege escalation or data exposure when combined with insecure authorization logic.

Because middleBrick scans the unauthenticated attack surface and tests input validation as one of its 12 parallel checks, it can surface prototype pollution risks in API endpoints that accept and forward user-controlled data to Firestore operations. Findings include insecure object merging, missing property filtering, and unsafe construction of document paths that may carry tainted data. middleBrick also runs LLM/AI Security checks, ensuring that prototype-polluted prompts or data do not leak into model outputs or get persisted through AI-driven integrations.

Firestore-Specific Remediation in Adonisjs — concrete code fixes

Remediation focuses on preventing untrusted input from reaching Firestore document and query construction. Validate and sanitize all incoming data before it is merged into objects that are passed to Firestore. Use strict parsing for numeric IDs, avoid extending native prototypes, and prefer shallow, controlled merges that exclude dangerous keys like __proto__, constructor, and prototype.

Safe Firestore document update with input filtering

Instead of spreading user input directly, extract only allowed fields and explicitly omit prototype-level keys:

import { schema, rules } from '@ioc:Adonis/Core/Validator'
import { Firestore, doc, updateDoc } from 'firebase-admin/firestore'

const updateSchema = schema.create({
  body: schema.object({
    documentId: schema.string({ trim: true, escape: false }),
    updates: schema.object({
      // explicitly allow only expected fields
      title: schema.string.optional(),
      status: schema.enum.optional(['draft', 'published', 'archived']),
      priority: schema.number.optional([rules.range(1, 10)])
    }, { extraFields: 'strip' })
  })
})

export async function updateDocument(ctx) {
  const { documentId, updates } = await ctx.validate({
    schema: updateSchema,
    data: ctx.request.body()
  })

  // Ensure no prototype pollution keys are forwarded
  const safeUpdates = Object.keys(updates).reduce((acc, key) => {
    if (!['__proto__', 'constructor', 'prototype'].includes(key)) {
      acc[key] = updates[key]
    }
    return acc
  }, {})

  const docRef = doc(Firestore.instance(), 'items', documentId)
  await updateDoc(docRef, safeUpdates)
  ctx.response.ok({ success: true })
}

Parameterized Firestore document path construction

Build document references using controlled identifiers rather than concatenating raw user input:

import { Firestore, doc, setDoc } from 'firebase-admin/firestore'
import { v4 as uuidv4 } from 'uuid'

export async function createDocument(ctx) {
  const body = ctx.request.body()
  // Use a server-generated ID or strict slug; avoid direct user input in path
  const documentId = body.slug || uuidv4()
  const docRef = doc(Firestore.instance(), 'tenants', ctx.tenantId, 'data', documentId)

  // Filter dangerous keys from payload
  const payload = { ...body }
  delete payload.__proto__
  delete payload.constructor
  delete payload.prototype

  await setDoc(docRef, payload)
  ctx.response.created({ id: documentId })
}

Query constraint safety

When building query constraints, avoid merging user objects directly into constraint maps:

import { Firestore, collection, query, where, getDocs } from 'firebase-admin/firestore'

export async function listDocuments(ctx) {
  const { status } = ctx.request.qs()
  const baseCollection = collection(Firestore.instance(), 'records')

  // Build constraints explicitly; do not merge untrusted objects into constraint maps
  const constraints = []
  if (status) {
    constraints.push(where('status', '==', status))
  }

  const q = query(baseCollection, ...constraints)
  const snapshot = await getDocs(q)
  const rows = snapshot.docs.map(d => ({ id: d.id, ...d.data() }))
  ctx.response.ok(rows)
}

These patterns ensure that Firestore interactions remain isolated from prototype pollution vectors. middleBrick can validate these protections by scanning endpoints that accept and forward user input to Firestore, highlighting insecure merges and missing property sanitization in its findings.

Frequently Asked Questions

Can middleBrick detect prototype pollution risks in APIs that forward user input to Firestore?
Yes. middleBrick runs input validation and security checks in parallel, including checks for insecure object merging and missing property sanitization. It reports findings that could lead to prototype pollution when user-controlled data is used to build Firestore document paths or update payloads.
Does middleBrick fix prototype pollution findings automatically?
No. middleBrick detects and reports findings with remediation guidance. It does not automatically patch or block code. Developers should apply input validation, strict filtering, and safe Firestore patterns as described in the remediation guidance.