Back to skill

Security audit

Get a clank.money Human Bitcoin Address

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent and purpose-aligned, but its copy-paste credential handling could expose a token that controls future Bitcoin address updates.

Install only if you are comfortable with a skill that manages a payment-address registration and stores an update token locally. Treat the management token like a password or API key; avoid shared machines, shell tracing, logs, and predictable temporary files, and prefer a private temp directory or secret store for any real use.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:61
Finding
Registration credentials are written to predictable temporary files## Vulnerability Details **File Location**: `SKILL.md`, lines 61-95 **Vulnerability Type**: Unsafe temporary-file handling and plaintext credential storage **Risk Level**: Medium ### Vulnerable Code ```bash # 1) Create challenge (or fail fast if name taken) curl -sS -X POST "$BASE/api/v1/registrations" \ -H "content-type: application/json" \ --data "{\"username\":\"$USERNAME\",\"bip321Uri\":\"$BIP321_URI\"}" \ > /tmp/clank_register_challenge.json ERROR_CODE="$(python3 -c 'import json; d=json.load(open("/tmp/clank_register_challenge.json")); e=d.get("error"); print((e.get("code") if isinstance(e,dict) else e) or "")')" if [ "$ERROR_CODE" = "username_unavailable" ]; then echo "Username is taken. Pick another USERNAME and rerun." exit 1 fi if [ "$ERROR_CODE" != "payment_required" ]; then echo "Unexpected challenge response:" cat /tmp/clank_register_challenge.json exit 1 fi MACAROON="$(python3 -c 'import json; print(json.load(open("/tmp/clank_register_challenge.json"))["macaroon"])')" INVOICE="$(python3 -c 'import json; print(json.load(open("/tmp/clank_register_challenge.json"))["invoice"])')" echo "Pay this invoice now:" echo "$INVOICE" # 2) After payment, paste your preimage read -r -p "PASTE_PREIMAGE=" PREIMAGE # 3) Complete paid registration curl -sS -X POST "$BASE/api/v1/registrations" \ -H "content-type: application/json" \ -H "Authorization: L402 $MACAROON:$PREIMAGE" \ --data "{\"username\":\"$USERNAME\",\"bip321Uri\":\"$BIP321_URI\"}" \ > /tmp/clank_register_result.json MGMT="$(python3 -c 'import json; d=json.load(open("/tmp/clank_register_result.json")); print(d.get("managementToken",""))')" if [ -z "$MGMT" ]; then echo "No managementToken in final response:" cat /tmp/clank_register_result.json exit 1 fi ``` ### Technical Analysis The documented workflow writes API responses to fixed paths in the shared `/tmp` directory. It does not estab ...[truncated 2202 chars]
Remediation
## Remediation Suggestions - Set `umask 077` before creating any file containing API responses or credentials. - Create a private temporary directory atomically with `mktemp -d` rather than using fixed filenames in `/tmp`. - Register a shell `trap` to remove temporary files on normal exit, errors, and signals. - Ensure temporary destinations are regular files and are not symbolic links. - Avoid retaining the entire final response after extracting the management token. - Write the management token atomically to a mode-`600` file inside a mode-`700` directory. - Do not print complete API responses on error when those responses may contain authentication material. A hardened pattern is: ```bash umask 077 TMP_DIR="$(mktemp -d)" trap 'rm -rf -- "$TMP_DIR"' EXIT HUP INT TERM CHALLENGE_FILE="$TMP_DIR/challenge.json" RESULT_FILE="$TMP_DIR/result.json" mkdir -p -- "$(dirname "$TOKEN_FILE")" chmod 700 -- "$(dirname "$TOKEN_FILE")" # Write responses only beneath the private temporary directory. # After validating the result, atomically install the token. TOKEN_TMP="$(mktemp "$(dirname "$TOKEN_FILE")/.management_token.XXXXXX")" printf '%s\n' "$MGMT" > "$TOKEN_TMP" chmod 600 "$TOKEN_TMP" mv -f -- "$TOKEN_TMP" "$TOKEN_FILE" ```

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:79
Finding
Authentication secrets are exposed through curl command-line arguments## Vulnerability Details **File Location**: `SKILL.md`, lines 79-85 and 119-128 **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```bash # 2) After payment, paste your preimage read -r -p "PASTE_PREIMAGE=" PREIMAGE # 3) Complete paid registration curl -sS -X POST "$BASE/api/v1/registrations" \ -H "content-type: application/json" \ -H "Authorization: L402 $MACAROON:$PREIMAGE" \ --data "{\"username\":\"$USERNAME\",\"bip321Uri\":\"$BIP321_URI\"}" \ > /tmp/clank_register_result.json ``` ```bash USERNAME="satoshi" TOKEN_FILE="$HOME/.clank/${USERNAME}.management_token" NEW_BIP321='bitcoin:?lno=lno1newbolt12offer' MGMT="$(cat "$TOKEN_FILE")" curl -sS -X PATCH "https://clank.money/api/v1/registrations/$USERNAME" \ -H "content-type: application/json" \ -H "Authorization: Bearer $MGMT" \ --data "{\"bip321Uri\":\"$NEW_BIP321\"}" ``` ### Technical Analysis The examples interpolate the L402 macaroon, payment preimage, and management token directly into curl command-line arguments. On systems where process arguments are visible to other local users, monitoring services, audit tooling, or diagnostic collectors, these values may be captured while curl is running. The same values may also be exposed if shell execution tracing is enabled or if wrapper scripts log invoked commands. HTTPS protects the credentials while in transit but does not prevent local disclosure before curl sends the request. The management token is a persistent bearer credential for modifying the registration. Anyone who obtains it can authenticate without proving possession of another secret. The L402 material is also sensitive because it authorizes completion of the paid registration flow. ### Attack Path 1. A local attacker or monitoring process observes command-line arguments, shell traces, or command-execution audit records. 2. The victim runs th ...[truncated 1002 chars]
Remediation
## Remediation Suggestions - Avoid placing bearer tokens, payment preimages, and macaroons directly in command-line arguments. - Pass sensitive curl configuration through a permission-restricted temporary configuration file or protected file descriptor. - Establish `umask 077` before creating credential-bearing configuration files. - Delete temporary configuration immediately after curl exits by using a shell cleanup trap. - Disable shell tracing with `set +x` before reading or using credentials. - Confirm that execution wrappers, audit systems, and debugging tools do not record Authorization headers. - Restrict process visibility on multi-user hosts where supported. For example, use a private curl configuration delivered through a file descriptor: ```bash set +x umask 077 curl -sS \ --config <(printf '%s\n' \ 'request = "PATCH"' \ 'header = "content-type: application/json"' \ "header = \"Authorization: Bearer $MGMT\"") \ "https://clank.money/api/v1/registrations/$USERNAME" \ --data "{\"bip321Uri\":\"$NEW_BIP321\"}" ``` Where process substitution is unsuitable or its descriptor path may be logged, use a mode-`600` file in a private temporary directory and remove it with a `trap`.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (3)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill correctly says to save the management token, but it does not explicitly warn that the token is a bearer secret: anyone who obtains it can update the registered address. In this context, the examples also write and later reuse the token from disk and send it in an Authorization header, so failing to warn about shell history, logs, temp files, backups, or process exposure increases the chance of account/address takeover.

External Transmission

Medium
Category
Data Exfiltration
Content
mkdir -p "$(dirname "$TOKEN_FILE")"

# 1) Create challenge (or fail fast if name taken)
curl -sS -X POST "$BASE/api/v1/registrations" \
  -H "content-type: application/json" \
  --data "{\"username\":\"$USERNAME\",\"bip321Uri\":\"$BIP321_URI\"}" \
  > /tmp/clank_register_challenge.json
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# 4) CRITICAL: persist token securely for future updates
printf '%s\n' "$MGMT" > "$TOKEN_FILE"
chmod 600 "$TOKEN_FILE"
echo "Saved management token to $TOKEN_FILE"
```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Static analysis

No suspicious patterns detected.