← Back to all reports

Unauthenticated Privilege Escalation Mints Paid Orders on Partner Books

ReportedMay 11, 2026
SeverityCritical
PlatformWeb API
Vulnerability ClassBroken Access Control (CWE-862)
Target TypeLive Experiences / Events Marketplace
ImpactReal paid orders billed to ~70% of probed partner organisations

The Risk

A complete stranger could sign up through a public web form, pick any of the company's business partners, and instantly become a manager inside that partner's account with no invitation, no approval, and no captcha. From there the attacker could create real ticket bookings that would be billed to the partner on their next weekly invoice and that would arrive with working entry barcodes. The researcher created three confirmed paid orders on one partner from clean accounts, and the same trick worked against roughly two thirds of the partners tried.

The Vulnerability

A B2B identity API endpoint of the form POST /api/iam/v1/orgs/{org_id}/businesses accepted unauthenticated requests with an attacker-chosen org_id and business_type. There was no authorization header, no captcha, no rate limit, and no invitation token. The server happily provisioned a real partner manager account inside whichever organisation the attacker named and emailed an activation link to the attacker's inbox.

Roughly 70% of probed partner organisation ids accepted this signup. The public web page that calls this endpoint was only the UI; the missing authorization was server-side.

Two further weaknesses turned the foothold into financial impact:

  • A payment-settings endpoint accepted a self-service flip from regular checkout to invoicing mode, even though the partner UI never exposes that control for self-onboarded accounts.
  • The reservation pay endpoint accepted payment_method=invoicing from the same self-onboarded account, transitioning the reservation to paid and rolling the bill into the partner's normal weekly invoice.

The Attack

  1. Open the public group-tickets signup form with an attacker-chosen partner id in the query string. Fill any details with a controlled email. Submit.
  2. Receive the welcome email, branded with the target partner's name (the cross-organisation binding is visible in the subject line). Click the create-password link, set a password.
  3. Log into the partner portal. The bearer token lands in localStorage. The top-right user chip reads the attacker's group name and the target partner's name.
  4. From the browser console, send a PUT to the payment-settings endpoint with {"payment_type":"invoicing","invoicing_period":"weekly"}. Server returns 204.
  5. In the partner UI, browse the partner's real upcoming inventory and reserve a seat. The reservation lands as TO BE PAID.
  6. From the browser console on the reservation detail page, send a POST to the pay endpoint with {"payment_gateway":"company","payment_method":"invoicing"}. The reservation flips to PAID, a real ticket with an active entry barcode appears, and a confirmation email goes to the synthetic customer address.
  7. The new paid reservation shows up in the partner's normal sales view with a green badge, indistinguishable from a legitimate sale. Venue staff will scan the barcode at the door.

What else was reachable

The bearer issued by login carried no role, scope, or partner claim, only user identity. Authorization was purely server-side via tenant membership lookup, so any endpoint that did not separately gate by role was reachable to the self-onboarded account. The portal JS bundle exposed additional mutation routes accessible by this role: refund a partner's real customer orders, cancel or reschedule customer reservations, inject and publish fake event listings, upload entry barcodes into partner inventory, pair POS terminals and kiosks, and a suspected payout-allowlist endpoint.

The server-side business_type field also accepted five internal staff role names that the client never exposed. Invalid values triggered a validation error that echoed the full enum, leaking internal role names. Activation against those values downgraded the resulting role to manager, so the internal-enum impact was limited to information disclosure.

The Impact

Three end-to-end paid orders were issued against one partner from clean attacker accounts and verified to appear in the partner's standard sales view with active scannable barcodes. Per-order ceiling on that partner via the group-sales channel was a low four-figure sum. Per-partner-year theoretical ceiling ran into six figures. Across the thousands of partners on the platform with roughly 70% accepting the signup, aggregate exposure ran into the hundreds of millions.

Operational consequences include billing fraud against partners, fake plan listings that could be used to phish consumers, and unauthorized refunds against partner customer orders.

Remediation

  • Remove unauthenticated partner-account creation from the public group flow entirely. Move it behind a partner-issued invitation token tied to a specific organisation and role.
  • Server-side: ignore client-supplied organisation and role parameters. Derive them from a signed invitation token, not the URL.
  • Restrict the server-side role enum on unauthenticated paths to public values only. Stop echoing the full enum in validation errors.
  • Re-validate authorization for payment-settings, reserve, and pay so a freshly-enrolled account cannot flip its own business to invoicing and transition orders to paid without partner-side approval.
  • Audit every mutation endpoint reachable by tenant membership (refund, cancel, plan publish, upload-codes, kiosk pair, payout whitelist). Authorization must be checked per action, not assumed from membership.
  • Rate-limit the signup endpoint per source IP.
  • Surface the payment type of every business in the partner UI so partners can detect unauthorized invoicing-configured accounts attached to their organisation.