T09 · Insecure Skill Coding Practices
- Location
scripts/shared/storage/keys.js:50- Finding
Private keys are stored in plaintext when no master key is configured
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill appears purpose-built for decentralized identity, but it handles private keys and authentication proofs in ways that deserve review before installation.
Install only if you are comfortable with this skill managing agent identity keys on the local machine. Set a strong `BILLIONS_NETWORK_MASTER_KMS_KEY` before creating or importing identities, protect `$HOME/.openclaw/billions` as sensitive secret storage, avoid passing real private keys or tokens on the command line, and verify every signing/linking request before allowing the agent to run it.
scripts/shared/storage/keys.js:50Private keys are stored in plaintext when no master key is configured
scripts/shared/storage/base.js:25Sensitive identity files are written without explicitly restrictive permissions
scripts/verifySignature.js:18Verification challenges do not expire and are not consumed after successful use
The declared description emphasizes decentralized identity workflows, but the documentation also reveals local private-key custody, optional plaintext key storage, and raw key management behavior. This mismatch is dangerous because users and orchestrators may approve or auto-invoke the skill as an identity helper without realizing it also handles highly sensitive key material and credential stores.
The documentation states that private keys may be stored in plaintext when the master KMS key is not configured, but this warning appears deep in the security section rather than prominently before identity creation. That creates a realistic risk that operators will generate identities and persist secrets insecurely on disk without understanding the exposure.
The skill explicitly accesses credential and identity storage files, including verifiable credentials and key material, which are highly sensitive assets in an agent environment. Even if intended for legitimate identity workflows, exposing a skill with broad access to these stores raises the risk of credential disclosure, misuse, or unintended exfiltration through subsequent tool actions.
- `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 denial-of-service issues in WebSocket handling. In an agent skill that may communicate with remote services, any reachable WebSocket surface increases risk because malformed or fragmented frames from a remote peer could crash the process or expose memory contents.
brace-expansion 2.0.2 has multiple denial-of-service issues caused by pathological expansion patterns that can cause extreme CPU or memory consumption. Even though this is often a build/tooling dependency, it is still a real vulnerability if any runtime path or auxiliary tooling processes attacker-controlled glob-like strings.
fast-uri 3.1.0 is reported vulnerable to multiple URL parsing and canonicalization issues, including host confusion and SSRF-relevant edge cases. This is particularly relevant for an identity-oriented skill that may fetch remote schemas, DID documents, or attestations, because parser inconsistencies can let attackers bypass allowlists or redirect requests to unintended internal targets.
ws 7.5.10 is flagged for a memory exhaustion DoS via fragmented frames and tiny chunks. If the affected WebSocket server/client code is reachable through RPC or network-facing components, a remote attacker may be able to degrade availability or crash the process with crafted traffic.
underscore 1.13.6 is flagged for uncontrolled recursion in functions such as flatten and isEqual, which can cause denial of service on maliciously nested inputs. If any dependency applies these helpers to untrusted request or response data, a remote attacker may trigger excessive recursion and process instability.
undici 5.29.0 is associated with multiple HTTP parsing, smuggling, and request/response confusion issues. This is especially concerning in a decentralized identity skill that likely performs outbound HTTP fetches for DID documents, registries, schemas, or attestations, because parser discrepancies can enable SSRF, cache poisoning, or cross-request contamination.
ws 8.17.1 is flagged for both uninitialized memory disclosure and memory exhaustion DoS. Because this project includes multiple network and RPC-related packages, any reachable WebSocket handling exposed to untrusted peers materially increases the chance of remote availability impact or data leakage.
The code persists credential material to a predictable local file (credentials.json), which can expose sensitive identity artifacts if the host is multi-user, compromised, or the file permissions are weak. In an agent identity skill, stored credentials may enable impersonation, privacy loss, or unauthorized proof generation, making local credential persistence more sensitive than ordinary application state.
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 code intentionally falls back to storing raw private key material on disk in plaintext. In a skill that manages decentralized identity and authentication keys, this creates a direct secret-at-rest exposure: any local user, malware, backup system, or accidental file disclosure can recover the agent's private keys and impersonate identities or forge authentication proofs.
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
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 lockfile pins ws 8.18.0 under @ethersproject/providers, and the reported advisories include uninitialized memory disclosure and memory-exhaustion DoS in WebSocket handling. In an identity/agent-authentication skill that may maintain network connections to blockchain or verifier infrastructure, vulnerable WebSocket code increases exposure to remote attacks that can crash the process or leak 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"),
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"),
This code explicitly falls back to storing private keys with provider: "plain" when no master key is available, which means sensitive cryptographic material can be persisted to disk unencrypted. In an agent identity skill, those keys are high-value secrets: compromise of the local filesystem, backups, logs, or container volumes could allow an attacker to steal the keys and impersonate the agent or misuse attestations.
The README instructs users to run npx clawhub@latest install verified-agent-identity, which fetches and executes the latest package version at install time. Using a moving target for an installation/bootstrap tool weakens supply-chain integrity because a compromised or malicious future release could be executed automatically by users or agents.
This second installation example repeats the same unsafe pattern of invoking npx clawhub@latest, which downloads and runs unpinned code. In an agent-skill context, users may copy-paste the command directly, increasing exposure to supply-chain compromise if the upstream package changes or is hijacked.
The documentation explicitly tells users to pass an Ethereum private key on the command line via --key <your-ethereum-private-key>. Secrets supplied as CLI arguments are commonly exposed via shell history, process listings, audit logs, terminal scrollback, and orchestration tooling, making this a direct credential-handling weakness for highly sensitive key material.
The skill requires Node, uses an optional environment secret, and explicitly performs network-backed identity and attestation operations, but it does not declare an explicit tool/permission scope. In an agent environment, missing scope declarations can cause the skill to be invoked with broader-than-expected access and make review and containment harder.
The invocation examples are broad enough to match common identity-related requests and instruct the agent to perform sensitive identity-linking actions with minimal exclusion conditions. In practice, that can lead to over-eager triggering of signing/linking flows in response to loosely phrased user prompts, increasing the chance of unauthorized proof generation or identity association.