Search indexing respects visibility; private excluded from results
Why it matters
A private profile that appears in site search or Google results is not private — it is merely hard to navigate to directly. Search engine indexing of private content breaches GDPR Art. 25's privacy-by-default requirement and CWE-200 (information exposure). Users who set their profiles to private expect complete exclusion from discovery, not just a locked profile page. Third-party search indices (Elasticsearch, Algolia) that ingest all records regardless of visibility are a particularly common oversight because indexing pipelines are often built before access control is finalized.
Severity rationale
Medium because the exposure is indirect — private content appears in search results rather than being directly accessible — but it defeats the user's explicit privacy intent.
Remediation
Filter visibility at the search query layer, not post-query. For Elasticsearch, apply a bool.filter clause; for Algolia, use optionalFilters or facetFilters. Emit noindex metadata for private profiles in your page generation.
Next.js generateMetadata example in src/app/u/[username]/page.tsx:
export async function generateMetadata({ params }) {
const user = await db.user.findUnique({ where: { slug: params.username } });
if (user?.profile_visibility !== 'public') {
return { robots: { index: false, follow: false } };
}
return { robots: { index: true, follow: true } };
}
For Elasticsearch, wrap searches with a visibility filter so private records are never returned regardless of requester — do not rely on post-query filtering, which can still expose counts and aggregations.
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 Community Privacy & Controls Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-285 — Improper Authorization
- owasp:2021 · A01 — Broken Access Control
- gdpr · Art. 25 — Data protection by design and by default
- cwe · CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor
Taxons
History
- 2026-04-18·v1.0.0·Initial import from community-privacy-controls·automated