T09 · Insecure Skill Coding Practices
- Location
scripts/shared/storage/keys.js:50- Finding
Private keys are stored in plaintext by default without enforced filesystem permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This identity skill appears purpose-aligned, but it handles long-lived private keys and authentication proofs with insecure defaults that users should review before installing.
Install only in an environment where you are comfortable storing agent identity keys under $HOME/.openclaw/billions. Configure BILLIONS_NETWORK_MASTER_KMS_KEY before creating or importing identities, avoid passing real private keys on the command line, and treat generated proofs and linking URLs as sensitive. Review the dependency state and the authentication challenge behavior before using this for production trust decisions.
scripts/shared/storage/keys.js:50Private keys are stored in plaintext by default without enforced filesystem permissions
scripts/shared/storage/challenge.js:8Authentication challenges never expire and remain reusable after successful verification
scripts/generateChallenge.js:17Generated authentication challenges contain insufficient entropy
scripts/verifySignature.js:25Signature verification relies on an unvalidated third-party DID resolver response
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 advertised purpose is identity linking and verification, but the skill also manages raw private key material and persists it locally, including possible plaintext storage when no master key is configured. That behavioral gap can mislead users and orchestrators into invoking a credential-handling skill without understanding it creates, imports, and stores long-lived secrets.
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 mentions that kms.json contains private keys encrypted only if a master key is set, otherwise in plaintext, but this warning is buried in the Security section rather than prominently disclosed up front. Because the skill directly handles authentication identities, understated plaintext-key risk can lead to secret compromise from local filesystem access, backups, logs, or multi-user environments.
The skill explicitly references local storage of verifiable credentials and adjacent key material in a predictable directory, which indicates access to sensitive authentication artifacts. In an agent environment, any skill that can read or manipulate such files creates a substantial credential-exposure risk if invoked improperly or combined with other filesystem-capable tools.
- `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
The lockfile contains ws 8.18.0 with advisories for uninitialized memory disclosure and memory-exhaustion DoS. Because identity/authentication tooling commonly uses websocket-based RPC connections to blockchain or verifier infrastructure, a websocket flaw can expose process memory or allow a remote party to degrade availability of verification services.
Brace-expansion 2.0.2 has multiple algorithmic complexity and expansion-related DoS advisories. This package is usually low-risk when only used in tooling, but if any runtime path accepts attacker-controlled glob-like patterns through transitive consumers, it can cause excessive CPU or memory consumption.
Fast-uri 3.1.0 is affected by multiple host-confusion and SSRF-style parsing issues. In a decentralized identity context, the software may resolve DIDs, schemas, contexts, registries, or remote verifier endpoints, so malformed URI handling can materially increase the risk of SSRF, incorrect trust decisions, or outbound requests to attacker-chosen hosts.
Ws 7.5.10 is vulnerable to memory exhaustion from fragmented frames and tiny chunks, making remote DoS feasible. Because this copy sits under jayson and RPC/websocket-related code, an exposed RPC or streaming interface could be knocked offline by a malicious peer, which is significant for an authentication service.
Underscore 1.13.6 has unlimited recursion in _.flatten and _.isEqual, enabling denial of service with crafted nested structures. If transitive components compare or normalize attacker-supplied identity documents or RPC payloads using these helpers, they can be crashed or tied up with pathological input.
Undici 5.29.0 carries multiple high-severity HTTP parsing and request-smuggling style advisories. This is particularly relevant for identity software that fetches remote contexts, schemas, DID documents, registry data, or verifier endpoints, because malformed upstream/downstream HTTP interactions can enable SSRF, cache poisoning, or trust-boundary bypass.
Ws 8.17.1 is affected by memory disclosure and DoS issues, and websocket transport is common in blockchain and decentralized identity integrations. In this skill's context, compromise of websocket handling can interrupt proof verification flows or leak process memory from a long-lived agent service interacting with remote nodes or verifiers.
The credential wallet stores credentials in a local file named credentials.json, indicating sensitive credential material is persisted in an easily discoverable location. In the context of a decentralized identity skill, these credentials may contain attestations and identity-linked data that can be stolen, copied, or reused for unauthorized access or profiling if the host filesystem is exposed.
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 sensitive cryptographic material can be persisted to disk unencrypted. In an agent identity skill, those keys are likely authentication or signing keys, so filesystem access, backups, logs, container snapshots, or accidental disclosure can directly compromise agent identity and enable impersonation.
The README instructs users to run npx clawhub@latest install ..., which fetches and executes the latest published package version at runtime rather than a pinned, reviewed version. This creates a supply-chain risk: if the package or one of its delivery paths is compromised, users may execute attacker-controlled code during installation.
This installation command again uses npx clawhub@latest, causing execution of the most recent remote package without version pinning. In a security-sensitive identity skill, that expands the attack surface because installation-time compromise could steal keys, credentials, or alter verification flows.
The documentation explicitly tells users to pass an existing Ethereum private key on the command line, which is a sensitive handling anti-pattern. Command-line secrets can be exposed through shell history, process listings, logs, or screenshots, making accidental credential disclosure likely.
The skill requires network access and reads environment configuration, but it does not declare an explicit tool scope or allowed-tools boundary. In an agent setting, that weakens containment and makes it easier for the skill to trigger networked identity operations or touch sensitive configuration without clear operator awareness.
The setup instructions tell the operator to create an identity and link it immediately, but they do not prominently warn that this generates and persists sensitive identity material on disk. Missing that warning undermines informed consent and can lead users to create durable credentials in environments that are shared, ephemeral, or insufficiently secured.
The invocation guidance is broad enough to match common identity-related user requests and can cause an agent to perform sensitive signing or identity-linking actions with minimal friction. In practice, this increases the chance of over-triggering the skill for ambiguous prompts, leading to unauthorized proof generation or account-linking workflows.
This script accepts or generates an Ethereum private key, derives identity material from it, and persists the resulting DID metadata without any user-facing warning about key sensitivity, storage implications, or operational risk. In an identity-management skill, silent handling of long-lived private keys increases the chance of accidental disclosure, unsafe invocation in automation, or misuse by operators who do not realize they are creating a production identity tied to a wallet key.
The code sends the full authorization request payload to an external URL shortener service, which can expose sensitive verification metadata, scope details, callback information, and correlation data to a third party. In an identity-linking skill, this is especially risky because the off-box service can log, inspect, retain, or tamper with authentication request data without any visible user consent or disclosure.
The code persists key material and identity-related data to predictable local JSON files such as kms.json, identities.json, credentials.json, and defaultDid.json without any visible encryption, access control, or user warning. For an identity/authentication skill, this is particularly dangerous because compromise of these files can expose private keys, DID state, and credentials, enabling impersonation or unauthorized proof generation.
The lockfile includes uuid 13.0.0, and the cited advisory affects v3/v5/v6 APIs when a caller provides a custom output buffer without sufficient bounds checks. In an agent identity skill, UUID generation may be used for identifiers or request correlation, so the vulnerable code could be reachable if those APIs are exposed to untrusted input, though the practical impact is typically limited to crash/DoS rather than full compromise.
Uuid 9.0.1 is present and is covered by the same missing buffer bounds check issue in v3/v5/v6 APIs. In this package it is transitive, but still a real supply-chain risk if downstream code invokes the affected API patterns with attacker-influenced parameters.
No suspicious patterns detected.