diff --git a/crates/socket-patch-cli/tests/e2e_hosted_production.rs b/crates/socket-patch-cli/tests/e2e_hosted_production.rs index 6c7ca6f07..f293592a0 100644 --- a/crates/socket-patch-cli/tests/e2e_hosted_production.rs +++ b/crates/socket-patch-cli/tests/e2e_hosted_production.rs @@ -33,7 +33,7 @@ //! //! | Ecosystem | PURL | Patch UUID | Advisory | //! |-----------|------|------------|----------| -//! | npm | `pkg:npm/minimist@1.2.2` | `80630680-4da6-45f9-bba8-b888e0ffd58c` | GHSA-xvch-5gv4-984h (CVE-2021-44906) | +//! | npm | `pkg:npm/minimist@1.2.2` | `642d7f02-ebc1-4ab0-99e2-07f5dd8463cb` | GHSA-xvch-5gv4-984h (CVE-2021-44906) | //! | PyPI | `pkg:pypi/urllib3@1.26.18` | *any of three* (see [`PYPI_UUIDS`]) | GHSA-gm62-xv2j-4w53 &co | //! | gem | `pkg:gem/activestorage@6.0.3` | *any of* [`GEM_UUIDS`] (six today; the sixth merges three advisories) | GHSA-m42x-37p3-fv5w (CVE-2020-8162), GHSA-w749-p3v6-hccq (CVE-2022-21831), GHSA-9xrj-h377-fr87 (CVE-2026-33195), GHSA-r4mg-4433-c7g3 (CVE-2025-24293), GHSA-xr9x-r78c-5hrm (CVE-2026-66066) | //! @@ -123,7 +123,7 @@ const PATCH_HOST: &str = "patch.socket.dev"; const NPM_PURL: &str = "pkg:npm/minimist@1.2.2"; const NPM_NAME: &str = "minimist"; const NPM_VERSION: &str = "1.2.2"; -const NPM_UUID: &str = "80630680-4da6-45f9-bba8-b888e0ffd58c"; +const NPM_UUID: &str = "642d7f02-ebc1-4ab0-99e2-07f5dd8463cb"; const PYPI_PURL: &str = "pkg:pypi/urllib3@1.26.18"; const PYPI_NAME: &str = "urllib3"; diff --git a/crates/socket-patch-cli/tests/e2e_npm.rs b/crates/socket-patch-cli/tests/e2e_npm.rs index 63de6c636..4df29c4d7 100644 --- a/crates/socket-patch-cli/tests/e2e_npm.rs +++ b/crates/socket-patch-cli/tests/e2e_npm.rs @@ -1,7 +1,7 @@ //! End-to-end tests for the npm patch lifecycle. //! //! These tests exercise the full CLI against the real Socket API, using the -//! **minimist@1.2.2** patch (UUID `80630680-4da6-45f9-bba8-b888e0ffd58c`), +//! **minimist@1.2.2** patch (UUID `642d7f02-ebc1-4ab0-99e2-07f5dd8463cb`), //! which fixes CVE-2021-44906 (Prototype Pollution). //! //! # Prerequisites @@ -26,14 +26,14 @@ use common::cache_env; // Constants // --------------------------------------------------------------------------- -const NPM_UUID: &str = "80630680-4da6-45f9-bba8-b888e0ffd58c"; +const NPM_UUID: &str = "642d7f02-ebc1-4ab0-99e2-07f5dd8463cb"; const NPM_PURL: &str = "pkg:npm/minimist@1.2.2"; /// Git SHA-256 of the *unpatched* `index.js` shipped with minimist 1.2.2. const BEFORE_HASH: &str = "311f1e893e6eac502693fad8617dcf5353a043ccc0f7b4ba9fe385e838b67a10"; /// Git SHA-256 of the *patched* `index.js` after the security fix. -const AFTER_HASH: &str = "043f04d19e884aa5f8371428718d2a3f27a0d231afe77a2620ac6312f80aaa28"; +const AFTER_HASH: &str = "ec956dcafb886f14315570bf3981d44aa12c561716abb46eed8b067aaa1f6bdf"; // --------------------------------------------------------------------------- // Helpers diff --git a/crates/socket-patch-cli/tests/e2e_safety_pnpm.rs b/crates/socket-patch-cli/tests/e2e_safety_pnpm.rs index 783e7337a..e70b3511d 100644 --- a/crates/socket-patch-cli/tests/e2e_safety_pnpm.rs +++ b/crates/socket-patch-cli/tests/e2e_safety_pnpm.rs @@ -11,7 +11,7 @@ //! view and the store entry byte-identical. //! //! Fixture: minimist@1.2.2 + its Socket patch (UUID -//! `80630680-4da6-45f9-bba8-b888e0ffd58c`, CVE-2021-44906) — same +//! `642d7f02-ebc1-4ab0-99e2-07f5dd8463cb`, CVE-2021-44906) — same //! pair `e2e_npm.rs` uses, so the BEFORE/AFTER hashes are known. //! //! Network: yes (pnpm install + socket-patch get). Toolchain: pnpm. @@ -24,12 +24,12 @@ mod common; use common::{assert_run_ok, git_sha256_file, has_command, pnpm_run, write_package_json}; -const NPM_UUID: &str = "80630680-4da6-45f9-bba8-b888e0ffd58c"; +const NPM_UUID: &str = "642d7f02-ebc1-4ab0-99e2-07f5dd8463cb"; /// Git-SHA-256 of the *unpatched* `index.js` shipped with minimist 1.2.2. const BEFORE_HASH: &str = "311f1e893e6eac502693fad8617dcf5353a043ccc0f7b4ba9fe385e838b67a10"; /// Git-SHA-256 of the *patched* `index.js` after the security fix. -const AFTER_HASH: &str = "043f04d19e884aa5f8371428718d2a3f27a0d231afe77a2620ac6312f80aaa28"; +const AFTER_HASH: &str = "ec956dcafb886f14315570bf3981d44aa12c561716abb46eed8b067aaa1f6bdf"; // ── Setup helpers ───────────────────────────────────────────────────── diff --git a/crates/socket-patch-cli/tests/e2e_vendored_production.rs b/crates/socket-patch-cli/tests/e2e_vendored_production.rs index 51a34a20f..53f2f2d9c 100644 --- a/crates/socket-patch-cli/tests/e2e_vendored_production.rs +++ b/crates/socket-patch-cli/tests/e2e_vendored_production.rs @@ -49,7 +49,7 @@ //! //! | Ecosystem | PURL | Patch UUID | Marker in the patched bytes | //! |-----------|------|------------|-----------------------------| -//! | npm | `pkg:npm/minimist@1.2.2` | `80630680-4da6-45f9-bba8-b888e0ffd58c` | `Socket Community Patch` header | +//! | npm | `pkg:npm/minimist@1.2.2` | `642d7f02-ebc1-4ab0-99e2-07f5dd8463cb` | `Socket Community Patch` header | //! | PyPI | `pkg:pypi/urllib3@1.26.18` | *any of three* (see [`PYPI_UUIDS`]) | `Socket Community Patch` header | //! | gem | `pkg:gem/activestorage@6.0.3` | *any of* [`GEM_PATCHES`] | `Socket Community Patch` header | //! @@ -137,7 +137,7 @@ const PROXY: &str = "https://patches-api.socket.dev"; const NPM_PURL: &str = "pkg:npm/minimist@1.2.2"; const NPM_NAME: &str = "minimist"; const NPM_VERSION: &str = "1.2.2"; -const NPM_UUID: &str = "80630680-4da6-45f9-bba8-b888e0ffd58c"; +const NPM_UUID: &str = "642d7f02-ebc1-4ab0-99e2-07f5dd8463cb"; const PYPI_PURL: &str = "pkg:pypi/urllib3@1.26.18"; const PYPI_NAME: &str = "urllib3"; diff --git a/docs/testing/bun-compatibility.md b/docs/testing/bun-compatibility.md index 26ef8e5d5..a65b4b96d 100644 --- a/docs/testing/bun-compatibility.md +++ b/docs/testing/bun-compatibility.md @@ -5,7 +5,7 @@ projects using text `bun.lock` or native binary `bun.lockb`. Real-Bun evidence b - **The native matrix** — `scripts/backtest-bun.py` runs real Bun releases against the public free Socket patch for `minimist@1.2.2` - (`80630680-4da6-45f9-bba8-b888e0ffd58c`) with the production CLI and patch + (`642d7f02-ebc1-4ab0-99e2-07f5dd8463cb`) with the production CLI and patch service, without a token or substitute service, and checks the INSTALLED bytes, lock stability, digest rejection and rollback on Linux, macOS and Windows ([workflow](../../.github/workflows/bun-compatibility.yml)). diff --git a/scripts/backtest-bun.py b/scripts/backtest-bun.py index 71020c4c8..8487c7b05 100644 --- a/scripts/backtest-bun.py +++ b/scripts/backtest-bun.py @@ -117,7 +117,7 @@ # former `vendored-detached` leg collapsed into `vendored`: same footprint. MODES = ['hosted', 'vendored'] PURL = 'pkg:npm/minimist@1.2.2' -UUID = '80630680-4da6-45f9-bba8-b888e0ffd58c' +UUID = '642d7f02-ebc1-4ab0-99e2-07f5dd8463cb' # The registry slot bun writes for a non-default registry: the full tarball URL. REGISTRY_SLOT = 'https://registry.npmjs.org/minimist/-/minimist-1.2.2.tgz' LOCAL_TUPLE_SPEC = f'minimist@.socket/vendor/npm/{UUID}/minimist-1.2.2.tgz' diff --git a/scripts/backtest-vlt.py b/scripts/backtest-vlt.py index 18ed56f9d..fb8533fa2 100644 --- a/scripts/backtest-vlt.py +++ b/scripts/backtest-vlt.py @@ -88,7 +88,7 @@ VERSIONS = ['0.0.0-16', '0.0.0-32', '1.0.0-rc.14', '1.0.0-rc.32', '1.0.4', '1.0.10', '1.2.0'] MODES = ['hosted', 'vendored', 'agent'] PURL = 'pkg:npm/minimist@1.2.2' -UUID = '80630680-4da6-45f9-bba8-b888e0ffd58c' +UUID = '642d7f02-ebc1-4ab0-99e2-07f5dd8463cb' NAME = 'minimist' VERSION = '1.2.2' TARGET = f'{NAME}@{VERSION}' @@ -1069,7 +1069,7 @@ def holds(self, root, lock_text, side): ok = True for copy_dir in self.copies(root, lock_text): for key, hashes in self.record['files'].items(): - path = copy_dir / key.split('/', 1)[1] + path = copy_dir / key.removeprefix('package/') digest = git_hash(path.read_bytes()) if path.is_file() else None details[str(path.relative_to(root))] = digest ok = ok and digest == hashes.get(f'{side}Hash') diff --git a/scripts/tests/test_backtest_harnesses.py b/scripts/tests/test_backtest_harnesses.py index bc2ee49dc..3ec7557aa 100644 --- a/scripts/tests/test_backtest_harnesses.py +++ b/scripts/tests/test_backtest_harnesses.py @@ -814,6 +814,39 @@ def test_shapes_are_depscan_capture_shapes(self): self.assertLessEqual(set(vlt.SHAPES), capture_names) +class VltInstalledBytesTests(unittest.TestCase): + def test_holds_checks_root_and_nested_files_with_optional_package_prefix(self): + contents = { + 'index.js': {'before': b'original entrypoint', 'after': b'patched entrypoint'}, + 'test/proto.js': {'before': b'original test', 'after': b'patched test'}, + } + for prefix in ('', 'package/'): + for side in ('before', 'after'): + with self.subTest(prefix=prefix, side=side), tempfile.TemporaryDirectory() as temp: + root = Path(temp) + package = root / 'node_modules' / 'minimist' + record = {'files': { + prefix + name: {s + 'Hash': vlt.git_hash(data) for s, data in sides.items()} + for name, sides in contents.items() + }} + cell = vlt.Cell({'out': root, 'record': record}, '1.2.0', 'vendored', 'direct') + expected = {} + for name, sides in contents.items(): + path = package / name + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(sides[side]) + expected[str(path.relative_to(root))] = vlt.git_hash(sides[side]) + self.assertEqual(cell.holds(root, '{}', side), (True, expected)) + other_side = 'after' if side == 'before' else 'before' + self.assertFalse(cell.holds(root, '{}', other_side)[0]) + + nested = package / 'test' / 'proto.js' + nested.write_bytes(b'corrupted') + self.assertFalse(cell.holds(root, '{}', side)[0]) + nested.unlink() + self.assertFalse(cell.holds(root, '{}', side)[0]) + + class VltConfigTests(unittest.TestCase): """write_vlt_json follows the DESIGN §8.3 per-era registry table."""