Back to skill

Security audit

Dashpass

Security checks for vulnerabilities and agentic risk

Overview

This is a credential-vault skill, but it overstates key protections and lets any agent with the vault environment read, export, rotate, or delete critical secrets without the promised human approval.

Review before installing. Use only testnet or low-impact secrets unless the approval and audit controls are fixed. Do not assume critical credentials require human approval in the current implementation, avoid eval-based env export for sensitive secrets, disable cache if needed, and treat CRITICAL_WIF and the recovery mnemonic as full vault-control secrets.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dashpass-cli.mjs:519
Finding
Mutual confirmation can be automatically fabricated and bypassed by one process<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dashpass-cli.mjs:519-535`; `scripts/mutual-confirm.mjs:233-242,273-299` **Vulnerability Type**: Broken multi-party authorization **Risk Level**: High ### Vulnerable Code ```javascript // scripts/dashpass-cli.mjs:519-535 // Protocol: request → approve → execute const req = requestDecrypt(service, 'cli get --mutual', 'cc'); approveDecrypt(req, 'evo'); const shareA = readShareA(); const shareB = readShareB(); let decrypted; try { decrypted = executeDecrypt( shareA, shareB, decodeByteArray(best.data.encryptedBlob), decodeByteArray(best.data.salt), decodeByteArray(best.data.nonce), ); } catch (e) { console.error('[get] Mutual decryption failed:', e.message); process.exit(1); } ``` ```javascript // scripts/mutual-confirm.mjs:233-242 export function approveDecrypt(request, approverRole) { auditLog({ action: 'approve', service: request.credentialName, requester: request.requesterRole, approver: approverRole, result: 'approved', }); return { ...request, approver: approverRole, approvedAt: new Date().toISOString(), status: 'approved' }; } ``` ```javascript // scripts/mutual-confirm.mjs:273-299 export function executeDecrypt(shareAHex, shareBHex, encryptedBlobBuf, saltBuf, nonceBuf) { const privKeyBytes = combineShares(shareAHex, shareBHex); let aesKey = null; try { const ecdh = createECDH('secp256k1'); ecdh.setPrivateKey(privKeyBytes); const sharedSecret = ecdh.computeSecret(ecdh.getPublicKey()); aesKey = Buffer.from(hkdfSync('sha256', sharedSecret, saltBuf, 'dashpass-v1', 32)); sharedSecret.fill(0); const tag = encryptedBlobBuf.slice(encryptedBlobBuf.length - 16); const ct = encryptedBlobBuf.slice(0, encryptedBlobBuf.length - 16); const decipher = createDecipheriv('aes-256-gcm', aesKey, nonceBuf); decipher.setAuthTag(tag); const plain = Buffer.concat([decipher.update(ct), decipher.final()]); audit ...[truncated 2254 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store the two shares under independently authenticated principals or on separate hosts. No single CLI process should be able to read both raw shares. 2. Require the approver to sign a canonical request containing: - Request ID - Credential/document ID - Requested operation - Credential version - Requester identity - Expiration time - Random nonce 3. Pass the signed approval into `executeDecrypt()` and verify its signature, scope, expiry, and replay status before reconstructing the key. 4. Enforce requester and approver separation instead of accepting arbitrary role strings. 5. Persist used request IDs or nonces to prevent replay. 6. Make decryption impossible when the approval object is missing, denied, expired, malformed, or for a different credential. 7. Add negative tests proving that self-approval, role spoofing, approval reuse, and approval substitution all fail. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dashpass-cli.mjs:489
Finding
Documented human approval for critical credentials is not enforced<![CDATA[ ## Vulnerability Details **File Location**: `references/trust-architecture.md:27-36`; `scripts/dashpass-cli.mjs:489-648,724-790,893-930,967-1058` **Vulnerability Type**: Missing authorization enforcement **Risk Level**: High ### Vulnerable Code and Security Claim ```markdown <!-- references/trust-architecture.md:34 --> **CRITICAL-level human confirmation:** Credentials marked "critical" (like mainnet private keys or primary API keys) require explicit human approval before any AI agent can access or modify them. The AI cannot escalate its own permissions. ``` The normal retrieval path decrypts the selected record without checking its security level or obtaining human approval: ```javascript // scripts/dashpass-cli.mjs: standard cmdGet path const sorted = docs.sort((a, b) => (b.data.version ?? 1) - (a.data.version ?? 1)); const best = sorted[0]; let decrypted; try { decrypted = decryptDoc(best.data); } catch (e) { console.error('[get] Decryption failed:', e.message); process.exit(1); } const result = { id: best.id, service: best.data.service, label: best.data.label, credType: best.data.credType, level: best.data.level, status: best.data.status, version: best.data.version ?? 1, expiresAt: best.data.expiresAt ?? 0, decrypted, }; ``` The environment export path similarly decrypts records without a level-based authorization gate: ```javascript // scripts/dashpass-cli.mjs: cmdEnv path const best = docs.sort((a, b) => (b.data.version ?? 1) - (a.data.version ?? 1))[0]; decrypted = decryptDoc(best.data); ``` ### Technical Analysis The `level` field is treated only as metadata. The CLI does not branch on `level === "critical"` before retrieval, environment export, rotation, or deletion. The implementation therefore does not enforce the documented rule that critical credentials require explicit human approval. Ordinary `get`, `get --pipe`, and `env` operations can expose critical secrets using only the p ...[truncated 1431 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Resolve the target record before performing any sensitive operation and enforce policy based on its stored `level`. 2. For `level === "critical"`, require authenticated, out-of-band human approval for: - Plaintext retrieval - Environment export - Rotation - Deletion - Level changes 3. Bind each approval to the exact document ID, version, service, operation, requester, and expiration time. 4. Reject missing, expired, replayed, or mismatched approvals. 5. Do not allow the invoking Agent to designate itself as the approver through a command-line string. 6. Consider requiring approval for all operations involving credential types such as `wif`, `ssh-key`, or `encryption-key`, independent of user-controlled level metadata. 7. Add integration tests showing that ordinary `get`, `env`, `rotate`, and `delete` fail for critical records without valid human authorization. 8. Until enforcement exists, remove the human-confirmation guarantee from documentation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dashpass-cli.mjs:127
Finding
Standard cryptographic paths leave sensitive buffers in process memory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dashpass-cli.mjs:127-155` **Vulnerability Type**: Insufficient erasure of cryptographic key material and plaintext **Risk Level**: Medium ### Vulnerable Code ```javascript function deriveAesKey(wif, salt) { const privKeyBytes = wifToPrivateKey(wif); const ecdh = createECDH('secp256k1'); ecdh.setPrivateKey(privKeyBytes); const sharedSecret = ecdh.computeSecret(ecdh.getPublicKey()); privKeyBytes.fill(0); // Zero private key buffer const key = Buffer.from(hkdfSync('sha256', sharedSecret, salt, 'dashpass-v1', 32)); return key; } function encrypt(wif, payload) { const salt = randomBytes(32); const nonce = randomBytes(12); const aesKey = deriveAesKey(wif, salt); const cipher = createCipheriv('aes-256-gcm', aesKey, nonce); const plain = Buffer.from(JSON.stringify(payload), 'utf8'); const ct = Buffer.concat([cipher.update(plain), cipher.final()]); const tag = cipher.getAuthTag(); return { encryptedBlob: Buffer.concat([ct, tag]), salt, nonce }; } function decrypt(wif, encryptedBlobBuf, saltBuf, nonceBuf) { const aesKey = deriveAesKey(wif, saltBuf); const tag = encryptedBlobBuf.slice(encryptedBlobBuf.length - 16); const ct = encryptedBlobBuf.slice(0, encryptedBlobBuf.length - 16); const decipher = createDecipheriv('aes-256-gcm', aesKey, nonceBuf); decipher.setAuthTag(tag); const plain = Buffer.concat([decipher.update(ct), decipher.final()]); return JSON.parse(plain.toString('utf8')); } ``` ### Technical Analysis Although `privKeyBytes` is erased, the normal cryptographic path does not erase: - The ECDH `sharedSecret` - The derived AES key returned by `deriveAesKey()` - The plaintext serialization created during encryption - The plaintext buffer created during decryption No `try/finally` block guarantees cleanup after successful operations or exceptions. These buffers remain eligible for garbage collection rather than being explicitly ove ...[truncated 1227 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Refactor key derivation, encryption, and decryption to use `try/finally`. 2. Explicitly overwrite `sharedSecret`, `aesKey`, and mutable plaintext buffers as soon as the operation completes. 3. Ensure cleanup also occurs when authentication, parsing, encryption, or serialization throws. 4. Minimize conversion of secrets into immutable JavaScript strings. 5. Avoid retaining decrypted result objects longer than required, especially in `env` and formatted output paths. 6. Keep caching restricted to encrypted data, as the current implementation intends. 7. Document that JavaScript cannot provide absolute memory-erasure guarantees and avoid describing the implementation as fully memory-safe. 8. Add tests or instrumentation that verify mutable key buffers are cleared on success and error paths. ]]>

T08 · Insecure Dependencies

Warning
Location
setup.md:24
Finding
Security-sensitive runtime dependencies lack a reproducible integrity boundary<![CDATA[ ## Vulnerability Details **File Location**: `setup.md:24-31,103-110`; `SKILL.md:8-14` **Vulnerability Type**: Unlocked and development-stage dependency installation **Risk Level**: Medium ### Vulnerable Configuration ```bash # setup.md:24-31 npm install @dashevo/evo-sdk@3.1.0-dev.1 ``` ```yaml # SKILL.md:8-14 requires: env: - CRITICAL_WIF - DASHPASS_IDENTITY_ID bins: - node packages: - "@dashevo/evo-sdk@3.1.0-dev.1" - "@scure/bip39@^2.2.0" ``` The audited project structure contains no `package.json` or committed dependency lockfile. ### Technical Analysis The Skill handles a wallet private key and arbitrary high-value credentials, making every runtime dependency part of its trusted computing base. Setup instructs users to install a development release directly from the package registry, while `@scure/bip39` is declared with a floating caret range. Without a committed manifest and lockfile, transitive dependency versions and integrity metadata are not reproducibly fixed by the project. Registry-delivered lifecycle scripts may also run during installation unless separately disabled. The audit did not identify a confirmed malicious dependency. The risk is the absence of controls needed to make installation reproducible and resistant to registry, maintainer-account, or transitive-package compromise. ### Attack Path 1. A user follows the setup guide and runs the documented `npm install` command. 2. npm resolves the selected package and its current transitive dependency graph from the configured registry. 3. A compromised package release, transitive dependency, or maintainer account supplies malicious code or a lifecycle script. 4. Installation or later module import executes the dependency under the user's account. 5. The dependency can inspect process environment variables, including `CRITICAL_WIF`, or intercept plaintext credentials handled by the CLI. ### Impact Assessment A compromised dependency executing in the ...[truncated 348 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a reviewed `package.json` containing exact dependency versions. 2. Commit a lockfile generated by the selected package manager. 3. Replace floating version ranges such as `@scure/bip39@^2.2.0` with an exact reviewed version. 4. Prefer a stable Evo SDK release when API compatibility permits. 5. Use `npm ci` rather than ad hoc `npm install` for reproducible installation. 6. Use `--ignore-scripts` when dependencies do not require lifecycle scripts; otherwise, document and audit every required script. 7. Enable dependency provenance, integrity, vulnerability, and license checks in CI. 8. Review transitive dependencies and update them through controlled, tested changes. 9. Consider isolating recovery functionality from the networked SDK in a separately locked dependency set. ]]>

other

Warning
Location
scripts/mutual-confirm.mjs:197
Finding
Audit-trail guarantees materially exceed the implemented logging controls<![CDATA[ ## Vulnerability Details **File Location**: `references/trust-architecture.md:17-21,84-94,106-112`; `scripts/mutual-confirm.mjs:197-205`; `scripts/dashpass-cli.mjs:424-1058` **Vulnerability Type**: Misleading and incomplete security audit control **Risk Level**: Medium ### Security Claims and Actual Implementation ```markdown <!-- references/trust-architecture.md:19 --> **On-chain audit trail:** Every credential operation (create, read, rotate, delete) can be logged to the Dash blockchain. Blockchain entries are immutable — nobody can edit or delete the history, not even the system administrators. ``` ```markdown <!-- references/trust-architecture.md:91 --> | **Audit trail** | Internal logs (you trust the company) | On-chain logs (you trust math) | ``` The implemented mutual-confirmation audit log is a local file: ```javascript // scripts/mutual-confirm.mjs:197-205 function auditLog(entry) { ensureDir(); const record = { timestamp: new Date().toISOString(), ...entry }; appendFileSync(AUDIT_LOG_PATH, JSON.stringify(record) + '\n', { mode: 0o600 }); } export { auditLog }; ``` The CLI's normal CRUD and export paths do not create an on-chain `accessLog` document. ### Technical Analysis The project contract defines an `accessLog` document type, but the reviewed CLI does not submit these documents for ordinary credential operations. Only mutual-confirmation request, approval, denial, and execution events are appended to `~/.dashpass/audit.log`. That local file is not cryptographically chained, signed, append-only at the operating-system level, or stored on-chain. A process running as the same user can alter, truncate, replace, or delete it. Standard `get`, `env`, `put`, `rotate`, and `delete` operations are not recorded through this logger. Consequently, the system does not provide the immutable, comprehensive audit trail described in its trust architecture. ### Attack Path 1. An Agent invokes ordinary `get`, `env`, `put`, `rotate`, or ...[truncated 881 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Implement authenticated `accessLog` document creation for every sensitive operation if on-chain auditing is a required security property. 2. Include the operation, service or document ID, credential version, requesting principal, result, timestamp, and a non-secret integrity reference. 3. Ensure audit records are submitted independently of normal success output and define behavior when audit submission fails. 4. Avoid logging plaintext credentials, WIF values, mnemonic words, shares, or derived keys. 5. If local logging remains, add cryptographic chaining or signatures and protect log storage through a separately controlled logging service. 6. Record standard retrieval and environment-export operations, not only mutual-confirmation events. 7. Correct the documentation until implementation is complete: describe the current log as local, mutable, and partial rather than immutable and on-chain. 8. Add tests confirming that every supported command creates the expected audit event without exposing secret material. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (26)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
node $CLI share-status

# If shares are missing or unhealthy, re-initialize:
rm -f ~/.dashpass/evo.share ~/.dashpass/cc.share
node $CLI init-shares
```
Confidence
85% confidence
Finding
The troubleshooting guidance includes `rm -f ~/.dashpass/evo.share ~/.dashpass/cc.share`, a destructive filesystem operation, without a warning about consequences or a safer verification step first. Although targeted to a fixed path, it can still cause loss of mutual-confirmation material and operational lockout if run carelessly or in the wrong environment.

Credential Access

High
Category
Privilege Escalation
Content
* dashpass-recovery.mjs — Phase 0 (P0-3): BIP-39 backup/recover for the
 * CRITICAL_WIF-derived 32-byte private key. Pure local crypto, no Platform deps.
 *
 * Model (borrowed from oak-keyring's BIP-39 recovery-words pattern):
 *   backup:  CRITICAL_WIF -> 32-byte privKey -> 24-word BIP-39 mnemonic (stdout only)
 *   recover: mnemonic -> 32-byte entropy -> privKey -> WIF (re-set CRITICAL_WIF)
 *
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill requires sensitive environment variables (`CRITICAL_WIF`, `DASHPASS_IDENTITY_ID`) but does not declare any explicit tool or permission scope. In an agent setting, that weakens least-privilege boundaries and makes it easier for the skill to access or encourage use of highly sensitive secrets without transparent scoping or user consent expectations.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The documentation exposes a destructive `delete` operation without an adjacent warning that deletion can cause irreversible loss of access to stored credentials. For a credential vault skill, this is more dangerous than usual because users may assume recovery is available when the same document also discusses backup and recovery for keys, not deleted records.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The `eval $(node $CLI env ...)` example encourages placing decrypted secrets directly into the shell evaluation flow without warning about exposure risks. This can leak secrets through shell history, process inspection, downstream child processes, debugging output, or command-injection if output formatting is ever compromised.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Shares must be 0600, directory must be 0700
chmod 700 ~/.dashpass
chmod 600 ~/.dashpass/evo.share ~/.dashpass/cc.share
```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Shares must be 0600, directory must be 0700
chmod 700 ~/.dashpass
chmod 600 ~/.dashpass/evo.share ~/.dashpass/cc.share
```

If `init-shares` reports success but `share-status` shows wrong permissions, check if a umask override is active.
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The contract defines an on-chain `accessLog` document that records `service`, `action`, `agentId`, and `timestamp`, which expands the skill beyond a simple encrypted vault into persistent behavioral telemetry. Even if secret values remain encrypted, immutable on-chain metadata can reveal which services are used, when credentials are accessed, and by which agents, creating privacy leakage and operational intelligence for attackers or observers.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The `get --json` example shows the fully decrypted secret in normal command output without warning users that this can end up in terminal scrollback, CI logs, shell captures, observability tooling, or copied transcripts. In a credential-vault skill, normalized examples that print raw secrets materially increase accidental disclosure risk.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The manifest describes DashPass as an encrypted credential vault on Dash Platform with encrypted on-chain storage. In this file, the `delete` command is documented as permanently removing all versions of a credential from the blockchain, which is semantically at odds with an immutable on-chain vault model and with the earlier rotation/audit language that emphasizes retained history on-chain.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The documented `env` workflow encourages decrypting secrets and exporting them into the shell environment, then applying them via `eval $(...)`. This expands exposure well beyond vault retrieval: environment variables can leak to subprocesses, debugging output, shell history/workflows, and command injection becomes possible if output is not perfectly escaped or is attacker-influenced.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
Recommending `eval $(node dashpass-cli.mjs env ...)` is dangerous because it executes command output in the current shell, not just data assignment. If service names, labels, values, or any upstream output formatting are ever attacker-controlled or improperly escaped, this becomes a direct code-execution vector while simultaneously placing decrypted secrets into the ambient shell environment.

Session Persistence

Medium
Category
Rogue Agent
Content
### "invalid identity nonce"

This happens when you do write operations (put, rotate) too quickly in succession. The Dash Platform needs a few seconds between operations to process each transaction.

**Fix:** Wait 3-5 seconds between consecutive write operations. This is a known platform timing limitation, not a DashPass bug.
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
| ID | Issue | Fix |
|----|-------|-----|
| P0-1 | Plaintext cache in world-readable `/tmp/` | Cache moved to `~/.dashpass/cache/`, encrypted with AES-256-GCM, file permissions 0600 |
| P0-2 | `--value` exposed in shell history | Added `--value-stdin` flag; warning printed when `--value` used via CLI args |
| P0-3 | Decrypted values stored in cache | Cache stores only encrypted blobs; decryption happens on read |
Confidence
70% confidence
Finding
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
| ID | Issue | Fix |
|----|-------|-----|
| P0-1 | Plaintext cache in world-readable `/tmp/` | Cache moved to `~/.dashpass/cache/`, encrypted with AES-256-GCM, file permissions 0600 |
| P0-2 | `--value` exposed in shell history | Added `--value-stdin` flag; warning printed when `--value` used via CLI args |
| P0-3 | Decrypted values stored in cache | Cache stores only encrypted blobs; decryption happens on read |
Confidence
70% confidence
Finding
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Session Persistence

Medium
Category
Rogue Agent
Content
If an agent misbehaves or a key is compromised:
- **Instant:** Delete the `CRITICAL_WIF` environment variable → agent loses all access immediately
- **Permanent:** Rotate the WIF → all old ciphertext becomes undecryptable
- **On-chain:** Revoke the Identity key → no more write access to the blockchain

## Local cache
Confidence
88% confidence
Finding
The document describes a 5-minute local cache of encrypted credential data. Even though the cache is encrypted and permissioned, it extends the lifetime of sensitive material on disk and creates residual access after an agent session ends, especially if the WIF remains available in the environment or is later recovered from the host. In a credential-vault skill, any persistence of secret-adjacent data increases the attack surface and weakens the claim of immediate revocation.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The document promotes on-chain audit logging as a trust feature but does not pair that claim with a clear warning that blockchain audit metadata is durable, broadly visible to observers with chain access, and effectively irreversible once written. For a credential vault, users may not realize that operation history, service associations, timing, and usage patterns can create lasting intelligence about their systems even if secret values remain encrypted.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The document states that plaintext is given to the AI agent during retrieval, but it does not present this as a prominent security warning or clearly explain the consequence: once decrypted, the secret is exposed to the agent runtime and can be copied, logged, forwarded, or mishandled by prompts, tools, or memory systems. In a credential-management skill for AI agents, this omission can mislead users into believing the system is trustless end-to-end when in fact retrieval intentionally breaks that boundary at the agent layer.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The default `get` flow ends by calling `printCredential`, which prints `cred.decrypted?.value` directly to stdout. Although the file warns about passing secrets on the command line, it does not similarly warn users that retrieving a credential will display the secret in terminal output, shell scrollback, logs, or recordings.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The `env` command decrypts stored secrets and emits them as shell `export VAR="value"` statements intended for `eval $(...)`. That expands the vault from storage/retrieval into direct environment injection, which increases accidental disclosure risk through shell history, process environments, logging, debugging tools, and downstream child processes that inherit the exported secrets.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
This code provides shell-oriented secret injection capability by transforming vault entries into environment variable assignments for direct shell evaluation. Even with basic escaping, the feature materially increases the blast radius of a retrieved secret because it encourages loading decrypted credentials into the ambient shell session, where unrelated commands and tools can access or leak them.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The `env` command outputs fully decrypted secrets directly to stdout as shell export statements without a strong disclosure warning at the point of use. This can leak secrets into terminal scrollback, command substitution contexts, CI logs, audit trails, or wrappers that capture stdout, making accidental exposure likely in real operational use.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The skill advertises encrypted credential storage on Dash Platform, but this code stores both secret shares and audit logs as local files under the user's home directory. In a credential-vault skill, this mismatch is security-relevant because users and downstream agents may assume platform-backed isolation, durability, and access controls that do not actually exist, increasing the risk of local compromise, backup leakage, or accidental exposure.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
This routine reconstructs the full private key locally and performs decryption on the host, contradicting the stated model of an encrypted on-platform credential vault. In the context of a secret-management skill, local reconstruction materially expands the attack surface: any host compromise, debugging hook, crash dump, or malicious co-resident process may target the reconstructed key or decrypted plaintext during execution.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The setup guide instructs users to place a private key in an environment variable, but does not warn that env vars may be readable by other local processes, captured by process inspection tools, inherited by child processes, logged by shell tooling, or persisted in session/config files. Because this skill manages decryption keys for a credential vault, exposing the WIF can directly compromise all stored secrets and the associated blockchain identity.

Static analysis

No suspicious patterns detected.