Skip to content

v0.6.2 — an npx rule that works without a prompt

Choose a tag to compare

@echennells echennells released this 26 Aug 00:26
· 11 commits to main since this release

Note: 0.6.3 corrects one line below. npm ci runs install scripts, so it needs --ignore-scripts too — the bare npm ci recommended here does not protect you.

Security

  • An npx rule that holds without a prompt. Since 0.5.0 the mitigation against npx's registry fallback had been "if npx offers to install something, answer NO and stop," carried in SKILL.md, AGENTS.md and README. That rule assumes a prompt. Verified against npm 11: npx only prompts on an interactive TTY. With no TTY — a CI job, a script, or an AI agent running commands through a tool call, which is the context SKILL.md and AGENTS.md exist for — npx installs the fetched package and executes it silently, with nothing displayed and nothing to decline. It protected an interactive human and no one else while reading as general protection. The rule is now one that needs no prompt to work: never run a bare npx for a wallet command — use npm exec --no -- sparkbtcbot <command> or ./node_modules/.bin/sparkbtcbot, and never pass -y/--yes. The pinned npx --package=sparkbtcbot-skill ... form is documented for a human at a terminal and explicitly not offered to agents: --package= names the owned package outright and cannot fall back to a command-name lookup, but it is still an unpinned fetch outside the lockfile.

  • Install guidance uses --ignore-scripts. One production dependency (protobufjs) executes code at npm install time, before the consumer's code has imported anything — the supply-chain footgun with the largest blast radius here, since it runs on the developer's machine with the agent's privileges rather than merely risking wallet funds. The flag costs nothing: the CLI resolves and runs, and both sparkbtcbot-skill and @buildonspark/spark-sdk import cleanly without install scripts.

  • cli.js argument gate no longer falls through on inherited Object properties. The dispatcher looked up COMMANDS[cmd], which walks the prototype chain, so sparkbtcbot constructor, toString, valueOf and __proto__ resolved to a truthy non-entry and reached import(undefined) — a stack trace instead of the usage message, in the one gate whose own comment promises that an unknown command "cannot fall through to anything." Now Object.hasOwn(COMMANDS, cmd). Not exploitable (nothing executed, exit stayed non-zero), but it was the 0.4.3 fall-through class in miniature.

Changed

  • SECURITY.md ships in the npm tarball and gained a section on registry-name reservations — which names this project owns, and why owning them is what protects the npx fallback. Its scope section also named the package sparkbtcbot; that name now resolves to the reservation stub, so it reads sparkbtcbot-skill.