2

This is a question for software engineers who are tasked with managing the development cycle for a Web application using NPM packages for deployment on a customer's Intranet or the Internet.

This is not about what could theoretically be done managing security risks but what you are actually doing when bringing a commercial Web app to market.

If you think that you have good procedures in place to manage security risks, then please share your knowledge!

The answer should ideally outline the steps taken at various points in the development cycle. Example only, not exhaustive:

  1. Before we opt to install a package we assess trustworthyness. We [also review][do not review] secondary dependencies.
  2. We have selected developments tools [React][Angular][etc.] because [any security considerations][just developer preference]
  3. We [disable][do not disable] scripts when installing packages and we do this [...]
  4. Before production or development packages are accepted for wider use we do [...]
  5. For installed packages we monitor for vulnerabilities [by running npm audit every x days][by subscribing to monitoring service x][by using tool y]
  6. For any vulnerability found we do this [...]
  7. We [accept][do not accept] these vulnerabilities in dev packages [...]
  8. We [accept][do not accept] these vulnerabilities in production packages [...]
  9. When testing we [do][do not] monitor for network activity, CPU usage, and we also test [...]
  10. For release, vulnerabilites [are][are not] acceptable if [...]
  11. Also [...]

The sections below elaborate a bit more on the subject and specific concerns.


When setting up a Javascript/Typescript tool chain to develop a Web application using, for example, webpack, React and Jest, then you may be able to select a few "must have" and a few "wanted" NPM top level packages. But even when these are carefully chosen, there will usually be hundreds if not thousands of secondary, tertiary, etc., dependencies dragged in that fall outside of the "carefully chosen" realm and it is impossible to keep track of security and quality for all of them.

An npm audit will show vulnerabilities and it may be possible to get these to zero at least for the production code. But often interdependencies prevent an outright update of all packages, even when prepared to adapt for breaking changes. That means that, at least for the dev dependencies, vulnerabilities may remain and each vulnerability should be carefully considered before allowing development to continue. This could become a time consuming task as changes can be frequent.

I'm aware that there are commercial offerings that may assist in managing vulnerabilities but I have no experience with those.

Within the current software landscape of 2022, and with cybersecurity on everybody's mind:

If you are developing web applications commercially using NPM packages, what do you do to reduce risks?

In other words:

How do you setup your tool chain and manage the development cycle securely in a commercial setting where there are constraints on time and money?


Following the comment by @Flater, I'd like to elaborate on what I consider 'risks'.

My concern would not be breaking the build or breaking functionality due to altered behavior (i.e. unintended bugs in the package). The former is obvious and the latter should be caught during product testing.

Firstly, there is a risk of infecting the developer machine with malware; this could be ransomware or some other destructive software, i.e. software that deletes files randomly and spreads across the network. Would you install each NPM update onto an isolated machine and observe for x hours or x days before the update can be considered secure for deployment on developer machines? That's probably not workable. Use some third party tool that must flag the NPM package as secure? Which tool and how would that work? Update first onto a virtual machine then run the tool for a scan? Or trust that someone else would have discovered any misbehavior of NPM packages and simply run the update? Any other approach?

Secondly, there is the risk of delivering malware to the customer, i.e. hidden bitcoin miners, adware, spyware, possibly even Web apps that attempt to exploit browser vulnerabilities. Do you monitor the Web app for a while as part of the testing regime, for example running in the browser while monitoring network activity or looking out for "unusual behavior"? Do you monitor browser CPU usage as part of your testing?

Thirdly, less severe, there may be unwanted 'pings' (i.e. downloading an icon via CDN rather than locally) or other 'phoning home' incidents (i.e. usage monitoring) originating from packages that you may otherwise consider trustworthy. These could be something simply forgotten by the author or it is documented "somewhere" that this is expected behavior unless this or that configuration parameter is set. Web apps that are deployed onto Intranets of security conscious customers would question these incidents flagged by their firewalls. Although this may not turn out to be a security risk per se, random attempts to contact the Internet may be a risk to your reputation. Again, do you monitor network activity in a browser to ensure that no unwanted Internet contact is established? If there is contact from what you consider a trustworthy package, would you halt the release? Or add it to the release notes to explain it away and prepare to answer awkward questions asked by customers? Any other steps taken?

