Order Details Screens and PII

When ordering a product or service online, it’s fairly common to get a confirmation email from the provider, often with a link where you can view details of your order. This is all very helpful, but have you ever considered whether the link you can follow is secure, or if it might be vulnerable to attack?

We started thinking about this after ordering from a small business who used Shopify, along with Google Customer Reviews. Shopify is a commerce platform, which is used by 1 million+ merchants. It has a history of resolving bugs and disclosing reports to demonstrate its commitment to security. Google Customer Reviews is a Google programme to try to generate verified customer reviews, which are then shown in search results.

One of the features Shopify offers is a customised order status screen (https://help.shopify.com/en/manual/orders/status-tracking/customize-status-tracking), where a link is sent to the customer after they have ordered, leading to a page containing details such as the address where the order is being sent to and whether it has been dispatched. This link uses a long hexadecimal string as an identifier, and when visiting displays only very basic details unless the customer logs in – even things like address are shown as blank spaces, and the data isn’t included in the HTML source. The details of what was ordered, the amount it cost, and the amount that shipping cost are shown, but these are unlikely to be considered sensitive – in most cases, they’ll be available in the main part of the shop anyway.

image1

To view the full details, the customer needs to provide the email address they used for the purchase, and the order number, which is included in the email sent by the store.

So far, all good – in order to see anything sensitive, an attacker would have to guess the order number and email address.

As mentioned before, though, a specific site we were using also used Google Customer Reviews. The documentation for Google Customer Reviews includes details about what is required when integrating it into a site (https://support.google.com/merchants/answer/7106244?hl=en-gb&ref_topic=7105160) which includes a merchant id to identify the shop, an order id to identify the specific order, and an email address to identify the customer. This means when you land on the page, you get a pop-up asking if you would like to leave a review.

image2

The pop-up contains the email address for the order. Still, an attacker would have to guess the order number in order to see anything important, right? Sadly, while the terminology isn’t a perfect match, the “order number” from Shopify and the “order id” from Google Customer Reviews turns out to be the same thing. In fact, both appear in the HTML source of the page, in a required block to use Google Customer Reviews.

// REQUIRED
"merchant_id":"MERCHANT_ID",
"order_id": "ORDER_ID",
"email": "CUSTOMER_EMAIL",
"delivery_country": "COUNTRY_CODE",
"estimated_delivery_date": "YYYY-MM-DD",

Entering these details into the appropriate fields allowed access to the full billing and shipping address details.

image3

It is unlikely that an attacker could stumble across the order status page for a given order by accident – as mentioned, the URL for the page contains a long hexadecimal string – but it’s fairly common to send these to other people as a quick way of showing what has been ordered. In fact, it was doing this which suggested to us that there might be a possibility of gaining access to further details from the status screen.

We submitted a report to the Shopify bug bounty program but it was closed as Informative. They responded that they consider the default configuration secure. They agreed that the current structure for the order status customization may need revisiting given the increasing use of this type of review module – it is currently not possible to provide distinct content for the authenticated and unauthenticated versions of the page.

image4

While Google Customer Reviews happened to be on the shop where we first identified this issue, it is not the only script which can expose these details. For example, from the Shopify documentation on adding conversion tracking data to the order status page (https://help.shopify.com/en/manual/orders/status-tracking/add-conversion-tracking-to-thank-you-page), one example includes code which would expose the order number. Other customer tracking systems would also cause the details to be exposed:

This also potentially leads to a situation where using multiple tracking systems results in a problem, while the individual scripts are each fine in isolation.

Our suggestions to Shopify were therefore:

  1. Prevent access to the order.id property and customer object from the order status screen, since these either contain personal data, or can be used to access personal data. This would however break any existing integrations which rely on being able to access these values.
  2. Consider allowing customisation of the order status screen depending on whether the customer is authenticated or not. In theory this is already possible using the {% if customer %} construct, but this appears to always consider the customer as being logged in on the order status screen. If this was modified, code such as below would only include these details in the code for logged in customers:
    {% if customer %}
    //example.com/tracker?email=%20customer.email%20&order_num=%20order_number%20
    {% endif %}
  3. Update the documentation around the Additional Scripts box (https://help.shopify.com/en/manual/orders/status-tracking/customize-status-tracking#add-additional-scripts) to be clear that some variables could expose personal data of customers on the unauthenticated order status screen – currently, it is not clear that the same code will appear for unauthenticated users as for authenticated ones.

While the impact of this issue could be high, we agree with Shopify that the chances of attackers obtaining access to the order status page are slim, unless the customer specifically shares the link through, for instance, social media.

For shops using the Shopify platform, it may however be worth reminding customers that the order status link shouldn’t be shared publicly, even if no sensitive data appears to show when viewing the page normally. It’s still possible that personal data is available in the source code.