Back to skill

Security audit

Verified Agent Identity

Security checks for vulnerabilities and agentic risk

Overview

The skill largely does what it says, but it stores powerful identity private keys unencrypted without enforcing safe file permissions, so it should be reviewed carefully before installation.

Install only if you are comfortable with this skill creating or importing identity keys and storing them unencrypted under your home directory. Do not pass valuable wallet keys through `--key`; use a fresh, low-risk identity key, restrict file permissions on `$HOME/.openclaw/billions`, avoid `@latest` install flows in sensitive environments, and treat signed tokens or verification links sent by the skill as sensitive authentication material.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/shared/storage/base.js:9
Finding

Plaintext Private Keys Are Stored Without Enforced Filesystem Permissions

Content
View full analysis
entry.alias === args.alias); if (index >= 0) { keys[index].privateKeyHex = args.key; } else { keys.push({ alias: args.alias, privateKeyHex: args.key }); } await this.writeFile(keys); } ``` `scripts/shared/storage/base.js:9-12, 27-33`: ```js async ensureDirectory() { const dir = path.dirname(this.filePath); await fs.mkdir(dir, { recursive: true }); } async writeFile(data) { await this.ensureDirectory(); const json = JSON.stringify(data, null, 2); const tempPath = `${this.filePath}.tmp`; await fs.writeFile(tempPath, json, "utf-8"); await fs.rename(tempPath, this.filePath); } ``` ### Technical Analysis `KeysFileStorage.importKey()` stores raw private keys in the `privateKeyHex` field and passes them directly to the generic JSON storage implementation. The resulting `$HOME/.openclaw/billions/kms.json` file is unencrypted. The storage implementation does not explicitly set mode `0700` on the containing directory or mode `0600` on the temporary and final files. Access therefore depends entirely on the process's ambient `umask` and pre-existing directory permissions. Under a permissive configuration, the temporary file or final key store may be readable by other local users or processes. The temporary-file approach also uses a predictable `.tmp` path and does not use exclusive creation. Although the subsequent rename reduces partial-write risks, it does not establish confidentiality or protect against unsafe pre-existing filesystem objects. This implementation conflicts with the README statement that private keys are “ ...[truncated 1361 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/verifySignature.js:18
Finding

Signature Verification Challenges Can Be Replayed Indefinitely

Content
View full analysis
entry.did === did); if (index >= 0) { // Update existing entry entries[index] = { did, challenge, created_at }; } else { // Add new entry entries.push({ did, challenge, created_at }); } await this.writeFile(entries); } async getChallenge(did) { const entry = await this.find(did); return entry?.challenge; } ``` `scripts/verifySignature.js:18-25, 47-57`: ```js // Get the stored challenge const challenge = await challengeStorage.getChallenge(args.did); if (!challenge) { console.error(`Error: No challenge found for DID: ${args.did}`); console.error("Generate a challenge first with generateChallenge.js"); process.exit(1); } // Verify the challenge matches const payload = basicMessage.body; if (payload.message !== challenge) { console.error( `Error: Invalid signature: challenge mismatch ${payload.message} !== ${challenge}`, ); process.exit(1); } outputSuccess("Signature verified successfully"); ``` ### Technical Analysis Challenge records contain a `created_at` value, but `getChallenge()` returns only the challenge string. Consequently, `verifySignature.js` cannot enforce an expiration period. After successful verification, the challenge is neither deleted nor marked as consumed. Any correctly signed token for the current stored challenge therefore remains valid until another challenge overwrites that DID's record. The generated challenge is also limited to the range `0` through `9,999,999,999`, providing approximately 33 bits of possible challe ...[truncated 1319 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (42)

Known Vulnerable Dependency: shell-quote==1.8.3 — 2 advisory(ies): CVE-2026-13311 (shell-quote: Quadratic-complexity Denial of Service in `parse()` (CWE-407)); CVE-2026-9277 (shell-quote quote() does not escape newlines in object .op values)

Critical
Category
Supply Chain
Confidence
97% confidence
Finding

shell-quote 1.8.3 is reported vulnerable to both parsing DoS and improper newline escaping in quote(), which can enable command injection in shell-building scenarios. This is especially dangerous in an agent skill because agents commonly transform user or workflow input into subprocess commands, making shell-construction libraries high-risk when flawed.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: shell-quote==1.8.3 — 2 advisory(ies): CVE-2026-13311 (shell-quote: Quadratic-complexity Denial of Service in `parse()` (CWE-407)); CVE-2026-9277 (shell-quote quote() does not escape newlines in object .op values)

Critical
Category
Supply Chain
Confidence
96% confidence
Finding

The manifest includes shell-quote 1.8.3, which is flagged with critical advisories including a quadratic-complexity DoS in parse() and newline escaping issues in quote(). In an agent identity/authentication skill, inputs may be influenced by external parties, so vulnerable shell argument parsing/quoting can increase the chance of denial of service or command-construction flaws if this library is used on attacker-controlled data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The stated purpose is identity/authentication, but the documented behavior also includes outbound direct messaging via openclaw message send. That mismatch is dangerous because agents or reviewers may authorize the skill for verification tasks without realizing it can transmit signed tokens, verification URLs, or other data to external recipients.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · SKILL.md (reported line 10)May include surrounding context.


name: verified-agent-identity description: Billions/Iden3 authentication and identity management tools for agents. Link, proof, sign, and verify. metadata: { "category": "identity", "clawbot": { "requires": { "bins": ["node", "openclaw"] } }} homepage: https://billions.network/

When to use this Skill

Lets AI agents create and manage their own identities on the Billions Network, and link those identities to a human owner.

  1. When you need to link your agent identity to an owner.
  2. When you need sign a challenge.
  3. When you need link a human to the agent's DID.
  4. When you need to verify a signature to confirm identity ownership.
  5. When use shared JWT tokens for authentication.
  6. When you need to create and manage decentralized identities.

After installing the plugin run the following commands to create an identity and link it to your human DID:

bash
cd scripts && npm install && cd

Known Vulnerable Dependency: ws==8.18.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
96% confidence
Finding

ws 8.18.0 is flagged for memory disclosure and memory exhaustion DoS issues. In an agent identity skill that may maintain websocket/RPC connections to blockchain or verifier infrastructure, an exposed vulnerable websocket stack can let a remote peer crash the process or potentially leak memory contents.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: brace-expansion==2.0.2 — 4 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-33750 (brace-expansion: Zero-step sequence causes process hang and memory exhaustion); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro) +1 more

High
Category
Supply Chain
Confidence
92% confidence
Finding

brace-expansion 2.0.2 has multiple denial-of-service issues involving pathological expansion patterns that can hang or exhaust memory. Even if transitive, these parser-style bugs are dangerous wherever attacker-controlled patterns may be processed during build, tooling, or runtime request handling.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: fast-uri==3.1.0 — 7 advisory(ies): CVE-2026-13676 (fast-uri vulnerable to host confusion via failed IDN canonicalization); CVE-2026-18446 (fast-uri vulnerable to host confusion via backslash authority introducer); CVE-2026-75975 (fast-uri vulnerable to server-side request forgery via malformed IPv6 normalizat) +4 more

High
Category
Supply Chain
Confidence
95% confidence
Finding

fast-uri 3.1.0 is reported vulnerable to host confusion and SSRF-related parsing flaws. This is especially relevant in an identity stack that may resolve DIDs, fetch JSON-LD contexts, or contact verifier/issuer endpoints, because malformed attacker-controlled URLs could bypass host validation or trigger unexpected outbound requests.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==7.5.10 — 1 advisory(ies): CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
95% confidence
Finding

ws 7.5.10 is vulnerable to memory exhaustion DoS from crafted fragmented traffic. Because this skill depends on blockchain/network libraries that may establish websocket sessions, a malicious or compromised endpoint could consume resources and deny service to the agent.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: jsonpath==1.2.1 — 1 advisory(ies): CVE-2026-1615 (jsonpath has Arbitrary Code Injection via Unsafe Evaluation of JSON Path Express)

High
Category
Supply Chain
Confidence
93% confidence
Finding

jsonpath 1.2.1 is flagged for arbitrary code injection via unsafe evaluation of JSONPath expressions. This is a serious issue if any untrusted JSONPath or related selector reaches the library, because it can turn data processing into code execution within the agent environment.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: minimatch==5.1.6 — 3 advisory(ies): CVE-2026-27904 (minimatch ReDoS: nested *() extglobs generate catastrophically backtracking regu); CVE-2026-26996 (minimatch has a ReDoS via repeated wildcards with non-matching literal in patter); CVE-2026-27903 (minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja)

High
Category
Supply Chain
Confidence
92% confidence
Finding

minimatch 5.1.6 is affected by multiple ReDoS issues due to catastrophic backtracking on crafted patterns. If any untrusted glob patterns are accepted by tooling or runtime helpers, an attacker could cause severe CPU consumption and service degradation.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: underscore==1.13.6 — 1 advisory(ies): CVE-2026-27601 (Underscore has unlimited recursion in _.flatten and _.isEqual, potential for DoS)

High
Category
Supply Chain
Confidence
90% confidence
Finding

underscore 1.13.6 is reported vulnerable to unlimited recursion in flatten/equality helpers, enabling denial of service with crafted deeply nested input. In an agent context that may ingest complex claims, proofs, or JSON documents, unbounded recursion can crash or stall the process.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: undici==5.29.0 — 12 advisory(ies): CVE-2026-1525 (Undici has an HTTP Request/Response Smuggling issue); CVE-2026-6733 (undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse); CVE-2026-1527 (Undici has CRLF Injection in undici via `upgrade` option) +9 more

High
Category
Supply Chain
Confidence
96% confidence
Finding

undici 5.29.0 is flagged for multiple HTTP parsing and request/response smuggling style flaws. This is highly relevant for an identity-management skill that performs outbound HTTP to issuers, resolvers, or verifier services, because parser ambiguities and header handling bugs can lead to SSRF, cache poisoning, or cross-request contamination.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.17.1 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
96% confidence
Finding

ws 8.17.1 is vulnerable to memory disclosure and resource exhaustion issues. Given this skill's blockchain and identity networking dependencies, a hostile websocket peer or compromised upstream service could exploit these flaws to destabilize the agent or expose process memory.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 97)May include surrounding context.

md
function newDataStorage(ethStateStorage) {
  return {
    credential: new CredentialStorage(
      new IdentitiesFileStorage("credentials.json"),
    ),
    identity: new IdentityStorage(
      new IdentitiesFileStorage("identities.json"),

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 174)May include surrounding context.

md
function newDataStorage(ethStateStorage) {
  return {
    credential: new CredentialStorage(
      new IdentitiesFileStorage("credentials.json"),
    ),
    identity: new IdentityStorage(
      new IdentitiesFileStorage("identities.json"),

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/shared/bootstrap.js (reported line 54)May include surrounding context.

js
function newDataStorage(ethStateStorage) {
  return {
    credential: new CredentialStorage(
      new IdentitiesFileStorage("credentials.json"),
    ),
    identity: new IdentityStorage(
      new IdentitiesFileStorage("identities.json"),

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

The README instructs users to execute npx clawhub@latest install ..., which pulls and runs the latest package version at install time rather than a pinned, reviewed release. If the upstream package, dependency chain, or publishing account is compromised, users and agents could execute attacker-controlled code during installation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

This is a second occurrence of the same unsafe installation guidance using npx clawhub@latest, again causing execution of an unpinned remote package. Repeating the pattern in human-facing installation instructions increases the likelihood that operators will follow a non-reproducible and compromise-prone setup path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README explicitly states that private keys are stored in kms.json as unencrypted material, but it does not present a strong, prominent warning about the sensitivity and consequences of that choice. For an identity-management skill, plaintext private key storage is dangerous because compromise of the local account, backups, logs, or filesystem access could allow full identity theft and unauthorized signing.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes external Node/OpenClaw tooling and operates on local sensitive state, yet it declares no explicit tool scope or permissions boundary. In an agent setting, that omission increases the chance the runtime will allow broader environment and network access than users expect, which can enable unintended exfiltration or outbound actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation encourages passing a private key with --key on the command line, which can expose the secret via shell history, process listings, audit logs, and agent transcripts. Because the same document states private keys are stored unencrypted, accidental disclosure could immediately compromise the associated identity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script accepts or generates an Ethereum private key, imports that raw secret into the KMS-backed key store, and also reuses the same key material as the seed for identity creation. This expands the exposure surface of highly sensitive material and can surprise users who may expect a supplied key to be used transiently rather than persisted and repurposed for identity state, increasing the risk of unintended key retention or compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The script sends a pairing/verification URL directly to a recipient without any explicit user-facing notice that opening it will initiate identity-linking and disclosure of identity proof material. In an identity-management skill, this omission is security-relevant because recipients may be socially engineered into linking a human identity to an agent without informed consent or understanding of the privacy implications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code persists private cryptographic keys directly to a JSON file as plaintext (privateKeyHex) and also exposes them via list() and get(). If the filesystem, backups, logs, or the working directory are accessible to another process or user, the keys can be stolen and used to impersonate the agent or sign arbitrary data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This utility exposes a direct outbound messaging capability by invoking the external openclaw CLI, enabling the skill to send messages to arbitrary targets. Although execFileSync avoids shell interpolation and there is some input validation, the behavior still creates an unexpected exfiltration/communication channel that is broader than the stated identity/authentication purpose of the skill.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.