T09 · Insecure Skill Coding Practices
- Location
scripts/shared/storage/keys.js:47- Finding
Private Keys Are Stored in Plaintext by Default Without Enforced Owner-Only Permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This identity skill is coherent and not deceptive, but it needs review because it creates and uses long-lived signing keys that can be stored in plaintext by default.
Review before installing. Use this only if you intend the agent to hold a persistent DID signing key. Set a strong, random BILLIONS_NETWORK_MASTER_KMS_KEY before creating identities, protect $HOME/.openclaw/billions with restrictive permissions, avoid shared or backed-up hosts for this data, and require explicit confirmation before signing challenges or linking identities. Update or pin dependencies before production use.
scripts/shared/storage/keys.js:47Private Keys Are Stored in Plaintext by Default Without Enforced Owner-Only Permissions
scripts/verifySignature.js:17Verification Challenges Do Not Expire and Remain Reusable After Successful Verification
scripts/shared/storage/crypto.js:9Master Keys Are Derived with a Fast Unsalted Hash
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 skill is presented as identity verification/linking, but the content reveals it also performs sensitive key management and local persistence of private keys, including possible plaintext storage when no master key is set. This mismatch increases the chance that users or orchestrators invoke it without understanding that it can create, import, store, and use long-lived cryptographic 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 documents storage of highly sensitive materials including private keys, credentials, identities, and profiles under a predictable local path, and notes that kms.json may be plaintext if no master key is configured. In an agent environment, any skill that can access or influence handling of such files materially increases the risk of credential theft, identity impersonation, and persistence compromise.
- `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 present and the cited advisories indicate memory disclosure and memory-exhaustion denial of service in WebSocket handling. In an agent identity/authentication skill, network-facing WebSocket components can be exposed to untrusted peers, making availability and possible data leakage concerns more significant than in an offline utility.
brace-expansion 2.0.2 has multiple denial-of-service conditions from pathological expansion patterns, and the vulnerable version is present in the lockfile. This is mainly dangerous where attacker-controlled patterns reach the library, but DoS issues are still meaningful for agent services that process external input or tooling requests.
fast-uri 3.1.0 is present with multiple host confusion and SSRF-related advisories, making it a genuine security issue in software that parses attacker-controlled URLs. This skill’s decentralized identity stack may resolve DIDs, fetch JSON-LD contexts, or contact registries over the network, so URI parsing flaws can materially increase SSRF and trust-boundary bypass risk.
ws 7.5.10 is affected by a memory exhaustion denial-of-service issue and is present in the dependency tree. Because identity and proof services may maintain persistent client/server WebSocket connections, an attacker could potentially degrade or crash the service with crafted fragmented traffic.
underscore 1.13.6 has recursion-based DoS issues in _.flatten and _.isEqual, and the vulnerable version is included. If attacker-controlled nested structures are compared or flattened anywhere in the dependency chain, this can lead to stack exhaustion or heavy resource consumption in a long-running agent service.
undici 5.29.0 is present with multiple HTTP smuggling, queue poisoning, and injection-related advisories, making it a significant genuine dependency risk. This is especially relevant here because identity workflows often perform outbound HTTP requests to registries, DID documents, or context endpoints, so request handling flaws can enable SSRF-like abuse, desynchronization, or cross-request contamination.
ws 8.17.1 is present and affected by memory disclosure and memory exhaustion vulnerabilities. In a networked authentication/identity skill, WebSocket flaws can threaten both service availability and confidentiality if exposed components or transitive consumers handle untrusted traffic.
The code stores credentials and identity records in predictable local files such as credentials.json and identities.json. Because this skill handles decentralized identity and authentication proofs, exposing credential contents can enable privacy compromise, replay support, profiling, or facilitate impersonation when combined with stolen key material.
function newDataStorage(ethStateStorage) {
return {
credential: new CredentialStorage(
new IdentitiesFileStorage("credentials.json"),
),
identity: new IdentityStorage(
new IdentitiesFileStorage("identities.json"),
This code intentionally falls back to storing privateKeyHex unencrypted on disk when no master key is available. Because this module manages cryptographic identity keys for agents, plaintext-at-rest storage can expose long-lived private keys to any attacker, process, backup system, or user with filesystem access, enabling identity theft, impersonation, and unauthorized signing.
The README instructs users to run npx clawhub@latest install verified-agent-identity, which fetches and executes the latest package version at install time rather than a pinned, reviewed version. This creates a supply-chain risk: if the upstream package or a dependency is compromised, users may execute attacker-controlled code during installation.
The human installation instructions also use npx clawhub@latest, again causing remote code execution of whatever package version is current at the time of use. Because this is an identity/key-management skill, compromise at install time could directly expose private keys, credentials, or manipulate trust flows.
The README explicitly documents that when BILLIONS_NETWORK_MASTER_KMS_KEY is not set, private keys are stored as raw hex strings on disk. Although encryption is described as optional, this skill manages decentralized identities and signing keys, so plaintext-at-rest storage materially increases the chance of credential theft from local compromise, backups, logs, or misconfigured file permissions.
The skill explicitly describes networked identity operations and access to sensitive local state under $HOME/.openclaw/billions, but it declares no tool scope or permissions boundary. In an agent environment, missing explicit restrictions can allow broader-than-expected execution, network access, and exposure of local identity material during normal invocation.
The invocation guidance is broad enough to match common identity and authentication requests such as signing challenges or linking ownership, which are sensitive actions. In an agentic setting, generic triggers can cause the skill to activate in situations where user intent is ambiguous, leading to unintended signing, identity linking, or disclosure of verification artifacts.
The example user request 'Link your agent identity to me' is overly generic for a sensitive identity-linking action and the example proceeds directly to execution. This creates a realistic path for social engineering or accidental authorization of ownership-linking operations without validating who requested it, what challenge is being signed, or whether the user intended a trust-binding action.
This code performs a persistent storage write via didsStorage.save(), which affects user data/state. Although there are comments describing the action for developers, there is no user-facing confirmation, prompt, or visible disclosure in this file before saving the new default identity.
The bootstrap code persists sensitive wallet material and identity data to local JSON files via KeysFileStorage and IdentitiesFileStorage without any visible encryption, permission hardening, or user disclosure. In an identity/authentication skill, local file storage of keys and identities materially increases the risk of credential theft, impersonation, and accidental leakage from backups, shared workspaces, or compromised hosts.
The code reads BILLIONS_NETWORK_MASTER_KMS_KEY from the environment, which is a credential-sensitive operation. While there are internal comments about validation, there is no user-facing warning, log, prompt, or disclosure in this file indicating that the skill accesses a sensitive secret from the environment.
This code persists data by saving a generated challenge under the provided DID, but the file itself only comments on the action for developers and does not provide any user-facing confirmation, warning, or disclosure. Under the code-file criteria, file or data writes should have some visible disclosure unless clearly covered elsewhere, which is not evident in this file.
The lockfile includes uuid 13.0.0, and the cited issue affects v3/v5/v6 when a caller supplies an output buffer with insufficient bounds. In a dependency lockfile this is a real supply-chain risk because vulnerable code is present, though exploitability depends on whether the skill or a dependency actually invokes the affected APIs with attacker-influenced inputs.
uuid 9.0.1 is present and is affected by the same missing buffer bounds check issue for v3/v5/v6 with a provided buf argument. This is a real vulnerable dependency entry, but practical impact remains limited unless the affected API shape is exercised with attacker-controlled parameters.
No suspicious patterns detected.