← Back to all reports

Unauthenticated Order Lookup Leaks Subscriber Data by Counting

Reported Jun 15, 2026
Severity High
Platform Web
Vulnerability Class Insecure Direct Object Reference (CWE-639)
Target Type News / Media
Impact Millions of subscribers' contact data exposed

The Risk

Anyone on the internet could read a news subscriber's full contact details, their name, email, phone number, and home address, just by typing in an order number, with no account and no login. Order numbers ran in a plain counting sequence, so every order on the platform, several million of them across more than one news brand, could be downloaded one after another. Because the lookup could be triggered straight from any web page, the harvesting could even be spread across ordinary visitors' browsers, making it hard to block. This is a large personal-data exposure of real paying customers that fuels spam, scam calls, and identity fraud.

The Vulnerability

The subscription checkout used an order-details endpoint to look up an order by its number. The endpoint had three problems at once:

  • No authentication. It returned the full order, including the customer block, to any caller with no account, token, cookie, or referer.
  • Sequential identifiers. The order number was a strict global counter that incremented by exactly one per order across all customers, so the entire order namespace was walkable end to end.
  • No tenant filtering. The lookup took no brand parameter, so a single sweep of the one shared counter returned orders for every brand on the multi-tenant platform.

This was not an unrelated side asset. The in-scope checkout's own shipped code hardcoded this backend as its data source and defined the exact order-details route, so the vulnerable call was the literal call the checkout makes. A second in-scope brand shipped the byte-identical bundle pointing at the same backend.

The Attack

Establishing the Counter

An attacker creates one throwaway order (the same call the checkout makes) to learn the current high-water number. Repeating the create returns numbers that increment by exactly one each time, proving the identifier is a shared global counter rather than random.

Walking the Range

Reading the number just below the one received returns an order created by someone else: a real customer's name, email, phone, and address. From there the entire contiguous range is enumerable by decrementing and incrementing. A read-only sample of a few hundred consecutive numbers returned many real paying customers (non-zero paid amounts, genuine addresses) interleaved with empty slots, confirming the namespace is densely populated. Only a minimal real sample plus the researcher's own throwaway orders were read.

Cross-Brand and Browser-Deliverable

Creating one order against each brand's identifier returned consecutive numbers from the same counter, confirming a single sweep harvests multiple brands at once. The endpoint also responded with a wildcard cross-origin header and required no credentials, so any attacker web page could read the response directly from a visitor's browser. That lets a mass harvest be distributed across many visitor browsers and addresses, defeating naive per-address rate limiting.

The Impact

Each populated order returned the customer's first and last name, email address, invoice email, phone number, street and house number, postal code and city, country, order amount and currency, and payment method, plus an internal sequential customer key that links a single person across all their orders. Business subscribers additionally exposed a company name and registration number.

With order numbers running into the millions across the shared counter, the entire subscriber base of multiple in-scope news brands was reachable from a single enumeration. The exposure is bounded at High rather than Critical because only contact data was returned: no national identity number, date of birth, card data, payment token, or account access was exposed, and the authenticated self-service surface (invoices, subscriptions, stored cards) remained correctly access-gated.

Remediation

  • Require authentication. The endpoint should return an authorization error unless the caller proves ownership of the specific order through a session bound to that order.
  • Replace sequential order numbers with non-sequential, unguessable tokens so the namespace cannot be walked by counting.
  • Scope the lookup to the authenticated tenant so one read cannot cross brands.
  • Remove the wildcard cross-origin header on any endpoint returning personal data, and add rate limiting and abuse detection.