Back to skill

Security audit

Mirage Marketplace Skill

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real marketplace-bidding skill, but it combines credentialed automation, bid submission, custom providers, local executors, and weak local control files in ways users should review carefully before installing.

Review this before installing on any machine with valuable credentials. Avoid custom provider endpoints and local generator scripts unless you fully trust them, disable preset auto-accept if you want per-job control, secure ~/.openclaw/marketplace.env with user-only permissions, and prefer a version that fixes the /tmp signaling, confirmation timeout, provider URL validation, and credential scoping issues.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/provider-engine.js:110
Finding
Custom Provider Configuration Can Exfiltrate Arbitrary Environment Secrets<![CDATA[ ## Vulnerability Details **File Location**: `scripts/provider-engine.js:110-153` **Additional Location**: `references/onboarding.md:124-145` **Vulnerability Type**: Unrestricted secret selection and transmission to a configurable endpoint **Risk Level**: High ### Vulnerable Code ```js async function callProvider(capability, specPath, resultBase) { const apiKey = process.env[capability.envKey]; if (!apiKey) throw new Error(`Missing env: ${capability.envKey}`); const spec = JSON.parse(fs.readFileSync(specPath, 'utf-8')); const prompt = buildPrompt(spec); const provider = resolveProvider(capability); if (!provider.endpoint) { throw new Error(`No endpoint for "${capability.api}". Set endpoint in config or add to data/providers.json`); } const sizeVal = resolveSize(provider.sizeMap, spec.ratio); const vars = { apiKey, prompt }; // ... const headers = {}; if (provider.auth) { headers['Authorization'] = interpolate(provider.auth, vars); } const body = interpolate(provider.body, vars); // ... const res = await fetchWithRetry(provider.endpoint, fetchOpts); ``` The documented custom-provider flow permits both values to be supplied through configuration: ```json { "api": "<api name>", "envKey": "<env var>", "endpoint": "<url>", "provider": { "auth": "Bearer {{apiKey}}", "body": { "prompt": "{{prompt}}" }, "response": { "type": "json", "imagePath": "data[0].url" } } } ``` ### Technical Analysis The implementation treats `capability.envKey` as an unrestricted lookup into `process.env` and sends the resulting value to `provider.endpoint`. Neither the environment-variable name nor the destination is constrained. Because `scripts/lib/env.js` imports every value from `~/.openclaw/marketplace.env`, a custom capability can select any loaded marketplace or provider secret. It can also select unrelated secrets already present in the parent process environment. The endpoint has no HTTPS requiremen ...[truncated 1275 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace arbitrary `process.env[capability.envKey]` access with an allowlist of credential identifiers supported by the Skill. 2. Bind each registered provider to a fixed credential name and fixed hostname. 3. Require explicit, separate user authorization before enabling a custom endpoint or credential. 4. Require HTTPS and reject URLs containing embedded credentials. 5. Resolve destination addresses and reject loopback, private, link-local, multicast, and metadata-service ranges. 6. Revalidate the destination after every redirect. 7. Store provider credentials in a secret manager where possible instead of exposing all credentials through the process environment. 8. Ensure logs and error responses never include authorization values. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/provider-engine.js:169
Finding
Unvalidated Provider Response URLs Enable SSRF and Resource Exhaustion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/provider-engine.js:169-181, 207-222` **Vulnerability Type**: Server-side request forgery and unbounded remote download **Risk Level**: High ### Vulnerable Code ```js // Direct image URL const imageUrl = resolvePath(data, provider.response.imagePath); if (!imageUrl) { throw new Error(`No image URL at "${provider.response.imagePath}" in response`); } return await downloadImage(imageUrl, resultBase); ``` ```js async function downloadImage(url, resultBase) { const res = await fetch(url); if (!res.ok) throw new Error(`Image download failed: ${res.status}`); const buffer = Buffer.from(await res.arrayBuffer()); const ext = resolveExt(res.headers.get('content-type')); const outputPath = `${resultBase}${ext}`; fs.writeFileSync(outputPath, buffer); return outputPath; } ``` The asynchronous polling path also passes a provider-controlled URL into the same helper: ```js if (status === poll.completeValue) { const imageUrl = resolvePath(data, poll.imagePath); if (!imageUrl) throw new Error(`No image URL at "${poll.imagePath}" after completion`); return await downloadImage(imageUrl, resultBase); } ``` ### Technical Analysis The Skill trusts an image URL returned by a remote provider and fetches it from the Agent host. It does not validate the URL scheme, hostname, resolved IP address, port, redirect chain, response size, or actual media type. Node's `fetch()` follows HTTP redirects by default. Therefore, validating only the initial provider endpoint would not be sufficient: a provider-controlled image URL can redirect to an internal destination. The use of `arrayBuffer()` buffers the entire response in memory before writing it, with no maximum size. The download request also lacks an `AbortController` timeout. ### Attack Path 1. A malicious or compromised provider receives a generation request. 2. It returns an image URL such as a loopback address, private-network service, link-local ...[truncated 955 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Permit only `https:` image URLs. 2. Resolve hostnames before connection and reject loopback, private, link-local, multicast, reserved, and cloud metadata address ranges for both IPv4 and IPv6. 3. Disable automatic redirects or validate the destination after every redirect. 4. Maintain provider-specific download-host allowlists where practical. 5. Add an `AbortController` timeout to every download and polling request. 6. Stream responses to disk rather than buffering the entire response. 7. Enforce a strict maximum response size using `Content-Length` and a streaming byte counter. 8. Accept only expected image or video MIME types and verify the file signature rather than relying solely on `Content-Type`. 9. Delete partial files after timeout, validation failure, or size-limit violation. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/approve.js:198
Finding
Local Generation Executors Inherit All Marketplace and Provider Credentials<![CDATA[ ## Vulnerability Details **File Location**: `scripts/approve.js:198-209` **Additional Locations**: `scripts/lib/env.js:15-22`, `scripts/listen.js:248-255` **Vulnerability Type**: Excessive credential exposure to child processes **Risk Level**: High ### Vulnerable Code The environment loader imports every entry in the marketplace credential file: ```js function loadEnv() { if (!fs.existsSync(ENV_PATH)) return; fs.readFileSync(ENV_PATH, 'utf-8').split('\n').forEach(line => { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith('#')) return; const idx = trimmed.indexOf('='); if (idx === -1) return; const key = trimmed.slice(0, idx).trim(); const val = trimmed.slice(idx + 1).trim().replace(/^["']|["']$/g, ''); if (key && !(key in process.env)) process.env[key] = val; }); } ``` The configured local executor is then started without a restricted environment: ```js if (typeof capability === 'string') { const executorPath = capability.replace(/^~/, os.homedir()); if (!fs.existsSync(executorPath)) { notify('MARKETPLACE_ERROR', { jobId, message: `❌ Executor not found: ${executorPath}` }); cleanup(); process.exit(1); } const defaultExt = jobType === 'video' ? '.mp4' : '.png'; const resultPath = resultBase + defaultExt; const { spawnSync } = require('child_process'); const result = spawnSync(executorPath, [resultPath, specPath], { encoding: 'utf-8', timeout: 15 * 60 * 1000 }); ``` The listener also passes its complete environment to `approve.js`: ```js const child = spawn('node', [ path.join(SKILL_DIR, 'scripts/approve.js'), jobId, '--from-daemon', ...((isParallel || isPreset) ? ['--quiet'] : []) ], { env: { ...process.env }, stdio: ['ignore', 'pipe', 'pipe'] }); ``` ### Technical Analysis Child processes inherit the parent environment by default when the `env` option is omitted. Consequently, every configured local generator receives all credentials loaded from ...[truncated 1431 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pass a minimal explicit `env` object to every child process. 2. Include only essential non-secret variables such as a controlled `PATH`, `HOME`, `LANG`, and temporary-directory location. 3. If an executor genuinely needs a provider credential, pass only that single credential after explicit user authorization. 4. Do not propagate `MARKETPLACE_API_KEY` to media-generation executors. 5. Run local executors in a sandbox with restricted filesystem and network access. 6. Validate that executor paths are absolute, user-owned, not group/world-writable, and not symbolic links to untrusted locations. 7. Document the executor trust boundary and warn users that local scripts execute with their account permissions. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/approve.js:32
Finding
Predictable Shared Temporary Files Permit Bid Workflow Manipulation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/approve.js:32-42, 109-113, 336-345, 417-430, 445-493` **Additional Location**: `SKILL.md:323-337` **Vulnerability Type**: Insecure temporary files, path injection, and fail-open confirmation **Risk Level**: High ### Vulnerable Code The externally supplied job ID is embedded directly into predictable paths: ```js const jobId = process.argv[2]; const quiet = process.argv.includes('--quiet'); const fromDaemon = process.argv.includes('--from-daemon'); if (!jobId) { console.error('Usage: approve.js <jobId>'); process.exit(1); } if (!fromDaemon) { try { fs.writeFileSync(`/tmp/bid_intent_req_${jobId}`, jobId); } catch (_) {} } ``` ```js const specPath = `/tmp/job_spec_${jobId}.json`; const resultBase = `/tmp/result_${jobId}`; const protectionPath = `/tmp/protection_${jobId}.txt`; const pricePath = `/tmp/price_${jobId}.txt`; ``` Protection and price values are consumed from shared files: ```js while (Date.now() < protectionDeadline) { if (fs.existsSync(protectionPath)) break; await new Promise(r => setTimeout(r, 2000)); } if (fs.existsSync(protectionPath)) { protection = fs.readFileSync(protectionPath, 'utf-8').trim(); fs.unlinkSync(protectionPath); } ``` ```js while (Date.now() < priceDeadline) { if (fs.existsSync(pricePath)) break; await new Promise(r => setTimeout(r, 2000)); } if (fs.existsSync(pricePath)) { const raw = parseInt(fs.readFileSync(pricePath, 'utf-8').trim(), 10); if (Number.isInteger(raw) && raw >= MIN_BID && raw <= budget) { bidPrice = raw; } fs.unlinkSync(pricePath); } ``` Final confirmation also uses a predictable file and fails open on timeout: ```js const confirmPath = `/tmp/confirm_${jobId}.txt`; // ... const confirmDeadline = Date.now() + 5 * 60 * 1000; while (Date.now() < confirmDeadline) { if (fs.existsSync(confirmPath)) break; await new Promise(r => setTimeout(r, 2000)); } let confirmed = true; // default: submit if timeout ...[truncated 2571 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace shared-file signaling with authenticated IPC, such as a user-owned Unix-domain socket. 2. If files remain necessary, use a per-process directory created with `fs.mkdtemp()` under a mode-`0700` runtime directory. 3. Generate a cryptographically random nonce for every job workflow and require callbacks to carry that nonce. 4. Open files atomically with exclusive creation and no symbolic-link following where supported. 5. Verify ownership, mode, file type, and link count before reading any signal. 6. Validate job IDs against a strict format such as an expected hexadecimal or UUID expression; reject path separators and traversal sequences. 7. Validate protection values against `low`, `medium`, and `high` after reading. 8. Default confirmation timeout to cancellation, not submission. 9. Bind confirmation to the expected Telegram chat, user, message, job ID, and one-time nonce. 10. Remove stale workflow artifacts securely on startup and completion. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:236
Finding
API Credentials Are Stored in Plaintext Without Enforced Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:236-242` **Additional Locations**: `references/config.md:100-113`, `references/onboarding.md:112-117` **Vulnerability Type**: Insecure plaintext credential storage **Risk Level**: Medium ### Vulnerable Code The setup instructions write the marketplace key directly to a plaintext file: ```bash rm -f ~/.openclaw/marketplace-config.json ~/.openclaw/marketplace.env rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json ``` ```bash echo "MARKETPLACE_API_KEY=<pasted_key>" > ~/.openclaw/marketplace.env ``` The same file is documented as holding several reusable credentials: ```bash MARKETPLACE_API_KEY=mrg_... # One of the following depending on chosen image API: OPENAI_API_KEY=sk-proj-... # for GPT Image 1.5 XAI_API_KEY=xai-... # for Grok Imagine FAL_KEY=... # for fal.ai models HF_API_KEY=hf_... # for HuggingFace Inference ``` ### Technical Analysis The setup procedure stores long-lived marketplace and cloud-provider credentials in `~/.openclaw/marketplace.env`. It does not first create the containing directory with mode `0700`, create the credential file with mode `0600`, or validate the file's owner and permissions when loading it. The actual permissions therefore depend on the user's current umask and pre-existing filesystem state. On a multi-user machine or permissively configured environment, the file may be readable by other users or processes. Rewriting with shell redirection also does not provide atomic replacement or symbolic-link protection. Plaintext storage may be necessary when no secret manager is available, but restrictive access controls are the minimum privilege required for such storage. ### Attack Path 1. The user follows the documented onboarding procedure under a permissive umask or with an unsafe pre-existing path. 2. The shell creates `marketplace.env` with permissions that permit access beyond the inte ...[truncated 664 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer the operating system's credential store or an OpenClaw-supported secret manager. 2. If a file is required, create `~/.openclaw` with mode `0700`. 3. Create a temporary credential file with mode `0600`, write and synchronize it, then atomically rename it into place. 4. Reject symbolic links and verify that the file is a regular file owned by the current user. 5. Validate permissions during every load and refuse to use a group- or world-readable secret file. 6. Avoid placing pasted secrets in shell command history or process arguments. 7. Separate marketplace and provider credentials where possible so components can receive only the secret they require. 8. Document credential rotation and immediate revocation procedures for suspected exposure. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (67)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Or manually:
```bash
rm ~/.openclaw/marketplace-config.json
rm -f ~/.openclaw/marketplace.env
rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json
```
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Or manually:
```bash
rm ~/.openclaw/marketplace-config.json
rm -f ~/.openclaw/marketplace.env
rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json
```
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Or manually:
```bash
rm ~/.openclaw/marketplace-config.json
rm -f ~/.openclaw/marketplace.env
rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json
```
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
rm ~/.openclaw/marketplace-config.json
rm -f ~/.openclaw/marketplace.env
rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json
```

---
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
rm ~/.openclaw/marketplace-config.json
rm -f ~/.openclaw/marketplace.env
rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json
```

---
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
rm ~/.openclaw/marketplace-config.json
rm -f ~/.openclaw/marketplace.env
rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json
```

---
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
rm ~/.openclaw/marketplace-config.json
rm -f ~/.openclaw/marketplace.env
rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json
```

---
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
     rm -f ~/.openclaw/marketplace.env
     rm -f /tmp/marketplace_pending.json
     rm -f /tmp/marketplace_completed.json
     ```
     Then send intro message and wait for API key (see "First Install" case below)
   - **Present, no agentId** → Run `node scripts/register.js`
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Ae1

High
Category
analysis-evasion
Content
`node scripts/approve.js <jobId> [--quiet] [--from-daemon]`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
`node scripts/approve.js <jobId> [--quiet] [--from-daemon]`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
`node scripts/approve.js <jobId> [--quiet] [--from-daemon]`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
1. Reset existing files:
   ```bash
   rm -f ~/.openclaw/marketplace-config.json ~/.openclaw/marketplace.env
   rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json
   ```
2. Save key to env file:
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Ae1

High
Category
analysis-evasion
Content
| `scripts/bid.js` | Image/video upload + bid API call |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| `scripts/provider-engine.js` | API calls based on providers.json |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| `scripts/lib/format.js` | Formatting helpers (credits, no-show rate) |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Known Vulnerable Dependency: socket.io-parser==4.2.5 — 2 advisory(ies): CVE-2026-69185 (Socket.IO: Zero-attachment Memory Exhaustion); CVE-2026-33151 (socket.io allows an unbounded number of binary attachments)

High
Category
Supply Chain
Confidence
96% confidence
Finding
The lockfile pins socket.io-parser to 4.2.5, and the cited advisories describe denial-of-service conditions caused by unbounded or zero-attachment handling. In this skill, socket.io-client is used for marketplace connectivity, so a malicious or compromised server, relay, or man-in-the-middle endpoint could send crafted packets that trigger excessive memory consumption in the client process.

Known Vulnerable Dependency: ws==8.18.3 — 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
93% confidence
Finding
The lockfile includes ws 8.18.3, which is flagged for memory exhaustion and possible memory disclosure issues. Because this skill maintains websocket connectivity to a remote marketplace service, malformed fragmented frames from an attacker-controlled or compromised websocket peer could crash the agent or potentially expose process memory, making the networked context materially relevant.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Reset / Re-onboard

```bash
rm ~/.openclaw/marketplace-config.json
rm -f /tmp/marketplace_pending.json
rm -f /tmp/marketplace_completed.json
rm -f /tmp/protection_*.txt /tmp/price_*.txt
Confidence
93% confidence
Finding
The command deletes the local marketplace configuration file, which can erase onboarding state and force reconfiguration. In an agent ecosystem, documented shell commands can be copied or invoked with limited user scrutiny, so destructive file operations are risky when not strongly gated and explained.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
rm ~/.openclaw/marketplace-config.json
rm -f /tmp/marketplace_pending.json
rm -f /tmp/marketplace_completed.json
rm -f /tmp/protection_*.txt /tmp/price_*.txt
# Restart the gateway — onboarding will start automatically
Confidence
90% confidence
Finding
This command deletes a temporary pending-job state file. Although the target is limited to a specific file, accidental execution can still disrupt job processing or lose local task state.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
rm ~/.openclaw/marketplace-config.json
rm -f /tmp/marketplace_pending.json
rm -f /tmp/marketplace_completed.json
rm -f /tmp/protection_*.txt /tmp/price_*.txt
# Restart the gateway — onboarding will start automatically
```
Confidence
90% confidence
Finding
This removes the local completed-job tracking file, which may erase bookkeeping needed for idempotency or history. While the scope is narrow, direct deletion commands in docs can still cause avoidable operational issues if copied blindly.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
rm ~/.openclaw/marketplace-config.json
rm -f /tmp/marketplace_pending.json
rm -f /tmp/marketplace_completed.json
rm -f /tmp/protection_*.txt /tmp/price_*.txt
# Restart the gateway — onboarding will start automatically
```
Confidence
92% confidence
Finding
This wildcard deletion removes multiple temporary control files under /tmp, which can alter approval, protection, or pricing flow and may affect in-flight operations. Wildcard-based shell deletion is more error-prone and, in an agent setting, can be propagated into unsafe automated behavior if treated as a normal recovery action.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
This does NOT delete `~/.openclaw/marketplace.env`. The API key is preserved.

For a full reset including the API key: also run `rm ~/.openclaw/marketplace.env`.

---
Confidence
97% confidence
Finding
This command deletes the environment file containing the marketplace API key, creating both credential loss and possible service disruption. In this skill, the API key is central to operation, so documentation that includes direct credential-file deletion without prominent safeguards is more dangerous than in a generic context.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- **yes** → start listener normally (catch-up runs automatically on connect)
   - **no** → clear pending/completed files before starting:
     ```bash
     rm -f /tmp/marketplace_pending.json /tmp/marketplace_completed.json
     ```
4. `node scripts/listen.js` — Start WebSocket listener. **This is a long-running daemon. Run it in the background (do NOT await/block on it).** It sends messages to Telegram on its own via messaging.js. After starting it, immediately return control to the user — do NOT wait for it to finish.
5. listen.js automatically prints the **welcome message** on first start. No need to send the command list manually.
Confidence
95% confidence
Finding
The skill includes a direct shell deletion command against local files, which is a tool-parameter abuse pattern because it performs destructive filesystem action from workflow logic. Even though the paths are fixed and not obviously user-injected, the command is still dangerous because it bypasses safer application-level state reset handling and can silently destroy local operational data.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README instructs users to paste a marketplace API key during onboarding but does not warn that this is a sensitive credential or advise against sharing it in insecure contexts. In an agent/chat-driven workflow, users may paste secrets into logs, chat history, screenshots, or sessions visible to plugins and operators, increasing credential exposure risk.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README provides manual deletion commands to reset the skill but does not clearly warn that these commands remove local configuration, environment data, and pending/completed marketplace state. This can cause accidental data loss and disrupt operation, especially for non-technical users copying commands verbatim.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/approve.js:206

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/bid.js:80

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/config-handler.js:28

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/lib/messaging.js:20

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/listen.js:248

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/provider-engine.js:110