I realize that businesses and budgets for software testing and quality assurance vary greatly. So assuming you are not NASA and must remain competitive, what steps does your business take to minimize the above risks? Is there a "best practice" when it comes to NPM with it's unique authoring and delivery mechanisms, fit for 2022?


If you are downvoting then please comment why so that I can learn from it.

5
  • I have rephrased the question so that it is note purely opinion based. If there is a better place for this question then please advise in the comments.
    – J.R.
    May 1, 2022 at 23:28
  • Define "risk". Are we talking about security vulnerabilities? The possibility of a build breaking due to some package introducing breaking changes? Possibly altered behavior due to a package update? What is a reasonable approach varies based on the size and scope of the risks you're trying to shield against. As a clear example: NASA has a significantly more rigorous testing and approval process for its external dependencies than your average blog site. Different severities of consequences lead to different reasonable levels of protection needed.
    – Flater
    May 2, 2022 at 9:07
  • @Flater, thank you, good point. My concern is security vulnerabilities, not breaking the build or introducing breaking changes since these should be managed within the "normal" development cycle. I'll add a section at the end of the question to explain about the risks I am concerned about.
    – J.R.
    May 2, 2022 at 11:25
  • You may need to handle different threats in different ways. Parts that handle financial data may need much higher level of scrutiny than less sensitive parts. And have mitigation strategies, like the ability to revert to a previous version if some library misbehaves. Because whatever you do there is always the chance you will miss things. Also note that vulnerabilities are not exclusive to external code.
    – JonasH
    May 4, 2022 at 9:41
  • @JonasH I'm not sure if you can review parts more stringently and then assume that the whole is secure; i.e. it would not matter which part introduces malware into your dev environment. Reverting should be easy enough with source control but irreparable damage may already be done. True that vulnerabilities can be in internal code, but there should at least be no malicious attempts because you trust your own "authors".
    – J.R.
    May 4, 2022 at 19:20

3 Answers 3

2

The only truly secure option for working with NPM (or other package managers) is to not use them directly. You need a private repository for every package you use and you need to scan it with every update or addition. From there you set thresholds of what vulnerabilities are show stoppers and which are acceptable. Then it's just a matter of having a process to mange updates and new packages, to prevent introducing exploits. Supply chain attacks are a concern with all package managers, but particularly NPM which has excessive dependency trees.

Using NPM directly isn't secure and the best you can get is security theater.

2
  • Not using NPM at all is not viable (for the intended development), so I was looking at reducing the risks. What is that process of managing updates and new packages while producing a commercially viable product? If you/your business is using NPM to develop a commercial product, then can you describe the process you are taking? I have outlined a few steps that came to mind in the OP.
    – J.R.
    Oct 4, 2022 at 6:12
  • If you need security the only option is not having a direct dependency on NPM. If you want half measures, don't update before verifying packages are secure, and monitor or find a tool that can notify you about new vulnerabilities (especially in dependencies). The enterprise solution is taking packages from NPM, hosting them internally after scanning, and only using that to build production code.
    – Ryathal
    Oct 5, 2022 at 13:58
1

Relevant to point out: it was confirmed in comments that OP is concerned with the risk of security vulnerabilities.

Package management is one of those things that can cause a lot of paperwork and boxes needing to be ticked, unless you choose to blindly trust your package providers.

If, for example, your package developers are from within the same company and have the same main objective, then you can generally blindly trust them as any risks or vulnerabilities will blow back on them, not on you. On the other end of the spectrum, if the package developers are unknown to you, then you will personally suffer the consequences of any vulnerabilities that these packages will introduce.

