dependabot / dependabot/dependabot-core

Dependabot should gracefully handle the `overrides` field in `package.json`

Open
#5,590 1 comment 15 reactions 0 assignees View on GitHub
F: configuration-file Keep L: javascript:npm T: feature-request versioning
Dominant language
Ruby
Stars
5.8k
Forks
1.5k
Avg merge
2d 18h
Merged PRs (30d)
149

Description

## 🖼️ Context

npm 8.3.0 added support for the [`overrides` field in `package.json`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides), which allows authors to force sub-dependencies to resolve to specific versions.

Example: top-level dependency `foo@^1.3.0` depends on `bar@^6.4.1`, which is a vulnerable version. Fortunately there is a patch in `bar@6.4.2`. If, however, the author decided to force `bar` to resolve to the vulnerable version in the `overrides` field, it would be impossible to resolve the vuln. (This is precisely what happens with `npm audit fix`, i.e., it fails to fix the vuln.)

```json
"overrides": {
"foo@^1.3.0": {
"bar": "6.4.1"
}
}
```

When such an example is given to the dry-run script, Dependabot believes a fix is possible by updating from `bar@6.4.1` to `bar@6.4.1`, and creates a PR stating as much, which is obviously nonsense.

```
Updates `pg` from 6.4.1 to 6.4.1

Commits



```

While this is unlikely to come up often and is arguably user error, Dependabot should still gracefully handle this field.

There 2 situations where we would definitely want to raise an `update not possible` error:

1. a security update where a vulnerable dependency (or its vulnerable sub-dependency) is overridden to a vulnerable version
2. a version update where an override locks a dependency to an older version

Those situations make sense to error with `update not possible`, but what if a an override is used to lock a non-vulnerable dependency to a non-vulnerable version?

Example: non-vulnerable sub-dependency `B` of some vulnerable dependency `A` is overridden to a non-vulnerable version.

```
--> A (vulnerable and receives security update, requires non-vulnerable B@v2.5.1)
|--> B (overrides to non-vulnerable `v2.5.0`)
```

Opening a PR in this situation could help maintainers fix vulnerabilities quicker, even if it doesn't work.

But it might still be appropriate to raise `update_not_possible` because an `overrides` entry is still preventing a security update, the only difference being the blocked dependency is the parent rather than the sub-dependency itself.

Seeing a failure indicating that use of the `overrides` field prevented a security update of the vulnerable parent is explicit and doesn't require having to figure out why Dependabot opened a PR with a potentially empty diff to update the parent from `2.5.1` to `2.5.1`.

Anyhow, here's a scenario where Dependabot might still want to open a PR with an override present:

Example: some dependency `A` receives a version update and has a sub-dependency `B` that is overridden to an older version. Would we still want to raise an `update not possible` error on the version update for `A`?

```
--> A (receives a version update, requires B@v2.5.1)
|--> B (overrides to `v2.5.0`)
```

### ✅ Tasks

- [ ] Check for and handle `overrides` field in `package.json`
- [ ] Raise `update_not_possible` with descriptive error message

Contributor guide

Open the contributing guide

Research direction

Start with the package.json overrides documentation and the dry-run script described in the issue. Trace how overridden dependencies are resolved and how update PR messages are generated, then determine the agreed security and version-update outcomes. Done means overrides are handled without empty or nonsensical updates and update_not_possible errors have descriptive messages.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js, ruby
Domain
devtools, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.