Back to skill

Security audit

Xian Node

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its node-management purpose, but it gives unsafe validator-key handling examples that could accidentally expose high-value secrets.

Review this skill before installing. Use it only in an isolated environment, avoid pasting validator private keys into commands or agent chats, do not run the key generator where stdout is logged, pin and review upstream code before building, and back up configuration before wipe/reset commands.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_validator_key.py:53
Finding
Validator Private Keys Are Disclosed Through Standard Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_validator_key.py:53-64`; additional occurrence in `SKILL.md:87-97` **Vulnerability Type**: Plaintext disclosure of cryptographic private keys **Risk Level**: High ### Vulnerable Code ```python private_key, public_key = generate_keypair() address = pubkey_to_address(public_key) pubkey_b64 = pubkey_to_base64(public_key) if args.genesis_entry: entry = { "address": address, "pub_key": { "type": "tendermint/PubKeyEd25519", "value": pubkey_b64 }, "power": args.power, "name": args.name } print("Genesis validator entry:") print(json.dumps(entry, indent=2)) print(f"\nPrivate key (keep secret!): {private_key}") else: print(f"Private key: {private_key}") ``` The documentation also instructs users to generate and print a private key: ```python from nacl.signing import SigningKey import secrets sk = SigningKey(secrets.token_bytes(32)) print(f'Private key: {sk.encode().hex()}') print(f'Public key: {sk.verify_key.encode().hex()}') ``` ### Technical Analysis The key-generation script always writes the newly generated Ed25519 private key to standard output. The `--genesis-entry` option does not suppress this disclosure; it prints the private key after the public genesis entry. In an AI-agent or automated execution environment, standard output can be captured in conversation transcripts, command logs, CI/CD logs, telemetry, terminal history, or other retained execution records. Labeling the output as secret does not protect it from those capture mechanisms. The Base64 conversion at `scripts/generate_validator_key.py:32-34` is not itself a vulnerability. It encodes only the public key in the representation required by the CometBFT genesis format and performs no transmission. The security issue is the separate plaintext private-key output. ### Attack Path 1. A user or agent invokes `scripts/generate_validator_key ...[truncated 914 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not print private keys by default. 2. Write the private key directly to a user-selected file opened with restrictive permissions such as `0600`. 3. Print only non-sensitive information, including the public key, validator address, genesis entry, and protected key-file path. 4. If plaintext display is retained as an exceptional feature, require an explicit option such as `--show-private-key` and display a clear warning and interactive confirmation. 5. Avoid returning private keys through agent-visible tool output. 6. Document secure backup, access-control, rotation, and deletion procedures for validator keys. 7. Consider integrating an encrypted keystore, hardware security module, or dedicated secret-management system. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:46
Finding
Validator Private Keys Are Passed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:46-48` and `SKILL.md:107-109` **Vulnerability Type**: Insecure secret transport through process arguments **Risk Level**: High ### Vulnerable Instructions ```bash make configure CONFIGURE_ARGS='--moniker "my-validator" --genesis-file-name "genesis-mainnet.json" --validator-privkey "<your-privkey>" --seed-node-address "..." --copy-genesis' ``` The same pattern is repeated for a genesis validator: ```bash make configure CONFIGURE_ARGS='--moniker "genesis-validator" --genesis-file-name "genesis-custom.json" --validator-privkey "<privkey>"' ``` ### Technical Analysis The Skill instructs users to place a validator private key directly in a command-line argument. Depending on the shell, operating system, build tooling, and agent environment, command arguments may be exposed through: - Shell history - Agent transcripts and tool-call records - Build and debug logs - Process inspection interfaces - Audit or telemetry systems - Error messages that reproduce the invoked command - Makefile diagnostic output Passing the secret through the nested `CONFIGURE_ARGS` variable can also cause it to be expanded and logged by multiple process layers. Although access to process arguments is restricted on some systems, it is not a reliable confidentiality boundary. ### Attack Path 1. A validator operator follows the documented `make configure` command. 2. The private key is entered literally in the command line. 3. The command is retained in shell history, an agent transcript, build output, process metadata, or telemetry. 4. Another local user, administrator, log reader, or compromised monitoring component obtains the key. 5. The attacker configures another node with the stolen validator key. 6. The attacker impersonates the validator or creates conflicting signatures. ### Impact Assessment A successful attacker obtains the signing authority of the affected validator. This can permit validator impersonation, un ...[truncated 229 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `--validator-privkey` with a protected key-file option such as `--validator-key-file`. 2. Require the key file to be owned by the validator account and have mode `0600` or stricter. 3. Read the key from a secret manager, encrypted keystore, hardware security module, or protected file descriptor. 4. Do not place private keys in environment variables because they may also leak through diagnostics and process environments. 5. Ensure setup scripts never echo secret-bearing arguments. 6. Add documentation explaining how to remove any existing secret-bearing entries from shell history and retained automation logs. 7. Rotate any validator key that has already been entered into an agent conversation, shared terminal, or externally retained build log. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:21
Finding
Unpinned Mutable Dependencies Are Downloaded and Executed<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:21-25`; additional occurrences at `SKILL.md:68-73` and `SKILL.md:193-195` **Vulnerability Type**: Unpinned third-party dependency and mutable remote source **Risk Level**: Medium ### Vulnerable Instructions ```bash git clone https://github.com/xian-network/xian-stack.git cd xian-stack make setup CORE_BRANCH=mainnet CONTRACTING_BRANCH=mainnet make core-build make core-up ``` The network-creation workflow repeats the mutable branch selection: ```bash git clone https://github.com/xian-network/xian-stack.git cd xian-stack make setup CORE_BRANCH=mainnet CONTRACTING_BRANCH=mainnet make core-build make core-up make init ``` The SDK is also installed without a fixed version or integrity hash: ```bash pip install xian-py ``` ### Technical Analysis The instructions clone the current default state of a remote Git repository and select mutable `mainnet` branches for additional components. They then execute Makefile targets and build container content from those sources. The effective code can therefore change after this Skill has been reviewed. The `xian-py` package is installed without an exact version or hash. Package resolution can consequently select future releases and transitive dependency versions that were not part of this audit. No evidence shows that the named upstream projects are currently malicious. The vulnerability is the absence of reproducible version and integrity controls. If an upstream repository, maintainer account, package release process, or dependency is compromised, users following the instructions could execute altered code with access to Docker, local files, node configuration, and potentially validator material. ### Attack Path 1. An attacker compromises an upstream repository, maintainer account, package publication account, or mutable branch. 2. The attacker modifies a Makefile, build script, container definition, Python package, or transitive dependency. 3. A user fol ...[truncated 859 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every Git dependency to a reviewed full commit hash rather than a mutable branch. 2. Record and verify expected commit signatures, release signatures, or archive checksums. 3. Pin `xian-py` and all transitive Python dependencies to exact reviewed versions. 4. Use a lock file and require package hashes, for example with `pip install --require-hashes`. 5. Build dependencies in an isolated, non-privileged environment without access to validator keys. 6. Avoid exposing a privileged host Docker socket to untrusted or newly fetched build code. 7. Periodically review and deliberately update pinned revisions rather than automatically tracking branch heads. 8. Preserve a software bill of materials for the container images and Python environment. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill contains clear network-oriented operational commands and RPC usage, but it does not declare any tool scope or permission boundaries. In an agent setting, this increases the chance that an agent may perform network actions without explicit guardrails or user awareness, especially because the skill is designed to connect to remote seed nodes and interact with blockchain services.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The validator-node example instructs users to pass a validator private key directly on the command line without warning about shell history, process inspection, logging, or insecure storage risks. Exposure of a validator key can allow an attacker to impersonate the validator, sign malicious actions, or permanently compromise node identity and funds tied to that key.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The key-generation example prints the newly generated validator private key directly to the terminal and provides no warning about protecting or securely storing it. Terminal output may be captured in scrollback, logs, recordings, or remote session transcripts, making accidental disclosure of a highly sensitive validator secret much more likely.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documented reset commands include wipe operations that erase node data, but the skill does not place an explicit warning immediately around those commands. In an operational blockchain context, a user or agent could run them during troubleshooting and unintentionally destroy local state, causing downtime, forced resync, or loss of unrecoverable local artifacts if backups are missing.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script emits the validator private key directly to stdout, which can expose it through terminal scrollback, shell logging, CI/CD logs, remote session recording, or operational copy/paste mistakes. In the context of blockchain validator management, disclosure of this key can allow an attacker to impersonate the validator or compromise node identity and network participation.

Missing User Warnings

Low
Confidence
87% confidence
Finding
The SDK example includes a live transaction-sending call without warning that it changes blockchain state and may spend real assets when pointed at a funded wallet or production node. In this node-management skill, readers may reasonably test snippets against localhost/mainnet infrastructure, so the lack of a caution increases the risk of unintended transactions.

Static analysis

No suspicious patterns detected.