Ihor
Feoktistov
CTO at Relevant

React.js Security Guide: Threats, Vulnerabilities, and Ways to Fix Them

Cybersecurity

Cybersecurity is intangible at first glance. However, all the unique features, attractive UIs, and seamless performance won’t matter unless your app is secure. These saddening statistics prove the previous statement: 

React.js Security Guide statistics

As you can see, without a proper security layer in place, your application will often fall victim to hacks and attacks, leading to numerous re-testing and re-development rounds. This also applies to applications based on React.js, the second-most in-demand web framework in 2020. 

Given that, if React.js is a prominent part of your app’s tech stack, you’re in the right place. As a company that has delivered more than 100 web applications with a JavaScript tech stack, we know a thing or two about how to secure a React.js web application. That’s why we gathered these practical tips for building secure React.js apps.

The most common React.js cyberattacks 

According to Snyk, every time React.js makes an update, new security vulnerabilities that go unnoticed crop up. To this end, it’s impossible to encompass all possible cyberattacks that React.js (as well as any framework) might be vulnerable to. However, these four are the most common ones. Let’s explore them in more detail. 

Cross-Site Scripting (XSS)

XSS is an injection of a malicious script into the code of a web application. The browser picks up this script and interprets it as legitimate. After that, the malicious code is executed as a part of an app. Here’s what the process looks like when the attacker injects an XSS code to steal users’ and visitors’ session cookies: 

Cross-Site Scripting (XSS) in React.js security

A successful XSS attack might enable the perpetrator to capture user input to steal their credentials, steal sensitive data from the app’s pages, send requests to servers, and beyond. More often than not, an XSS that goes unnoticed can lead to the full compromise of an app. 

Like most modern frameworks, React.js offers built-in defenses against XSS. Unfortunately, they are not 100% effective. XSS remains the most common JavaScript attack.

XSS is often confused with SQL injection (SQLi). However, the two are not the same thing. Though both imply malicious code injections, XSS makes users vulnerable while SQLi targets the application itself. 

Distributed Denial of Service (DDoS)

DDoS attacks overwhelm a web app infrastructure with more traffic than it is able to handle. Their purpose is to make an application inaccessible and unavailable to its users. Some of the most common ways to conduct DDoS attacks are UDP, ICMP, SYN and HTTP request flooding. Because a server and a firewall must process each request and respond to it, an attacker tries to exhaust resources, such as memory and CPU processing time.

Cross-Site Request Forgery (CSRF)

To commit a CSRF attack, a perpetrator crafts an email or a web page that will convince a victim to perform a state-changing request on the web app. It can be transfering funds or granting permissions, for example. Usually, an attacker exploits links or invisible (0 by 0 pixels) images to conduct a GET request or a form for a POST or PUT request. JavaScript code provides another way to craft those requests, but it will be prevented by any modern browser unless it’s explicitly allowed on the web app server.

XML External Entity Attack (XXE)

XXE attacks occur in web applications that use XML (Extensible Markup Language), the text-based language utilized for storing and organizing data in a web app. For transforming XML into readable code, an app needs an XML parser. Such parsers often fall victim to XXE injections. Using XXE, a perpetrator can perform a CSRF or DDoS attack.

The problem is that XML parsers are vulnerable to XXE by default, so it’s up to your development team to make sure that the code is free from such vulnerabilities. 

React.js security vulnerabilities and solutions

As described above, XSS, DDoS, CSRF, and XXE are the most common cyberattacks when it comes to web applications. But what exactly allows malicious code to slip into such apps? Below, we will explore security flaws specific to React.js, those common for all frameworks, and ways to fix them both. 

Vulnerabilities specific to React.js

When building a React-based application, you should watch out for the following vulnerabilities: 

  • Server-side rendering
  • Dangerous URI schemes
  • “DangerouslySetInnerHTML”
  • Escape hatches 

Let’s discuss each one in more detail. 

Server-side rendering

