T09 · Insecure Skill Coding Practices
- Location
scripts/shared/storage/keys.js:44- Finding
Private keys are stored in plaintext by default without enforced owner-only file permissions
- 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 can store long-lived private keys in plaintext by default, so users should review it carefully before installing.
Install only if you are comfortable with an agent creating or importing identity private keys. Set BILLIONS_NETWORK_MASTER_KMS_KEY before creating identities, restrict permissions on $HOME/.openclaw/billions, avoid importing valuable Ethereum keys, treat signed tokens as reusable until challenges are rotated, and prefer pinned installs plus updated dependencies.
scripts/shared/storage/keys.js:44Private keys are stored in plaintext by default without enforced owner-only file permissions
scripts/verifySignature.js:18Signed authentication challenges can be replayed because they do not expire or get consumed
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.
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 functionality, but the documented behavior also includes local private-key storage, optional encryption/decryption, and key record management. That mismatch is dangerous because users or agents may invoke the skill without realizing it handles long-term secret material, increasing the risk of credential exposure, unsafe automation, and inappropriate trust assumptions.
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
ws 8.18.0 is identified with memory disclosure and memory exhaustion DoS advisories. Because this skill depends on blockchain, DID, and RPC/websocket-heavy libraries, vulnerable websocket handling is more relevant than in a purely offline package and could expose process memory or enable denial of service when handling untrusted websocket peers.
brace-expansion 2.0.2 has multiple DoS advisories related to pathological expansion behavior. This is a true vulnerable dependency, but its practical security impact here is moderated because it is typically exercised in tooling or parsing contexts rather than directly exposed as a network service primitive.
fast-uri 3.1.0 is associated with multiple host-confusion and SSRF-related advisories. In an identity-verification skill that may resolve DIDs, fetch JSON-LD contexts, or interact with remote registries, URI parsing flaws are particularly relevant because attacker-controlled identifiers or documents may influence outbound requests.
ws 7.5.10 is flagged for a memory exhaustion DoS issue. Since this package appears through JSON-RPC/websocket-related dependencies, a remote party may be able to consume excessive resources via crafted fragmented websocket traffic if those features are exposed.
underscore 1.13.6 is reported vulnerable to unlimited recursion in _.flatten and _.isEqual, enabling potential DoS on maliciously nested inputs. This is credible, though practical exposure depends on whether untrusted data reaches those utility calls through transitive libraries.
undici 5.29.0 carries numerous HTTP parsing, smuggling, queue-poisoning, and injection advisories. This is especially concerning in a decentralized identity skill that likely performs outbound HTTP fetches for DIDs, attestations, or JSON-LD resources, because malformed upstream or attacker-directed endpoints could abuse client behavior.
ws 8.17.1 is vulnerable to both memory disclosure and memory exhaustion DoS. Given the dependency stack includes several networking and RPC components, retaining multiple vulnerable ws versions increases the attack surface if any websocket endpoints or clients interact with untrusted peers.
This bootstrap code stores credential, identity, DID, challenge, and key-related data in predictable local JSON files, which can expose sensitive identity artifacts if the host is multi-user, backups are accessible, or the files are read by other processes. In an agent identity skill, these files may contain credentials and proof-related data that enable impersonation, privacy loss, or unauthorized reuse if not strongly protected.
function newDataStorage(ethStateStorage) {
return {
credential: new CredentialStorage(
new IdentitiesFileStorage("credentials.json"),
),
identity: new IdentityStorage(
new IdentitiesFileStorage("identities.json"),
When no master key is available, the storage layer silently falls back to provider="plain" and writes the private key directly to disk in JSON. For an identity/authentication skill handling agent private keys, this creates a serious confidentiality risk because any local user, backup system, log collector, container escape, or filesystem compromise can recover long-lived credentials and impersonate the agent.
The README instructs users to execute npx clawhub@latest install verified-agent-identity, which pulls and runs the latest published package version at install time rather than a pinned, reviewed release. This creates a supply-chain risk: if the package or a dependency is compromised, users may execute attacker-controlled code during installation.
This is the same supply-chain issue repeated in the Human CTA section: npx clawhub@latest install verified-agent-identity causes execution of an unpinned remote package. Because this skill manages identities and keys, compromise of the install path is especially sensitive and could lead to theft of credentials or malicious modification of the agent environment.
The documentation states that private keys are stored in kms.json and explains optional encryption, but normalizes plaintext storage when BILLIONS_NETWORK_MASTER_KMS_KEY is not set. For an identity-management skill, failing to prominently warn that keys may be stored unencrypted by default can lead operators to unintentionally leave highly sensitive secrets recoverable from disk.
The skill requires Node execution, optional access to an environment-held master key, and interaction with external identity infrastructure, yet it declares no explicit tool scope or allowed-tools boundary. In an agent setting, missing capability scoping increases the chance of over-broad execution and unintended access to env/network resources during identity operations.
The instructions tell users to create identities and store identity material under $HOME/.openclaw/billions, while later admitting kms.json may contain plaintext private keys if BILLIONS_NETWORK_MASTER_KMS_KEY is not set. Encouraging key creation without an upfront warning about plaintext secret storage can directly lead to private-key compromise on multi-user or poorly secured systems.
This code accepts a user-supplied private key and derives a signer from it, but there is no confirmation prompt, warning message, or explanatory comment indicating that sensitive credential material is being consumed. Because handling private keys is safety-critical, the absence of any user disclosure increases the risk of accidental misuse.
The code sends the full authorization request object to an external URL shortener without any explicit user-facing disclosure or consent. In this identity-linking context, the payload can contain sensitive metadata such as verifier information, callback data, scope details, and proof request parameters, which may leak relationship, workflow, or identity context to a third party and create privacy and trust risks if the shortener logs, inspects, or is compromised.
The code initializes a file-backed key store with "kms.json", which causes sensitive key material to be written to disk. While there are docstrings describing the component, there is no user-facing warning, confirmation, or explicit disclosure here that cryptographic keys and related wallet state will persist locally.
The importKey path persists supplied secret key material to disk by calling writeFile(), and because writeFile may encode entries as plaintext when no master key is configured, key import can silently create an unencrypted at-rest secret. In this skill's context of decentralized identity and authentication proofs, imported keys are highly sensitive because compromise enables fraudulent attestations or identity impersonation.
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, but its exploitability depends on the application actually invoking the affected APIs with attacker-influenced buffer handling; in a dependency lockfile alone, there is no evidence of active exploitation.
uuid 9.0.1 is also covered by the same bounds-check advisory affecting certain namespace-based UUID generation paths. This is a genuine dependency weakness, though typically lower severity unless the application passes attacker-controlled buffers into those APIs.
ajv 8.17.1 is reported vulnerable to ReDoS when the $data option is used. This is a real issue, but exploitability depends on whether this package or its consumers validate attacker-controlled schemas/data with $data enabled; the lockfile alone cannot confirm active exposure.
No suspicious patterns detected.