URL patterns do not expose internal tenant IDs
Why it matters
Sequential integer organization IDs in URLs (e.g., /orgs/1042/) allow any authenticated user to enumerate all tenants by incrementing the ID — a reconnaissance step that maps your customer base, exposes competitor relationships, and simplifies targeted IDOR attacks. CWE-200 and CWE-639 both apply. While this is lower severity than direct data exposure, it is a forcing function for more serious attacks and may violate contractual confidentiality obligations between competing tenants on the same platform.
Severity rationale
Low because ID exposure alone does not grant data access, but it significantly reduces the effort required to mount enumeration or IDOR attacks against other tenants.
Remediation
Use human-readable slugs for tenant-identifying URL segments, enforced at the schema level:
// schema.prisma
model Organization {
id String @id @default(uuid())
slug String @unique // e.g., "acme-corp" — enforced unique by DB index
}
Generate the slug from the organization name on creation using a library like slugify, and resolve collisions with a numeric suffix (acme-corp-2). Update all route definitions from /orgs/[id]/ to /orgs/[slug]/ in src/app/. If UUIDs must be used (e.g., for API compatibility), ensure they are v4 (random) — not v1 (timestamp-based) or sequential, which are enumerable.
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-639 — Authorization Bypass Through User-Controlled Key
- cwe · CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor
- owasp:2021 · A01 — Broken Access Control
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-multi-tenancy·automated