Back to skill

Security audit

pulseai-skill

Security checks for vulnerabilities and agentic risk

Overview

This is a real on-chain marketplace skill, but it exposes wallet private keys and handles money-affecting actions with insufficient safeguards.

Review before installing. Do not run wallet generation in JSON mode unless you are prepared for the private key to appear in logs or transcripts, protect or rotate any key stored in ~/.pulse/config.json, and treat all buy, settle, cancel, operator, and provider-runtime commands as real mainnet actions that can spend funds or change on-chain state. Avoid untrusted offerings with remote schema URLs until schema fetching is restricted.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/commands/job.ts:544
Finding

Attacker-Controlled Schema URI Enables Server-Side Request Forgery

Content
View full analysis
{ let schemaPayload: unknown; if (schemaUri.startsWith('data:')) { schemaPayload = parseDataUriJson(schemaUri); } else if (schemaUri.startsWith('http://') || schemaUri.startsWith('https://')) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 30_000); try { const response = await fetch(schemaUri, { signal: controller.signal }); if (!response.ok) { throw new Error(`Failed to fetch requirements schema URI (${response.status} ${response.statusText})`); } const buf = await response.arrayBuffer(); if (buf.byteLength > 1_048_576) { throw new Error(`Schema too large (${buf.byteLength} bytes). Limit is 1MB`); } schemaPayload = JSON.parse(new TextDecoder().decode(buf)); } finally { clearTimeout(timeoutId); } } else if (schemaUri.trim().startsWith('{')) { schemaPayload = JSON.parse(schemaUri); } else { return null; } if (!isOfferingSchema(schemaPayload)) { throw new Error('requirementsSchemaURI did not resolve to a valid OfferingSchema document'); } return schemaPayload; } ``` ### Technical Analysis The `requirementsSchemaURI` value comes from marketplace offering data and is therefore controlled by the offering publisher. When a buyer creates a job with requirements, the CLI passes that value directly to `fetch()`. The implementation only verifies that the URI starts with `http://` or `https://`. It does not: - Reject loopback, privat ...[truncated 2874 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/commands/wallet.ts:63
Finding

Wallet Private Keys Are Printed to Standard Output and Stored Without Explicit Restrictive Permissions

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (32)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description centers on an on-chain commerce marketplace for AI services on MegaETH, including browse/buy/sell and escrow flows. The supplied code does not implement any marketplace actions. Instead, it provides CLI subcommands for registering an agent in an identity registry, initializing it in Pulse, fetching agent details, and updating the operator address. This is a materially different primary purpose: agent identity and administration rather than commerce. Therefore the description does not accurately represent the actual behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding

The declared description presents a full agent-to-agent commerce marketplace experience on MegaETH, including browsing, buying, and selling AI services with escrow. The supplied code chunk instead implements only a provider-side serving command: it starts a runtime that listens for incoming jobs, optionally loads a handler from disk, auto-accepts jobs, and can auto-deliver placeholder content. This is related at a high level to fulfilling marketplace jobs, but it does not implement the broader marketplace functions claimed in the description, especially browsing, purchasing, or escrow management. The code also exposes a concrete CLI trigger (serve start) despite no triggers being declared. Therefore the description does not accurately represent this specific code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description is about an on-chain AI services marketplace with escrow and agent-to-agent commerce. The supplied code chunk does not implement marketplace actions at all. Instead, it provides CLI wallet utilities: querying ETH and ERC-20 balances, generating a private key, deriving an address, and saving the key to ~/.pulse/config.json. These are materially different capabilities from the declared purpose. While wallet functionality could support a commerce tool, this chunk’s primary behavior is wallet management, not browsing, buying, selling, or escrow-based marketplace interaction.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared purpose describes a commerce/marketplace skill on MegaETH with browsing, buying, selling, and escrow functionality. The supplied code does not implement any marketplace actions, escrow logic, service discovery, or transaction workflows related to agent-to-agent commerce. Instead, it handles credential/config management and client initialization for Pulse mainnet, including filesystem access to ~/.pulse/config.json and use of a private key. These are materially different behaviors and resources from the stated purpose, so this is a clear description-to-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The supplied code does not implement marketplace, escrow, MegaETH, agent-to-agent commerce, browsing, buying, or selling functionality. Instead, it is a generic console output helper for formatting and printing results in JSON or human-readable terminal form. While such a module could be a supporting utility within a larger commerce skill, this chunk by itself is unrelated to the declared primary purpose and demonstrates materially different behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The wallet generation flow both persists the private key and may echo it back to the caller without a strong safety warning. In this skill's context—an on-chain commerce CLI that can spend assets and manage agents—private key disclosure directly enables theft of funds, agent hijacking, and fraudulent marketplace actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

When an existing key is present, JSON mode includes the raw private key in command output, which can be captured by shell history, logs, CI systems, terminal scrollback, or other automation consuming stdout. Because this skill manages blockchain wallets for marketplace activity, disclosure of the private key enables full account takeover and theft of funds or abuse of delegated operator permissions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README instructs users to generate a wallet and notes that the private key is saved automatically to ~/.pulse/config.json, but it does not warn that this file contains highly sensitive credentials or advise on securing it. In a blockchain commerce skill where the wallet can authorize purchases and receive or release funds, this omission increases the risk of accidental key exposure, insecure backups, or unsafe filesystem permissions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README presents buy, create-job, settle, and related payment-affecting commands as simple quick-start steps without warning that these trigger real blockchain actions that may be irreversible and can spend or release user funds. In the context of an on-chain marketplace with escrow, users may execute commands in production without realizing the financial consequences.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares no explicit tool scope even though it clearly requires network access and local environment/file interactions, including wallet generation and persistence. In an agent framework, missing permission boundaries can cause the skill to be granted broader capabilities than users expect, increasing the chance of unintended external calls or sensitive local-state access.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

The workflow tells the agent to create a third-party job, wait for completion, and return results, which introduces cross-session state and delegation of user requests to an external service. That is risky because sensitive prompts or data may be sent to another agent and later returned without strong consent, provenance checks, or handling rules for pending jobs across sessions.

Content

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

md
When a user asks you to do something you can't do directly, search the Pulse marketplace for a specialized agent:

1. **Search**: `pulse browse "image generation" --json` to find relevant offerings
2. **Create Job**: `pulse job create --offering <id> --agent-id <your-agent-id> --json`
3. **Wait**: `pulse job status <jobId> --wait --json` to poll until completion
4. **Return results** to the user

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to generate a wallet and save the keypair to ~/.pulse/config.json without any explicit warning about secret handling, encryption, file permissions, backup risk, or multi-tenant exposure. Because this wallet is tied to on-chain identity and funds, insecure storage or casual disclosure can lead to theft, impersonation, or unauthorized marketplace actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

saveConfig writes the wallet private key to ~/.pulse/config.json in plaintext without setting restrictive file permissions or using a secure secret store. On multi-user systems, backup agents, developer tooling, or malware can read this file and obtain full control of the associated wallet.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The wallet generation command stores a raw private key locally and, in JSON mode, includes the private key in command output. Any logging pipeline, shell history wrapper, CI runner, or downstream tool consuming JSON output could capture and persist the secret, leading to full wallet compromise and unauthorized on-chain transactions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The serve start --handler path resolves a user-supplied file path and dynamically imports it, then executes exported handler logic inside the provider runtime. This is effectively arbitrary code execution in the context of the user's wallet-bearing process, so a malicious or trojanized handler can steal private keys, sign transactions, exfiltrate job data, or alter marketplace behavior.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · dist/pulse.js (reported line 344)May include surrounding context.

js
jobCommand
  .command('create')
  .description('Create a new job (auto-approves USDm, deploys WARREN terms)')
  .requiredOption('--offering <id>', 'Offering ID')
  .requiredOption('--agent-id <id>', 'Your (buyer) agent ID')
  .option('--requirements <json>', 'JSON requirements to attach')

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · src/commands/job.ts (reported line 45)May include surrounding context.

ts
jobCommand
  .command('create')
  .description('Create a new job (auto-approves USDm, deploys WARREN terms)')
  .requiredOption('--offering <id>', 'Offering ID')
  .requiredOption('--agent-id <id>', 'Your (buyer) agent ID')
  .option('--requirements <json>', 'JSON requirements to attach')

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The settle command triggers release of escrowed payment immediately with no interactive confirmation, dry-run summary, or explicit user acknowledgment. In a commerce CLI handling real on-chain funds, a mistyped job ID, automation mistake, or compromised agent workflow could irreversibly release payment before the operator notices.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The cancel command performs an irreversible job cancellation transaction without warning or confirmation. Because this is an on-chain marketplace command affecting escrow and job lifecycle state, accidental invocation or parameter mix-ups can cause financial loss, workflow disruption, and potentially forfeited business opportunities.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The command generates a new wallet private key and persists it to ~/.pulse/config.json without any visible warning, confirmation, or indication that this file now contains highly sensitive signing material. In an agent-to-agent commerce context, that key likely controls funds and on-chain permissions, so silent local storage increases the chance of accidental exposure through backups, weak file permissions, multi-user systems, or operator misunderstanding.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code persists a wallet private key to ~/.pulse/config.json in plaintext using fs.writeFileSync, with no file-permission hardening, encryption, or user-facing warning in this file. In the context of an on-chain commerce skill, compromise of this file can directly lead to wallet takeover and irreversible asset loss, making the practical impact higher than a generic config-secret issue.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · src/config.ts (reported line 63)May include surrounding context.

ts
}

/**
 * Create a Pulse client from PULSE_PRIVATE_KEY env var.
 * All contract addresses and indexer URL are embedded in the SDK.
 */
export function getClient(): PresetPulseClient {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The manifest uses a caret range for @pulseai/sdk, which permits automatic installation of newer minor and patch releases. For an agent skill that interacts with an on-chain marketplace and escrow flows, dependency drift can introduce unexpected behavior or a compromised upstream release into the runtime without any code change in this repository.

Content

Scanner excerpt · package.json (reported line 27)May include surrounding context.

json
"typecheck": "tsc --noEmit"
  },
  "dependencies": {
    "@pulseai/sdk": "^0.1.0",
    "commander": "^12.0.0",
    "viem": "^2.21.0",
    "chalk": "^5.3.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The commander dependency is not pinned and allows semver-compatible updates to be pulled at install time. Even for a CLI library, supply-chain compromise or a breaking behavioral change could affect command parsing and execution paths used by the skill.

Content

Scanner excerpt · package.json (reported line 28)May include surrounding context.

json
},
  "dependencies": {
    "@pulseai/sdk": "^0.1.0",
    "commander": "^12.0.0",
    "viem": "^2.21.0",
    "chalk": "^5.3.0"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The viem dependency is unpinned, allowing newer releases to be installed automatically. Because this skill is for agent-to-agent commerce on MegaETH with escrow, an unexpected upstream change in blockchain transaction handling or signing logic has elevated risk compared with a purely local utility.

Content

Scanner excerpt · package.json (reported line 29)May include surrounding context.

json
"dependencies": {
    "@pulseai/sdk": "^0.1.0",
    "commander": "^12.0.0",
    "viem": "^2.21.0",
    "chalk": "^5.3.0"
  },
  "devDependencies": {

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
dist/pulse.js:124

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
dist/pulse.js:102

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/commands/wallet.ts:79