T09 · Insecure Skill Coding Practices
- Location
scripts/generate-address.py:255- Finding
Wallet private keys and mnemonic phrases are exposed through plaintext output and files
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Kaspa development skill is purpose-related but contains unsafe wallet, transaction, dependency, and node-operation guidance that could put funds or systems at risk if followed directly.
Review carefully before installing or using. Treat the included scripts and examples as unsafe for real funds unless revised: do not print or save private keys or mnemonics in plaintext, do not rely on the Python transaction builder for signing or submission, test only on testnet/devnet first, pin and verify all packages/images/binaries, and bind node RPC to localhost unless you have explicit authenticated remote-access controls.
scripts/generate-address.py:255Wallet private keys and mnemonic phrases are exposed through plaintext output and files
scripts/build-transaction.py:420Transaction submission accepts private-key presence as proof of signing while returning an unsigned transaction
scripts/build-transaction.py:209Fee is excluded from UTXO selection, allowing invalid transactions or unintended excessive fees
references/kaspa-go-sdk.md:420Go transaction example can underflow change and signs against an unrelated output index
references/node-operations.md:82Recommended node configurations expose the RPC service on all network interfaces
references/node-operations.md:213Downloaded executables are installed with root privileges without checksum or signature verification
references/node-operations.md:95Mutable latest container tags permit unreviewed code changes in persistent services
references/kaspa-wasm-sdk.md:577Wallet-sensitive browser code imports a mutable module directly from a third-party CDN
references/kaspa-python-sdk.md:1Unpinned unofficial Python package is recommended for wallet-related operations
The description substantially overstates the functionality present in the supplied code. The actual code is limited to a Python command-line utility for constructing simple Kaspa transfer transactions and KRC20 payload transactions using a hosted API for UTXO lookup, fee estimation, and submission. It does not provide the broad multi-language blockchain development toolkit described, nor wallet management, address generation, dApp/block explorer tooling, integration helpers, node setup, or SDK coverage. Most importantly, the script advertises building and signing transactions in comments/docstring, but its signing function is a placeholder that returns the transaction unsigned after printing warnings. While transaction building, KRC20 handling, and optional broadcast do align with a subset of the declared purpose, the overall description does not accurately represent this code chunk’s real scope or implemented capabilities.
The example prints the raw private key to stdout, which is a full wallet secret. Console output is commonly captured in shell history, logs, notebooks, CI systems, or screenshots; disclosure would let an attacker immediately take control of the associated funds.
The complete example prints the mnemonic phrase, which grants full recovery of the wallet and all derived accounts. In a blockchain SDK guide, users are likely to copy-paste and run examples verbatim; exposing the mnemonic to terminal output or logs creates immediate account-compromise risk.
The file header and usage text claim the script 'builds and signs' Kaspa transactions, but _sign_transaction is only a placeholder that emits warnings and returns the transaction unchanged. In a blockchain tooling context, this can mislead operators into believing a transaction has been signed and is ready for submission, causing failed transfers, broken automation, or unsafe downstream handling based on false assumptions about transaction state.
The submit path checks only for the presence of --private-key before calling submit_transaction, even though providing a private key does not actually sign the transaction in this script. This creates a dangerous trust boundary error: callers and automation may interpret private-key presence as proof of signing, leading to submission of invalid transactions and possible operational or financial disruption.
The skill documents behaviors that imply network access and file-writing related workflows, but it does not declare any explicit tool scope or permissions boundary. In an agent ecosystem, this can cause capability ambiguity: a caller may authorize or execute the skill with broader-than-expected privileges, increasing the chance of unintended network actions or file modifications.
The skill includes wallet/address generation and transaction broadcasting examples, including printing a private key and connecting to a mainnet RPC endpoint, without prominent warnings about secret handling, irreversible transfers, and real-funds risk. In a blockchain context, users may copy these examples directly into production or client-side environments, leading to key exposure, accidental fund loss, or unsafe signing flows.
The markdown describes submitting a signed transaction to the network, which can affect user funds and is generally irreversible once propagated, but it does not include any cautionary note. For markdown files, safety-relevant behavior that can affect user data or system integrity should be accompanied by a clear warning.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Get balance
def get_balance(address):
response = requests.post(
f'{BASE_URL}/api/v1/rpc/get-balance-by-address',
json={'address': address},
headers=HEADERS
The example includes a complete mainnet fund-transfer flow, including UTXO selection, signing, and SubmitTransaction, but does not warn that copying it as-is can create and broadcast real transactions that move assets. In a developer skill focused on blockchain integration, users may paste examples directly into production code, so the absence of an explicit safety warning increases the chance of accidental mainnet transfers or unintended loss through testing mistakes.
The file exposes a direct transaction submission method without a prominent warning that broadcasting blockchain transactions can be irreversible and may transfer real funds. In this skill context, which is aimed at wallet and transaction development, omission of such warnings increases the chance of accidental mainnet broadcasts during experimentation.
The function signature and docstring imply the private key is used to build a usable transaction, but the code never signs inputs and leaves signature_script empty. In a blockchain-development skill, this is dangerous because developers may assume the output is ready for submission, causing failed transactions, unsafe downstream workarounds, or accidental integration of insecure signing logic.
The document presents a BIP39 mnemonic generator while explicitly using an incomplete word list, yet indexes it as though all 2048 entries exist. This can produce runtime errors or, worse, non-standard mnemonics that users may believe are valid backups, leading to irreversible wallet loss when funds are stored against keys derived from incompatible seed material.
The document includes wallet/private key handling and transaction construction examples without an explicit warning that private keys, mnemonics, WIFs, and signed transactions are highly sensitive and that broadcasting transactions can irreversibly transfer funds. In a blockchain development skill, users are likely to copy example code directly into real environments, which increases the chance of secret exposure or unintended mainnet transfers.
This markdown file includes a complete sendKaspa example that signs and submits a transaction to Mainnet, which can move real funds irreversibly. Although the file includes general best practices, it does not clearly warn users near the example that running it may broadcast a real transaction and spend assets.
The file includes instructions and an example for burning tokens, and explicitly states this will 'Permanently destroy tokens.' However, the documentation does not provide a clear cautionary warning to users about the irreversibility and risk of accidental loss when performing this operation. For markdown files, destructive behaviors affecting user assets should be accompanied by an explicit warning.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"""Get KRC20 token balance for an address."""
response = requests.get(
f"https://api.kaspa.org/api/v1/addresses/{address}/tokens",
headers={"Authorization": f"Bearer {api_key}"}
)
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.
The Docker example uses kaspanet/kaspad:latest, a mutable tag that can silently change over time. This harms reproducibility and can cause operators to deploy an unexpected or compromised image if the upstream tag is replaced or updated.
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.
Create docker-compose.yml:
version: '3.8'
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
unzip kaspad-v0.12.18-linux-amd64.zip
sudo mv kaspad kaspactl kaspaminer /usr/local/bin/
sudo chmod +x /usr/local/bin/kasp*
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
unzip kaspad-v0.12.18-linux-amd64.zip
sudo mv kaspad kaspactl kaspaminer /usr/local/bin/
sudo chmod +x /usr/local/bin/kasp*
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
unzip kaspad-v0.12.18-linux-amd64.zip
sudo mv kaspad kaspactl kaspaminer /usr/local/bin/
sudo chmod +x /usr/local/bin/kasp*
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
unzip kaspad-v0.12.18-linux-amd64.zip
sudo mv kaspad kaspactl kaspaminer /usr/local/bin/
sudo chmod +x /usr/local/bin/kasp*
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
unzip kaspad-v0.12.18-linux-amd64.zip
sudo mv kaspad kaspactl kaspaminer /usr/local/bin/
sudo chmod +x /usr/local/bin/kasp*
No suspicious patterns detected.