#0108
Your SaaS platform stores records partitioned by tenant. Each record carries both a tenantId and an ownerId. The access-control function checks that the requesting user owns the record — but forgets to verify that the record even belongs to their tenant.
An attacker enrolled in Tenant A can enumerate record IDs from Tenant B. Because the ownership check passes (they own a record with that ID in their own tenant), the function happily returns sensitive data belonging to a completely different organisation.
Multi-tenant systems are high-value targets. A missing tenant check means every customer's data is reachable by any other customer who can guess or enumerate record identifiers — a GDPR and contractual nightmare.
getTenantRecord('alice', 'tenant-B', 'rec-1', records)// throws 'Forbidden' — alice belongs to tenant-A
getTenantRecord('alice', 'tenant-A', 'rec-1', records)// returns { id: 'rec-1', tenantId: 'tenant-A', ownerId: 'alice', data: '...' }