Increasingly, we rely on digital devices to manage our shopping, banking, and overall communications. It goes without saying that it’s our responsibility as designers and front end developers to help protect customers from scams and security issues, just as much as it is for backend developers.
Whether you’re developing an ecommerce site (and Shopify looks after the vast majority of the risk) or a different kind of online experience, there are many pitfalls you need to be aware of. For this article we interviewed seven security experts to find out about the most common front end vulnerabilities, and what you can do to mitigate risks and avoid getting hacked.
Grow your business with the Shopify Partner Program
Whether you offer marketing, customization, or web design and development services, the Shopify Partner Program will set you up for success. Join for free and access revenue share opportunities, tools to grow your business, and a passionate commerce community.
Sign up1. Security must be part of the development process
Lately, there’s been a lot of buzz about front end performance in the community. It made software engineerBenedek Gagyirealize how similar it is to security.
“I keep nodding when I hear statements like ‘you have to add it to your process as early as possible’, or ‘the strongest force opposing your efforts is developer convenience’, since they are equally true both for performance and security,” he explains. “It’s obviously possible to fix all the security-related bugs and holes later in the development lifecycle, but it’s considerably harder and more expensive. That’s why addingthreat modelling sessionsand regular security reviews is vital to any bigger development step, entailing that security is there by design, not just as a patch.”
Benedek points out that while awareness is important, there should be more talk about the actual developer experience.
“I expect to see far fewer security bugs in software that’s written using libraries and frameworks that make writing secure software easy. It’s trivial, right? A good example in the front end world is how the big frameworks let you know if you are opening yourself up for a cross-site scripting (XSS) attack by giving risky operations names likedangerouslySetInnerHTML
in React or thebypassSecurityTrust
APIs in Angular.”
2. Use a modern framework that handles security automatically
JavaScript frameworks have become an essential part of modern web development. Most sites now seem to be built around a framework likeReact,Vue, orAngular。From a security point of view, they offer significant benefits.
“The reincarnation of the Angular framework is a perfect example,” saysPhilippe De Ryck, founder and secure coding instructor atPragmatic Web Security。“角自动防止variety of XSS attack vectors. It offers automatic encoding for simple outputs through {{}}. When usinginnerHTML
, Angular automatically sanitizes the output. When using variable URLs or CSS, Angular also automatically ensures the values are safe to be used in this context.”
Other frameworks offer similar protections, but according to Philippe they’re not as extensive. Still, using any modern framework significantly reduces the risks a developer needs to be aware of to mitigate XSS attacks.
You might also like:Web Security Fundamentals: What Every Developer Should Know。
3. Avoid typical XSS mistakes
While much less common when using modern JavaScript frameworks, it’s still possible to code in inadvertent XSS flaws into your front end.
“Let’s say we wanted to address a user by their name by linking to them from a marketing email,”James Hall,可怕的ctor of digital innovation agencyParallax, suggests. “Adding?name=James
to the query string, and then simply adding that to the DOM, would be a quick way to do it.”
For example:
document.querySelector('.tagline').innerHTML = nameFromQueryString
James warns that using code like the above, however, means anyone can inject code into your site and take over. He cautions that just by changing the name to, an attacker could craft a URL that can make a fake payment page look like it’s serving from your SSL-encrypted website.
4. Consider Trusted Types
Even with countermeasures such as output encoding or sanitization, XSS attacks are still a major problem for web-facing applications. Modern front end frameworks such as Angular or React are not entirely immune to it, warnsLiran Tal, developer advocate at open source security firmSnykand member of theNode.js Security Working Group。
Liran recommendsTrusted Types, a new browser API championed by Google’s security folksKrzysztof KotowiczandMike Samuel, to address XSS issues by leveraging the Content Security Policy specification (see below, under 12) to define templates of data sources that are used with sensitive APIs such asinnerHTML
-like sinks.
The Trusted Types spec still needs to mature but Liran calls for developers to opt in and start using this secure API.
“Luckily, we’re seeing signs of recognition and adoption in the front end community,” he says. “For example, the React framework recentlymerged a pull requestto further extend support for Trusted Types in newer releases.”
You might also like:An Insider's Look at the Technology That Powers Shopify。
5. Consider usingtextContent
instead ofinnerHTML
To prevent XSS attacks, you can use a sanitization library like DOMPurify (see below, under 11), but front end consultantZell Liewsuggests that, if you’re changing text only, you can usetextContent
instead ofinnerHTML
。
“Let’s say you want to get a text value from an input field, and you want to output that text value into the DOM. Here’s the code to get the text value:
const value = input.value
But the user can try to enter something malicious, like this snippet:
If you useinnerHTML
, you’ll create theelement and run the
onerror
handler. This is where XSS begins.”
Zell recommends usingtextContent
instead, as it can only output text and doesn’t generate any HTML.
“If you don’t generate HTML, there’s no way to insert JavaScript,” Zell explains. You’ll seein the DOM, but the JavaScript won’t run.
6. Compartmentalize your application
Web applications are often built as single applications, deployed in a single origin within the browser. For example, an app running inhttps://app.example.com
offers public parts, authenticated parts, and even administrator features. However, Philippe De Ryck warns that a successful attack against the public part of the application automatically affects the other parts as well, potentially causing significant damage.
“在后台,经常独立应用程序split up into smaller components, each running individually,” he explains. “We can apply a similar pattern to front end applications. For example, we could separate the front end application into a public part, an authenticated part, and an admin part. By deploying each part in a separate origin—for example,https://public.example.com
,https://users.example.com
, andhttps://admin.example.com
—we can ensure that the browser isolates these applications from each other.”
Compartmentalization is key to reducing the impact of client-side vulnerabilities, Philippe believes. “Proper compartmentalization would prevent an XSS vulnerability in the public part of the application from automatically compromising the user information as well.”
You might also like:Deconstructing the Monolith: Designing Software that Maximizes Developer Productivity。
7. Be careful when using Google Tag Manager
UsingGoogle Tag Managermakes it very easy to add the latest tracking scripts, that chatbot the support team wanted, andHotjarfor user analytics.
But James Hall points out that while it’s tempting to allow everyone in an organization (and sometimes outside) access to your Google Tag Manager, you need to be careful.
“If a Google account gets hacked, it’s possible to add any arbitrary JavaScript to your website,” he warns. “A sophisticated attack could take your users off to a fake payment page for them to complete their order, sending money to someone else!”
8. Be more selective with third-party scripts
Even if access to your Google Tag Manager isn’t compromised, the tracking scripts you choose to add could themselves get hacked. The use of third-party libraries and open source components in JavaScript-based web applications is a common practice, but it opens you up to vulnerabilities you can only control to a degree.
“If you add the ‘flavor-of-the-week’ chat widget to your site, anyone gaining access to their servers can now modify your website,” James Hall cautions. “This happened to British Airways and Ticketmaster when they included a push notification library calledFeedify。”
James advises that being more selective about which third parties have access to your pages will also help you comply with the EU’sGeneral Data Protection Regulation (GDPR)。The less information you’re giving away, the less you’ll need to make people aware of in your privacy policy, which means there’s a lower chance of violating GDPR.
Instead of having other third parties host your JavaScript framework, James also recommends considering getting Shopify to host it for you.
“They’ll do a better job at keeping you safe from any nasties than automatically hotlinking the latest version of an open-source dependency,” he suggests.
You might also like:What App Developers Need to Know About GDPR。
9. Audit your dependencies
You likely use many local build tools to create your front end, like SCSS plugins, for example. James Hall advises making sure you periodically runnpm audit
to show a list of vulnerable packages and upgrade them to avoid including security issues into your built JavaScript files inadvertently.
If you use GitHub, it will now flag vulnerable dependencies, and there are also alternative services likeSnykthat can check your source code automatically and open pull requests to bump versions.
Finally, if you’re building a theme for a client without Google Tag Manager access, James recommends performing a quick audit with a tool likeBuiltWith。
10. Use Subresource Integrity for third-party CDN hosting
Sometimes you can’t avoid third parties, however. Snyk’s Liran Tal points out that we often use externally-hosted libraries for fonts and CSS and import them to web apps with a content-delivery network (CDN).
“What would happen if someone were to gain access to the code of these libraries and replaced them with their own malicious version?,” he asks. “What would happen if the network medium was compromised or found to be insecure? Our own source code could even get compromised by attackers gaining access to a build server or to the cache or storage of our own code that’s being delivered from a CDN!”
To help solve this problem, Liran suggestsSubresource Integrity, a spec that provides proof of integrity of the resource being used in a web page and conveys that its content hasn’t been tampered with. Resources are declared using an integrity attribute that makes use of a cryptographic hash that the browser validates before making a functional use of the resource.
James Hall agrees and says Subresource Integrity is great for ensuring that the asset is identical to the one that you intended to include. This is a checksum that makes sure your script is the same as it was:
11. HTML encoding is not enough
Ilya Verbitskiy, co-founder of WebStoating, an agency helping companies to create a successful online business, recommends paying special attention to HTML encoding.
“It works well if a user’s input is placed within an HTML tag, for example Ilya points out that, for example, the following snippet is dangerous: It is dangerous because Another dangerous code might look like the following: In this case, This will cause trouble for users since the script will be executed once the user will click it. “Writing all the encoders to prevent XSS is not an easy task,” Ilya admits. “First, the library should support different execution contexts. It must understand different encoding supported by browsers and be aware of potentially dangerous HTML attributes that must be filtered out.” Ilya recommends using libraries that have already implemented recommended XSS protection techniques and are freely available: ‘Layered security’ or ‘layered defence’ are well known approaches in the cybersecurity space and describe the practice of combining multiple security controls to protect data. Ilya Verbitskiy says it’s applicable to front end security as well. “Even if the site was compromised via a XSS vulnerability, we must minimize user damage,” he advises. “The usual result of an XSS attack is that scripts are being injected into a vulnerable webpage,” Ilya explains. “The script either steals a user’s cookies and data from local and session storages, injecting a keylogger or even doing cryptocurrency mining. Most attacks require a channel to communicate between the hacker’s server and a victim. The communication channel might be an AJAX call, an All modern browsers have already implemented a solution:Content Security Policy (CSP), an added layer of security that helps to detect and mitigate certain types of attacks, including XSS and data injection attacks. To enable CSP, you need to configure your web server to return the If your website URL is Alternatively, you can define a policy using the Content Security Policy provides a lot of directives to help you define the policy that works best for your project. Some of the most widely used directives include default-src, child-src, script-src, style-src, img-src, connect-src, etc. Ilya recommends making sure you always define default-src as a fallback in case you forgot a directive. You might also like:Mobile Design Trends in 2019。 Finally, be really mindful of the data you’re exposing to the front end in your code. “Making use of product JSON on the product page may be beneficial in some cases, but it can also mean you’re displaying what should be private merchant data to the frontend,” cautionsKelly Vaughn, founder ofThe Taproom Agency。“A good practice is to store this sort of data in a metafield, as each unique metafield has to be manually given permission to be readable via the API.” And if you’re using source control for theme development such as GitHub, always keep your API keys hidden, Kelly recommends. Making your config.yml or .env file available on GitHub gives anyone access to your store’s theme (and any additional permissions you allowed via the private app). Also only allow access to the features you truly need for an app. If you’re using a private app just to build or make changes to a theme, you should disallow all access except for read/write themes. Security is more important than ever before. Breaches can happen to anyone, whether it’s a large corporation or a small site. We need to be careful not to expose customer data, and we need to be aware of the many attacks that are possible and the errors that can happen when deploying a website or app. Modern JavaScript frameworks take care of a lot of the risk, but they can’t be relied upon entirely. Customers expect their online experience to be safe and that any information they provide will not be stolen or used in ways they didn’t expect. Clients in turn expect you to protect their sites, their data, and their customers. Follow the various ways you can secure sites yourself and reduce vulnerabilities that we explored in this article and you will foster trust and show your client that you take security seriously. How do you prioritize security?Share your thoughts in the comments below. Get design inspiration, development tips, and practical takeaways delivered straight to your inbox. No charge. Unsubscribe anytime.。It also works for the data that is used within HTML attributes. But HTML encoding won’t help you when you are rendering a user’s input inside a
tag, or in a URL, or within an event handler like
onclick
oronerror
。”
Model.UserInput
might bealert(document.location)
or:eval(String.fromCharCode(105,102,40,33,119,105,110,100,111,119,46,120,41,123,97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,108,111,99,97,116,105,111,110,41,59,119,105,110,100,111,119,46,120,61,49,59,125))
Model.UserLink
might be:javascript:eval(String.fromCharCode(105,102,40,33,119,105,110,100,111,119,46,120,41,123,97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,108,111,99,97,116,105,111,110,41,59,119,105,110,100,111,119,46,120,61,49,59,125))
12. Implement Content Security Policy
tag, an iframe, or a web-socket. Your aim should be to break the communication channel.”
Content-Security-Policy
HTTP header that helps you mitigate XSS risks by declaring which resources are allowed to load. For example:Content-Security-Policy: default-src 'self'; child-src child-src 'none'; img-src https://cdn.example.com 'self'; object-src 'none'
https://example.com
, CSP blocks usage of the,
, and
tags, as well as frames and web workers. The browser will only load images from
https://example.com
andhttps://cdn.example.com
。All other resources, for example, scripts and stylesheets, have to be hosted onhttps://example.com
。tag within your HTML page:
13. Be mindful of what you’re exposing
Security fosters trust
Let’s grow your digital business