Back to skill

Security audit

Lightning Security Module

Security checks for vulnerabilities and agentic risk

Overview

This skill is Review because it sets up a legitimate Lightning remote signer but uses high-risk defaults for credentials, secrets, network exposure, and dependency installation.

Install only after reviewing and changing the defaults: use a signer-scoped macaroon instead of admin.macaroon, avoid copy-paste/base64 transfer of privileged credentials, protect or avoid plaintext seed and password files, bind REST/RPC to private interfaces or a VPN/firewall, and pin/verify Docker images or source commits before using this with real funds.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/export-credentials.sh:220
Finding

Unrestricted Admin Macaroon Is Exported to the Less-Trusted Agent Machine

Content
View full analysis
&2 exit 1 fi cp "$MACAROONPATH" "$BUNDLE_DIR/admin.macaroon" elif [ -n "$CONTAINER" ]; then MACAROON="$LND_SIGNER_DIR/data/chain/bitcoin/$NETWORK/admin.macaroon" docker cp "$CONTAINER:$MACAROON" "$BUNDLE_DIR/admin.macaroon" 2>/dev/null if [ ! -f "$BUNDLE_DIR/admin.macaroon" ]; then echo "Error: Admin macaroon not found at $MACAROON in container '$CONTAINER'" >&2 exit 1 fi else MACAROON="$LND_SIGNER_DIR/data/chain/bitcoin/$NETWORK/admin.macaroon" if [ ! -f "$MACAROON" ]; then echo "Error: Admin macaroon not found at $MACAROON" >&2 exit 1 fi cp "$MACAROON" "$BUNDLE_DIR/admin.macaroon" fi echo " admin.macaroon copied." echo "" # Create portable base64-encoded tar.gz bundle. BUNDLE_ARCHIVE="$LNGET_SIGNER_DIR/credentials-bundle.tar.gz.b64" echo "Creating portable bundle..." tar -czf - -C "$BUNDLE_DIR" accounts.json tls.cert admin.macaroon | base64 > "$BUNDLE_ARCHIVE" ``` ### Technical Analysis The Skill's legitimate requirement is to authorize the watch-only node to invoke a limited set of remote-signing and key-derivation operations. Instead, the default workflow copies the signer's unrestricted `admin.macaroon` and transfers it to the agent machine. An LND admin macaroon authorizes substantially more RPC operations than the signing workflow requires. Transferring it across the signer trust boundary ther ...[truncated 1471 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
templates/docker-compose-signer.yml:22
Finding

Signer RPC and Wallet-Management REST Services Are Published on All Host Interfaces

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/export-credentials.sh:127
Finding

Base64 Credential Archive Can Be Created with World-Readable Permissions

