Skip to content

fix(remediation): name the child in npm within-range parent updates (#1286) - #1287

Open
alex-powell wants to merge 1 commit into
OWASP:mainfrom
alex-powell:fix/issue-1286-exact-pinned-parent-update
Open

alex-powell wants to merge 1 commit into
OWASP:mainfrom
alex-powell:fix/issue-1286-exact-pinned-parent-update

Conversation

@alex-powell

Copy link
Copy Markdown
Contributor

What changed and why

For an npm transitive finding whose direct parent already allows a fixed child version (update-parent-within-range), the "parent updates within range" section suggested npm update <parent>. That command does not refresh the child: npm update only re-resolves the packages it is given, and a child that still satisfies the parent's range is left alone.

Checked on npm 9 and npm 10 with astro 5.13.2 and devalue 5.9.2 (astro declares devalue: ^5.1.1, fixed in 5.9.4):

astro in package.json npm update astro npm update devalue
5.13.2 (exact) no change, devalue stays 5.9.2 devalue 5.9.4
^5.13.2 astro moves to 5.18.2, devalue still 5.9.2 devalue 5.9.4

So the exact pin in #1286 is the most visible case, but naming the parent is the root cause. The deep-chain npm path and the pnpm / yarn / bun lockfile refresh already name the child; this brings the direct-parent npm path in line.

  • src/remediation/fix-commands.ts: the npm within-range command is now npm update <child>, with the existing workspace scoping (--workspace=<ws> / --workspaces). The target keeps the shape from fix(remediation): stop parent-update rendering a child's version as the parent's #1174: package and targetVersion are the parent's, the child is on childPackage / childTargetVersion. The no-explicit-command fallback in buildCommandForTargets names childPackage too.
  • src/utils/fix-runner.ts: --fix already runs the target's command, so it picks up the fix; only the comment about shared commands is updated.
  • examples/exact-pinned-parent-within-range: hand-crafted fixture (astro exact at 5.13.2, devalue 5.9.2), listed in examples/readme.md.
  • Tests: new fixture test in tests/fixture-scan.test.ts (remediation, plan command, target fields, findSuggestedCommandForFinding, buildTargetCommand), workspace-scoped variants, --fix runner dedupe cases, and existing assertions that expected npm update <parent> updated to the child.
  • Docs: README, how-it-works.md, remediation-strategy.mdx, comparison.md, comparison/npm-audit.md and comparison/snyk.md described this command as npm update <parent>; reworded to the child refresh.

npm run build, npm run lint:tests and npm test pass (163 suites, 2253 tests).

Fixes #1286

…WASP#1286)

For an npm transitive finding whose direct parent already allows a fixed
child version, the suggested command was `npm update <parent>`. npm update
only re-resolves the packages it is given, so a child that still satisfies
the parent range stays on the vulnerable version. With an exact-pinned
parent the command changes nothing at all.

Emit `npm update <child>` instead, keeping workspace scoping, and keep the
target shape from OWASP#1174 (package and targetVersion belong to the parent,
the child is on childPackage / childTargetVersion). The --fix runner uses
the same command. Adds the exact-pinned-parent-within-range fixture and
updates docs that described the command as `npm update <parent>`.

Fixes OWASP#1286
@prx-my

prx-my commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Heads-up: this branch is currently behind main, which blocks the merge. Could you update it?

  • Click Update branch on this PR, or
  • Rebase locally:
    git fetch upstream
    git rebase upstream/main
    git push --force-with-lease
    

Once updated, CI will re-run. Thanks!

@sonukapoor

Copy link
Copy Markdown
Collaborator

I owe you a straight explanation here.

Yesterday I hit this same bug from a different direction, through an adopter's scan artefacts, diagnosed it, and merged a fix in #1313 without reading far enough down the review queue to find that you had already reported it in #1286 and already fixed it here. Your report predates my work by seven days and your PR predates my branch by six. Our own rule gives the oldest duplicate priority, and that was yours.

Your diagnosis is also better than mine. I had concluded the defect fires when the parent is already at its newest allowed version, which is the case I happened to measure. Your table across both pin styles and two npm majors shows the real rule, that npm update only re-resolves the packages it is given, so naming the parent never refreshes the child whether or not the parent moves. I have corrected my own notes accordingly.

Two things in your PR are not on main and are still wanted: the buildCommandForTargets fallback naming childPackage, which I looked at and wrongly dismissed as unreachable, and the examples/exact-pinned-parent-within-range fixture.

#1313 has made this conflict, which is my doing and not something I am going to hand back to you. I will rebase your commits myself, keeping your authorship so it lands under your name, and carry the two pieces above. If you would rather do it, say so and I will leave it alone.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] parent-update suggests npm update <parent> that cannot refresh the child when the parent is exact-pinned

3 participants