skip to content

A dependency has a known vulnerability and no fixed version exists. What are your options?

level: juniorimportance: must knowfreq 68%

answer

  1. no fixed version is not no options
  2. count four families, not one
  3. the cheapest fix removes code
  4. patching it yourself is adoption
  5. anything kept needs an owner and expiry

basics

~20 s

Four options: delete the dependency, replace it with a maintained equivalent, patch it yourself and own that patch forever, or contain it behind a control that blocks the vulnerable path. Deletion is often cheapest and rarely even costed.

solid answer

~50 s

First check that there really is no fix: confirm the advisory has no fixed range in a newer major you have been avoiding, and that the flaw is in code your application actually calls. If it is genuinely unfixed and the project is unmaintained, there are four real moves. Remove the dependency outright: for a small utility that is often an afternoon of standard-library code, and it deletes the problem permanently. Replace it with a maintained equivalent, paying a migration cost once. Patch it yourself, which makes you the maintainer of a private fork from that day on. Or leave it in place and constrain what can reach the vulnerable code, treating that as debt with a named owner and a review date. Cost all four before defending the one you already prefer; teams routinely jump to "we will patch it ourselves" without ever pricing removal.

go deeper

for a junior

Be ready to name more than one option out loud: remove, replace, self-patch, or contain. Knowing that a missing fixed version is not the end of the conversation is most of what is being tested here.

for a middle

Explain how you verify there is genuinely no fix before choosing, and what each option costs over time rather than today. Say plainly why pinning and suppressing are not remediation.

for a senior

Show you would cost removal and replacement before defending a fork, and that anything you keep in place leaves with a named owner and a review date. Interviewers listen for whether you close the loop or just file it.

for a principal

Own the policy question: what your organisation is allowed to accept, who signs off on an unfixable component staying in a product, and how you stop a one-off exception becoming the default answer across hundreds of services.

## What "no fix" actually means A vulnerability advisory normally carries an affected range and a fixed version. When the fixed version is missing, the entry is telling you one of several very different things, and the first job is to find out which: - **Nobody has fixed it yet.** The maintainer is active and a release is coming. This is a waiting problem, not this problem. - **The project is abandoned.** No release in years, issues unanswered, the last maintainer gone. No fix is ever coming. - **The project is end-of-life by declaration.** The maintainer has said the branch you are on is unsupported, and the fix exists only in a major version that is a rewrite. - **The maintainer disputes it,** or considers the behaviour intended and the caller's responsibility. Only the middle two are the "no upstream fix" case. They are permanent, so whatever you decide has to be something you are willing to live with, not a stopgap. ## The four families of response **1. Delete it.** The cheapest fix is the one that removes code. A large share of ecosystem dependencies, especially in npm, are tiny utilities: a padding function, a type check, a date formatter. If a package is forty lines and the language now has a standard-library equivalent, removing it is an afternoon of work that closes the finding forever, shrinks your inventory by one component, and removes one more thing you have to watch. This option is systematically under-considered because it looks like product work rather than security work, and because nobody wants to touch a call site that has worked for four years. Cost it explicitly; it frequently wins. **2. Replace it.** A maintained equivalent exists for most abandoned libraries, and migration is a bounded one-time cost with a permanent payoff: you inherit somebody else's ongoing maintenance. The judgment is whether the equivalent is genuinely maintained (recent releases, more than one maintainer, a response to past advisories) or merely younger. **3. Patch it yourself.** You take the upstream fix, if one exists on a branch you are not on, or write one, and ship a modified build. This works and is sometimes the only option, but understand what you bought: you are now the maintainer of that code, you own review of a security patch with no second reviewer who knows the codebase, and no advisory feed will ever match your artifact again. **4. Contain it.** Leave the vulnerable code present but make the attack path unreachable or the consequence survivable: filter or normalise the input that reaches it, strip the feature that exercises it, isolate the process that runs it, remove the credentials and network access it holds. A containment decision is only legitimate when it is written down with the specific attack step it blocks, a named owner, and a date on which somebody re-examines it. Undated mitigations outlive the people who understood them. ## Reachability is a reason to defer, not to close If the vulnerable function is never called from your code, your risk today is low. That is a legitimate reason to rank this below other work. It is not a reason to mark it resolved: reachability analysis is blind to reflection, dynamic dispatch, plugin loading and configuration, and your own next release can call the vulnerable path without anyone noticing. Record it as a deferred decision with a trigger, not as a closure. Keep three distinctions straight while you reason. A **vulnerability** is the flaw in the code. An **exploit** is a working attack against it. **Reachability** asks whether the vulnerable code is called at all in your build; **exploitability** asks whether an attacker can actually drive input into it. A package can be reachable and unexploitable (only your own trusted config reaches it) or unreachable today and exploitable tomorrow. ## What does not count as remediation Suppressing the scanner finding changes the report, not the exposure. Pinning the version changes nothing about the flaw already in the pinned version. Filing a ticket is a plan, not a control. And "it is stable, it has not needed a release in five years" is not evidence of safety: no releases and no advisories can equally mean nobody is looking. ## How to present the decision Interviewers are listening for the shape of the answer more than the choice: did you verify there is really no fix, did you enumerate more than one option, did you price removal, and does whatever you keep have an owner and an expiry? A candidate who says "no fixed version, so we accept the risk" has skipped every interesting step.

  • How would you choose between replacing the package and patching it yourself?
    Replacement wins whenever a genuinely maintained equivalent exists, because it converts a permanent obligation into a one-time migration. Patching yourself is for the case where nothing equivalent exists, the code is small enough that you can actually read and reason about it, and removal is impossible. Size of the code you would inherit is usually the deciding factor: a few hundred lines you understand is very different from a native parser.
  • Why is removing the dependency the option teams forget?
    It looks like product work rather than security work, so it lands on the wrong backlog and gets no security budget. It also means touching working call sites, which feels riskier than adding a filter. Nobody costs it, so it never wins the comparison it was never entered into. For small utility packages it is frequently the cheapest and only permanent answer.
  • If the vulnerable function is never called from your code, is the problem solved?
    It lowers priority, not risk to zero. Reachability analysis cannot see reflection, dynamic loading or configuration-driven paths, and your own next feature can start calling the vulnerable code without anyone re-checking. Record it as a deferred decision with an owner and a trigger for revisiting, rather than closing it.

A discontinued part in a machine you still run: you can redesign the part out, buy a compatible one, machine a replacement yourself and own it forever, or fence off the machine so nobody can be hurt when it fails.

saying these in an interview costs you the question

  • Says no fixed version means nothing can be done
  • Jumps straight to forking without costing removal
  • Treats suppressing the scanner finding as remediation
  • Assumes a private fork is free after the first patch
  • Claims an unmaintained package is safe because it is stable

context