Search and filter do not cross tenant boundaries
Why it matters
Search endpoints are frequently overlooked during tenant-isolation reviews because they feel like read-only features. But a full-text search that runs across a shared index returns matching documents from every tenant that contains the search term — exposing business names, customer data, proprietary content, and internal notes to anyone who knows what to search for. CWE-285 and OWASP A01 apply; Algolia and Elasticsearch indices that lack per-tenant filters are particularly dangerous because the search engine optimizes for broad recall.
Severity rationale
High because an unfiltered search index is a structured reconnaissance tool that any authenticated user can use to extract data from arbitrary tenants.
Remediation
For Algolia, generate tenant-scoped secured API keys server-side so the filter is baked into the key and cannot be removed by the client:
const securedKey = algoliasearch.generateSecuredApiKey(
process.env.ALGOLIA_SEARCH_KEY,
{ filters: `organizationId:${session.user.organizationId}`, validUntil: Math.floor(Date.now() / 1000) + 3600 }
)
For Typesense, use scoped API keys with a filter condition that locks the key to the tenant's records. For database full-text search (ILIKE, tsvector), always AND organizationId = $1 alongside the search predicate in src/app/api/search/route.ts. Autocomplete endpoints need the same treatment — they are search endpoints too.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Multi-Tenancy Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-285 — Improper Authorization
- cwe · CWE-639 — Authorization Bypass Through User-Controlled Key
- owasp:2021 · A01 — Broken Access Control
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-multi-tenancy·automated