Monitoring Third Party Dependencies In React Projects

OpenReplay Tech Blog - May 17 - - Dev Community

by Martin Kobimbo

Modern web development relies heavily on third-party dependencies, these dependencies are convenient and efficient for modern web apps but they also tend to bring in performance issues, failures, and security issues in our web apps. This article explains the significance of monitoring third-party dependencies within React applications and how to identify their effects on web performance.

Session Replay for Developers

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — an open-source session replay suite for developers. It can be self-hosted in minutes, giving you complete control over your customer data.

OpenReplay

Happy debugging! Try using OpenReplay today.


Monitoring third-party dependencies in React

Introduction

Prerequisites

  • Javascript
  • React
  • Node.js and NPM
  • Bash

What are third-party dependencies?

These are external resources integrated into web apps to accomplish tasks or provide functionality beyond the core capability of the web application. These dependencies include libraries, APIs, and services, and they provide web applications with features such as data retrieval, user authentication, and UI enhancements.

In React, common third-party dependencies are Material UI for User interfaces, Redux for state management, and the PayPal API for payments.

These dependencies save developers a lot of time and effort, allowing them to focus on the project's more important core functionalities. One key feature of third-party dependencies is their flexibility and customization. Developers can adjust configurations and integrate them into codebases.

Most of these third-party dependencies have vibrant developer communities and good documentation. This ensures that developers have valuable support channels to help them overcome challenges and problems associated with the dependencies.

The types of third-party dependencies

Libraries are Pre-written collections of code that provide some specific functionality. Most if not all companies and developers use libraries in their work as no one wants to "re-invent the wheel". Libraries encompass a range of tools and components that cater to the different aspects of front-end development like state management and data manipulation.

Examples of some common libraries for front-end development are Material UI, React Bootstrap, chakra UI, and Ant design.

APIs, or Application Programming Interfaces, are a set of rules that allow different applications to communicate with each other and exchange relevant data. They serve as a bridge between two applications and allow your application to rely on external services and functionalities that other third-party providers have developed.

Developers can choose from a variety of APIs. Whether they need to access payment gateways like Stripe or PayPal or integrate with social media platforms like Instagram, APIs offer the developer many possibilities to enhance their applications.

Microservices are small independent applications that work with other different microservices to implement a larger collective app functionality.

When selecting dependencies to use, it is important to consider various factors like the performance, compatibility with your tech stack, security considerations, and the long-term viability of the said dependency. This will help minimize potential drawbacks.

Using third-party dependencies can introduce risks and challenges that developers need to consider.

The challenges and risks associated with third-party dependencies

Let's explore some of the problems associated with relying on external libraries, APIs, and services.

Performance is a critical aspect of any application's success. When it comes to performance issues caused by third-party dependencies, it's important to consider the negative effects on user experience and loading times. Having a lot of dependencies can significantly bloat a web application, resulting in slower performance and frustrating user interactions. You should carefully select your dependencies to ensure a seamless user experience and streamline your app's performance.

In addition to optimizing dependency size, other factors, such as caching strategies and code efficiency, play an important role in maintaining optimal performance.

Security is very important when managing third-party dependencies. Hidden malware and unpatched vulnerabilities pose a significant risk to your application's integrity and user data. We could mitigate these risks by keeping dependencies up to date, conducting security audits, and implementing clean, secure coding practices.

Service downtime can negatively impact your application's availability and user satisfaction. As a developer, you must be prepared for API outages, vendor discontinuations, and unexpected changes. This is key to maintaining uninterrupted service to your users and clients.

To mitigate the impact of service disruptions, you have to implement failover mechanisms and alternative backup solutions, as well as have service-level agreements with your vendors.

Monitoring techniques

When it comes to monitoring third-party dependencies, developers can employ an array of techniques to ensure and maintain the security, performance, and reliability of their applications. In this section, let's look at various techniques for monitoring third-party dependencies.

Active monitoring is continuously tracking and assessing third-party dependencies to find vulnerabilities. Active monitoring includes version monitoring, usage analytics, integration testing, and security audits.

Version monitoring involves Tracking the dependency versions and being notified of updates with potential changes. Monitoring versions make sure developers can address compatibility issues and implement the necessary updates.

Usage analytics involves monitoring how your application uses dependencies to identify underutilized libraries or performance issues. It allows you to note how applications utilize dependencies. It allows identifying areas that can be improved on or show performance bottlenecks.

Integration testing means continuously testing how your application interacts with dependencies to ensure seamless integration. It is important because it ensures developers can detect and resolve integration issues promptly, minimizing problems during deployment.

Security audits involve regular security audits of your application and dependencies to identify vulnerabilities. These regular audits enable developers to implement security measures and patches quickly.

In addition to active monitoring, proactive strategies play an important role in ensuring the reliability of apps that rely on third-party dependencies. These proactive strategies are continuous monitoring, vendor communication, and rate limiting.

Continuous monitoring involves integrating dependency monitoring into your CI/CD pipeline to detect and resolve issues early in the development process.

Vendor communication simply means establishing communication channels with vendors to stay informed about updates, planned outages, and security vulnerabilities. Developers can address issues earlier by maintaining communication with vendors and deliver updates on time.

Implementing rate limiting and throttling mechanisms is important to avoid overwhelming dependencies and impacting your application's performance.

To optimize your monitoring efforts as a developer you can consider setting up alerts for security vulnerabilities to enable a proactive response. You can also establish a regular review regime for dependency usage and updates. Lastly, it is advisable to document your monitoring procedures for future reference and knowledge sharing.

Implementation Strategies

Various practical approaches exist for managing third-party dependencies. In this section, we will look at a simple implementation of npm audit and the Webpack bundle analyzer.

How to monitor security vulnerabilities with npm audit. This command retrieves a report of the vulnerabilities in an NPM package, including any vulnerabilities in third-party dependencies.

  1. First, install NPM and Node.js if you don't have them on your machine. In your command line interface, type the command;
sudo npm install -g npm
Enter fullscreen mode Exit fullscreen mode
  1. Make sure you are in the root directory of our project, and in the command line interface, type the command;
npm audit
Enter fullscreen mode Exit fullscreen mode
  1. The output will display something like this;
                       === npm audit security report ===

# High Severity Vulnerability

Package: color-convert
Severity: High
Vulnerability: Arbitrary Code Execution
Description: Color-convert versions prior to 2.0.0 are vulnerable to arbitrary code execution due to improper input validation. An attacker could exploit this vulnerability to execute malicious code on the system.
Recommendation: Update color-convert to version 2.0.0 or later. Alternatively, implement proper input validation and sanitization in your code.

# Low Severity Vulnerability

Package: cross-env
Severity: Low
Vulnerability: Denial of Service
Description: Cross-env is susceptible to a denial of service attack due to inadequate error handling. An attacker could exploit this vulnerability to cause the application to crash, resulting in a denial of service.
Recommendation: Upgrade to cross-env version 7.0.4 or later, which addresses this vulnerability by implementing robust error handling.

# No Vulnerabilities Found

Package: react-dom
No vulnerabilities found.

Package: react
No vulnerabilities found.
Enter fullscreen mode Exit fullscreen mode

To address some of these vulnerabilities you can perform updates, remove the said dependencies altogether, and look for alternatives.

Monitoring the bundle size with Webpack bundle analyzer. It is a tool used to identify large and redundant modules contributing to bundle size.

  1. First, install the Webpack bundle analyzer using the command;
npm install --save-dev webpack-bundle-analyzer
Enter fullscreen mode Exit fullscreen mode
  1. Then create or modify your webpack.config.js file;
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  // ... other Webpack configuration
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: 'static', // Generates an HTML report
      generateStatsFile: true, // Optionally creates a stats.json file
    }),
  ],
};
Enter fullscreen mode Exit fullscreen mode

require imports the BundleAnalyzerPlugin from the webpack bundle analyzer package.

module.exports exports a configuration object for Webpack. In the configuration we have here, it specifies the plugins to be used.

  • analyzerMode: 'static': Generates an HTML report used to analyze the bundle.
  • generateStatsFile: true: Creates a JSON file that contains statistics about the bundle.
  1. Run Webpack with a build command;
npm run build
Enter fullscreen mode Exit fullscreen mode
  1. Then lastly open the HTML report at dist/stats.html. Here you can analyze your file sizes and dependencies so that you can identify bloat and optimize bundle size.

Useful tools for dependency management

Below are a few listed tools for managing dependencies.

Snyk is a cloud-native tool that helps developers secure dependencies, infrastructure as code, and containers. It does this by continuously scanning for vulnerabilities and providing insights. Snyks interface and robust scanning algorithms make it one of the best choices for teams looking to enhance the security of their applications.

OWASP Dependency-Check is a software composition analysis tool that detects vulnerabilities within a project's dependencies. It works by scanning a project's dependencies against a database of known vulnerabilities, then it alerts developers to all potential security risks.

Let's take a look at two tools used for security purposes.
WhiteSource is a tool that pinpoints the vulnerable functionality in your code. It goes beyond the traditional vulnerability scanning we have discussed so far in this article. WhiteSource's advanced reporting capabilities provide developers with actionable insights to solve all the problems in their applications.

AquaSec is a security tool that utilizes machine-learning techniques to analyze container behavior. It only allows observed behaviors and capabilities to be accessed. By monitoring and analyzing containers in real time, Aquasec can mitigate threats before they impact your application. This proactive approach makes AquaSec a valuable asset for developers and organizations looking to secure their containerized environments.

Each of these tools listed, as well as those not listed in this article, offer unique features to help developers effectively manage dependencies and beef up the security in their applications. As a developer, it is important to evaluate them based on your specific requirements and use cases to select the perfect fit for your organization.

For further research and exploration, I recommend looking at documentation, tutorials, and case studies provided by the tool vendors. Going into forums and Reddit discussions on these tools to hear the experiences of other users can provide valuable insights about their effectiveness.

You can follow the two links below to read more about dependency monitoring.

Dependency monitoring in React.
Monitoring third-party dependencies in React and Node.js.

Conclusion

The goal of monitoring third-party dependencies is to ensure the performance, reliability, and availability of external resources integrated into web applications, by monitoring these dependencies. The main objectives of this monitoring are to identify and resolve performance bottlenecks for a great user experience, to prevent service downtime, and to maintain site reliability.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .