T09 · Insecure Skill Coding Practices
- Location
scripts/shared/storage/keys.js:44- Finding
Private Keys Are Stored Unencrypted by Default with Unrestricted File Modes
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears purpose-aligned for decentralized identity, but it handles long-lived private keys in ways that can expose them by default.
Install only if you are comfortable with this skill creating persistent identity files outside the workspace. Configure BILLIONS_NETWORK_MASTER_KMS_KEY before creating or importing an identity, avoid passing existing private keys on the command line, restrict permissions on $HOME/.openclaw/billions, and review the network endpoints and dependency lockfile before using it for valuable identities.
scripts/shared/storage/keys.js:44Private Keys Are Stored Unencrypted by Default with Unrestricted File Modes
scripts/createNewEthereumIdentity.js:12Private-Key Import Through Command-Line Arguments Exposes Secrets to Process and Shell Telemetry
scripts/shared/storage/challenge.js:8Authentication Challenges Have No Expiration and Remain Reusable After Verification
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| `identities.json` | Identity metadata |
| `defaultDid.json` | Active DID and associated public key |
| `challenges.json` | Per-DID challenge history |
| `credentials.json` | Verifiable credentials |
There are several ways of storing private keys, to enable master key encryption as described in the **KMS Encryption** section below.
The public description frames the skill as identity proof generation/verification, but the content also documents local key management, private key storage, optional plaintext-at-rest storage, and filesystem interaction. That mismatch is dangerous because operators may approve or trust the skill for verification tasks without realizing it also handles long-lived credentials and secret material.
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
Lets AI agents create and manage their own identities on the Billions Network, and link those identities to a human owner.
cd scripts && npm inst
The skill explicitly documents storage of private keys, credentials, and related identity artifacts under a predictable directory, with private keys potentially stored in plaintext when the master key is absent. In an agent environment, predictable sensitive-storage paths materially raise the risk of credential theft by other tools, plugins, users, or malware with local access.
- `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
ws 8.18.0 is flagged for memory disclosure and memory exhaustion issues in WebSocket handling. In an agent skill that may communicate with wallets, chains, or remote verifiers over network channels, a vulnerable WebSocket implementation can expose sensitive process memory or allow denial of service via crafted frames.
brace-expansion 2.0.2 is associated with multiple denial-of-service conditions from pathological expansion input. If any package path exposes globbing or pattern parsing to untrusted input, an attacker may trigger excessive CPU or memory consumption and disrupt the agent process.
fast-uri 3.1.0 is flagged for multiple URL parsing and host confusion issues, including potential SSRF-related behaviors. In a decentralized identity skill that may resolve DIDs, fetch schemas, registries, or verifier endpoints, incorrect URI normalization can materially increase risk by allowing requests to unintended hosts or bypassing host-based protections.
ws 7.5.10 is vulnerable to memory exhaustion DoS from fragmented/data-chunk handling. Because this older ws is pulled in by RPC-related tooling, a malicious peer or server could potentially degrade availability of the agent during blockchain or remote procedure interactions.
underscore 1.13.6 is flagged for uncontrolled recursion in functions like _.flatten and _.isEqual, leading to potential denial of service on crafted input. If any transitive code compares or flattens attacker-controlled structures, this can crash the process or consume excessive stack/CPU.
undici 5.29.0 is flagged for multiple high-severity HTTP parsing and request/response handling issues, including smuggling and queue poisoning classes. This is especially relevant for an identity-verification skill because it likely performs outbound HTTP(S) requests to fetch DID documents, registries, attestations, or proofs, making network-layer confusion and SSRF-like impacts more dangerous.
ws 8.17.1 is affected by memory disclosure and memory exhaustion issues similar to other vulnerable ws entries in this lockfile. Multiple vulnerable ws versions increase the attack surface for denial of service or possible sensitive memory exposure in any component using WebSocket transport.
This bootstrap code initializes credential storage backed by a local file (credentials.json), and the same module also persists identities, DIDs, challenges, and KMS-backed keys. In an agent identity system, these artifacts can contain sensitive credentials, identity metadata, and authentication material; if stored unencrypted or with weak permissions, local compromise, other processes, or accidental leakage could expose or tamper with identity state.
function newDataStorage(ethStateStorage) {
return {
credential: new CredentialStorage(
new IdentitiesFileStorage("credentials.json"),
),
identity: new IdentityStorage(
new IdentitiesFileStorage("identities.json"),
This code explicitly falls back to storing private keys with provider: "plain" when no master key is available, meaning secret key material is written to disk unencrypted. For an identity/authentication skill, local file compromise, backups, logs, or accidental file sharing could directly expose agent private keys and enable impersonation or unauthorized proof generation.
The README instructs users to execute remote packages via npx clawhub@latest install ..., which fetches whatever the latest published version is at execution time. This creates a supply-chain risk: a compromised publisher account, malicious update, or dependency hijack could lead users or agents to run attacker-controlled code during installation.
The documented npx skills add ... flow invokes an unpinned remote package, so the code executed depends on the current registry state rather than a reviewed version. In an identity-management skill that handles keys and credentials, installer compromise could directly expose secrets or install backdoored skill content.
This human-facing installation command again uses npx clawhub@latest, causing users to run whatever code is current in the registry at install time. Because this skill is centered on decentralized identity and key material, any installation-time compromise has an elevated chance of leading to credential theft or malicious persistence.
The README instructs users to run npx skills add ... without pinning the package version, which is a classic supply-chain exposure. An attacker controlling the package, one of its dependencies, or a transient registry resolution path could execute arbitrary code on the user's system during setup.
The README explicitly supports passing an existing Ethereum private key on the command line and states that keys are stored unencrypted when BILLIONS_NETWORK_MASTER_KMS_KEY is not set. Command-line secrets can leak through shell history, process listings, logs, or agent transcripts, and plaintext-at-rest storage compounds the exposure for highly sensitive identity keys.
The skill declares execution requirements and clearly performs operations that touch environment variables, local sensitive storage, and network-backed identity/attestation systems, but it does not declare an explicit tool/permission scope. In an agent setting, missing scope boundaries increases the chance that the skill is invoked with broader capabilities than users expect, especially around access to secrets and outbound actions.
Passing a raw private key as a command-line argument is unsafe because command lines are often exposed via shell history, process listings, audit logs, CI logs, and agent telemetry. This can directly leak the private key, allowing full compromise of the DID identity and any signatures or attestations derived from it.
This code accepts a raw private key from arguments or generates one locally, then immediately uses it as seed material for identity creation. Although the code has comments and error logs, there is no user-facing disclosure or warning that highly sensitive key material is being handled, which is a safety-relevant credential operation for a code file.
This code initializes persistent file storage for sensitive wallet-related data using local JSON files, including KMS material and identity artifacts. While the behavior may be functional, there is no confirmation prompt, user-facing log, or explicit warning in this file that such sensitive data will be written to disk.
The code persists identity metadata by calling the storage layer, but there is no visible user disclosure before or during the write explaining that data will be stored. For code-file warning checks, file/storage writes that affect user data should have some form of confirmation, visible log, or documentation unless already clearly disclosed elsewhere.
The lockfile includes uuid 13.0.0, which is flagged for a buffer bounds check issue in v3/v5/v6 when a caller supplies a buf argument. This is a real supply-chain risk, although it is typically only reachable if application code or a dependency uses the affected APIs with attacker-influenced parameters, so the practical impact here is limited from the lockfile evidence alone.
uuid 9.0.1 is also present and affected by the same missing bounds check issue. This is a genuine vulnerable dependency, though the exploitability depends on whether vulnerable UUID generation modes are invoked with attacker-controlled buffer arguments.