The question here is one of balancing your risk assessment with your effort. How much effort is this worth for you to reduce your susceptibility to vulnerabilities.

One major thing to consider here is whether you automatically update to new package versions or not. On the one hand, most package updates (within the same major version) will be bugfixes and minor non-breaking improvements. Having to manually certify the library for every update is definitely a cumbersome process.
On the other hand, the package developers are able to push virtually any update to their code, and there's no way of trusting that they don't change something that introduces a significant vulnerability.

Secondly, even if the package developers don't introduce vulnerabilities by mistake, what about deliberate vulnerabilities? Do you really trust third party code? Since we're focusing on the topic of securiy vulnerabilities, this inherently limits the relevant libraries to libraries that are somehow involved in your security process or have found clever way around it (log4j is a great example here).

How do you prevent those? Well, you'd need to vet all the source code. For every version update. I don't think I need to tell you that this is a lot of work.

Sometimes, this level of effort makes sense. When you have a billion-dollar project, or are handling life critical applications; the extra effort pales in comparison to the practical or ethical violations you'd otherwise deal with. Standard examples here are NASA (failure in space costs billions) or medical equipment (lives are literally at stake).

However, beyond these examples, it's often not worth it to try and protect against literally every possible vulnerability, simply because of the sheer effort required to do so. If your blog site goes down, nothing bad is going to happen, so you're better off not investing hours upon hours of pedantic code checking just for the off chance that someone somewhere made a mistake.

It's much easier to just have it break, look at the problem, and roll back to a previous version if you can't otherwise fix it.

Mostly, I tend to rely on the credibility of both the package developers and the package delivery network. Is that a guarantee of security? No. But it's usually a good balance between protection and avoiding additional effort.

1
  • 1
    "this inherently limits the relevant libraries to libraries that are somehow involved in your security process" Wait, what? You lost me here. Can you explain what you mean by that?
    – JimmyJames
    May 2, 2022 at 16:24
1

For most organizations, it will be very difficult to assess vulnerabilities on your own in a vacuum to the level of rigor you desire. Even if you can assess the trustworthiness of a specific package developer, you probably don't have the bandwidth to do that for transitive dependencies, which present as real of a threat as direct dependencies.

For such organizations, it will be essential to rely upon the assessment of other trusted groups to look at packages and give them a red or green light. When I worked on government projects we often relied upon the assessment of the Department of Defense, for example, where there is a very real need for a very strong level of scrutiny.

Additionally, tooling that ranges from open source to commercial software exists to scan your full package dependencies and report on vulnerabilities. I have used trivy with some level of success.

As an overall strategy, you will need to have some process for acceptance of risk. In the early stages, we chose to accept risk for vulnerabilities that passed review by the Department of Defense. We would explicitly exclude individual vulnerabilities in specific places in our vulnerability scanner. It is important to ensure you aren't blindly ignoring a vulnerability across your entire code base when doing this.

Modern tooling makes it completely practical to use a package lock to ensure you are only ever using versions of code you desire, because they alert you to new versions and allow you to quickly decide whether to upgrade versions.

Aside from this initial vetting process and the version locking, you need to have a vulnerability response process. That should include:

  • A means of being alerted in a timely fashion when a new vulnerability is found
  • A way to quickly triage the finding in order to understand what the vulnerability is and whether you are affected
  • An immediate next step recommendation
  • Review by a security team to ensure that the recommendation is sensible
  • Procedures for backing out of each major dependency
  • An assessment of potential mitigation (defined as ways to reduce risk without eliminating it)
  • An assessment of potential remediation

It is reasonable to use a private package repository. This repository would contain scanned or vetted dependencies only, and many commercial offerings have feed forwarding as well if you don't want to intentionally curate your packages.

Your overall security plan should be documented so that everyone can know what to do, and so you can provide it to customers (if you do that sort of thing).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.