Engagements  /  PSY-WEB-0412

One tenant could read every other tenant’s invoices

A Series B invoicing platform needed a penetration test to close its first enterprise customer. The headline finding would have ended the deal had the customer found it first.

Representative engagement. Client names, figures and identifying details are changed or combined; no client findings are published in identifiable form.

Sector
SaaS and technology
Engagement
Web app & API pentest
Frameworks
OWASP ASVS 5.0 Level 2, OWASP API Security Top 10 (2023), SOC 2 CC6
Duration
12 test days, retest at week 6

A multi-tenant invoicing platform.

The platform served around four thousand small businesses from a single shared database, separated by a tenant ID on every row. Its largest prospect, a national distributor, required a third-party penetration test less than twelve months old before procurement would sign.

The engineering team had run an automated scanner and fixed what it reported. They expected a clean result.

What we did

Three moves, in order.

Map every role against every object

We built a matrix of the platform’s five roles against its forty-odd object types, then tested every cell — including cross-tenant access, which the scanner had no way to reason about.

Follow the mobile app to its API

The mobile app called a version of the API not listed in the documentation. It reused the web session but skipped the tenant check on four endpoints.

Write it for procurement as well as engineering

The executive summary was written so the client could share the summary letter with the prospect’s security team without exposing a single request.

What we found

Nineteen findings; one that mattered most.

SeverityFindingMaps toStatus at retest
CriticalInvoice IDs were sequential and the v2 invoice endpoint checked authentication but not tenant ownership.API1:2023 · ASVS V8 · CWE-639Closed
HighUsers removed from a tenant kept a valid refresh token for 30 days.ASVS V7 · A07:2025Closed
HighThe “import logo from URL” feature fetched internal addresses, including cloud metadata.A01:2025 · CWE-918Closed
HighCSV export of customer lists was vulnerable to formula injection.ASVS V1 · CWE-1236Closed
MediumNo rate limit on login or password reset.API4:2023 · ASVS V6Closed

What changed.

The tenant-isolation flaw was patched within 48 hours of the same-day escalation, and the fix was extended to a shared authorisation layer rather than patched endpoint by endpoint. Every critical and high finding was verified closed at retest.

The summary letter went to the prospect’s security team, and the same report became evidence for the client’s SOC 2 Type II audit the following quarter.

Next engagement

Want this for your application?

Tell us what you ship and who is asking for proof. We will come back with a scope and a range.