Back to skill

Security audit

Bitkit Cli

Security checks for vulnerabilities and agentic risk

Overview

This is a real Bitcoin/Lightning wallet skill, but its install and agent workflows expose users to unnecessary risk of code execution and irreversible fund loss.

Install only after reviewing and pinning the installer or building from trusted source. Do not use --no-password for wallets holding real funds, keep seed phrases out of agent transcripts and logs, use small isolated wallets, set explicit fee and spending limits, and require approval before any send, pay, channel, or LSP funding action.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:17
Finding

Mutable Remote Installer Is Executed Directly Through a Shell

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
install.sh:40
Finding

Installer Trusts Mutable Precompiled Binaries and Same-Origin Checksums

Content
View full analysis
/dev/null 2>&1; then grep "$archive" checksums.sha256 | sha256sum -c --quiet elif command -v shasum >/dev/null 2>&1; then grep "$archive" checksums.sha256 | shasum -a 256 -c --quiet else echo "Warning: cannot verify checksum (no sha256sum or shasum found)" >&2 fi # Extract and install tar xzf "$archive" dir="${BINARY}-${tag}-${target}" install -m 755 "${dir}/bitkit" "${install_dir}/bitkit" install -m 755 "${dir}/bk" "${install_dir}/bk" ``` ### Technical Analysis The installer dynamically resolves the newest release and retrieves both the executable archive and its checksum file from the same GitHub release channel. If that repository or release channel is compromised, an attacker can replace both files, causing checksum validation to succeed for a malicious executable. A checksum verifies accidental corruption only when its expected value is obtained from an independently trusted source. It does not establish publisher authenticity when the binary and checksum share the same compromise boundary. The verification logic is also fail-open: if neither `sha256sum` nor `shasum` exists, the installer emits a warning and proceeds to extract and install the executable. The script does not verify a publisher signature, pin a release digest, or constrain the installation to a version reviewed by the ...[truncated 1478 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:167
Finding

Agent Workflows Recommend Plaintext Wallet Seeds and Expose Mnemonics in JSON

Content
View full analysis
` | one of | Encrypt seed with AES-256-GCM + Argon2id | ``` The same insecure initialization pattern is used in the quick-start and end-to-end agent examples, including `SKILL.md:41`, `SKILL.md:1307`, and `SKILL.md:1342`. ### Technical Analysis The recommended agent initialization command explicitly disables seed encryption. The documentation states that this mode stores the seed in plaintext. A BIP39 seed phrase is sufficient to reconstruct the wallet and authorize transfers, so it must be treated as a high-value authentication secret. The documented JSON response also includes the seed phrase in machine-readable output. Agent environments commonly retain command output in transcripts, execution logs, observability platforms, CI logs, or debugging records. Redirecting stdout to `/dev/null` in some later examples does not eliminate the plaintext file risk and does not protect other invocations. This approach prioritizes unattended automation over safe secret management without imposing compensating controls such as an OS keychain, hardware-backed key storage, isolated signer, restricted wallet balance, or explicit log redaction. ### Attack Path 1. A ...[truncated 1003 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:1274
Finding

Messaging Workflow Pays Externally Supplied Invoices Without Required Validation or Approval

Content
View full analysis
/dev/null) if [ "$TYPE" = "invoice" ]; then BOLT11=$(echo "$MSG" | jq -r '.data.content' | jq -r '.bolt11') echo "Received invoice: $BOLT11" break fi done # 4. Pay the invoice bk pay "$BOLT11" --json ``` A corresponding automatic-payment pattern also appears in the Agent A workflow at `SKILL.md:1346-1358`. ### Technical Analysis The workflow treats a message whose JSON `type` equals `invoice` as sufficient authorization to invoke an irreversible payment. It does not require the agent to decode and validate the BOLT11 invoice before payment. Missing controls include verification of the encoded amount, expected payee, Bitcoin network, expiry, description, request correlation identifier, duplicate-payment status, maximum amount, and maximum routing fee. The `pay` invocation does not use the documented `--max-fee` restriction. End-to-end encryption protects message confidentiality and integrity in transit, but it does not establish that a peer remains trustworthy or that every invoice sent by that peer is authorized. A malicious or compromised expected peer can still provide an excessive, substituted, stale, or unrelated invoice. The shell example also relies on a variable assigned inside a piped `while` loop, which may execute in a subshell in common shells. Although that can cause the example to fail rather ...[truncated 1241 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (19)

