Skip to main content
MemCyber
API · 8 min read

Chaining IDOR and Object Metadata Leaks in Fintech APIs

How combining a seemingly low-impact IDOR with an object-metadata leak escalated to cross-tenant financial data access on a Series B fintech. Sanitized writeup and defenses.

By Atilla Mammadli

Single-vulnerability reports are what scanners find. Real risk lives at the seams — where two merely-annoying issues combine into something that would end a company’s quarter. This writeup walks through a sanitized version of a chain we disclosed to a Series B fintech, where an IDOR that their internal triage had labeled P3 became the primary path to cross-tenant financial data access.

The two pieces

On the surface, each of the two findings was unimpressive.

Finding A — IDOR on document metadata. A GET /documents/{doc_id}/meta endpoint returned the name, size, and creation timestamp of any document in the system when you provided a valid doc_id, regardless of whether the requester owned the document. The endpoint returned no file contents — only metadata. The team had triaged it as low severity: “Name and timestamp aren’t sensitive.”

Finding B — Predictable tenant segmentation. Tenant IDs were short monotonic integers, not UUIDs. A newly-onboarded tenant in the low thousands could enumerate every tenant that had onboarded before them, simply by iterating tenant_id = 1..N.

Neither alone justified a P1 label. Together they did.

The chain

The document metadata endpoint leaked the document’s tenant_id in its JSON response. Combined with tenant enumeration, that meant an authenticated user — any user, on any tenant — could:

  1. Enumerate doc_id ranges (also monotonic) to collect metadata for every document in the system.
  2. Bucket the returned tenant_id values per document.
  3. For each tenant, reconstruct the document naming scheme (e.g. "KYC-passport-{customer_id}.pdf", "payroll-{month}-{year}.xlsx").
  4. Infer — from names and timestamps alone — customer acquisition rates, payroll cycles, KYC processing volume, and in some cases the identities of high-net-worth customers by matching name patterns to public records.

No document body was ever read. No “data breach” in the traditional sense occurred. But the metadata was enough to reconstruct enough of the business that a competitor, an acquirer in diligence, or a nation-state actor would pay for it.

Why triage missed it

The initial P3 label came from asking the wrong question: what does this endpoint leak in isolation? The right question for any IDOR is: what other fields does this response contain that I can correlate across calls?

Document metadata feels harmless until you recognize it is a queryable index into the rest of the system. The same pattern shows up in:

  • Comment endpoints that leak author_id and parent_id.
  • Notification endpoints that leak recipient_tenant_id.
  • Audit-log endpoints that leak actor/action pairs across tenants.
  • Search auto-complete endpoints that return other tenants’ titles.

Defense

The right fix was not just to add an authorization check to the metadata endpoint. The real defenses were layered:

  1. Scope-bind every object identifier to the caller’s tenant at the data-access layer, not at the handler. Handlers forget. A repository pattern that requires tenant_id on every lookup eliminates this class of bug by construction.
  2. Make tenant and object IDs unguessable (UUIDv4 or ULID, not sequential integers). This does not fix IDOR, but it raises the floor: a chain like the one above becomes computationally infeasible even if one of the checks misses.
  3. Treat metadata as data. Document names, timestamps, counts, and statuses often encode more information than the underlying content. They should be subject to the same authorization checks.

Takeaway

When reviewing your own APIs, run through every GET response field and ask: “If I could call this for any ID, what does this field tell me about the rest of the system?” If the answer is anything other than “nothing,” that field is part of your attack surface even when the endpoint feels innocuous.

The critical bugs are rarely the ones a single report describes. They are the ones that emerge when two reports live next to each other in the backlog.

Tags IDORBOLAfintechchaining

Continue reading

Recognize this pattern in your own stack?

We run targeted reviews against exactly these classes of bug. One email away.

Request Assessment