Back to skill

Security audit

holdcc_eth

Security checks for vulnerabilities and agentic risk

Overview

This skill is for agent identity management, but it handles powerful identity keys in risky ways and references missing install code that cannot be reviewed.

Install only if you understand that this skill creates and uses long-lived identity credentials. Configure BILLIONS_NETWORK_MASTER_KMS_KEY before creating identities, avoid importing real private keys via command-line arguments, verify the missing scripts and package lockfile from a trusted source before running npm install, and treat $HOME/.openclaw/billions as a sensitive credential store.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:143
Finding
Identity Private Keys May Be Stored in Plaintext<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 143-149 **Vulnerability Type**: Plaintext storage of sensitive cryptographic material **Risk Level**: High ### Vulnerable Code Snippet ```markdown ## Security **CRITICAL - Data Storage and Protection:** The directory `$HOME/.openclaw/billions` contains all sensitive identity data: - `kms.json` - **CRITICAL**: Contains private keys (encrypted if BILLIONS_NETWORK_MASTER_KMS_KEY is set, otherwise in plaintext) - `defaultDid.json` - DID identifiers and public keys ``` The environment variable controlling encryption is documented as optional: ```yaml metadata: { "category": "identity", "clawdbot": { "requires": { "bins": ["node"] }, "config": { "optionalEnv": ["BILLIONS_NETWORK_MASTER_KMS_KEY"] } } } ``` ### Technical Analysis The documented storage design allows identity private keys to be written to `$HOME/.openclaw/billions/kms.json` without encryption whenever `BILLIONS_NETWORK_MASTER_KMS_KEY` is not configured. Private keys are bearer-equivalent cryptographic secrets: possession permits an attacker to produce valid signatures and impersonate the associated decentralized identity. Encryption therefore fails open rather than failing closed. The document also does not specify restrictive file permissions, ownership checks, key rotation, or use of an operating-system secret store. ### Attack Path 1. An operator creates an identity without setting the optional `BILLIONS_NETWORK_MASTER_KMS_KEY` environment variable. 2. The implementation stores the generated private key in plaintext in `$HOME/.openclaw/billions/kms.json`. 3. A local process, another account with access, backup collector, diagnostic tool, or malware reads the file. 4. The attacker imports the recovered private key into another environment. 5. The attacker signs challenges and impersonates the agent's DID. ### Impact Assessment Successful exploitation can result in complete compromise of the affected decentralized id ...[truncated 332 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Make encrypted private-key storage mandatory and terminate identity creation if a secure encryption key is unavailable. - Store private keys in an operating-system keychain, hardware-backed keystore, or dedicated secrets manager where possible. - Enforce restrictive ownership and permissions on the storage directory and files, such as owner-only access. - Never log private keys or include them in diagnostic output. - Document key rotation and revocation procedures for suspected exposure. - Validate the protection and permissions of existing key stores before loading or using them. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:41
Finding
Existing Private Keys Are Accepted Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 41-53 **Vulnerability Type**: Secret exposure through process arguments and shell history **Risk Level**: High ### Vulnerable Code Snippet ```markdown ### createNewEthereumIdentity.js **Command**: `node scripts/createNewEthereumIdentity.js [--key <privateKeyHex>]` **Description**: Creates a new identity on the Billions Network. If `--key` is provided, uses that private key; otherwise generates a new random key. The created identity is automatically set as default. **Usage Examples**: ```bash # Generate a new random identity node scripts/createNewEthereumIdentity.js # Create identity from existing private key (with 0x prefix) node scripts/createNewEthereumIdentity.js --key 0x1234567890abcdef... # Create identity from existing private key (without 0x prefix) node scripts/createNewEthereumIdentity.js --key 1234567890abcdef... ``` ``` ### Technical Analysis The documented interface passes a raw private key as a command-line argument. Command arguments are not an appropriate secret-input channel because they may be exposed through: - Shell history files - Process inspection utilities - System audit and endpoint-monitoring records - Terminal session recordings - CI/CD logs or command tracing - Parent-process telemetry and crash diagnostics Unlike a short-lived authentication token, exposure of an identity private key can allow persistent impersonation until the corresponding identity is revoked or replaced. ### Attack Path 1. An operator imports an existing identity with the documented `--key` argument. 2. The shell or operating-system telemetry records the complete command line. 3. Another local principal, monitoring service, log reader, or attacker retrieves the recorded argument. 4. The attacker extracts the private key and imports it into an attacker-controlled wallet or identity implementation. 5. The attacker generates valid signatures as the compromised identity. ### Impact Ass ...[truncated 279 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove support for supplying private keys directly through command-line arguments. - Accept secret input through non-echoing standard input, an operating-system keychain, or a dedicated secrets-management interface. - If file-based import is unavoidable, require an owner-readable encrypted file and verify its permissions before access. - Ensure secret input is never echoed, logged, included in exceptions, or retained in command history. - Warn users to rotate any real keys previously supplied through the documented `--key` interface. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:164
Finding
Caller-Controlled Values Are Interpolated into Shell Command Examples<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 164-177 **Vulnerability Type**: Potential operating-system command injection **Risk Level**: High ### Vulnerable Code Snippet ```markdown 3. Use `node scripts/linkHumanToAgent.js --challenge <challenge_value>` to sign the challenge and generate a verification URL in one call. - If caller provides specific challenge, use that. - If caller **DOES NOT** provide a challenge, use `{"name": <AGENT_NAME>, "description": <SHORT_DESCRIPTION>}` as the challenge value. 4. Return the result to the caller. **Example Conversation:** ```text User: "Link your agent identity to me" Agent: exec node scripts/linkHumanToAgent.js --challenge <challenge_value> ``` ``` Additional caller-controlled DID and token values are used similarly: ```markdown 3. Use `node scripts/generateChallenge.js --did <user_did>` to create a <challenge_value>. 4. Ask the user: "Please sign this challenge: <challenge_value>" 5. User signs and returns <user_token>. 6. Use `node scripts/verifySignature.js --did <user_did> --token <user_token>` to verify the signature ``` ### Technical Analysis The Skill tells the agent to use challenge, DID, and token values provided by another user or agent in executable command templates. It does not require: - Non-shell process execution with an explicit argument array - Shell escaping - Strict input validation - Length limits or control-character rejection - Format validation for DIDs, challenges, or JWS tokens If an agent implements the documented `exec` operation through a shell and directly substitutes a malicious value, shell metacharacters may terminate the intended argument and introduce additional commands. This finding concerns the unsafe instruction pattern. The referenced scripts are absent, so script-level validation could not be assessed. ### Attack Path 1. An attacker provides a crafted challenge, DID, or token containing shell syntax. 2. The agent substitutes that va ...[truncated 832 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require process spawning without a shell and pass each value as a separate argument, such as an argument-array API. - Explicitly prohibit command construction through string concatenation or interpolation. - Validate DIDs against the expected DID grammar and supported network. - Validate tokens against the expected compact JWS structure and impose conservative size limits. - Define a strict challenge schema, permitted character set, maximum length, and JSON validation rules. - Reject null bytes, control characters, line breaks, and unexpected shell metacharacters. - Add tests demonstrating that malicious values remain literal arguments and cannot create additional commands. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:22
Finding
Unauditable Dependency Installation Is Required by an Incomplete Artifact<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 22 **Vulnerability Type**: Unpinned and unverifiable dependency installation **Risk Level**: Medium ### Vulnerable Code Snippet ```bash cd scripts && npm install && cd .. ``` The submitted project contains only: ```text ./ SKILL.md ``` No `scripts/` directory, `package.json`, package lockfile, or implementation files are present. ### Technical Analysis The Skill instructs users to run `npm install`, but the artifact does not include the referenced package manifest, lockfile, or scripts. Consequently, the audit cannot determine: - Which packages and versions would be installed - Whether dependency versions are pinned - Whether package integrity hashes are present - Whether installation lifecycle scripts execute - Whether package names are vulnerable to dependency confusion or typosquatting - Whether the scripts perform the documented identity operations safely Running `npm install` can execute package lifecycle hooks. If users obtain the missing `scripts` directory or manifest from an untrusted or mutable source, dependency or lifecycle code may execute locally without having been reviewed as part of this artifact. ### Attack Path 1. A user attempts to follow the installation instructions and discovers that the required `scripts` directory is absent. 2. The user obtains replacement files from another source or receives a modified package manifest. 3. The replacement manifest references malicious, compromised, or unexpectedly updated dependencies, or defines a malicious lifecycle hook. 4. The user runs `npm install` as directed. 5. npm downloads packages and may execute installation lifecycle code with the user's privileges. ### Impact Assessment A malicious dependency or lifecycle hook could execute code with the privileges of the user running npm. This could expose identity keys, environment variables, project data, and other files accessible to that account. The artifact do ...[truncated 181 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Include every referenced script and the complete package manifest in the reviewed artifact. - Commit a package lockfile with resolved versions and integrity hashes. - Use `npm ci` rather than unconstrained `npm install` for reproducible installation. - Pin direct dependencies and review transitive dependencies for known vulnerabilities and suspicious ownership changes. - Use `--ignore-scripts` unless lifecycle hooks are necessary and have been explicitly audited. - Document the trusted source and integrity verification procedure for all distributed files. - Add automated dependency scanning and lockfile verification to the release process. - Do not publish installation instructions until the artifact contains the implementation required to execute them. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Content
nk agents to human identities using Billions ERC-8004 and Attestation Registries. Verify and generate authentication proofs. Based on iden3 self-sovereign identity protocol.
metadata: { "category": "identity", "clawdbot": { "requires": { "bins": ["node"] }, "config": { "optionalEnv": ["BILLIONS_NETWORK_MASTER_KMS_KEY"] } } }
homepage: https://billions.network/
---