One of the most prominent advantages of React is SSR (server-side rendering). This feature ensures a faster page load, better performance, and ease of incorporating SEO. Unfortunately, it makes React apps prone to attacks. Here’s why.

Most React apps use Redux for app state management, which uses JSON, a lightweight data-interchange format, to set an initial app state: 

React apps use Redux for app state management

This is dangerous because “JSON.stringify” will not recognize sensitive data or XSS code. Although the example above also has code to mitigate simple XSS attacks, it’s not a silver bullet by any means. 

It’s also worth mentioning that SSR opens a way for attackers to exploit vulnerabilities in third-party NPM packages.

200+ companies from 25 countries outsourced software development to Relevant

We provide companies with senior tech talent and product development expertise to build world-class software. Let's talk about how we can help you.

Schedule a call
Solution

Dangerous URI schemes

URLs without a “http:” or “https:” protocol can allow malicious code to sneak into your React application. If such a URL is hardcoded, it’s harmless. But if it’s provided by a user, it poses a potential React XSS threat. 

Unfortunately, React.js security features neither prevent the use of such links during development nor provide built-in defenses against their potential threats. This means that it’s up to your development team to ensure that they are safe. 

Solution
  • Avoid URLs as input. For example, build an application that accepts YouTube video IDs instead of YouTube video URLs.
  • If the above option isn’t possible, use the proven third-party tools, like Sanitize URL NPM package to sanitize these potentially dangerous links. Ensure that all your development team members use the same sanitation code. 

“DangerouslySetInnerHTML” 

Sometimes developers have to render HTML code coming from untrusted sources (user input, for example). The easiest way to render it in a browser is to assign it to the inner HTML attribute directly. Since it may cause XSS vulnerabilities, React.js limits its use by engaging the “dangerouslySetInnerHTML” property. 

Unfortunately, this property doesn’t guarantee the code’s security and renders all the data whether its benign or dangerous. In fact, the role of “dangerouslySetInnerHTML” is to inform a developer that the code assigned to it might be insecure. Besides, it’s assumed that developers won’t use this feature without reading the documentation. 

Solution
  • Always sanitize dynamic values assigned to the “dangerouslySetInnerHTML” property with DOMPurify. Encapsulate this behavior in a security component and encourage developers to use it. 
  • Avoid using user-generated properties with the “createElement” API.

Escape hatches

One of the key advantages of React is that it saves developers from manually putting data into the browser DOM to render components. However, there are cases when developers need direct access to the DOM elements. 

For such scenarios, React offers escape hatches, such as “findDOMNode” and “createRef.” 

Since an escape hatch returns the native DOM elements with their full API, the application can manipulate the element directly without going through React. This can lead to an XSS vulnerability. 

Solution
  • Don’t output the HTML code, only text.
  • When a direct output is necessary, use proper DOM APIs to generate HTML nodes.
  • Sanitize data with DOMPurify before putting it into the page.

Vulnerabilities common for all web frameworks

The React.js security fundamentals listed above are effective. But when it comes to preventing some of the most common cyberattacks, they are no panacea. Though React.js stands out from the other libraries and frameworks, it isn’t immune to security concerns common for all frameworks, such as: 

  • Authentication issues
  • Broken access control
  • Security misconfigurations
  • Unreliably incorporated protection layers
  • Lack of End-to-End encryption
  • Third-party vulnerabilities 

Authentication issues

Compared to the server-side, the client-side is exposed to multiple actions performed by users. That’s why the client-side authentication and authorization often fall victim to security flaws. So, how can you prevent these flaws? Follow the checklist below:

  • Even the smallest mismatch in the authentication of different IDs and passwords will lead to unauthorized users accessing authentication information. To this end, to avoid mismatches, make sure that the domain “WWW” header has a realm attribute that authenticates different users with separate code variables.
  • Use authentication methods properly. For example, make sure that the “realm” attribute in the WWW-Authenticate header is set properly.
  • Introduce multi-factor authentication.
  • Use cloud-native authentication, like Azure AD or AWS IAM.
  • Ensure solid credential recovery procedures. 

