| name | cve-remediation |
| description | Domain knowledge for remediating CVEs in the iTwin.js Rush monorepo — pnpm-config.json structure, fix strategies, validation, and audit workflows. |
CVE Remediation in iTwin.js
This skill covers the domain knowledge for fixing security vulnerabilities in the iTwin.js Rush monorepo. It is referenced by the CVE audit agent, the merge-conflict-resolving skill, and the backport-resolution skill.
Key Files
| File | Purpose |
|---|
common/config/rush/pnpm-config.json | Global dependency overrides and audit exceptions |
common/config/rush/pnpm-lock.yaml | Resolved dependency tree (never manually edit) |
common/config/rush/common-versions.json | Rush version-consistency policy (preferredVersions) |
common/config/rush/repo-state.json | Auto-generated hash of repo state (commit alongside common-versions.json) |
<package>/package.json | Direct dependency version ranges per package |
pnpm-config.json Structure
This file has two conflict-prone sections:
globalOverrides
Forces specific dependency versions across the entire monorepo. Used when a transitive dependency cannot be updated via its parent's semver range.
{
"globalOverrides": {
"<package>": "<patched-version>",
"<package>@<range>": "<patched-version>"
}
}
Each override should include a trailing comment with:
- The advisory URL (GHSA or CVE link)
- The dependency path that pulls in the vulnerable package
Illustrative example (always consult the current common/config/rush/pnpm-config.json before editing):
"globalOverrides": {
"rollup-plugin-copy>globby": "^11.0.0",
"elliptic": "^6.6.1",
"fast-xml-parser": "^5.3.6",
"axios@<1.0.0": "^1.13.5",
"serialize-javascript": "^7.0.3"
}
Important: This file uses JSONC (JSON with comments). The last entry in any object/array must NOT have a trailing comma. When adding entries, ensure the previously-last entry gets a comma added and the new last entry does not have one.
ignoreCves (Audit Exceptions)
Located under a nested path. Used only for dev-tooling dependencies with no production path.
{
"unsupportedPackageJsonSettings": {
"pnpm": {
"auditConfig": {
"ignoreCves": [
"CVE-XXXX-XXXXX"
]
}
}
}
}
Fix Strategy (Strict Order)
Always attempt fixes in this order. Do not skip to overrides without trying the earlier steps.
1. Classify: Direct vs Transitive
- Direct: The vulnerable package is listed in a project's
package.json
- Transitive: The vulnerable package is pulled in by another dependency
2a. Direct Dependency Fix
- Update the version range in the affected
package.json
- Run
rush update then rush audit to verify
- If no safe version range exists, fall through to globalOverride (document why)
2b. Transitive Dependency Fix
- Check existing overrides first: Before adding a new override, check if the package already has an entry in
globalOverrides in pnpm-config.json to avoid conflicts or duplicates.
- Semver range update (try first): Update the direct parent's
package.json range to a version that resolves the transitive dep to a patched release
- Scoped globalOverride (last resort): Only if no safe parent version exists. Scope the override to only the vulnerable version range (e.g.,
"lodash@>=4.0.0 <=4.17.23": "^4.18.0") rather than overriding all versions blanket. This avoids interfering with future already-patched versions. Document why in the override comment.
Use rush-pnpm why <package> to trace transitive dependency paths when the audit output truncates them.
3. ignoreCves (Absolute Last Resort)
Only for non-production/dev-tooling risk. Requires:
- Explicit rationale in comment
- Advisory link
- Confirmation that the dependency has no production code path
Never ignore a Critical/High production-path CVE when a patch is available.
Severity Policy
| Severity | Action |
|---|
| Critical | Always fix or explicitly document blocker and risk |
| High | Fix unless unacceptable breakage; if deferred, create tracking issue |
| Moderate/Low | Defer and create tracking issue with recommendation |
Validation Workflow
After any remediation change:
rush update
rush audit
rush build
rush test
Note: rush audit does not accept --level or --json flags directly. Use rush-pnpm why <package> to investigate specific dependency paths.
When direct dependency version ranges were changed in a package.json:
rush extract-api
Skip extract-api only when the sole change is a globalOverride in pnpm-config.json.
Rush Change Files
After remediation, Rush requires changelog entries:
rush change --verify -b origin/<base-branch>
rush change --bulk --message "" --bump-type none -b origin/<base-branch>
Change files land in common/changes/@itwin/<package>/ as JSON files with unique filenames.
common-versions.json
If a direct dependency bump triggers Rush consistency errors, update common/config/rush/common-versions.json to align versions. Always commit the auto-generated common/config/rush/repo-state.json hash update alongside it.