registry  /  getleash  /  0.12.1

getleash@0.12.1

See what your Claude Code agents did last night. Fleet report, costs, loops, dead crons — in 10 seconds. Free cloud dashboard across machines.

AI Security Review

scanned 2h ago · by lpm-firewall-ai

Review flagged AI-agent configuration or capability changes. This remains warn-only unless evidence shows foreign-agent hijack through preinstall/install/postinstall, hidden persistence, exfiltration, remote code execution, or other concrete malicious behavior.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs getleash guard or getleash connect; normal CLI use can push only if cloud config already exists or user opts in interactively.
Impact
Can block Claude Code tool calls for budget guard and can auto-push metrics snapshots after sessions; no prompt/token/file-content exfiltration confirmed.
Mechanism
Explicit user-command Claude Code hook setup and metrics cloud sync
Rationale
The scanner’s credential and command-output exfiltration hints map to documented, package-aligned platform health checks and metrics sync, not concrete malware. Because the package explicitly mutates Claude Code hooks via user commands, classify as a warn-level agent capability/lifecycle risk rather than clean or publish-block malicious.
Evidence
package.jsondist/index.jsREADME.md~/.leash/providers.json~/.leash/gate.mjs~/.leash/guard.json~/.leash/cache.json~/.leash/cloud.json~/.claude/settings.json~/.claude/settings.json.pre-leash
Network endpoints7
api.github.comapi.vercel.comapi.render.comapi.cloudflare.combackboard.railway.app/graphql/v2getleash.vercel.app/api/ingestgetleash.vercel.app/api/alerts

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/index.js: guard command writes ~/.claude/settings.json PreToolUse hook to run ~/.leash/gate.mjs.
  • dist/index.js: connect command writes ~/.claude/settings.json SessionEnd hook for getleash push.
  • dist/index.js: push/connect can POST metrics snapshots to https://getleash.vercel.app/api/ingest.
  • dist/index.js: scans Claude transcripts, launchd, cron, systemd, local repos, and cloud platform status.
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle hooks.
  • Agent settings mutations are behind explicit CLI commands: guard/connect/connect --off, not install-time or import-time.
  • README documents dashboard, guard hooks, cloud push, platform token handling, and offline mode.
  • Provider tokens are sent to their own platform APIs; buildSnapshot strips prompts, transcript content, and file paths.
  • No remote payload download/eval, destructive action, credential exfiltration to package cloud, or stealth persistence found.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetwork
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 1 file(s), 86.7 KB of source, external domains: api.cloudflare.com, api.github.com, api.render.com, api.vercel.com, backboard.railway.app, dash.cloudflare.com, dashboard.render.com, discord.com, getleash.vercel.app, github.com, vercel.com

Source & flagged code

5 flagged · loading source
dist/index.jsView file
43function resolveGithubToken() { L44: for (const env of [process.env.GITHUB_TOKEN, process.env.GH_TOKEN]) { L45: if (env && TOKEN_RE.test(env.trim())) return env.trim(); ... L48: try { L49: const out = (0, import_node_child_process4.execFileSync)(bin, ["auth", "token"], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim(); L50: if (TOKEN_RE.test(out)) return out; ... L70: async function api(pathname, token) { L71: const res = await fetch("https://api.github.com" + pathname, { L72: headers: { ... L79: if (!res.ok) throw new Error(`github ${res.status}`); L80: return res.json(); L81: }
Critical
Credential Exfiltration

Source appears to send environment or credential material to an external endpoint.

dist/index.jsView on unpkg · L43
43function resolveGithubToken() { L44: for (const env of [process.env.GITHUB_TOKEN, process.env.GH_TOKEN]) { L45: if (env && TOKEN_RE.test(env.trim())) return env.trim(); ... L48: try { L49: const out = (0, import_node_child_process4.execFileSync)(bin, ["auth", "token"], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim(); L50: if (TOKEN_RE.test(out)) return out; ... L70: async function api(pathname, token) { L71: const res = await fetch("https://api.github.com" + pathname, { L72: headers: { ... L79: if (!res.ok) throw new Error(`github ${res.status}`); L80: return res.json(); L81: }
Critical
Command Output Exfiltration

Source executes local commands and sends command output to an external endpoint.

dist/index.jsView on unpkg · L43
43Trigger-reachable chain: manifest.bin -> dist/index.js L43: function resolveGithubToken() { L44: for (const env of [process.env.GITHUB_TOKEN, process.env.GH_TOKEN]) { L45: if (env && TOKEN_RE.test(env.trim())) return env.trim(); ... L48: try { L49: const out = (0, import_node_child_process4.execFileSync)(bin, ["auth", "token"], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim(); L50: if (TOKEN_RE.test(out)) return out; ... L70: async function api(pathname, token) { L71: const res = await fetch("https://api.github.com" + pathname, { L72: headers: { ... L79: if (!res.ok) throw new Error(`github ${res.status}`); L80: return res.json(); L81: }
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

dist/index.jsView on unpkg · L43
48try { L49: const out = (0, import_node_child_process4.execFileSync)(bin, ["auth", "token"], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim(); L50: if (TOKEN_RE.test(out)) return out;
High
Child Process

Package source references child process execution.

dist/index.jsView on unpkg · L48
43function resolveGithubToken() { L44: for (const env of [process.env.GITHUB_TOKEN, process.env.GH_TOKEN]) { L45: if (env && TOKEN_RE.test(env.trim())) return env.trim(); ... L48: try { L49: const out = (0, import_node_child_process4.execFileSync)(bin, ["auth", "token"], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim(); L50: if (TOKEN_RE.test(out)) return out; ... L70: async function api(pathname, token) { L71: const res = await fetch("https://api.github.com" + pathname, { L72: headers: { ... L79: if (!res.ok) throw new Error(`github ${res.status}`); L80: return res.json(); L81: }
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

dist/index.jsView on unpkg · L43

Findings

3 Critical1 High4 Medium4 Low
CriticalCredential Exfiltrationdist/index.js
CriticalCommand Output Exfiltrationdist/index.js
CriticalTrigger Reachable Dangerous Capabilitydist/index.js
HighChild Processdist/index.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/index.js
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings