T09 · Insecure Skill Coding Practices
- Location
scripts/shared/storage/keys.js:44- Finding
Private keys may be stored in plaintext without restrictive filesystem 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 handles long-lived private keys and can store them unencrypted on disk unless encryption is configured.
Only install this if you are comfortable with the skill creating or using agent identity private keys. Configure BILLIONS_NETWORK_MASTER_KMS_KEY before creating or importing identities, restrict access to $HOME/.openclaw/billions, avoid reusing imported keys, and treat generated signed tokens and pairing links as sensitive. Review the unexpected agent.json mismatch and dependency posture before using this for important authentication flows.
scripts/shared/storage/keys.js:44Private keys may be stored in plaintext without restrictive filesystem permissions
scripts/verifySignature.js:17Signed authentication challenges can be replayed indefinitely
scripts/shared/storage/crypto.js:27Encrypted key storage uses a fast unsalted master-key derivation function
shell-quote 1.8.3 has advisories for parsing complexity DoS and improper newline escaping in quote(). This package is especially sensitive in an agent skill because shell-quoting libraries are typically used near command construction, so escaping flaws can turn untrusted input into command injection or argument-splitting conditions if the skill invokes subprocesses.
The package explicitly includes shell-quote 1.8.3, which is reported as having denial-of-service and escaping flaws. Even though package.json alone does not prove the vulnerable functions are exercised, shell-quote is commonly used in command construction/parsing; if attacker-controlled input reaches parse() or quote()-based command generation, this could enable resource exhaustion or malformed shell argument handling. In an identity/authentication skill, availability and integrity matter, so parser or escaping weaknesses are more dangerous than in a low-trust toy project.
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 primarily as an identity-verification utility, but its documented behavior also includes local private-key storage, optional encryption, and direct handling of kms.json on disk. This mismatch is dangerous because operators may approve the skill for verification tasks without realizing it persists and manages long-lived secrets locally, which materially changes the risk profile.
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 manifest claims the skill is 'verified-agent-identity' for decentralized identity verification, but the embedded agent metadata instead identifies an unrelated 'BitBrawlers AI' Web3 automation agent. This mismatch is a strong supply-chain and trust-boundary red flag because users or orchestrators may install the skill expecting identity-proof functionality while actually loading a different agent definition, enabling deceptive capability substitution.
ws 8.18.0 is present with advisories for uninitialized memory disclosure and memory-exhaustion denial of service. In an agent skill that may maintain websocket connections to chains or RPC services, a vulnerable websocket stack can expose process memory or allow remote service degradation through crafted frames.
brace-expansion 2.1.0 is flagged for multiple denial-of-service issues related to pathological expansion and memory growth. Although often used indirectly in tooling, any runtime path that accepts attacker-controlled patterns could be abused to exhaust CPU or memory.
fast-uri 3.1.0 is affected by multiple host-confusion and SSRF-related parsing flaws. This is especially relevant in an identity-verification skill because DID, schema, registry, or proof workflows may fetch remote resources, and malformed URLs could bypass allowlists or redirect backend requests to unintended hosts.
ws 7.5.10 is affected by a memory-exhaustion DoS issue from fragmented frames and small chunks. If any part of the skill or its transitive RPC stack accepts websocket traffic from untrusted or semi-trusted peers, this can be triggered remotely to degrade availability.
underscore 1.13.6 has unlimited recursion issues in flatten and isEqual that can lead to denial of service. If dependency code compares or normalizes attacker-controlled nested structures, this can crash or hang the agent process.
undici 5.29.0 is affected by numerous HTTP parsing and request-handling flaws, including smuggling, queue poisoning, and CRLF-related issues. In a decentralized identity skill that may contact registries, resolvers, or verifiers over HTTP, these bugs materially increase SSRF, cache-poisoning, or cross-request confusion risk.
ws 8.17.1 is another affected websocket version with memory disclosure and DoS advisories. Having multiple vulnerable ws versions increases the chance that at least one reachable runtime path remains exposed, particularly through blockchain RPC or event-stream integrations.
The lockfile pins ws 8.18.0, which is flagged for uninitialized memory disclosure and memory-exhaustion denial of service. In an agent identity skill, WebSocket-based communication may be exposed to untrusted peers or services, so a vulnerable ws version is materially risky if any reachable WebSocket server/client path exists.
This bootstrap code initializes storage for credentials and identities in predictable local files such as credentials.json and identities.json, which can expose highly sensitive identity artifacts if the host environment is shared, compromised, or backed up insecurely. In an agent identity skill, these files may contain attestations and identifiers that are especially privacy-sensitive, making local plaintext persistence more dangerous than in ordinary application state.
function newDataStorage(ethStateStorage) {
return {
credential: new CredentialStorage(
new IdentitiesFileStorage("credentials.json"),
),
identity: new IdentityStorage(
new IdentitiesFileStorage("identities.json"),
This storage layer explicitly falls back to provider: "plain" and writes privateKeyHex directly to kms.json whenever no master key is available. That means highly sensitive agent private keys can be persisted unencrypted on disk with no guardrail, refusal, or user-visible warning, which is especially dangerous in an identity/authentication skill where compromise of a key can allow impersonation and fraudulent proof generation.
The README instructs users to execute npx clawhub@latest install ..., which fetches and runs remote code at install time without pinning to an immutable version. If the upstream package or one of its resolution targets is compromised, users or agents could execute attacker-controlled code during installation.
The README recommends npx skills add ... without a pinned package version, so execution depends on whatever package version is current at runtime. This creates a supply-chain risk because install-time code from a mutable package can change after publication of the README.
The human installation instructions again invoke npx clawhub@latest, repeating the same mutable-code execution pattern for a broader audience. Because this is an identity-management skill handling keys and credentials, compromise during installation could directly expose sensitive material.
The README tells users to run npx skills add ... with no pinned version in the human setup path as well. That exposes users to supply-chain compromise through install-time script execution from a mutable package source.
The README shows identity creation using new or existing Ethereum private keys before prominently warning that, unless a master KMS key is configured, private keys are stored in plaintext on disk. In an identity/authentication skill, this is especially dangerous because theft of these keys enables impersonation and unauthorized proof generation.
The skill declares executable behavior that uses environment variables and networked identity operations, but it does not declare any explicit tool scope or permissions boundary. In an agent setting, this increases the chance that an orchestrator or user cannot accurately understand or restrict what the skill can access, leading to overbroad execution and unintended exposure of local secrets or outbound requests.
The installation and usage instructions tell users to create identities immediately, but the plaintext private-key risk is only disclosed later in the document. Because kms.json may store private keys unencrypted when BILLIONS_NETWORK_MASTER_KMS_KEY is unset, users may create sensitive identities before understanding that they are placing long-lived credentials on disk in potentially recoverable form.
The script persists DID metadata and the associated public key to storage automatically, without any user-facing disclosure, consent step, or indication of where that data is being stored. In an identity-management skill, silent persistence of identity artifacts increases privacy risk and can expose sensitive linkage information if local storage, shared environments, or downstream storage backends are accessible to others.