Pentesting Shopify, or why its app permission model doesn’t work

If you are tasked with pentesting Shopify stores owned by your company, you might be thinking about completely skipping a classic pentest. Because the stores are hosted, patched and controlled in the cloud by Shopify itself, the risk doesn’t seem instantly obvious. Apart from large internal security team, the company runs a very successful bug bounty program – so a huge crowd of specialists make sure your stores are safe.

In reality, there are several weak spots which may introduce vulnerabilities or render some of Shopify’s defence mechanisms useless.

The first potential weak spot is the configuration of the store and admin accounts – let’s skip it for now. The second weakness is custom HTML template, which may include external scripts (first step to Magecart-like attacks), or sometimes results in DOM-based XSS flaws. The third one is Shopify App Store.

Have you ever seen a production Shopify store without any external apps installed? We practically haven’t. The apps usually have permissions to modify store template, JavaScript code and external scripts, read customer data via the API, etc. – all this without real control on Shopify side. For example, in December 2020 we reported a vulnerability in a popular App Store app which resulted in an exploitable XSS flaw on the login page of almost 5000 stores (stats from BuiltWith). In January 2021, we asked Shopify for help in fixing the bug. It’s June, and the XSS still remains.

While reviewing other weaknesses of the platform, we reported the following to Shopify (January 2021):


When store administrators install a 3rd party application, they are presented with an information screen regarding the API permissions this application requests, for example: „this application will be able to manage products; this includes products and collections”. This allows administrators to assess the risk related to a given application and decide whether they want to grant it specific access. Because the 3rd party apps are not covered by some of the Shopify internal application security mechanisms (like secure development process), and the data that is processed by the store is sensitive (personal data, payment data, passwords), the API permission mechanism is an important security boundary. Unfortunately, it does not seem to work in reality.
Issue 1. JavaScript access
The first issue is that once we have an API token [issued for an app on installation], there is a very high chance we get JavaScript write access. It seems standard for the applications to require template/script access. Also, „body_html” is not converted into static HTML, and it’s available within other permissions, like „products”

Issue 2. Passwords and payment flow access
The second issue is that if we can run JavaScript, we have full access to the data that the users enter on the pages in this domain (like credit card numbers), or their browsers autocomplete in this domain (like passwords), or are available in users profiles (like personal data). For example, […] is a video of an application that uses the browser’s History API and XMLHTTPRequest to spoof the payment page. The real payment iframe is not accessible to the script (cross-domain), and it seems no scripts are allowed on the payment page – however, it doesn’t matter, because the attacker just needs to convince the users they are on the payment page.

Issue 3. Misleading permission descriptions
The third issue is that the permission descriptions don’t mention JavaScript and all the derivative permissions it gives. If administrators allow e. g. „managing products”, they do not expect „full control over the store UI”, and even if they do, they may not understand all the consequences („access to all user data”).

The response:


Thank you for the report, and for your detailed analysis. We are aware that JavaScript execution on the storefront is possible through a variety of scopes in our admin API and interface, and of the implications of this behaviour. We list this as one of our known issues on our program page:
„XSS – Storefront – Any issue where a store administrator is able to insert javascript in the storefront area of their own store, including the checkout pages.”

The impact is similar to 2018 British Airways data breach: 3rd party applications have much wider access than their permissions show, including access to personal data, credit card numbers and passwords. In case any 3rd party application will be breached (which seems likely, considering the amount of vulnerabilities and lack of control from Shopify side), the store data can be breached as well. Due to Shopify defence mechanisms, the attack is more difficult to perform than a classic Magecart-like attack, but still realistic.

How to defend against this issue? The obvious solution is to strictly limit the external apps installed in your store. The other one is to tailor your store pentesting activities – instead of using your resources on pentesting Shopify core (done every day by dozens of specialists), make sure you cover every 3rd party application that has access to your data.