From 1b8beb266f46aab7daebffe3b50401b36c7024e3 Mon Sep 17 00:00:00 2001 From: Martin Vogel Date: Fri, 7 Aug 2026 20:49:46 +0200 Subject: [PATCH 1/2] harden(cli): stop shipping a policy-bypass invocation inside the binary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `cbm update` printed the Windows update command with an execution-policy override baked in as a string literal. That put one of the most heavily weighted malicious-script patterns there is inside every Windows artifact we distribute — to save the user a single documented step. The command now prints without it. Functionality is unchanged: the user still gets a runnable command, and the failure it was pre-empting (PowerShell refusing a file that arrived from the internet) is answered by Unblock-File, which the message now names. The restricted-policy case is documented in the README's Windows install section, which is the right home for that incantation — a shipped binary is not. Scope note, so this is not oversold: the 2026-08-07 dry-run detections are NOT attributable to this string. It is `#ifdef _WIN32`, and every Windows artifact scanned clean; the three flagged artifacts were Linux and macOS. This is margin hygiene, not a fix for that regression — see the analysis in the PR. Verification limit worth stating: the built-artifact check for this string is vacuous on a non-Windows host, since the literal was Windows-only to begin with. What is verified here is the source (no occurrence outside a comment) plus lint and the cli suite; a real artifact check needs the Windows build leg in CI. Signed-off-by: Martin Vogel --- src/cli/cli.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/cli/cli.c b/src/cli/cli.c index 37cb397d89..81a4f2ac21 100644 --- a/src/cli/cli.c +++ b/src/cli/cli.c @@ -11498,18 +11498,29 @@ int cbm_cmd_update(int argc, char **argv) { } printf("codebase-memory-mcp update (current: %s)\n\n", CBM_VERSION); #ifdef _WIN32 + /* The printed command deliberately carries NO execution-policy override. + * A policy-bypass invocation is one of the most heavily weighted + * malicious-script patterns there is, and emitting it as a literal put + * that signature inside every Windows artifact we distribute — to save + * the user one documented step. Pointing at Unblock-File reaches the + * same outcome and leaves the policy decision with them. README's + * Windows install section carries the override for the + * restricted-policy case: documentation is the right place to hand out + * that incantation, a shipped binary is not. */ printf("The update runs from install.ps1, not from this process. Close any\n" "running sessions, then run\n\n"); if (have_dir) { - printf(" powershell -ExecutionPolicy Bypass -File \"%s\\install.ps1\"\n\n", self_dir); + printf(" powershell -File \"%s\\install.ps1\"\n\n", self_dir); } else { - printf(" powershell -ExecutionPolicy Bypass -File install.ps1\n" + printf(" powershell -File install.ps1\n" " (ships in the release archive, and is placed beside the\n" " binary on install)\n\n"); } printf("It downloads the latest release, verifies its checksum, and replaces\n" - "this binary in place. If PowerShell refuses to run the script because\n" - "it came from the internet, Unblock-File it first.\n"); + "this binary in place. If PowerShell refuses to run the script, it is\n" + "usually because the file arrived from the internet: run\n" + "'Unblock-File install.ps1' first. If your execution policy still\n" + "blocks it, the README's Windows install section lists the options.\n"); #else printf("The update runs from install.sh, not from this process. Run\n\n"); if (have_dir) { From c7782e0b479db76de93ef9dd388159ba17f02e42 Mon Sep 17 00:00:00 2001 From: Martin Vogel Date: Fri, 7 Aug 2026 21:56:22 +0200 Subject: [PATCH 2/2] test(windows-bundle): pin the install.ps1 hand-off, not the bypass flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The contract asserted the literal "powershell -ExecutionPolicy Bypass -File" appeared in cbm_cmd_update, so removing that string from the binary reddened every test leg on every platform — the contracts run as step 0 of scripts/test.sh, so one violation stops the matrix before a single suite executes. 13 checks, one cause. The contract's stated intent is that the Windows update command "must hand off to install.ps1 and must NOT carry an in-process self-update path". The bypass flag was never that property, only the literal form the command happened to take. The assertion now pins the hand-off itself ("powershell -File" plus install.ps1), which is what the comment always claimed to protect. Adds the inverse assertion in the same place: the printed command must NOT contain an execution-policy override at all. Without it this contract would silently permit the pattern coming back, and the whole point of removing it was that a shipped binary is the wrong place to carry a canonical loader signature. Process note for myself: I ran the cli suite and lint before pushing, but not the contracts — which is precisely the gap recorded as "scripts/test.sh runs them as step zero of EVERY leg, so one violation reddens all 30 CI jobs". Ran the full contract set this time. Signed-off-by: Martin Vogel --- tests/test_windows_bundle_contract.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/test_windows_bundle_contract.sh b/tests/test_windows_bundle_contract.sh index 50382ee6d1..430b5ba60c 100644 --- a/tests/test_windows_bundle_contract.sh +++ b/tests/test_windows_bundle_contract.sh @@ -749,9 +749,20 @@ update_windows_block = ( require( update_start >= 0 and "install.ps1" in update_windows_block - and "powershell -ExecutionPolicy Bypass -File" in update_windows_block, + and "powershell -File" in update_windows_block, "cbm_cmd_update must print the install.ps1 command on Windows", ) +# The printed command must NOT carry an execution-policy override. That is a +# canonical malicious-loader pattern, and emitting it as a string literal put +# the signature inside every Windows artifact we ship — to save the user one +# documented step. The hand-off above is the property this contract cares +# about; the bypass flag was only ever the literal form it happened to take. +# Unblock-File covers the common case and the README covers the rest. +require( + "ExecutionPolicy" not in update_windows_block, + "cbm_cmd_update must not print an execution-policy override " + "(document it instead of shipping the pattern in the binary)", +) require( "cbm_windows_launcher" not in cli_source and "windows_launcher_state.h" not in cli_source,