## When to use this Skill

Lets AI agents create and manage their own identities on the Billions Network, and link those identities to a human owner.

1. When you need to link your agent identity to an owner.
2. When you need to sign a challenge.
3. When you need to link a human to the agent's DID.
4. When you need to verify a signature to confirm identity ownership.
5. When you use shared JWT tokens for authentication.
6. When you need to create and manage decentralized identities.

### After installing the plugin run the following commands to create an identity and link it to your human DID:

```bash
cd scripts && npm inst
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Credential Access

High
Category
Privilege Escalation
Content
- `kms.json` - **CRITICAL**: Contains private keys (encrypted if BILLIONS_NETWORK_MASTER_KMS_KEY is set, otherwise in plaintext)
- `defaultDid.json` - DID identifiers and public keys
- `challenges.json` - Authentication challenges history
- `credentials.json` - Verifiable credentials
- `identities.json` - Identity metadata
- `profiles.json` - Profile data
Confidence
84% confidence
Finding
The skill explicitly documents a local directory containing sensitive artifacts including private keys, credentials, identity metadata, and profiles. Even though this is documentation rather than exfiltration logic, it meaningfully lowers the barrier for a compromised agent, malicious plugin, or inattentive operator to locate and access high-value credential stores.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill instructs users to create a new decentralized identity and persist its associated key material under a local directory, but the usage flow does not clearly warn that this creates long-lived sensitive secrets on disk. In an agent setting, that omission is dangerous because operators may invoke the workflow without understanding that private keys may be stored locally and potentially unencrypted depending on environment configuration.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documented `--key` argument encourages passing a raw private key on the command line, which is highly sensitive because command-line arguments are often exposed through shell history, process listings, logs, and agent telemetry. In an automated agent environment this materially increases the chance of credential disclosure and identity compromise.

Static analysis

No suspicious patterns detected.