00:00

#0108

Multi-Tenant Data Leak

Hard+200 XPA01:2021 Broken Access ControlCWE-639
BOLAMulti-tenantAuthorization

Scenario

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.

Your Tasks

  1. Fix getTenantRecord so that it throws 'Forbidden' when either the tenantId OR the ownerId does not match the requested values. Throw 'Not found' only when the record does not exist at all.

Examples

Example 1Tenant mismatch blocked

getTenantRecord('alice', 'tenant-B', 'rec-1', records)
// throws 'Forbidden' — alice belongs to tenant-A

Example 2Both checks pass

getTenantRecord('alice', 'tenant-A', 'rec-1', records)
// returns { id: 'rec-1', tenantId: 'tenant-A', ownerId: 'alice', data: '...' }

Constraints

  • Throw exactly 'Forbidden' (no trailing punctuation) when tenantId or ownerId mismatches
  • Throw exactly 'Not found' when the record does not exist
  • Return the full record object on success

Hint

References

solution.js
Ln 1, Col 1UTF-8JavaScript
Sandbox ready
0/0/0not run