Docker Socket Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · CONTRIBUTING.md (reported line 128)May include surrounding context.

Docker socket not found: If you see Cannot connect to the Docker daemon, your Docker socket may not be at the default path. Set DOCKER_HOST:

sh
export DOCKER_HOST=unix:///var/run/docker.sock

Flaky channel timeouts: Economy tests wait up to 30 seconds for channels to become usable. If a test times out on wait_for_usable_channel, it's usually a timing issue — retry once. Ensure --test-threads=1 to avoid resource contention.

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

The | sh pattern creates an execution chain where remotely retrieved content is immediately executed, eliminating any opportunity for review or integrity validation. In an agent skill context this is more dangerous than in ordinary docs, because autonomous systems may follow installation guidance verbatim, turning documentation into a direct remote code execution path.

Content

Scanner excerpt · README.md (reported line 37)May include surrounding context.

Installation

bash
curl -sSL https://raw.githubusercontent.com/synonymdev/bitkit-cli/main/install.sh | sh

Or build from source:

External Script Fetching

High
Category
Supply Chain
Confidence
95% confidence
Finding

The installer fetches both the binary archive and its checksum file from the same remote source and then trusts that checksum for verification. If the GitHub release, redirect target, or network path is compromised, an attacker can supply both a malicious binary and matching checksum, defeating integrity verification and leading to arbitrary code execution once the installed binary is run.

Content

Scanner excerpt · install.sh (reported line 47)May include surrounding context.

sh
echo "Installing ${BINARY} ${tag} for ${target}..."

  # Download archive and checksums
  curl -sSL "${base_url}/${archive}" -o "${tmpdir}/${archive}"
  curl -sSL "${base_url}/checksums.sha256" -o "${tmpdir}/checksums.sha256"

  # Verify checksum

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The README presents fund-moving commands on mainnet by default, including address funding, channel ordering, invoice creation, and payment, without a clear warning that these actions can spend or receive real funds. For an agent-facing CLI, ambiguity about mainnet default behavior increases the chance of accidental financial loss from mistaken invocation or unsafe testing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README explicitly instructs users and agents to initialize a wallet with --no-password, which creates an unencrypted seed, but it does not clearly warn that this exposes the wallet secrets at rest. In an agent context, this is especially dangerous because automation often runs on shared hosts, CI runners, containers, or machines with broader process/file access, making theft of funds substantially easier if the wallet directory is exposed.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 143)May include surrounding context.

md
| Network | Chain Source | Default URL | Blocktank URL |
|---------|-------------|-------------|---------------|
| mainnet | Esplora | `https://blockstream.info/api` | `https://api1.blocktank.to/api` |
| regtest | Electrum | `tcp://127.0.0.1:60001` | `https://api.stag0.blocktank.to/blocktank/api/v2` |

