diff --git a/mcp/lua-platform/package-lock.json b/mcp/lua-platform/package-lock.json index 0f58663..884c130 100644 --- a/mcp/lua-platform/package-lock.json +++ b/mcp/lua-platform/package-lock.json @@ -3207,9 +3207,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", - "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz", + "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==", "dev": true, "license": "MIT", "dependencies": { diff --git a/mcp/lua-platform/package.json b/mcp/lua-platform/package.json index eff083f..aba35ad 100644 --- a/mcp/lua-platform/package.json +++ b/mcp/lua-platform/package.json @@ -26,7 +26,7 @@ }, "overrides": { "@babel/core": "^7.29.6", - "js-yaml@3": "^3.15.1", + "js-yaml@3": "^3.15.2", "brace-expansion@1": "1.1.16" } } diff --git a/package-lock.json b/package-lock.json index bf52fbc..bee1ef7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -655,9 +655,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", - "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz", + "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==", "dev": true, "license": "MIT", "dependencies": { @@ -3306,9 +3306,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index 67640b6..a27a9f2 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,8 @@ }, "overrides": { "@babel/core": "^7.29.6", - "js-yaml@4": "^4.3.1", - "js-yaml@3": "^3.15.1", + "js-yaml@4": "^4.3.2", + "js-yaml@3": "^3.15.2", "brace-expansion@1": "1.1.16" } } diff --git a/test/lockfile-security.test.mjs b/test/lockfile-security.test.mjs new file mode 100644 index 0000000..1b33667 --- /dev/null +++ b/test/lockfile-security.test.mjs @@ -0,0 +1,65 @@ +import { describe, test, expect } from '@jest/globals'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +const LOCKFILES = ['package-lock.json', 'mcp/lua-platform/package-lock.json']; +const readLock = (rel) => { + if (!LOCKFILES.includes(rel)) throw new Error(`unexpected lockfile ${rel}`); + return JSON.parse(readFileSync(join(process.cwd(), rel), 'utf8')); +}; + +const parse = (v) => v.split('.').map((n) => parseInt(n, 10)); +const lt = (a, b) => { + const [x, y] = [parse(a), parse(b)]; + for (let i = 0; i < 3; i++) if (x[i] !== y[i]) return x[i] < y[i]; + return false; +}; + +const resolved = (lock, name) => + Object.entries(lock.packages) + .filter(([p]) => p === `node_modules/${name}` || p.endsWith(`/node_modules/${name}`)) + .map(([p, e]) => ({ path: p, version: e.version })); + +const FIXED = { 3: '3.15.2', 4: '4.3.2' }; + +describe.each(LOCKFILES)('%s', (rel) => { + const lock = readLock(rel); + + test('js-yaml@4.3.2 / js-yaml@3.15.2: every resolved js-yaml is at or above its fixed line', () => { + const entries = resolved(lock, 'js-yaml'); + expect(entries.length).toBeGreaterThan(0); + for (const { version } of entries) { + const major = parseInt(version, 10); + expect(FIXED[major]).toBeDefined(); + expect(lt(version, FIXED[major])).toBe(false); + } + }); + + test('no vulnerable js-yaml@3.15.1 or js-yaml@4.3.1 literal remains', () => { + const versions = resolved(lock, 'js-yaml').map((e) => e.version); + expect(versions).not.toContain('3.15.1'); + expect(versions).not.toContain('4.3.1'); + }); + + test('browserslist stays above 4.28.6 (4.28.7)', () => { + const entries = resolved(lock, 'browserslist'); + expect(entries.length).toBeGreaterThan(0); + for (const { version } of entries) expect(lt('4.28.6', version)).toBe(true); + }); +}); + +describe('package-lock.json', () => { + const lock = readLock('package-lock.json'); + + test('node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml is 3.15.2', () => { + expect( + lock.packages['node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml'].version, + ).toBe('3.15.2'); + }); + + test('baseline-browser-mapping stays at or above 2.11.0 (2.11.1)', () => { + const entries = resolved(lock, 'baseline-browser-mapping'); + expect(entries.length).toBeGreaterThan(0); + for (const { version } of entries) expect(lt(version, '2.11.0')).toBe(false); + }); +});