All 20 checks with why-it-matters prose, severity, and cross-references to related audits.
A single unscoped query against a tenant-owned table is all it takes for one customer to read, overwrite, or delete another's data — the textbook definition of CWE-639 (Authorization Bypass Through User-Controlled Key) and OWASP A01 (Broken Access Control). In SaaS products this failure is catastrophic: it breaches contractual data-isolation guarantees, triggers GDPR and SOC 2 breach-notification obligations, and can expose trade-secret or PII data from every tenant in the database. The attack surface is wide because any route that touches a tenant-scoped table without a filter is exploitable by any authenticated user — no privilege escalation needed.
Why this severity: Critical because a single missing tenant filter gives any authenticated user unrestricted read and write access to every other tenant's data in the same table.
saas-multi-tenancy.data-isolation.every-query-tenant-scopedSee full patternCWE-285 (Improper Authorization) and OWASP A01 describe exactly this failure: an API that returns records without verifying the requester owns them. For list endpoints, a missing tenant filter exposes every record in the table to every authenticated user. For single-resource endpoints, guessing or enumerating a UUID is enough to retrieve another tenant's document, project, or user record — no special privilege required. This constitutes unauthorized disclosure of confidential business data and, where PII is involved, a reportable data breach under GDPR Art. 33.
Why this severity: Critical because unauthenticated enumeration of resource IDs — or simply calling a list endpoint — exposes every tenant's data to any valid session token.
saas-multi-tenancy.data-isolation.no-cross-tenant-api-responsesSee full patternSourcing tenant context from client-supplied values — a request body `tenantId`, a query parameter, or an unverified path segment — is CWE-639 and OWASP A04 (Insecure Design) in combination: any user who can forge or swap that value gains access to an arbitrary tenant's data. This is not a theoretical risk; it is one of the most common multi-tenancy bugs because the attack requires only changing a single field in a normal API call. NIST AC-3 requires that access decisions be based on authoritative session state, not client assertions.
Why this severity: Critical because any authenticated user can swap a single request parameter to impersonate a different tenant and read or write their data.
saas-multi-tenancy.data-isolation.tenant-context-from-sessionSee full patternFlat storage namespaces are a common AI-generated blind spot: code stores files as `uploads/{uuid}` with no tenant prefix, so any authenticated user who discovers a file key — via URL scraping, shared links, or support screenshots — can download another tenant's files. CWE-732 (Incorrect Permission Assignment for Critical Resource) and OWASP A01 both apply. Beyond privacy, tenant-to-tenant file exposure violates SOC 2 CC6.1 data classification requirements and, when files contain PII, triggers GDPR Art. 33 breach notifications.
Why this severity: High because a flat storage namespace lets any authenticated user retrieve another tenant's files by constructing or guessing the storage key, with no further privilege required.
saas-multi-tenancy.data-isolation.file-storage-segregatedSee full patternCWE-524 (Use of Cache Containing Sensitive Information) combined with OWASP A01 describes exactly this failure: a cache key like `dashboard-stats` that is populated by Tenant A's first request and then returned unchanged to Tenant B. Unlike database-layer isolation gaps, cache leaks are silent — no error is raised, the data looks valid, and the victim tenant never knows they received another org's numbers. The window for cross-tenant exposure is bounded only by the cache TTL, which is often measured in minutes or hours.
Why this severity: High because a cache key collision silently serves one tenant's business data to another tenant with no error or signal that a leak has occurred.
saas-multi-tenancy.data-isolation.cache-keys-include-tenantSee full patternWhen a user switches organizations, any prior-tenant data held in client-side state — React Query caches, SWR caches, Zustand stores, or sessionStorage — remains accessible until the browser is refreshed or the cache entry expires. CWE-524 and OWASP A01 both apply: the prior tenant's dashboards, user lists, and documents can be queried by API calls that still carry the old cache entries, or rendered from stale in-memory state. This is particularly dangerous in shared-device scenarios (kiosk, shared workstation) where the next person uses the same browser session.
Why this severity: High because incomplete session teardown lets prior-tenant data remain accessible through stale client-side cache or in-memory state after a switch.
saas-multi-tenancy.tenant-boundaries.tenant-switching-no-leakSee full patternSearch 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.
Why this severity: High because an unfiltered search index is a structured reconnaissance tool that any authenticated user can use to extract data from arbitrary tenants.
saas-multi-tenancy.tenant-boundaries.search-filter-no-cross-tenantSee full patternIDOR (Insecure Direct Object Reference) in multi-tenant APIs is CWE-639 and CAPEC-122: an attacker increments or guesses a resource ID and retrieves a resource that belongs to a different tenant. The assumption that a valid UUID implies authorization is the root cause — valid IDs are observable (from your own data, from shared links, from support interactions) and UUIDs are not as unguessable as developers assume when millions exist. OWASP A01 classifies IDOR as one of the most prevalent and impactful web vulnerabilities.
Why this severity: High because resource IDs can be observed through normal product usage, making cross-tenant access exploitable by any authenticated user without brute force.
saas-multi-tenancy.tenant-boundaries.cross-tenant-search-blockedSee full patternBackground jobs that query data without a tenant scope pull every tenant's records into a single job execution — a cross-tenant data commingling event that CWE-285 and OWASP A01 both flag. The practical impact: a report generation job produces a file containing all tenants' data, an email campaign job sends emails using the wrong tenant's template, or a cleanup job deletes records it shouldn't. Because jobs run asynchronously with no user context enforcing isolation, the error is often invisible until a tenant reports receiving data that isn't theirs.
Why this severity: Medium because the exposure is indirect — no user can directly trigger cross-tenant data access — but jobs can silently commingle data across all tenants in a single execution.
saas-multi-tenancy.tenant-boundaries.background-jobs-tenant-scopedSee full patternOutgoing webhooks are an often-overlooked data-egress channel. When a webhook payload is assembled from a broad database query — one not scoped to the triggering tenant — a tenant's webhook endpoint can receive data belonging to a different tenant. CWE-200 (Exposure of Sensitive Information) and OWASP A01 both apply. The business impact is compounded because webhook payloads are delivered to external URLs configured by tenants, meaning a data leak goes directly to a third party outside your control and cannot be retroactively revoked.
Why this severity: Medium because the data escapes to external systems controlled by tenants, making retrospective containment impossible once a webhook fires with cross-tenant data.
saas-multi-tenancy.tenant-boundaries.webhook-payloads-no-other-tenantSee full patternGlobal rate limits in multi-tenant systems create a noisy-neighbor availability problem: a single tenant with a burst of traffic — legitimate or scripted — exhausts the shared token bucket and causes 429 responses for all other tenants. CWE-770 (Allocation of Resources Without Limits or Throttling) is the relevant defect. While this is a low-severity finding in isolation, it becomes a practical denial-of-service vector in SaaS products with free tiers where abuse is common and the impact falls on paying customers.
Why this severity: Low because the impact is availability degradation for other tenants rather than data exposure, and is bounded by the rate limit window duration.
saas-multi-tenancy.tenant-boundaries.rate-limiting-per-tenantSee full patternShared resources — system templates, integration presets, global configuration — are a legitimate multi-tenancy pattern, but the absence of a schema-level distinction between shared and tenant-owned resources means any authenticated tenant can modify data visible to all other tenants. CWE-732 and OWASP A01 both apply. The business impact ranges from corrupted onboarding templates that affect every new signup, to shared integration presets poisoned with malicious data that other tenants then import into their workflows.
Why this severity: High because a tenant modifying a shared resource causes immediate, cascading impact on every other tenant that reads or references that resource.
saas-multi-tenancy.shared-resources.shared-resources-no-leakSee full patternInvitation flows are a privileged code path: they grant access to a tenant's data before the invitee is a verified member. CWE-330 (Insufficient Randomness) allows token prediction; CWE-613 (Insufficient Session Expiration) keeps compromised tokens valid indefinitely; CWE-285 allows a token issued by Org A to be accepted against Org B. OWASP A07 (Identification & Authentication Failures) covers all three. The real-world consequence is that an attacker who intercepts or guesses an invitation token can join any organization without being explicitly invited.
Why this severity: High because a guessable or non-expiring invitation token lets an attacker join an arbitrary tenant's workspace without authorization from any member of that tenant.
saas-multi-tenancy.shared-resources.invitation-validates-membershipSee full patternTenant settings frequently contain sensitive configuration: API keys, webhook secrets, custom domain names, and feature flag states. CWE-639 and OWASP A01 apply when settings are accessible by record ID without an `organizationId` check — an attacker who knows or can enumerate a settings UUID retrieves another tenant's configuration. For settings that contain integration credentials, this constitutes a direct credential disclosure event.
Why this severity: Low because exploiting the gap requires knowing a settings record UUID, which limits the attack surface, but successful exploitation exposes sensitive configuration data.
saas-multi-tenancy.shared-resources.tenant-settings-isolatedSee full patternIncomplete tenant deletion leaves orphaned records that violate both contractual data-isolation guarantees and GDPR Art. 17 (Right to Erasure). CWE-404 (Improper Resource Shutdown or Release) covers the defect. Orphaned records create concrete risks: a future tenant who is assigned a recycled UUID can inadvertently access predecessor data; orphaned API keys remain valid credentials; and billing records for deleted tenants create accounting liabilities. The ISO 25010 functional suitability requirement is simple — delete means delete.
Why this severity: High because orphaned records after tenant deletion expose residual data to future tenants or direct lookups, and violate GDPR Art. 17 erasure obligations.
saas-multi-tenancy.tenant-management.tenant-deletion-cascadesSee full patternAudit logs that are not scoped by tenant become a cross-tenant intelligence source: a tenant admin can query another organization's activity history, exposing who is active, what features they use, and what actions their users take. CWE-285 and NIST AU-9 both address this; SOC 2 CC7.2 requires that audit records be protected from unauthorized access. Beyond privacy, unscoped audit logs mean a legitimate tenant admin cannot be confident that the logs they see reflect only their organization's actions.
Why this severity: Low because exploiting unscoped audit logs requires tenant-admin privileges, limiting the attacker surface, but exposure of another tenant's activity trail is a direct SOC 2 CC7.2 control failure.
saas-multi-tenancy.tenant-management.audit-logs-tenant-scopedSee full patternPlatform admin routes that can write tenant data without logging are invisible to both the tenant and to compliance auditors. CWE-778 (Insufficient Logging) and OWASP A09 (Security Logging and Monitoring Failures) both apply; SOC 2 CC6.8 explicitly requires that privileged actions be logged with who, what, and when. The practical risk is that an insider threat — a rogue admin or compromised admin account — can modify or delete tenant data with no forensic trail, making incident response and regulatory defense impossible.
Why this severity: Low because admin routes are access-controlled, but an unlogged admin write operation eliminates any forensic trail for insider-threat scenarios or compliance audits.
saas-multi-tenancy.tenant-management.admin-view-no-modify-without-trailSee full patternSequential 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.
Why this severity: 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.
saas-multi-tenancy.tenant-management.url-no-internal-idsSee full patternData export endpoints that query broadly and filter in application memory load every tenant's records into a single server process — a cross-tenant data commingling event that violates CWE-285 and OWASP A01. For GDPR Art. 20 (Data Portability) compliance, the exported data must be scoped to the requesting tenant's own records. Beyond compliance, an export endpoint that generates a file for Tenant A and returns a download link that Tenant B can also use constitutes a direct data breach with a durable artifact.
Why this severity: Low because export endpoints are typically authenticated and require deliberate action, but successful exploitation produces a durable file artifact containing another tenant's data.
saas-multi-tenancy.tenant-management.tenant-data-export-scopedSee full patternTenant creation endpoints with no rate limiting and application-only slug uniqueness checks are vulnerable to two distinct attacks: bulk tenant creation to exhaust system resources or claim desirable slug namespaces (CWE-770), and concurrent-request slug duplication that bypasses the select-then-insert uniqueness check (CWE-20, OWASP A04). In freemium SaaS products, unthrottled tenant creation is also a primary spam and abuse vector that inflates billing, corrupts benchmark data, and degrades performance for legitimate tenants.
Why this severity: Low because the impact is resource exhaustion and namespace pollution rather than direct data exposure, but slug duplication via race condition can corrupt routing and break tenant isolation.
saas-multi-tenancy.tenant-management.tenant-creation-validatedSee full patternRun this audit in your AI coding tool (Claude Code, Cursor, Bolt, etc.) and submit results here for scoring and benchmarks.
Open Multi-Tenancy Audit