Skip to content

Instantly share code, notes, and snippets.

@kristovatlas
Last active July 22, 2026 14:14
Show Gist options
  • Select an option

  • Save kristovatlas/544b2d7a8314cf21c67e33b5a081695a to your computer and use it in GitHub Desktop.

Select an option

Save kristovatlas/544b2d7a8314cf21c67e33b5a081695a to your computer and use it in GitHub Desktop.
Install Claude Code based on known-good hash instead of curl-bashing; Install Codex with Socket.dev Firewall
#!/usr/bin/env bash
set -euo pipefail
# ── Helpers ──────────────────────────────────────────────────────
info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; }
ok() { printf '\033[1;32m[OK]\033[0m %s\n' "$*"; }
err() { printf '\033[1;31m[ERROR]\033[0m %s\n' "$*" >&2; }
# ── Pre-flight: require npm ──────────────────────────────────────
if ! command -v npm &>/dev/null; then
err "npm is not installed. Please install Node.js/npm first."
exit 1
fi
info "Node $(node -v) / npm $(npm -v)"
# ── Check for Socket Firewall (sfw) ─────────────────────────────
if command -v sfw &>/dev/null; then
ok "Socket Firewall is already installed: $(sfw --version 2>/dev/null || echo 'version unknown')"
else
info "Socket Firewall not found. Installing globally via npm..."
npm i -g sfw
# Verify the install succeeded
if command -v sfw &>/dev/null; then
ok "Socket Firewall installed successfully."
else
err "sfw command not found after install. Check that npm's global bin directory is in your PATH."
err "Hint: npm config get prefix → add <prefix>/bin to your PATH"
exit 1
fi
fi
# ── Clear npm cache (recommended by Socket before first use) ─────
info "Clearing npm cache so sfw can intercept all network requests..."
npm cache clean --force
# ── Run the guarded install ──────────────────────────────────────
info "Running: sfw npm i -g @openai/codex"
sfw npm i -g @openai/codex
ok "Done! @openai/codex installed with Socket Firewall protection."
curl -fsSL https://code.kimi.com/kimi-code/install.sh -o install.sh && checksum="$(sha256sum install.sh | awk '{print $1}')"; if [ "$checksum" = "638927825e96825edbb563de5e0cb06f8a0551c53e026ade8b717b0f25cb83d2" ]; then echo "Checksum matched."; echo "Proceed with installation? (Y/n)"; read response; if [ "$response" = "Y" ] || [ "$response" = "y" ] || [ -z "$response" ]; then bash install.sh && rm -f install.sh; else echo "Installation aborted."; rm -f install.sh; exit 0; fi; else echo "Error: Checksum failed"; exit 1; fi
curl -fsSL https://claude.ai/install.sh -o install.sh && checksum="$(sha256sum install.sh | awk '{print $1}')"
if [ "$checksum" = "b3f79015b54c751440a6488f07b1b64f9088742b9052bc1bd356d13108320d2a" ]; then
echo "Checksum matched."
echo "Proceed with installation? (Y/n)"
read response
if [ "$response" = "Y" ] || [ "$response" = "y" ] || [ -z "$response" ]; then bash install.sh && rm -f install.sh; else
echo "Installation aborted."
rm -f install.sh
exit 0
fi
else
echo "Error: Checksum failed"
exit 1
fi
curl -fsSL https://claude.ai/install.sh -o install.sh && checksum="$(sha256sum install.sh | awk '{print $1}')"; if [ "$checksum" = "b3f79015b54c751440a6488f07b1b64f9088742b9052bc1bd356d13108320d2a" ]; then echo "Checksum matched."; echo "Proceed with installation? (Y/n)"; read response; if [ "$response" = "Y" ] || [ "$response" = "y" ] || [ -z "$response" ]; then bash install.sh && rm -f install.sh; else echo "Installation aborted."; rm -f install.sh; exit 0; fi; else echo "Error: Checksum failed"; exit 1; fi
@kristovatlas

Copy link
Copy Markdown
Author

Today I'm adding the Kimi Code CLI install.sh.
Reviews: Opus 4.8 Max for malicious intent / modification:

Verdict: I found no malicious intent and no signs of tampering. This is a standard trust-on-first-use installer, and actually a more careful-than-average one. The single most sensitive behavior — that it will rename/delete an existing kimi command during migration — is legitimate but worth knowing about (details below).

What the script actually does: detects your OS/arch, resolves a version (pinned or "latest"), downloads a manifest.json and the matching binary from code.kimi.com, verifies the binary's SHA-256 against the manifest, installs it to ~/.kimi-code/bin/kimi, adds that to your PATH, and migrates any old Python kimi-cli shims. That flow matches the official docs exactly, and code.kimi.com/kimi-code/install.sh is the real documented install command from Moonshot AI's own docs and GitHub org — not a look-alike domain.

The things I specifically checked for and didn't find:

No hidden or secondary endpoints. Every network call goes to the one code.kimi.com base URL. No IP addresses, no pastebin/gist/webhook, no base64 -d, no eval, no obfuscation of any kind.
No data exfiltration. Nothing reads SSH keys, cloud credentials, env vars, or browser data. Every network operation is an outbound GET to download; nothing is POSTed anywhere.
Integrity check present. It fetches a checksum, validates its format (^[a-f0-9]{64}$), and refuses to install on mismatch. Many sketchy installers skip this entirely.
No silent privilege escalation. The script never calls sudo itself; it defaults to writing under $HOME. sudo only appears in the optional usage examples.
Good hygiene: set -euo pipefail, a mktemp working dir, and a cleanup trap on exit.

The riskiest part of any installer is anything that deletes or renames files, so I scrutinized the legacy-shim migration (lines ~227–469) closely. It's tightly fenced: it only touches files literally named kimi, only if they're executable, only if the first 4 KB contains the marker kimi_cli, and it explicitly refuses to classify anything inside its own install directory. It resolves symlinks only to sniff the marker but acts on the shim path itself (so it renames/removes the symlink, never the target), checks directory writability before acting, uses mv -- / rm -- to prevent option injection, and always preserves a kimi-legacy fallback. The blast radius is effectively just leftover copies of the old Python CLI. This matches the product's real history — Kimi Code CLI used to be a Python tool installed via uv, and it's now shipping as a single native binary, so cleaning up the old shims is exactly what you'd expect.

Two honest caveats — these are limitations of the approach, not evidence of malice:

Trust-on-first-use. The checksum is served from the same origin as the binary, so it protects against CDN/transport corruption but not against a compromised origin server (an attacker who controlled code.kimi.com would control both). This is inherent to every curl | bash installer, not something specific to this one. You did the right thing saving it and reviewing it rather than piping straight to bash.
This covers the installer, not the binary. The script fetches and installs a closed-source binary; the actual agent code lives there and is out of scope for a shell-script review.

One behavior to be aware of before you run it: the migration will rename your first existing kimi (old Python CLI) to kimi-legacy and delete any duplicate old shims further down your PATH. That's intentional and it keeps a fallback, but if you rely on the old kimi command, know that it's moving.

If you want byte-level certainty that your copy matches what's currently served, you can diff it yourself:

curl -fsSL https://code.kimi.com/kimi-code/install.sh | diff - kimi_install.sh

Two notes on that: a difference isn't necessarily sinister (the hosted script gets updated, so version drift is expected), and I couldn't run this diff from here — my sandbox can't reach kimi.com, and the fetch returns the script as a binary file type rather than text. If you'd prefer to route around direct execution entirely, the documented npm install -g @moonshot-ai/kimi-code path is an alternative that goes through the npm registry's own integrity checks.

virustotal.com: 0/61, but "Matches rule Usage Of Web Request Commands And Cmdlets" and "Matches rule Curl Usage on Linux by Nasreddine Bencherchali (Nextron Systems) at Sigma Integrated Rule Set (GitHub)"
638927825e96825edbb563de5e0cb06f8a0551c53e026ade8b717b0f25cb83d2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment