Unauthenticated Disclosure of Full Order PII via the Public GraphQL order Query
Affected versions: confirmed on commit dbff1127c86fba02cdf282d438b22dba37c8ad83 (npm 2.2.1)
Summary
The public, unauthenticated /api/graphql endpoint exposes an order(uuid: String!) query that returns the complete order record, including the customer's full name, email address, shipping and billing addresses (name, phone number, street address, city, postcode), payment method, and line items, for any order UUID, with no session, cookie, or token check of any kind.
Details
Order.resolvers.js's Query.order loads the order matching the caller-supplied uuid and returns it directly, with no ownership, session, or token check:
order: async (_, { uuid }, { pool }) => {
const query = getOrdersBaseQuery();
query.where('uuid', '=', uuid);
const order = await query.load(pool);
if (!order) {
return null;
} else {
return camelCase(order);
}
},The schema declares no auth directive either. The route is served at /api/graphql with "access": "public", and that route's own middleware chain explicitly clears any admin context for the request (it is meant for storefront/customer traffic), so the query resolves purely from the URL-supplied UUID.
Other parts of the codebase show the developers already treat an order UUID as an insufficient access credential on its own: the anonymous order-tracking page requires a signed, TTL'd tracking token before exposing an order UUID to its GraphQL context, and the checkout-success page requires the visitor's session ID to match the order row. Both of those page-level protections are bypassed by calling the GraphQL API directly, since the resolver itself enforces none of the checks its page layer relies on.
POC
(available upon request)
Impact
Any unauthenticated party who obtains an order UUID (from an order confirmation URL, referrer header, browser history, shared link, or log) can retrieve that customer's full name, email address, phone number, complete shipping and billing addresses, and payment method with a single unauthenticated HTTP request. This affects both guest and registered-customer orders.
Source: evershopcommerce/evershop