Mainnet also uses [Rapid Gossip Sync](https://docs.rs/lightning-rapid-gossip-sync) for fast graph updates.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill exposes extensive shell-driven capabilities for wallet creation, daemon control, networking, and irreversible fund movement, but does not declare any explicit tool scope or allowed-tools boundaries. In an agent setting, this increases the chance that a model can invoke high-risk shell actions without least-privilege constraints or operator review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The quick start recommends bk init --no-password specifically 'for agent use', normalizing plaintext seed storage for a self-custody wallet. Because the seed is the recovery secret for all funds, any host compromise, log capture, filesystem exposure, or multi-tenant agent environment can lead to full wallet theft.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The example output includes a full mnemonic seed phrase in documentation without an adjacent warning that it is highly sensitive recovery material. In agent workflows, users often copy examples into prompts, logs, tests, or screenshots; normalizing visible seed output greatly increases the likelihood of accidental secret disclosure and total loss of funds.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The send, bump-fee, and cpfp sections describe irreversible on-chain fund-moving operations without strong cautions, confirmation guidance, or safe-preview defaults. In an autonomous agent context, these commands can rapidly move or drain funds to attacker-supplied addresses, and mistakes are generally not reversible.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The pay command supports BOLT11, LNURL, and Lightning Address flows but lacks an explicit warning that successful payment irreversibly spends funds and may reveal metadata to external services during resolution. This is especially dangerous for agent use because untrusted messages or content can embed payment requests that the agent may process automatically.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
82% confidence
Finding

The daemon API password persists across restarts and is stored on disk, creating a reusable local secret that can be abused by malware, other local users with access, or compromised agent sessions. In a wallet-managing skill, persistent local API credentials materially increase the blast radius because they protect endpoints capable of reading balances and initiating financial actions.

Content

Scanner excerpt · SKILL.md (reported line 1152)May include surrounding context.

Location: <wallet_dir>/api-password (e.g., ~/.bitkit/api-password) Format: 32 random bytes encoded as 64 hex characters Permissions: File mode 0600 (owner read/write only)

bash
# Read the password

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 29)May include surrounding context.

sh
# Find install directory
  if [ -w /usr/local/bin ]; then
    install_dir="/usr/local/bin"
  elif [ -d "$HOME/.local/bin" ] || mkdir -p "$HOME/.local/bin" 2>/dev/null; then
    install_dir="$HOME/.local/bin"
  else
    echo "Cannot find writable install directory." >&2

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · install.sh (reported line 33)May include surrounding context.

sh
install_dir="$HOME/.local/bin"
  else
    echo "Cannot find writable install directory." >&2
    echo "Run with sudo or create ~/.local/bin" >&2
    exit 1
  fi

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This shell script fetches release artifacts from GitHub and installs binaries into /usr/local/bin or ~/.local/bin, which modifies the user's system. Although it prints progress messages, it does not ask for confirmation or provide a clear warning that it will download remote code and place executables on PATH before doing so.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

Low
Category
Tool Misuse
Confidence
15% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · CONTRIBUTING.md (reported line 138)May include surrounding context.

sh
cd bitkit-docker
docker compose down -v
rm -rf ./lnd ./lnurl-server/data
docker compose up -d

External Script Fetching

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The installation instructions recommend fetching a remote script over the network and piping it directly to sh, which executes unreviewed code immediately with the user's privileges. If the hosting source, repository, network path, or account is compromised, users and agents could be induced to run arbitrary malicious code.

Content

Scanner excerpt · README.md (reported line 37)May include surrounding context.

Installation

bash
curl -sSL https://raw.githubusercontent.com/synonymdev/bitkit-cli/main/install.sh | sh

Or build from source:

External Script Fetching

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The installation instruction pipes a remotely fetched script directly into sh, which prevents integrity review and makes the environment trust the current contents of a network resource at execution time. If the source repository, distribution path, TLS trust chain, or local network is compromised, arbitrary code can run with the user's privileges.

Content

Scanner excerpt · SKILL.md (reported line 17)May include surrounding context.

md
Bitcoin Lightning payment CLI for agents. Lowest LSP fees. Self-custody wallet with LNURL/Lightning Address support, typed exit codes, JSON envelope output, encrypted Pubky messaging, and daemon mode.

**Install:** `curl -sSL https://raw.githubusercontent.com/synonymdev/bitkit-cli/main/install.sh | sh`
**Binary names:** `bitkit` or `bk` (identical alias)
**Always use:** `--json` flag on every invocation for parseable output.

Excessive Permissions

Low
Category
Privilege Escalation
Confidence
80% confidence
Finding

Skill requests more permissions than appear necessary for its stated functionality. Review if elevated access is justified.

Content

Scanner excerpt · SKILL.md (reported line 1152)May include surrounding context.

Location: <wallet_dir>/api-password (e.g., ~/.bitkit/api-password) Format: 32 random bytes encoded as 64 hex characters Permissions: File mode 0600 (owner read/write only)

bash
# Read the password

Static analysis

No suspicious patterns detected.