Fix CVE Dependency Upgrade
Required input
- Package name (e.g.
axios,ws,ip-address) - Minimum fix version from the CVE description
- Jira ticket ID (e.g.
CRW-11204)
If $ARGUMENTS is missing fields, extract them from context (open Jira ticket, branch name, etc.).
Workflow
1. Check current version
grep -A 3 '"<package>@npm' yarn.lock | head -6
If current ≥ fix version, document as already fixed and stop.
2. Find the best upgrade target
Pick the latest indexed version, not just the minimum fix version:
yarn npm info <package> dist-tags 2>/dev/null | grep latest
For each candidate (latest, latest-1, fix-version), check ClearlyDefined score:
curl -s --max-time 10 \
"https://api.clearlydefined.io/definitions/npm/npmjs/-/<package>/<version>" \
| python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('scores',{}).get('effective',0), d.get('licensed',{}).get('declared','?'))"
Choose the highest-versioned package with score > 0 and a resolved SPDX license. A newer un-indexed version resolves via semver (^) and breaks yarn license:generate — pin the exact indexed version.
3. Update package.json
Update in ALL locations:
- Root
package.json→resolutionsfield (exact version, e.g."<package>": "1.16.1") - Any workspace
package.jsonwith it as a direct dep (update range, e.g."<package>": "^1.16.1")
grep -rn '"<package>"' packages/*/package.json package.json
Pinning rules:
- Use exact version (no
^) inresolutionsto prevent resolution to newer un-indexed versions - For packages crossing a major semver boundary (e.g.
^9.x→10.x), theresolutionsoverride is mandatory
4. Reinstall and verify
yarn install
grep -A 2 '"<package>@npm' yarn.lock | head -4 # confirm lock updated
5. Regenerate license files
yarn license:generate
If UNRESOLVED exits:
Check ClearlyDefined individually:
curl -s --max-time 10 \
"https://api.clearlydefined.io/definitions/npm/npmjs/-/<dep>/<version>" \
| python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('scores',{}).get('effective',0), d.get('licensed',{}).get('declared','?'))"
- Score > 0: batch API timed out — retry (usually succeeds on attempt 2–4)
- Score = 0: not yet indexed — add to
.deps/EXCLUDED/prod.md(runtime) or.deps/EXCLUDED/dev.md(dev only):
| `<package>@<version>` | [clearlydefined](https://clearlydefined.io/definitions/npm/npmjs/-/<package>/<version>) |
Then re-run yarn license:generate.
6. Verify
yarn license:check # must exit 0
6.5. Build and test
MANDATORY before committing and pushing:
yarn build # must exit 0; dep upgrades can break TypeScript compilation
yarn test # must exit 0; new package versions can cause test suite failures
If tests fail: the upgraded package likely introduced a breaking API change or new peer requirements. Investigate the failure, update test code or pin a different version, then rerun.
Never commit or push with a failing build or failing tests.
7. Commit
git add package.json packages/*/package.json yarn.lock \
.deps/dev.md .deps/prod.md .deps/EXCLUDED/dev.md .deps/EXCLUDED/prod.md
Commit message:
fix(deps): upgrade <package> to <version> to fix <vulnerability-type> (<JIRA>)
<Package> versions prior to <fix-version> <vulnerability description>.
Upgrade from <old-version> to <new-version> (pinned in resolutions) and
regenerate license dependency files.
CVE reference: <CVE-ID or GHSA>
Fixed in: <package> <fix-version>
Assisted-by: {AGENT_NAME}
Signed-off-by: {AUTHOR_NAME} <{AUTHOR_EMAIL}>
8. Push
git push -u origin <branch>
Special cases
Package crosses major semver boundary (e.g. 9.x → 10.x)
The fix version exceeds the range declared by transitive dependents ("ip-address": "^9.0.5" won't accept 10.x). Add a hard pin:
"ip-address": "10.2.0"
Multiple CVEs in one PR
Fix all packages in a single commit; list each in the commit body:
1. <package-a> — fixes <type> (CRW-XXXXX)
2. <package-b> — fixes <type> (CRW-XXXXX)
ClearlyDefined batch API failures
The batch API sometimes returns HTTP 502 or times out. Always retry before adding packages to EXCLUDED. Usually succeeds on attempt 2–4.