Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/cli/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
13 changes: 12 additions & 1 deletion tests/test_windows_bundle_contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading