T09 · Insecure Skill Coding Practices
- Location
scripts/shared/storage/keys.js:47- Finding
Private identity keys are stored unencrypted by default
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This identity skill is mostly purpose-aligned, but it should be reviewed carefully because it can store high-value private identity keys locally in plaintext by default.
Install only if you are comfortable creating a persistent agent DID and storing its private keys on this machine. Set BILLIONS_NETWORK_MASTER_KMS_KEY before creating or importing an identity, run it in an isolated account or environment, protect $HOME/.openclaw/billions, and treat old signed challenge tokens as reusable unless the implementation is changed to expire and consume them.
scripts/shared/storage/keys.js:47Private identity keys are stored unencrypted by default
scripts/verifySignature.js:19Authentication challenges can be replayed indefinitely
The stated purpose focuses on identity verification and attestation, but the skill also performs local private-key storage, persistence, and key-management operations. That mismatch can mislead users and agent frameworks into approving a skill with far more sensitive authority than its description suggests, enabling unexpected credential handling and long-term secret retention.
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 handles sensitive credential material, including private keys and verifiable credentials stored on disk. In context, identity tooling must process credentials, but storing them locally—especially with optional plaintext key storage—creates a high-value target for theft, misuse, or lateral access by other tools/processes.
- `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 includes ws 8.18.0, which is flagged for memory disclosure and memory-exhaustion denial of service issues. In an identity/authentication skill that may handle websocket-based RPC or provider traffic, remotely triggerable DoS or memory exposure in a networking library is a meaningful supply-chain risk.
brace-expansion 2.1.0 is flagged for multiple denial-of-service conditions caused by pathological expansion behavior and memory growth. Although often used in tooling or parsing paths, any reachable processing of attacker-controlled patterns can lead to CPU or memory exhaustion.
fast-uri 3.1.0 is reported for several URI parsing and canonicalization issues including host confusion and SSRF-related edge cases. Because this skill interacts with decentralized identity documents, registries, and remote resources, malformed URI handling could make trust or fetch decisions against the wrong host.
ws 7.5.10 is reported vulnerable to memory exhaustion from tiny fragments and data chunks, enabling denial of service via malicious websocket traffic. Since the dependency tree includes RPC and provider components, websocket exposure is plausible and makes this more relevant than a purely build-time issue.
underscore 1.13.6 is flagged for unlimited recursion in functions like _.flatten and _.isEqual, which can crash or hang a process on crafted deeply nested input. In services processing external credential, DID, or RPC data, this can become a reachable availability issue if these helpers are invoked on attacker-controlled structures.
undici 5.29.0 is associated with numerous HTTP parsing and request/response handling issues, including smuggling, queue poisoning, and CRLF-related flaws. This is especially concerning for an identity skill that likely fetches remote documents or communicates with registries and verifiers, where outbound HTTP trust boundaries matter.
ws 8.17.1 is another vulnerable websocket library instance affected by memory disclosure and memory exhaustion DoS issues. Multiple vulnerable websocket copies in the dependency tree broaden the attack surface and increase the chance that at least one reachable code path remains exploitable.
The lockfile includes ws 8.18.0, which is flagged for uninitialized memory disclosure and memory-exhaustion denial of service. This is especially relevant because the skill depends on networking-heavy identity, blockchain, and websocket-capable libraries; if the skill opens websocket connections to untrusted peers or relays, an attacker may be able to crash the process or potentially expose process memory.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
function newDataStorage(ethStateStorage) {
return {
credential: new CredentialStorage(
new IdentitiesFileStorage("credentials.json"),
),
identity: new IdentityStorage(
new IdentitiesFileStorage("identities.json"),
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
function newDataStorage(ethStateStorage) {
return {
credential: new CredentialStorage(
new IdentitiesFileStorage("credentials.json"),
),
identity: new IdentityStorage(
new IdentitiesFileStorage("identities.json"),
The code silently falls back to writing plaintext private keys to kms.json without any warning, consent, or hard failure when key encryption is not configured. This creates a high-risk secret exposure path that operators may not realize exists, especially dangerous here because the keys back identity verification and authentication proofs.
The README instructs users to run npx clawhub@latest install verified-agent-identity, which pulls and executes the latest published package version at install time. This creates a supply-chain risk because a compromised or malicious future release of clawhub could execute arbitrary code on the host during installation.
This installation command again relies on npx clawhub@latest, causing users to execute whatever code is published in the newest package version. In an identity-management skill that handles keys and credentials, this is especially sensitive because installer compromise could steal secrets or backdoor the environment before the skill is even used.
The skill declares executable behavior that can use environment variables and communicate with external registries, but it does not declare an explicit tool/permission scope. In an agent setting, this weakens operator visibility and policy enforcement, increasing the chance the skill is invoked with broader capabilities than users expect.
The setup instructions tell users to create an identity before prominently warning that private keys may be stored locally in plaintext when no master KMS key is configured. This can cause accidental insecure key creation, especially in automated agent environments where users may never review later security notes.
The linking workflow encourages challenge signing and identity linking without an upfront notice that DIDs, challenges, credentials, and related artifacts are persisted under the user's home directory. In a shared or managed agent runtime, that persistence can expose sensitive identity metadata or leave durable authentication artifacts behind.
When no master key is configured, _encodeEntry stores privateKeyHex directly on disk in plaintext. For an identity/authentication skill, exposure of private keys enables full impersonation, proof forgery, and persistent compromise of agent identity, so the skill context makes this more dangerous rather than less.
The list() method returns full private key material for every stored entry, unnecessarily broadening access to the most sensitive secret in the system. In a decentralized identity skill, listing private keys directly increases the blast radius of any misuse, logging leak, or downstream caller compromise because it exposes all agent identities at once.
uuid 13.0.0 is present and is reported vulnerable when v3/v5/v6 APIs are called with a caller-provided buffer lacking proper bounds checks. This is lower severity and may not be reachable in normal use, but it is still a real dependency risk if any code path passes attacker-influenced buffer arguments.
uuid 9.0.1 is also present and carries the same bounds-check weakness for certain namespace UUID generation APIs when buf is supplied. Multiple vulnerable versions in the tree increase maintenance risk even if exploitation requires a specific call pattern.
ajv 8.17.1 is reported vulnerable to ReDoS when the $data option is enabled, which can let crafted inputs consume excessive CPU during schema validation. In an identity-verification stack that may validate externally supplied claims or credential payloads, this can become a practical availability issue if that option is used.
elliptic 6.6.1 is identified as using a risky cryptographic implementation, which is concerning in a package set centered on authentication, keys, and proofs. Even when no active exploit is evident from the lockfile alone, weak crypto dependencies in identity-related code deserve treatment as real risk.