From a438175e8ae4e958c240d39af78764f074629f21 Mon Sep 17 00:00:00 2001 From: Reinier Criel Date: Mon, 27 Oct 2025 13:28:35 -0700 Subject: [PATCH] Fix tests --- README.md | 4 ++-- docs/shell-integration.md | 13 +++---------- .../shell-integration/startup-scripts/init-posix.sh | 4 ++-- packages/safe-chain/src/utils/safeSpawn.spec.js | 9 +++++++++ 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 5b393de..e438475 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Installing the Aikido Safe Chain is easy. You just need 3 simple steps: ``` - The output should show that Aikido Safe Chain is blocking the installation of this package as it is flagged as malware. -When running `npm`, `npx`, `yarn`, `pnpm`, `pnpx`, `bun`, `bunx`, `pip`, or `pip3` commands, the Aikido Safe Chain will automatically check for malware in the packages you are trying to install. It also intercepts Python module invocations for pip when available (e.g., `python -m pip install ...`, `python3 -m pip download ...`, and on Windows `py -m pip ...`). If any malware is detected, it will prompt you to exit the command. +When running `npm`, `npx`, `yarn`, `pnpm`, `pnpx`, `bun`, `bunx`, `pip`, or `pip3` commands, the Aikido Safe Chain will automatically check for malware in the packages you are trying to install. It also intercepts Python module invocations for pip when available (e.g., `python -m pip install ...`, `python3 -m pip download ...`). If any malware is detected, it will prompt you to exit the command. You can check the installed version by running: @@ -50,7 +50,7 @@ safe-chain --version ## How it works -The Aikido Safe Chain works by running a lightweight proxy server that intercepts package downloads from the npm registry and PyPI. When you run npm, npx, yarn, pnpm, pnpx, bun, bunx, `pip`, or `pip3` commands, all package downloads are routed through this local proxy, which verifies packages in real-time against **[Aikido Intel - Open Sources Threat Intelligence](https://intel.aikido.dev/?tab=malware)**. Python `-m pip[...]` invocations are also routed when invoked by command name. If malware is detected in any package (including deep dependencies), the proxy blocks the download before the malicious code reaches your machine. +The Aikido Safe Chain works by running a lightweight proxy server that intercepts package downloads from the npm registry and PyPI. When you run npm, npx, yarn, pnpm, pnpx, bun, bunx, `pip`, or `pip3` commands, all package downloads are routed through this local proxy, which verifies packages in real-time against **[Aikido Intel - Open Sources Threat Intelligence](https://intel.aikido.dev/?tab=malware)**. If malware is detected in any package (including deep dependencies), the proxy blocks the download before the malicious code reaches your machine. The Aikido Safe Chain integrates with your shell to provide a seamless experience when using npm, npx, yarn, pnpm, pnpx, bun, bunx, and pip commands. It sets up aliases for these commands so that they are wrapped by the Aikido Safe Chain commands, which manage the proxy server before executing the original commands. We currently support: diff --git a/docs/shell-integration.md b/docs/shell-integration.md index 97c96c1..e7afbe5 100644 --- a/docs/shell-integration.md +++ b/docs/shell-integration.md @@ -2,7 +2,7 @@ ## Overview -The shell integration automatically wraps common package manager commands (`npm`, `npx`, `yarn`, `pnpm`, `pnpx`, `bun`, `bunx`, `pip`, `pip3`) with Aikido's security scanning functionality. It also intercepts Python module invocations for pip when available: `python -m pip`, `python -m pip3`, `python3 -m pip`, `python3 -m pip3`, and on Windows PowerShell `py -m pip`/`py -m pip3`. This is achieved by sourcing startup scripts that define shell functions to wrap these commands with their Aikido-protected equivalents. +The shell integration automatically wraps common package manager commands (`npm`, `npx`, `yarn`, `pnpm`, `pnpx`, `bun`, `bunx`, `pip`, `pip3`) with Aikido's security scanning functionality. It also intercepts Python module invocations for pip when available: `python -m pip`, `python -m pip3`, `python3 -m pip`, `python3 -m pip3`. This is achieved by sourcing startup scripts that define shell functions to wrap these commands with their Aikido-protected equivalents. ## Supported Shells @@ -29,7 +29,7 @@ This command: - Copies necessary startup scripts to Safe Chain's installation directory (`~/.safe-chain/scripts`) - Detects all supported shells on your system - Sources each shell's startup file to add Safe Chain functions for `npm`, `npx`, `yarn`, `pnpm`, `pnpx`, `bun`, `bunx`, `pip`, and `pip3` -- Adds lightweight interceptors so `python -m pip[...]` and `python3 -m pip[...]` (and `py -m pip[...]` on Windows PowerShell) route through Safe Chain when invoked by name +- Adds lightweight interceptors so `python -m pip[...]` and `python3 -m pip[...]` route through Safe Chain when invoked by name ❗ After running this command, **you must restart your terminal** for the changes to take effect. This ensures that the startup scripts are sourced correctly. @@ -81,12 +81,6 @@ This means the shell functions are working but the Aikido commands aren't instal - Verify the `aikido-npm`, `aikido-npx`, `aikido-yarn`, `aikido-pnpm`, `aikido-pnpx`, `aikido-bun`, `aikido-bunx`, `aikido-pip`, and `aikido-pip3` commands exist - Check that these commands are in your system's PATH -**`python -m pip` is not being intercepted:** - -- Ensure you are invoking `python`/`python3`/`py` by name (not via an absolute path). Shell function interception only occurs for command names resolved through PATH and won’t catch absolute paths like `/usr/bin/python -m pip`. -- Restart your terminal so the updated startup scripts are sourced. -- On Windows PowerShell, verify `python`, `python3` or `py` resolves by running `Get-Command python` / `Get-Command py`. - ### Manual Verification To verify the integration is working, follow these steps: @@ -105,8 +99,7 @@ To verify the integration is working, follow these steps: After restarting your terminal, run these commands: - `npm --version` - Should show output from the Aikido-wrapped version - - `type npm` - Should show that `npm` is a function - - Optionally: `python -m pip --version` (or `python3 -m pip --version`) should show Safe Chain output at the end + - `type npm` - Should show that `npm` is a function 3. **If you need to remove the integration manually:** diff --git a/packages/safe-chain/src/shell-integration/startup-scripts/init-posix.sh b/packages/safe-chain/src/shell-integration/startup-scripts/init-posix.sh index 2415fb0..e4e0362 100644 --- a/packages/safe-chain/src/shell-integration/startup-scripts/init-posix.sh +++ b/packages/safe-chain/src/shell-integration/startup-scripts/init-posix.sh @@ -69,8 +69,7 @@ function pip3() { wrapSafeChainCommand "pip3" "aikido-pip3" "$@" } -# Intercept `python -m pip[...]` so it routes through safe-chain without changing python itself. -# Supports: `python -m pip`, `python -m pip3`, `python3 -m pip`, `python3 -m pip3`. +# `python -m pip`, `python -m pip3`. function python() { if [[ "$1" == "-m" && "$2" == pip* ]]; then local mod="$2" @@ -85,6 +84,7 @@ function python() { fi } +# `python3 -m pip`, `python3 -m pip3'. function python3() { if [[ "$1" == "-m" && "$2" == pip* ]]; then local mod="$2" diff --git a/packages/safe-chain/src/utils/safeSpawn.spec.js b/packages/safe-chain/src/utils/safeSpawn.spec.js index a07907d..9e25997 100644 --- a/packages/safe-chain/src/utils/safeSpawn.spec.js +++ b/packages/safe-chain/src/utils/safeSpawn.spec.js @@ -245,6 +245,15 @@ describe("safeSpawnPy", () => { }; return obj; }, + // Provide execSync so the module under test can import it without ESM errors. + // We don't actually execute it in safeSpawnPy flows, but Node's module loader + // validates the presence of the named export during import. + execSync: (cmd) => { + // Minimal stub: emulate `command -v ` returning a path + const match = /command -v (.*)/.exec(String(cmd) || ""); + const bin = match?.[1] || "mockbin"; + return `/usr/bin/${bin}\n`; + }, }, });