Building Secure Shopify Apps — Shopify App Development (2022)

Building Secure Shopify Apps
Feb 23, 2022


Ensuring great app security not only earns you the trust of your customers, it also greatly increases the long term chances of success for your business. 

Cyber attacks are only increasing in frequency and cost. The industry has a long, difficult road ahead, but both tooling and best practices are making headway, and we can see it making a big difference for modern apps built in this way.

Building an app for the Shopify ecosystem not only provides you with a fast, high-converting platform for millions of merchants, it also ensures credit card information and customer data is protected. Shopify is PCI compliant and handles the whole checkout. Credit card information is sent directly to Shopify for them to handle, which alleviates you and your app users from the burden of full PCI compliance.

That doesn’t mean you don’t still have to be careful when developing your Shopify apps. Basic web application security principles apply, and as the Shopify ecosystem grows, we have to be continuously vigilant in ensuring we uphold the security of our apps on the platform. When new functionality is introduced, it can sometimes mean we have to think about using customer data more carefully—such as if we’re sending it to an artificial intelligence (AI) engine for recommendations. 

Common web application flaws are often dealt with by using modern frameworks, like SQL injection—a method of breaking out the confines of a poorly constructed query and interacting with the database in unwanted ways. If you’re turning your legacy app into a Shopify app, you may have to spend a considerable amount of time checking and improving the codebase to meet modern security standards. Contracting an external penetration testing company or consultant is worth the investment, as this means you’re not “marking your own homework.” Developers can often be blind to their own security missteps.

A key challenge to consider when developing a Shopify app is the handling of Personally Identifiable Information (PII), especially in areas where you’re requesting your client’s customer information. One small mistake in this area can cost you the trust of your users, and damages the trust in the Shopify app ecosystem as a whole.

Make sure you check through the requirements for public apps, which include GDPR compliance, having a privacy policy, and responding to deletion requests.

In this article, we will cover 11 key areas you need to consider to ensure you’re building a secure Shopify app. Now that you know why it’s important, let’s explore the details.

1. Always use source control

When starting to build a new application, it’s important to use source control. It’s not only helpful to collaborate with other developers, but it also allows you to track and monitor changes. 

Using source control allows you to start automating the deployment and build process, which reduces the potential for human error. If you’re manually going through any steps to get your application live, it increases the likelihood of something going wrong.

Ideally, all your infrastructure would live as code. If you use AWS, that could be orchestration tools such as CloudFormation or Terraform. In Heroku, this would be your buildpack. In modern, low-config deployment environments like Vercel, a lot of best practices are built in by default. 

2. Environment variables

You should keep all secrets, like your Shopify keys, out of your codebase. This makes it easier to work on your code with other developers, and if your code were to ever be leaked, hackers wouldn’t have access to third-party services, databases, etc.

In your local development environment, it’s best practice to run completely different instances of third-party services that you use, set them up specifically for development, and then put these in a `.env` file in the root of your project, which is ignored from your source control. You can add a `.env.example` to your repo as well to show which variables need to be configured.

Starting a project with the shopify-cli will configure a `.env` file for you. 

For example, if you’re using a SaaS product for mailing lists and you use the same instance in both development and production, it not only carries a security risk, but potentially opens you up to mailing customers from your tests.

3. Be careful with user input

If you’re building a Shopify app, it’s likely you’re adding a custom user interface (UI) either into the storefront or the admin area.

It’s best practice to avoid direct DOM (Document Object Model) access with user-generated content. 

You should always encode user input before rendering it to the page. Persistent XSS (Cross Site Scripting) can occur if someone manages to temporarily get access to one of your Shopify app users’ accounts—raw user input could be persisted into the database and remain in their shop until you detect it. The worst-case scenario would be the ability to include a remote script tag and display fake payment pages which scrape credit card information.

This is easy to do with React by not calling `dangerouslySetInnerHtml` (so named to prevent you from using it). You should also check that your dependencies don’t do this. 

If you’re in an older codebase using jQuery, you can use the `.text()` method to escape content.

Alternatively, remove any HTML tags in the backend before saving user generated content into the database, which ensures any changes to the frontend won’t introduce an XSS flaw.

4. Checking dependencies

Using other people’s code is not risk-free, but it does make sense in modern web development. In some scenarios, it’d even be foolish to use your own code (e.g. cryptography/hashing algorithms). 

This is referred to as Schneier’s Law: “Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that they themselves can’t break. […] What is hard is creating an algorithm that no one else can break, even after years of analysis.”

Reinventing the wheel sometimes isn’t just a waste of time, it’s a security risk to boot.

It’s worth checking that your dependencies are kept up-to-date. You can use `npm audit` as a bare minimum for JavaScript applications, and Synk offers a much improved database, which is much more highly moderated and maintained by security professionals.

For Ruby on Rails apps, you can use bundler-audit, which will check your `Gemfile.lock` for any known vulnerabilities in your gems.

This should be implemented as part of your build tools, such as GitHub Actions or BitBucket Pipelines. If you make this action flag a warning, then developers can see early on that there are potential security issues in your app. You can also use tools like Dependabot to automatically open Pull Requests.

5. Hash all passwords

Never store passwords in plaintext in the database. Make sure you also check your log files and error tracking tools for any accidental recording. 

If you’re adapting an existing app, make sure you move from older hashing algorithms such as MD5 to the latest recommended salted options as defined by OWASP.

6. Static analysis

There are many static analysis tools available that are excellent at finding certain types of issues, like SQL injections. While they can’t discover issues in configuration, or more complex problems, they’re a very good starting point, and can often highlight ‘code smells’ that indicate areas of the codebase that need more in-depth human review and refactoring. 

If you’ve built your Shopify app over a longer period of time, it would be well worth manually reviewing areas flagged by static analysis.

7. Rotate keys

You’ll likely use a number of third-party services as part of a larger Shopify application. This requires the use of API keys, both for development and production. Over time, it becomes more likely that these keys have been mishandled or saved somewhere they shouldn’t (like a developer’s laptop). 

You’ll want a process in place to rotate important keys (like your Shopify Secret Key) frequently. This prevents potential security issues with laptops left in public places.

Each platform will have their own method of rotating keys but here’s how to rotate or revoke API credentials in Shopify

8. TLS/SSL

This is the reassuring padlock that appears next to your address bar to let you know your data is being encrypted while being sent to the server. In recent years, this has become much easier to set up. 

Let’s Encrypt started providing free certificates in 2014, and since then the tooling and support from third-party hosting companies has only improved.

By using TLS/SSL for all your connections, even the connection from your application server to your CDN (if you use one) is a surefire way to improve security and protect PII from tampering and logging.

If you’re hosted on AWS, you can use their Certificate Manager to generate free TLS certificates, which can be used on CloudFront, Elastic Load Balancing, and API Gateway.

Companies like Cloudflare also issue free TLS certificates.

9. Code reviews

App security isn’t simply a list of products you can buy or tips to follow, it’s an ongoing process. A big part of security is having enough eyeballs on the parts that matter. Getting your colleagues or peers to conduct regular code reviews can help start the right conversations about which measures you should be taking, and also hopefully catch some easy-to-make mistakes while writing your Shopify app.

Pull requests in GitHub, GitLab and Bitbucket are great for ad-hoc code reviews.

10. Multi-tenanted applications and query scoping

Like many developers who choose to build public Shopify apps to launch on the Shopify App Store, you will be selling it multiple times to many merchants. This means you will need to have multi-tenant functionality in place. You may already be doing this without calling it by the same name.

Each tenant is effectively a customer, and you want to ensure that all your database tables include a `tenant_id` and are scoped and filtered by that ID in all areas of your application.

For example, if you have an endpoint that deletes a resource, you should be checking to see if the person sending the request belongs to that tenant. 

There are many off-the-shelf multi-tenant libraries in Ruby, PHP, JavaScript and Python—often with helpers that hook into the ORM (Object–Relational Mapping, an object layer that represents your database) used by your framework. You should scope all database queries to the tenant using your application.

The best way to ensure you’re not leaking data or privileges across tenants is to build out automated tests for these.

Other ways to increase security could be to split tenants into regions, depending on the security, hosting and data requirements for your application. 

11. Automated tests

Maintaining a good quality automated test suite, such a one built in Jest, is a sign of a healthy codebase. It allows you to write complex functionality in less time, and allows new developers to write new code whilst ensuring existing features continue to work.

Permission checks are a great candidate for automated security tests, as this can be difficult to test manually, and the risk of breaking the correct checks is high enough to warrant spending the time building tests.

I thoroughly recommend reading Test Driven Development: By Example by Kent Beck if you want to really get into testing.

Secure your app, and you’ll secure customer trust 

Make sure you’re following the best practices in this article when building out your Shopify application. If you have an existing web app and are adding Shopify capabilities, make sure to do a thorough audit of existing code and data handling.

SQL injection and XSS (Cross-Site Scripting) flaws were common in 2008, now they’re much rarer in new builds thanks to application frameworks that help prevent shooting yourself in the foot.

This article should be a great starting point to make your next great Shopify app follow best practices in security. Stay safe!

NAKISISA GEORGE

Leave a Reply