To further secure your React authentication, consider the following:

  • Utilize OAuth and JSON Web Token (JWT). For building a more secure authentication wall, the latter can be used along with the Redux authentication. 
  • You can also consider using Passport.js.
  • Consider using the React Router library to secure your app against URL-related vulnerabilities. 

Broken access control

Make sure that all the limitations and restrictions on authorized users are sufficient. Ignoring this rule can lead to any user being able to access unauthorized control features. Given that, consider the following: 

Why these 200 tech companies & startups outsource to Ukraine
Download the whitepaper
  • Provide role-based authentication only.
  • Restrict functionality access.

Security misconfiguration & insufficient monitoring

Unfortunately, no framework follows all security measures by default. React is no exception. Vulnerabilities often occur as a result of incomplete security configurations or improperly built HTTP headers. Given that, it’s critical to incorporate security testing into the development process and conduct regular monitoring for security flaws during the entire lifecycle of your app.

So, how can you stay vigilant to your React app’s security configurations? Below are some tips:

  • Configure your servers according to the documentation and best practices. 
  • Periodically revise security-critical configurations so they are set according to official documentation and prevent newly discovered vulnerabilities in that particular software.
  • Conduct regular updates and upgrades in a timely manner.

Unreliably incorporated protection layer 

Even a mismatch in APIs may lead to sensitive data exposure. To prevent this, follow our tips: 

  • Disable automated form caching and auto-filling features in security-critical UI components.
  • Update the encrypted algorithms as soon as the latest version is available. 

Lack of end-to-end encryption

Providing end-to-end encryption is critical. This type of encryption secures the data exchange between end users, being a user’s browser and your servers or between your distributed services. The lack of the end-to-end encryption accounted for the majority of data breaches in 2019. 

Third-party vulnerabilities

In many cases, React alone has nothing to do with your app’s vulnerabilities. The use of third-party libraries, modules, APIs, and frameworks might allow security flaws to sneak into your application. Luckily, implementing the React web app security solutions listed below will protect your app against these “externally originated” vulnerabilities: 

  • Before incorporating any third-party components into your application, scan them for vulnerabilities.
  • Conduct updates manually.
  • Audit NPM packages for known vulnerabilities using npm-audit.
  • Make sure that old versions of components are patched with the newer ones.
  • Keep away from malicious packages.

React.js security checklist on other vulnerabilities and threats 

Threat/
Vulnerability
Measures 
DoS and DDoSDuring and after the development stage, scan the entire React app for known DDoS vulnerabilities. Install visitor identification. Use CAPTCHA or JS tests against DoS.Consider tools like Cloudflare to mitigate possible and ongoing DDoS attacks. 
CSRF and arbitrary code executionUse JWT tokens for session management.Make sure that your application reads only the stored CSRF tokens.Ensure it generates only relevant headers upon authentication.
XXEAvoid serialization of confidential data.Make sure that the XML parsers are updated.Use SAST tools to scan your code for XXE.
SQLiValidate API call functions against respective API schemas.Escape all incoming data or use proven ORMs.

Let us help you secure your React.js app

As you can see, securing a React web application is a complex process, which requires several (it depends) cybersecurity experts specializing in React.js. Still, if you don’t have these in your in-house team, you have at least two options to choose from. You can hire cybersecurity developers them from scratch or outsource the task to a software development vendor, such as Relevant Software.

Due to our security-first thinking, we have helped multiple companies comply with the OWASP’s Top 10, GDPR, and ISO 270001. With React.js and Node.js being our main tech stack, we’ve built more than 100 secure web applications, which you can find in our case studies

With that being said, whether you are looking for QA engineers to test your existing React.js solution or need experts to build one from scratch with all security measures in mind, don’t hesitate to drop us a line

Written by
Ihor Feoktistov
CTO at Relevant
I make sure our clients get the highest code quality and the best tech talent on the market. I am also a Software Engineering Advisor for startups. Let's connect.

What are you looking to do?

Do you want a price estimate for your project?