dependencies drifting out from under you

Version & Library Mismanagement

Floating version ranges, unpinned lockfiles, and copy-pasted helpers make the dependency tree itself unstructured input. A 'patch' bump changes behavior, two libraries demand incompatible versions, and 'works on my machine' becomes a deployment incident.

The code you tested and the code that ships resolve to different library versions.

01in the wild

In the wild

The Caret That Shipped a Surprise

A floating range pulls a new version you never tested at build time.

example.txt
// package.json -- WRONG: ranges float on every install
{
  "dependencies": {
    "date-utils": "^1.2.0"
  }
}
// ^1.2.0 allows any 1.x; a 1.3.0 with a regression slips in silently.
// RIGHT: commit package-lock.json and install with `npm ci`,
// which installs the locked tree verbatim.
^1.2.0 means 'any 1.x' -- a minor release with a behavior change installs silently. A committed lockfile plus npm ci makes installs reproducible.
// observed
^1.2.0: build A gets 1.2.0, build B gets 1.4.7
npm ci: every build gets the locked version
example.py
# requirements.txt -- WRONG: unpinned, resolves differently over time
requests
urllib3

# RIGHT: pin exact versions for reproducible installs
requests==2.31.0
urllib3==2.2.1
Unpinned requirements resolve to 'whatever is newest today'. Pinning makes the dependency set part of the code you reviewed.
// observed
unpinned: prod pulls a newer, untested urllib3
pinned:   prod matches the tested set exactly

Copy-Pasta Drift

A helper copied into three services becomes three subtly different helpers.

example.js
// service-a: the original, later patched for a leap-year bug
function daysInMonth(y, m) { /* ...fixed... */ }

// service-b: a copy-paste from a year ago -- never got the fix
function daysInMonth(y, m) { /* ...buggy in February... */ }

// The 'same' function now disagrees across services.
Copied code forks silently: a fix applied to one copy never reaches the others. The duplication is the version-mismanagement.
// observed
service-a: Feb 2024 -> 29 (fixed)
service-b: Feb 2024 -> 28 (stale copy)
example.txt
// RIGHT: one source of truth, versioned as a real dependency
{
  "dependencies": {
    "@acme/dates": "1.4.0"
  }
}
// One place to fix, one version to bump everywhere.
Extracting the helper into a versioned package replaces N drifting copies with one dependency every consumer pins.
// observed
copies:  N forks, fixes diverge
package: one fix, bump the version everywhere
02cross-pollination

Where this compounds

03weakness catalog

Mapped weaknesses (CWE)

On its own, this defect is catalogued by MITRE as one or more of these weaknesses. The exploitable vulnerability usually appears only when it chains or combines with another.