fix(vscode): patch MSAL packager dependency and remove waiver [skip ci]

CW-7639: replace vulnerable MSAL Node 6.0.1 with 7.1.2 through an
Azure Identity scoped override. Keep VSCE on its current supported route;
materialize the lockfile and remove the obsolete advisory acceptance from
the audit classifier and dependency-security documentation.

Verification: 47 existing extension checks passed; npm audit reported zero
vulnerabilities; replaying the old advisory is blocked. Credential-free
local VSIX packaging passed (30 files; no development dependencies).
Installed dependency graph resolves MSAL Node 7.1.2. No publishing or live
authentication was performed; no exploit or affected invocation is claimed.
This commit is contained in:
CodeWhale Bot committed 2026-10-29 07:26:00 -07:00
1 parent 62f0cc9536
commit abed61596a
6 files changed
+35 -49

No files matched your search

+2
View File
@@ -110,6 +110,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- **VS Code packaging security:** use patched MSAL Node in the extension packager, addressing [GHSA-xcx6-jx8p-x3h5](https://github.com/AzureAD/microsoft-authentication-library-for-js/security/advisories/GHSA-xcx6-jx8p-x3h5).
- **Compaction preserves task state:** a summary that is empty, a placeholder or only leaked reasoning tags (as local models sometimes return) no longer replaces your history. The recent tail is chosen by token budget on whole tool exchanges, the older span and any earlier checkpoint are summarized, and the original history is saved before the swap. Context budgeting learns from provider-reported usage within a turn and reports repeated rapid refills instead of looping. (#7133)
- **Vim Normal mode works on every terminal:** with `composer_vim_mode = "vim"`, Normal-mode keys no longer land in the draft as text on Windows terminals or on any terminal that does not report bracketed paste (everything except ghostty, iTerm, WezTerm and Apple Terminal, tmux and VS Code's terminal included). A held key now reaches Normal mode, shifted keys such as `G` move instead of typing, and `k` history recall repaints at once. Keys that arrive in one burst are still taken as a paste. (#7126, #7130) Thanks [@Lstarsky0](https://github.com/Lstarsky0).
+17 -26
View File
@@ -1,29 +1,20 @@
# Extension packager dependency acceptance
# Extension packager dependency security
The npm audit of `extensions/vscode` reports GHSA-xcx6-jx8p-x3h5, a high
severity CWE-346 advisory in `@azure/msal-node` 6.0.1. It reaches the lockfile
through `@vscode/vsce` 4.0.0 → `@azure/identity` 4.13.3 → `@azure/msal-node`, all
of which are build-only tooling. There is no upstream-consistent fix: every
published `@vscode/vsce` and `@azure/identity` release still declares
`@azure/msal-node: ^6.0.0`, so only a semver-breaking `overrides` pin or a major
downgrade of the packager would clear the report, and either changes the
packaging tool's behaviour.
The VS Code extension's packaging toolchain uses `@vscode/vsce` →
`@azure/identity` → `@azure/msal-node`. MSAL Node versions before 7.1.0 are
affected by [GHSA-xcx6-jx8p-x3h5](https://github.com/AzureAD/microsoft-authentication-library-for-js/security/advisories/GHSA-xcx6-jx8p-x3h5).
The extension manifest overrides Azure Identity's MSAL Node dependency to
`^7.1.2`; its lockfile resolves 7.1.2. Keep the override until Azure Identity
requires a patched version itself.
This is a reviewed acceptance of an unfixed advisory, not a mitigation. The
vulnerable package is a `devDependency`: `npm run package` invokes
`vsce package --no-dependencies`, so no dependency of it ships in the vsix and
the vulnerable authorization-code path is never executed when packaging. The
extension's published contents and runtime dependency set are unchanged.
`npm run audit:dependencies -- --report <path>` audits the complete lockfile
and keeps the raw report. Every reported vulnerability blocks the check.
Incomplete reports, count mismatches and critical findings also fail. There
is no advisory exception.
`npm run audit:dependencies` audits the complete lockfile and keeps the raw
report. Only this exact advisory, in `@azure/msal-node`, reachable through that
one chain, can be classified as accepted. Any other advisory, a second
`@azure/msal-node` installation, a critical finding, an incomplete audit, or a
count mismatch fails the check. CI stores the raw report, including the accepted
findings.
After an upstream fix is available, upgrade and verify it, then remove this
acceptance and its classification in the same slice. Never broaden the admitted
advisory list to get a passing check.
References: [upstream advisory](https://github.com/advisories/GHSA-xcx6-jx8p-x3h5).
After changing this dependency, materialize the lockfile with `npm ci`, run
the extension's existing `npm test` checks and build a local package with
`npm run package`. Packaging uses `vsce package --no-dependencies`, which
excludes development dependencies from the VSIX. A local package build does
not establish that a publishing authentication flow works; verify that flow
only when publication is separately authorized.
+2
View File
@@ -110,6 +110,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- **VS Code packaging security:** use patched MSAL Node in the extension packager, addressing [GHSA-xcx6-jx8p-x3h5](https://github.com/AzureAD/microsoft-authentication-library-for-js/security/advisories/GHSA-xcx6-jx8p-x3h5).
- **Compaction preserves task state:** a summary that is empty, a placeholder or only leaked reasoning tags (as local models sometimes return) no longer replaces your history. The recent tail is chosen by token budget on whole tool exchanges, the older span and any earlier checkpoint are summarized, and the original history is saved before the swap. Context budgeting learns from provider-reported usage within a turn and reports repeated rapid refills instead of looping. (#7133)
- **Vim Normal mode works on every terminal:** with `composer_vim_mode = "vim"`, Normal-mode keys no longer land in the draft as text on Windows terminals or on any terminal that does not report bracketed paste (everything except ghostty, iTerm, WezTerm and Apple Terminal, tmux and VS Code's terminal included). A held key now reaches Normal mode, shifted keys such as `G` move instead of typing, and `k` history recall repaints at once. Keys that arrive in one burst are still taken as a paste. (#7126, #7130) Thanks [@Lstarsky0](https://github.com/Lstarsky0).
+7 -7
View File
@@ -184,13 +184,13 @@
}
},
"node_modules/@azure/msal-node": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-6.0.1.tgz",
"integrity": "sha512-ixSO1Y/kCVRthRs+hSx/5qkwaunX1/RAePhlMN0wIpIQ4WEZ6AREGGnGd1AP0qspHVsAwzWQKGubpjh50JyJIQ==",
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-7.1.2.tgz",
"integrity": "sha512-52hKQLGpEQzwNufIXG1SPVU+wQ3RIe7Rp2+g+VdAmZojCAZ6yCdGEffzQEQ6RnBZGBEs40nl14rWBmfJpCoHsg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@azure/msal-common": "16.14.1",
"@azure/msal-common": "16.15.0",
"jsonwebtoken": "^9.0.0"
},
"engines": {
@@ -198,9 +198,9 @@
}
},
"node_modules/@azure/msal-node/node_modules/@azure/msal-common": {
"version": "16.14.1",
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.14.1.tgz",
"integrity": "sha512-Or6xhPNyi4zHW25158yxBoyxuCqNSPa5YBVqfF1J5Ks4MJWBo/USXdp05DQIPu1Zli00YZu6t0+h6KvHJealxQ==",
"version": "16.15.0",
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.15.0.tgz",
"integrity": "sha512-lwdLb1B9Q5nEhPLVIKe78XH5wFMN15fCiDkY7ylPDSWZuWcD93G3jpJajrKhO3CQld8SLKz0sHiOi24mxdvtsg==",
"dev": true,
"license": "MIT",
"engines": {
+5
View File
@@ -205,5 +205,10 @@
"@types/vscode": "1.96.0",
"@vscode/vsce": "^4.0.0",
"typescript": "^5.9.3"
},
"overrides": {
"@azure/identity": {
"@azure/msal-node": "^7.1.2"
}
}
}
@@ -3,26 +3,12 @@ import { writeFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const advisory = 'https://github.com/advisories/GHSA-xcx6-jx8p-x3h5';
export function classifyAudit(report) {
if (report.error || !report.vulnerabilities || !report.metadata?.vulnerabilities) throw new Error('Incomplete dependency audit');
const entries = report.vulnerabilities;
if (Object.keys(entries).length !== report.metadata.vulnerabilities.total) throw new Error('Dependency audit count mismatch');
if (report.metadata.vulnerabilities.critical) throw new Error('Critical dependency vulnerability');
function accepted(name, seen = new Set()) {
if (seen.has(name)) return false;
const entry = entries[name];
if (!entry || !Array.isArray(entry.via) || !entry.via.length) return false;
const next = new Set([...seen, name]);
return entry.via.every(via => typeof via === 'string'
? accepted(via, next)
: name === '@azure/msal-node' && via.name === '@azure/msal-node' && via.url === advisory && via.severity === 'high');
}
const nodes = entries['@azure/msal-node']?.nodes ?? [];
if (nodes.length > 1 || (nodes.length === 1 && nodes[0] !== 'node_modules/@azure/msal-node')) throw new Error('Unreviewed @azure/msal-node installation');
const blocked = Object.keys(entries).filter(name => !accepted(name));
return { upstreamFindings: report.metadata.vulnerabilities.total, accepted: Object.keys(entries).filter(name => !blocked.includes(name)), blocked };
return { upstreamFindings: report.metadata.vulnerabilities.total, blocked: Object.keys(entries) };
}
function main() {
@@ -36,7 +22,7 @@ function main() {
writeFileSync(process.argv[at + 1], JSON.stringify(report, null, 2) + '\n');
}
const verdict = classifyAudit(report);
console.log(JSON.stringify({ ...verdict, reviewedAcceptance: advisory }));
console.log(JSON.stringify(verdict));
if (verdict.blocked.length) process.exitCode = 1;
}