Security Concepts
Updated
6 min read

Security Concepts for Developers: Trivial Packages

Discover the hidden risks of using trivial packages in development. Learn how small, seemingly insignificant dependencies can lead to significant security vulnerabilities.

Security Concepts for Developers: Trivial Packages

In March of 2016, the widely known and used JS compiler Babel, was broken by a sole individual. The package, used by tech giants such as Facebook, PayPal, and GoDaddy was not brought down by a malicious hacker but rather due to the removal of the left-pad module within the npm registry that Babel relied on. 

This module that acted as the straw that broke the camel’s back was a mere eleven lines of elementary code that prefixed padding to strings. Here it is in its entirety:

module.exports = leftpad;
function leftpad (str, len, ch) {
  str = String(str);
  var i = -1;
  if (!ch && ch !== 0) ch = ' ';
  len = len - str.length;
  while (++i < len) {
    str = ch + str;
  }
  return str;
}

The developer of the left-pad module, Azer Koçulu, intentionally removed all of his 273 contributions to the registry after a dispute over another one of his packages named ‘kik’. The popular messaging application with the same name, Kik, via a contracted trademark agent by the name of Bob Stratton, had reached out to Koçulu with a request that he release the package name. After Koçulu declined, Kik threatened legal action and also contacted npm directly.

Ultimately, npm took the side of the company and turned the name over to Kik, leading to the disappearance of the left-pad function that so many projects relied on.

Examples of Trivial Packages

The left-pad module meets the criteria of what is known as a trivial package. A package is considered to be trivial if it is under 35 lines of code and simplistic. The terminology, coined by a research paper written by Concordia University, is used to describe dependencies that could easily be written by developers themselves. 

In the analysis provided by the same research paper, performed across more than 230,000 npm packages and 38,000 JavaScript applications, it was discovered that 16.8% of packages could be classified as trivial.

Some noteworthy trivial packages include:

  • isarray: Currently at a rate of 410 million installations per month and a dependency of 2,146 other projects, this module simply checks whether a given value is an array. While the package does provide backward compatibility for legacy systems, the native Array.isArray method was introduced in ECMAScript 5 (ES5), which was released in 2009 and has been fully supported by all modern browsers since July 2013.
  • is-windows: Merely checks if code is being run on Windows. Even though process.platform, a native Node.js feature that checks for multiple operating systems exists and has since its initial release – the is-windows package still has over 18 million weekly downloads.
  • is-even/is-odd: With 644,000 and 1.2 million downloads per month respectively, these modules simply do what their names imply. The remainder (%) operator has been available from the very beginning of the JavaScript language.

Trivial Choices with Substantial Impact

When you are facing a deadline, it may be tempting to use a prebuilt solution. Code reuse, in theory, is a great thing, as it allows a “work smarter, not harder” approach to development. Trivial packages, however, take this mentality to the extreme by outsourcing even the smallest tasks in your code.

In the study done by Concordia University, amongst the surveyed Node.js developers, the main response received for why trivial packages are used was that developers just want to use code that is well-tested and works. However, though over half of the developers stated that these packages are “well implemented and tested”, only 45.2% of trivial npm packages actually have tests. Additionally, 10.9% of all the applications evaluated in the study used trivial packages.

Trivial packages also, on average, receive less maintenance and updates and are slightly less likely to use version pinning. This lack of attention can lead to security issues such as dependency confusion and package hijacking attacks. Revisiting the left-pad fiasco, an inventory of all of Koçulu’s removed packages was taken, and within just a few hours after being unpublished, 230 of the packages were replaced with name squatting packages.. If the name squatter had malicious intent, anyone that did not remedy the situation brought about by the unpublished packages could have been compromised by a supply chain attack.

Despite these security threats, 57.9% of developers surveyed did not consider using trivial packages as bad practice.

The Chain Reaction

