T09 · Insecure Skill Coding Practices
- Location
scripts/shared/storage/keys.js:47- Finding
Private keys are stored in plaintext by default without enforced file permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This identity skill appears purpose-aligned, but it needs review because it creates durable identity secrets and can store private keys in plaintext unless encryption is configured.
Review before installing. Use only on a trusted host, set BILLIONS_NETWORK_MASTER_KMS_KEY before creating or importing any identity, avoid passing real private keys with --key, and update vulnerable dependencies before relying on the skill for authentication-sensitive workflows. If it was already run without KMS encryption, treat stored keys as potentially exposed depending on host permissions and backups.
scripts/shared/storage/keys.js:47Private keys are stored in plaintext by default without enforced file permissions
scripts/verifySignature.js:48Authentication challenges remain reusable after successful verification
scripts/createNewEthereumIdentity.js:23Existing private keys are accepted through command-line arguments
This is a substantively similar issue: the documented purpose understates that the skill persists sensitive key material to the filesystem and may store it unencrypted unless a master key is configured. In an agent ecosystem, that behavioral gap can lead operators to authorize the skill without understanding that it creates credential-storage risk on the host.
This is a substantively similar issue: the documented purpose understates that the skill persists sensitive key material to the filesystem and may store it unencrypted unless a master key is configured. In an agent ecosystem, that behavioral gap can lead operators to authorize the skill without understanding that it creates credential-storage risk on the host.
ws 8.18.0 is reported with memory disclosure and memory-exhaustion DoS advisories, both of which are serious in software that accepts WebSocket traffic from untrusted peers. In an agent identity skill that may communicate over networked protocols and process external data, retaining a vulnerable WebSocket stack increases exposure if any reachable component uses this package.
brace-expansion 2.0.2 has multiple DoS-class issues involving pathological expansion patterns that can hang or exhaust memory. This is a genuine vulnerable dependency, though reachability is uncertain here because exploitability usually requires attacker control over glob-like pattern strings.
fast-uri 3.1.0 is flagged for multiple URI parsing issues including host confusion and SSRF-relevant normalization flaws. In an identity/verification stack that may fetch schemas, DID documents, registries, or remote metadata, incorrect URL parsing can materially increase risk by bypassing allowlists or sending requests to unintended hosts.
ws 7.5.10 is vulnerable to memory-exhaustion DoS from fragmented data handling. Any reachable WebSocket server or client processing attacker-controlled traffic can be forced into excessive resource consumption, which is especially problematic for agent services expected to remain available.
underscore 1.13.6 is reported to allow uncontrolled recursion in functions like _.flatten and _.isEqual, enabling DoS with crafted nested structures. If any JSON-RPC or utility code in this stack applies such helpers to attacker-provided data, the process can be crashed or stalled.
undici 5.29.0 is flagged for multiple serious HTTP issues including smuggling, queue poisoning, and CRLF-related problems. Because this skill's ecosystem likely performs outbound HTTP requests for DID resolution, schema retrieval, attestations, or verification services, a vulnerable HTTP client materially increases the attack surface.
ws 8.17.1 is affected by both memory disclosure and memory exhaustion issues, making it a significant network-facing dependency problem. In an identity/authentication context, service availability and confidentiality matter, so vulnerable WebSocket handling is more concerning than in purely local tooling.
Persisting credentials.json creates a local cache of credential material in an authentication/identity skill, which is especially sensitive in this context because credentials may include attestations, identifiers, and proof-related metadata. Unauthorized access to this file can expose private identity data and may facilitate impersonation, targeted phishing, or abuse of downstream verification workflows.
function newDataStorage(ethStateStorage) {
return {
credential: new CredentialStorage(
new IdentitiesFileStorage("credentials.json"),
),
identity: new IdentityStorage(
new IdentitiesFileStorage("identities.json"),
When no master key is configured, _encodeEntry() silently stores private keys in plaintext on disk under provider: "plain". This creates immediate secret-at-rest exposure to local users, backups, logs, or any filesystem compromise, and is particularly unsafe for a skill handling decentralized identity authentication keys.
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.
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.
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, which is flagged for both uninitialized memory disclosure and memory-exhaustion denial of service. In an agent identity skill that may maintain network-facing WebSocket/RPC connections through blockchain and DID libraries, a vulnerable ws version is especially concerning because malformed remote traffic could leak process memory or crash the agent.
The code creates a credential store backed by a local file named credentials.json, indicating direct local persistence of sensitive credentials. For an identity skill, credential contents can include personally identifying or authentication-related material; unauthorized read or tampering can enable privacy breaches, fraud, or acceptance of altered identity state.
function newDataStorage(ethStateStorage) {
return {
credential: new CredentialStorage(
new IdentitiesFileStorage("credentials.json"),
),
identity: new IdentityStorage(
new IdentitiesFileStorage("identities.json"),
When no master key is present, the storage layer silently falls back to provider: "plain" and writes raw privateKeyHex values to kms.json. For an identity/authentication skill, these keys are highly sensitive: any local user, backup system, container escape, log/archive process, or malware that can read the file can steal agent identities and generate valid authentication proofs.
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
The README instructs users to create identities and private keys before prominently warning that keys may be stored in plaintext unless BILLIONS_NETWORK_MASTER_KMS_KEY is set. For an identity/authentication skill, this increases the chance that users generate sensitive credentials under insecure defaults, which can lead to key theft and identity compromise if the host is accessed.
The skill declares executable behavior that clearly requires network access and likely environment-variable access, but it does not declare any explicit tool scope or permissions boundary. In an agent setting, missing scope declarations can cause overbroad execution authority, making it easier for the skill to perform unintended outbound requests or access sensitive runtime configuration without transparent user consent.
The installation and quick-start flow encourages immediate identity creation and linking without an upfront warning that sensitive identity data and private keys will be written under $HOME/.openclaw/billions. Users may follow the commands in an automated or shared environment and unintentionally create durable secrets on disk without evaluating storage protections, backups, or host exposure.