How to Secure React.js Application
React has taken the world of frontend web development by storm, skyrocketing in popularity in record time. Some say it’s because Facebook is behind it, while others attribute its success to its reactive nature and deliberate decision not to include everything, forcing users to include 3rd libraries, unlike, say, Angular. Regardless of the reasons, one thing is for certain: React isn’t going anywhere anytime soon.
Now, don’t get me wrong – React isn’t perfect. It’s not a one-size-fits-all solution and can come with some compromises (good luck with SEO if you’re using client-side rendered React apps). But for the majority of modern front-end needs, it does a darn good job. That’s why it’s important to make sure that such a widely used technology is being used in accordance with React security best practices.
Common Vulnerabilities in Web Applications
If you would like to understand how to handle the security in react applications, you need to understand some of the common vulnerabilities to watch out for and know who can prevent and react to security breaches. Here are some of the vulnerabilities you should know:
One of the most common vulnerabilities, XSS, is basically the injection of malicious JS code in the user’s browser via a web application. There are several types of XSS attacks, but to put it simply, malicious code can come from anywhere our frontend reads some data from:
- Reflected XSS – The user clicks on a URL crafted by the attacker containing some encoded JS statements, which are then read & executed by our frontend
- Stored XSS – Attacked has injected the DB of our app with some malicious code, and when this data is returned by the backend, our frontend tries to display it and accidentally executes it
Normally, XSS is protected against by strict escaping of all potentially malicious inputs. In React, this escaping is done automatically when using JSX binding syntax, but still, the developer has the ability to disable this behavior and make the application vulnerable to XSS injection.
HTML & DOM Injections
There are some valid scenarios where we want to manipulate the underlying DOM structure directly, although, in the majority of cases, this is a signal that we are misusing React framework. Architectural concerns aside, this also introduces some potential security risks, just as in the case of usual XSS vulnerabilities.
Server-Side Render Injections
Similar to server-side SQL injections and similar, when using server-side rendered approach for React application, one may accidentally concatenate unsanitized strings to the output of ReactDOMServer.renderToString() and ReactDOMServer.renderToStaticMarkup() methods before sending it to the client for hydration.
This is something related not exclusively to securing React apps but any application in general. Developers should be careful about what libraries he includes in the project, as these libraries may have vulnerabilities on their own. Usually, this translates to some remote code execution exploits in the case of backend code (Log4j vulnerability as an example) or to XSS vulnerabilities on the frontend side. I’m not even talking about some malicious packages in public NPM that were harvesting sensitive data of applications that were using them
Lazy Loading Modules
When an attacker starts analyzing web applications for vulnerabilities, generally, his first step is to try to use the application as it is supposed to be used and understand what components it has. Even though it is not something directly related to technical security measures, it is a good practice to limit the amount of code that is sent to the user’s browser. Although this is mainly done to speed up the loading of applications and to improve performance, one more positive side effect of this lazy loading approach is to limit attacker knowledge & understanding of, for instance, whether the app has some admin console or other private modules inside. This, again, is not a definitive mechanism (for example, when using a translation library like i18next attacker can manually inspect translation strings which are usually transferred as one big JSON file, and gain an understanding from there), but it can make attackers’ life a bit harder.
Many developers are not aware of common React security vulnerabilities, but it may be an eye-opening experience to see them being exploited in action. Usually, keeping in mind that all inputs not controlled by the developer himself may be potentially malicious and sanitizing it before usage should solve the majority of potential React native security issues. This, again, is related to all development in general, not only front-end development with React. It may appear that vulnerabilities on the client side of web apps may not be as critical as, let’s say, backend-side SQL injection allowing attackers to steal all the data from the database, or access role misconfiguration, allowing a malicious user to gain admin-like permissions, but even these JS & HTML injections may result in a disastrous reputational and financial loss for the business.
In case you have already been attacked, you may need to learn how did people react to the Equifax security breach. The case provides useful insights into how to handle security issues as they happen.