Content
View full analysis
/dev/null; then echo "Error: lncli not found in container '$CONTAINER'." >&2 exit 1 fi elif [ -z "$RPCSERVER" ]; then if ! command -v lncli &>/dev/null; then echo "Error: lncli not found. Run install.sh first." >&2 exit 1 fi else if ! command -v lncli &>/dev/null; then echo "Error: lncli not found. Install lncli to connect to the remote signer." >&2 exit 1 fi fi # Create bundle directory. mkdir -p "$BUNDLE_DIR" chmod 700 "$BUNDLE_DIR" ``` The sensitive archive is subsequently written without setting a restrictive mode: ```bash # Create portable base64-encoded tar.gz bundle. BUNDLE_ARCHIVE="$LNGET_SIGNER_DIR/credentials-bundle.tar.gz.b64" echo "Creating portable bundle..." tar -czf - -C "$BUNDLE_DIR" accounts.json tls.cert admin.macaroon | base64 > "$BUNDLE_ARCHIVE" ``` ### Technical Analysis The script restricts `credentials-bundle/` to mode `0700`, but it does not set a restrictive process umask, explicitly protect the parent directory, or apply mode `0600` to `credentials-bundle.tar.gz.b64`. When `export-credentials.sh` is invoked independently and the parent hierarchy does not already exist, `mkdir -p "$BUNDLE_DIR"` can create parent directories according to the user's umask. Under a common `022` umas ...[truncated 1213 chars]
Remediation
View remediation
"$tmp_archive" chmod 600 "$tmp_archive" mv -f "$tmp_archive" "$BUNDLE_ARCHIVE" ``` 4. Explicitly apply `chmod 600` to every credential file and archive. 5. Remove obsolete archives before rotation and provide a secure cleanup command. 6. Consider encrypting the transfer bundle to a specific recipient with age, GPG, or another authenticated encryption mechanism instead of relying on base64. ]]>

T08 · Insecure Dependencies

Error
Location
scripts/install.sh:81
Finding

Signer Dependencies Are Retrieved and Executed Without Immutable Verification

Content
View full analysis
/dev/null || echo "") if [ -n "$LATEST_TAG" ]; then echo "Using latest tag: $LATEST_TAG" git checkout --quiet "$LATEST_TAG" else echo "Using HEAD (no tags found)." fi fi ``` Docker installation pulls and executes a tag without digest verification: ```bash IMAGE="${LND_IMAGE:-lightninglabs/lnd}" TAG="${VERSION:-${LND_VERSION:-v0.20.0-beta}}" echo "Image: $IMAGE:$TAG" echo "" # Pull the image. echo "Pulling image..." docker pull "$IMAGE:$TAG" echo "" # Verify the image works. echo "Verifying installation..." docker run --rm "$IMAGE:$TAG" lnd --version 2>/dev/null || true ``` ### Technical Analysis Git tags and Docker image tags are references rather than immutable content identities. The source workflow does not verify a commit hash, signed tag, source checksum, or release signature. If no version is provided externally, it selects the latest available tag or even repository `HEAD`. The Docker workflow uses an image tag and immediately executes the downloaded image. It does no ...[truncated 1345 chars]
Remediation
View remediation
``` 4. Store the expected commit, image digest, and release checksums inside the audited project rather than relying exclusively on an optional external `versions.env`. 5. Fail closed when immutable version metadata is missing. 6. Verify downloaded release artifacts using published checksums and signatures. 7. Generate and retain an SBOM and build provenance record for signer deployments. 8. Do not run an image merely to test its version until its digest and provenance have been validated. ]]>
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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The documentation normalizes exporting and packaging an admin macaroon credential bundle and supports direct remote RPC export, while presenting the skill primarily as a protective isolation mechanism. That description-behavior gap is dangerous because users may trust the skill as hardening-focused while it also facilitates movement of highly privileged credentials between machines.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documentation normalizes exporting and packaging an admin macaroon credential bundle and supports direct remote RPC export, while presenting the skill primarily as a protective isolation mechanism. That description-behavior gap is dangerous because users may trust the skill as hardening-focused while it also facilitates movement of highly privileged credentials between machines.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documentation normalizes exporting and packaging an admin macaroon credential bundle and supports direct remote RPC export, while presenting the skill primarily as a protective isolation mechanism. That description-behavior gap is dangerous because users may trust the skill as hardening-focused while it also facilitates movement of highly privileged credentials between machines.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documentation normalizes exporting and packaging an admin macaroon credential bundle and supports direct remote RPC export, while presenting the skill primarily as a protective isolation mechanism. That description-behavior gap is dangerous because users may trust the skill as hardening-focused while it also facilitates movement of highly privileged credentials between machines.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The skill documents storage of the wallet password and 24-word seed in plaintext files under the user's home directory. Even with 0600 permissions, plaintext seed and passphrase files materially increase the chance of theft through local compromise, backups, logs, malware, agent overreach, or accidental disclosure, directly enabling full fund compromise.

Content

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

md
| Path | Purpose |
|------|---------|
| `~/.lnget/signer/wallet-password.txt` | Signer wallet passphrase (0600) |
| `~/.lnget/signer/seed.txt` | Signer seed mnemonic (0600) |
| `~/.lnget/signer/credentials-bundle/` | Exported credentials |
| `~/.lnget/signer/signer-lnd.conf` | Signer config (native mode) |

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Bundling a full admin macaroon and promoting copy/paste transfer creates a portable bearer token that can be reused by any recipient with access to the file or base64 blob. In the context of a skill advertised as firewalling private key material for watch-only nodes, this is especially dangerous because it preserves a high-privilege control channel to the signer despite key isolation.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The script documentation explicitly states that the wallet password and seed mnemonic are stored on disk in plaintext. Even with restrictive filesystem permissions, persistent plaintext storage of the signer seed and passphrase creates a high-value target: any local compromise, backup leakage, or accidental file exposure can result in full wallet takeover.

Content

Scanner excerpt · scripts/setup-signer.sh (reported line 14)May include surrounding context.

sh
#   setup-signer.sh --native --password "mypass" # Custom passphrase
#
# Stores credentials at:
#   ~/.lnget/signer/wallet-password.txt           (mode 0600)
#   ~/.lnget/signer/seed.txt                      (mode 0600)
#   ~/.lnget/signer/credentials-bundle/           (exported credentials)

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

This line defines host-side file paths used to persist the wallet password and seed material. In the context of a remote signer whose purpose is isolating private key material, creating predictable plaintext credential locations materially increases the risk that malware, another local user, or automated backup/sync tooling can exfiltrate the secrets.

Content

Scanner excerpt · scripts/setup-signer.sh (reported line 140)May include surrounding context.

sh
mkdir -p "$LND_SIGNER_DIR"
fi

PASSWORD_FILE="$LNGET_SIGNER_DIR/wallet-password.txt"
SEED_OUTPUT="$LNGET_SIGNER_DIR/seed.txt"
CONF_FILE="$LNGET_SIGNER_DIR/signer-lnd.conf"

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

Copying the wallet password file into the container duplicates sensitive secret material and expands the attack surface. Any compromise of the container, container filesystem inspection, docker daemon access, or accidental image/debug artifact leakage could expose the wallet passphrase needed to unlock signer-controlled funds.

Content

Scanner excerpt · scripts/setup-signer.sh (reported line 160)May include surrounding context.

sh
# Copy password file into container if applicable.
if [ -n "$CONTAINER" ]; then
    docker cp "$PASSWORD_FILE" "$CONTAINER:/root/.lnd/wallet-password.txt"
    echo "Password file copied into container."
fi

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The entrypoint creates /root/.lnd/wallet-password.txt inside the persistent signer data volume before starting lnd. Even if initially empty, this establishes a predictable credential file path in a volume that also stores sensitive wallet state, increasing the risk that later automation, operators, backups, or co-tenant access will populate, discover, or misuse wallet secrets from disk.

Content

Scanner excerpt · templates/docker-compose-signer.yml (reported line 24)May include surrounding context.

yaml
image: ${LND_IMAGE:-lightninglabs/lnd}:${LND_VERSION:-v0.20.0-beta}
    container_name: litd-signer
    restart: unless-stopped
    entrypoint: ["/bin/sh", "-c", "touch /root/.lnd/wallet-password.txt && cp /tmp/lnd.conf /root/.lnd/lnd.conf && exec lnd"]
    ports:
      # RPC for watch-only node connections.
      - "${SIGNER_RPC_PORT:-10012}:10012"

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The configuration enables automatic wallet unlock using a password file stored on disk, which creates a durable local secret that can be stolen by anyone who gains filesystem, container, backup, or image access. In the context of a remote signer that protects private keys, storing the unlock credential alongside the signer materially weakens the isolation goal because compromise of the host/container can lead directly to wallet access and signing capability.

Content

Scanner excerpt · templates/signer-lnd-example.toml (reported line 23)May include surrounding context.

toml
restlisten=0.0.0.0:10013

# Auto-unlock wallet on startup using stored passphrase.
wallet-unlock-password-file=/root/.lnd/wallet-password.txt
wallet-unlock-allow-create=true

# TLS: allow connections from any IP (watch-only on different machine).

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill explicitly instructs users to run multiple shell scripts that install software, start containers, export credentials, and manage services, yet it declares no tool scope or allowed-tools. In an agent ecosystem, missing tool restrictions weakens governance and makes it easier for the skill to trigger powerful shell operations without clear sandbox expectations or user consent boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users to copy a credentials bundle that includes an admin macaroon and TLS certificate, and even offers a base64 blob for easy transfer, without a strong warning that this is highly sensitive privileged material. In this context, the bundle can give the recipient authenticated administrative RPC access to the signer, undermining the security boundary the skill claims to create.

Content

No source excerpt is available for this finding.

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 · SKILL.md (reported line 59)May include surrounding context.

md
# 6. Start litd in watch-only mode
skills/lnd/scripts/start-lnd.sh --watchonly

# 7. Create watch-only wallet
skills/lnd/scripts/create-wallet.sh

# 8. Check status

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation states that the signer REST service is exposed on 0.0.0.0:10013, and the ports table also lists it on 0.0.0.0, without emphasizing the attack-surface implications. Exposing wallet-related or signer management interfaces broadly on the network can allow unauthorized probing or exploitation if authentication, TLS, or firewalling is misconfigured.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script explicitly copies an admin macaroon into an export bundle and instructs users to transfer it to another machine, granting far more than watch-only visibility. An admin macaroon typically confers broad control over the node, so this defeats the stated security boundary of isolating sensitive capabilities away from the agent host.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

The script pulls a Docker image by mutable tag from a value that can come from versions.env or user input, without digest pinning or signature verification. Tags can be retargeted or the upstream registry/account could be compromised, causing installation of an unexpected or malicious signer image on a host intended to protect private key material.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
84% confidence
Finding

The docker run itself is using the same unpinned image that was pulled by mutable tag, so the verification step executes code from an image whose contents are not immutably fixed. In this skill's context, that is more dangerous because the host is meant to isolate Lightning signing keys; running a substituted image undermines that trust boundary and could expose sensitive material or backdoor the signer environment.

Content

No source excerpt is available for this finding.

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 · scripts/setup-signer.sh (reported line 2)May include surrounding context.

sh
#!/usr/bin/env bash
# Set up a remote signer: create wallet, export credentials bundle.
#
# Container mode (default — auto-detects litd-signer container):
#   setup-signer.sh                              # Auto-detect container

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · scripts/export-credentials.sh (reported line 162)May include surrounding context.

sh
# Create directories with restricted permissions.
mkdir -p "$LNGET_SIGNER_DIR"
chmod 700 "$LNGET_SIGNER_DIR"

if [ "$NATIVE" = true ]; then
    mkdir -p "$LND_SIGNER_DIR"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · scripts/setup-signer.sh (reported line 134)May include surrounding context.

sh
# Create directories with restricted permissions.
mkdir -p "$LNGET_SIGNER_DIR"
chmod 700 "$LNGET_SIGNER_DIR"

if [ "$NATIVE" = true ]; then
    mkdir -p "$LND_SIGNER_DIR"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · scripts/setup-signer.sh (reported line 154)May include surrounding context.

sh
# Store passphrase with restricted permissions on the host.
echo -n "$PASSWORD" > "$PASSWORD_FILE"
chmod 600 "$PASSWORD_FILE"
echo "Passphrase saved to $PASSWORD_FILE (mode 0600)"
echo ""

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · scripts/setup-signer.sh (reported line 238)May include surrounding context.

sh
# Store passphrase with restricted permissions on the host.
echo -n "$PASSWORD" > "$PASSWORD_FILE"
chmod 600 "$PASSWORD_FILE"
echo "Passphrase saved to $PASSWORD_FILE (mode 0600)"
echo ""

Session Persistence

Medium
Category
Rogue Agent
Confidence
73% confidence
Finding

Starting lnd with nohup in the background can leave a long-lived signer process running beyond the setup phase without explicit lifecycle control. In a security-sensitive remote signer context, unintended daemon persistence increases exposure by leaving RPC/REST services and key-handling software active longer than expected, especially if configuration or network binding changes later.

Content

Scanner excerpt · scripts/setup-signer.sh (reported line 197)May include surrounding context.

sh
echo "Signer lnd is already running."
    else
        echo "Starting signer lnd temporarily for wallet creation..."
        nohup lnd \
            --lnddir="$LND_SIGNER_DIR" \
            --configfile="$CONF_FILE" \
            > "$LNGET_SIGNER_DIR/signer-setup.log" 2>&1 &

Static analysis

No suspicious patterns detected.