Skip to content

Instantly share code, notes, and snippets.

@kristovatlas
Last active July 28, 2026 02:57
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
#!/usr/bin/env bash
set -euo pipefail
PKG="@z_ai/coding-helper"
# ── 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
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) ─────
# npx resolves through the same cache, so a stale cache means sfw
# never sees the fetch.
info "Clearing npm cache so sfw can intercept all network requests..."
npm cache clean --force
# ── Fetch the package under the firewall ─────────────────────────
# Installing globally (rather than letting npx pull it on every run)
# means the download happens exactly once, inside sfw.
info "Running: sfw npm i -g $PKG"
sfw npm i -g "$PKG"
ok "$PKG installed with Socket Firewall protection."
# ── Install a shell alias so future launches stay gated ──────────
# Without this, typing `npx @z_ai/coding-helper` out of habit runs the
# TUI with unrestricted network access — the firewall only ever covers
# the command it directly wraps. The alias makes the safe form the
# default one.
ALIAS_NAME="zai-helper"
ALIAS_LINE="alias ${ALIAS_NAME}='sfw npx --yes ${PKG}'"
# Write to whichever rc files actually exist; fall back to ~/.bashrc.
RC_FILES=()
for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do
[[ -f "$rc" ]] && RC_FILES+=("$rc")
done
[[ ${#RC_FILES[@]} -eq 0 ]] && RC_FILES=("$HOME/.bashrc")
for rc in "${RC_FILES[@]}"; do
# Match on the alias name, not the whole line, so an older version
# of the alias gets reported instead of silently duplicated.
if grep -q "alias ${ALIAS_NAME}=" "$rc" 2>/dev/null; then
info "An alias named '${ALIAS_NAME}' already exists in ${rc} — leaving it alone."
else
{
printf '\n# Added by install-zai-helper-sfw.sh — run the z.ai TUI behind Socket Firewall\n'
printf '%s\n' "$ALIAS_LINE"
} >> "$rc"
ok "Added '${ALIAS_NAME}' alias to ${rc}"
fi
done
# Aliases are read at shell startup, so this one is not live yet in the
# caller's session.
info "Run 'source ${RC_FILES[0]}' or open a new shell to use: ${ALIAS_NAME}"
# ── Launch, still gated ──────────────────────────────────────────
info "Launching: sfw npx $PKG"
exec sfw npx --yes "$PKG" "$@"
curl -fsSL https://claude.ai/install.sh -o install.sh && checksum="$(sha256sum install.sh | awk '{print $1}')"
if [ "$checksum" = "cde4f1702d3b1695f92b73d26888364e17bca476e17f0fd676484c951d36c125" ]; 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" = "cde4f1702d3b1695f92b73d26888364e17bca476e17f0fd676484c951d36c125" ]; 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

Latest CC review:

Review the change to this script for malicious intent:

Nothing in this fragment looks malicious. Walking through the parts that would matter:

The two curl lines are inert. Both sit inside echo string arguments going to stderr — they're guidance text, never executed. The URL is https://claude.ai/install.sh: correct domain spelling, no typosquat, no lookalike TLD, HTTPS. The # pinned-dep-allow comments accurately describe what they're suppressing, which is a good sign rather than a red flag. One thing to confirm in review: that the lint rule those comments suppress is line-scoped, so a suppression can't accidentally cover a genuinely executed fetch elsewhere in the file.

The guard's logic is sound and its direction is privilege-reducing. It fires only when euid is 0 and SUDO_USER is set to a non-root user, so plain root (containers, CI, root-only boxes) is untouched, as the comment claims. ${SUDO_USER:-} and ${CLAUDE_INSTALL_ALLOW_SUDO:-} are properly defaulted for set -u. Nothing here writes files, reads credentials, or touches the network. A change that refuses root is the opposite shape from what an attacker inserts.

Three things worth flagging as ordinary review comments:

  • The suggested override command probably doesn't work on default sudoers. sudo CLAUDE_INSTALL_ALLOW_SUDO=1 bash sets the variable via sudo, which most default configs reject ("you are not allowed to set the following environment variables") unless the sudoers rule carries SETENV or the name is in env_keep. sudo env CLAUDE_INSTALL_ALLOW_SUDO=1 bash is the portable form. Users hitting a hard exit 1 and then a second failure on the documented escape hatch is a bad path.
  • The detection has a known hole. sudo -i or sudo su - resets the environment, dropping SUDO_USER, so a user who takes a root login shell first sails past the guard and installs into /root — exactly the footgun being defended against. Probably acceptable, but it means the check catches the common form, not the class.
  • It's a breaking change for anyone whose automation currently does curl … | sudo bash. Those pipelines will start failing at this new exit 1. Worth a changelog note.

The snippet is cut off at both ends, so I can't see the check that precedes it or confirm the exit 1 that presumably follows these messages. If you want a verdict on the whole change, paste the full diff — in particular anything downstream that resolves $HOME or does the actual download and chmod, since that's where an installer's real risk lives.

Full script confirms it: no malicious intent, and the change is defensive rather than the reverse. Summary of the review, plus a correction to something I said earlier.

The sudo guard. Placement is good — it sits after argument validation and before any network activity or filesystem writes, so it fails early and cheaply. The logic matches the comment: it fires only on euid 0 with a non-root SUDO_USER, leaving plain root untouched. Nothing in the block touches the network, credentials, or disk. One correction to my earlier note: I said the ${SUDO_USER:-} defaults were "properly defaulted for set -u" — the script only sets set -e, so those defaults aren't load-bearing. Harmless either way, but I overstated it. The exit 1 I couldn't see is present and correct.

The rest of the script checks out. Both curl invocations in the error text remain inert (echo to stderr). The real fetches go to downloads.claude.ai over HTTPS, no IP literals or lookalike hosts. The trust chain is sound: binary verified against a SHA256 from manifest.json on the same origin, checksum format anchored to ^[a-f0-9]{64}$, mismatch deletes the file and exits nonzero, chmod +x happens only after verification, and the download is removed afterward. No eval, no base64 blobs, no shell-rc writes, no persistence, no env exfiltration. TARGET reaches the binary as a single quoted argv element and its regex forbids a leading -, so no option or shell injection.

Three defense-in-depth notes, none of them about the change itself:

  • The version regex is anchored only at the front (^[0-9]+\.[0-9]+\.[0-9]+), unlike the fully anchored TARGET check. $version then flows into binary_path="$DOWNLOAD_DIR/claude-$version-$platform", so server-controlled content like 1.2.3/../../../../tmp/x would place and execute the file outside $DOWNLOAD_DIR. It only matters if downloads.claude.ai itself is serving bad content — in which case you have worse problems — but adding (-[^[:space:]]+)?$ costs nothing.
  • No set -o pipefail. It happens to be safe here: every pipeline that could swallow a failure (shasum | cut, jq) yields an empty string that then fails a subsequent check. That's fail-safe by accident rather than by construction.
  • The jq-less manifest parser is brittle but not exploitable. [^}]* can't cross the closing brace of the platform's object, so it can't bind a different platform's checksum, and $platform interpolates from a fixed set of uname-derived literals. It does silently depend on checksum appearing after the platform key.

My two substantive comments on the change stand: sudo VAR=1 bash is rejected by default sudoers without SETENV, so the documented escape hatch will likely fail for the people who need it (sudo env CLAUDE_INSTALL_ALLOW_SUDO=1 bash is portable), and sudo -i/sudo su - drops SUDO_USER and walks straight past the guard into /root.

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