Even these trivial packages have their own dependencies and those dependencies are dependent on other modules and libraries as well. Over 40% of trivial packages have at least one dependency, with 11.5% having more than twenty. This creates a chain reaction of dependencies, each one adding complexity and danger, neutralizing the intended use in the first place – simplicity.

This bloat in dependency overhead can create an overly complex dependency management process. Every single entry added to your package.json file can be a potential attack vector for supply chain attacks, expanding your attack surface exponentially due to the chain reaction of third-party reliance.

Even in the absence of a dependency confusion or package hijacking attack, this interwoven web can present issues all by itself. After the left-pad incident, npm released a statement that disclosed measures to make it more difficult to remove a package from their registry if doing so would break other packages..

This has since been abused. In January, a group of npm users uploaded a package named ‘everything’. This package caused a Denial of Service (DoS) for anyone that installed it, as it made itself dependent on every other public package in the registry. Due to the changes implemented by npm in regard to unpublishing, even though the developer of ‘everything’ wanted to remove the package after things got out of control – he was unable to do so himself. npm had to intervene themselves. 

This is not even an isolated incident, in 2023 the no-one-left-behind package used the same concept of mass dependency and in 2012 the hoarders package attempted the same thing with modules.

Trivial Package Risk Mitigation: A Checklist for Developers

Although even the most basic packages can reduce development time, the dangers greatly outweigh the benefits. To mitigate your risk level, there are several manual steps you can take to review your environment - you should be aware of each and every dependency your project relies on and their functionality. Create an accurate ledger or update an existing one and proceed with the following checklist:

Question the Maintenance

View the release history of the dependency to ensure trustworthy entities actively maintain it. Those developed by large organizations with good standing or well known open source developers are more likely to be reliable. Consider how often updates are released and how active the commit history is. Are issues resolved in a reasonable time?

Research the vulnerability history of a dependency. Analysis of past vulnerabilities can give you an idea of how responsive maintainers are to security concerns. Thorough analysis can also give insight into vulnerabilities that have been persistent, even after patches were released. This can hint toward the level of security awareness behind the dependency.

Changes in ownership or maintenance should be investigated as changes can lead to unfamiliarity with the code base, inconsistent quality and security risks.

Evaluate Necessity

Ask yourself if the trivial package is providing something that you or your team could not implement yourselves. Even just the increase in time spent towards package management processes may very likely outweigh the initial time saved. Single functions should not be considered packages. Modules with a small set of functions should also be reconsidered.

Additionally, look for a natively integrated equivalent to reduce your reliance on third-party software. Is there a function within the standard library if you target more recent releases?

The trivial package in use may not even be written correctly or optimally. Review all packages with a small number of lines to see if they could be rewritten to increase performance. Even though Concordia University deems trivial packages to be less than 35 lines, this is not a stringent rule that must be adhered to. Take a liberal stance on what constitutes a trivial package when it comes to file size.

Furthermore, this variance in code quality between different contributors can create weak or vulnerable areas in your project. Even though they may have been pieced together in a way that works, this does not mean that they are interconnected in a manner that is secure.

Remove any dependencies that are no longer required for your project to work properly. These may include ones that were only used for development and are not necessary in a production environment. Instead of importing trivial packages into your project, directly integrate (vendor) the code into your project (with the appropriate license comments). These measures will reduce the supply chain attack surface of your project.

Tools can help

At Arcjet, we use Socket to analyze all our dependencies. This includes an alert on trivial dependencies so we can deliberately review any occasions where we use them.

Conclusion

By reconsidering the use of these trivial packages, you can reduce the risk of a security breach that could be attributed to something as insignificant as a couple minutes saved.

Adopting manual review practices can help reduce your attack surface and avoid unnecessary complexity when it comes to package management.

As third-party component integrations become more widespread - staying vigilant and proactive in dependency management will continue to grow in importance.

Related articles

Subscribe by email

Get the full posts by email every week.