Back to skill

Security audit

Agent Marketplace

Security checks for vulnerabilities and agentic risk

Overview

The marketplace skill is coherent, but its installer can save unverified remote or registry-provided code locally, which needs user review before use.

Review this before installing or using it with real registries. Use only trusted HTTPS registries, do not install unsigned or unverified skills through this code, and avoid storing sensitive user identifiers or activity unless the cache directory permissions and retention policy are acceptable.

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

T08 · Insecure Dependencies

Warning
Location
src/installer.js:174
Finding

<![CDATA[Untrusted Package Retrieval Without Origin, Integrity, or Size Validation]]>

Content
View full analysis
{ const url = skill.downloadUrl; const client = url.startsWith('https:') ? https : http; const req = client.get(url, { timeout: 60000 }, (res) => { if (res.statusCode !== 200) { reject(new Error(`Download failed with status ${res.statusCode}`)); return; } const chunks = []; res.on('data', chunk => chunks.push(chunk)); res.on('end', () => { const data = Buffer.concat(chunks); fs.writeFileSync(targetDir, data); resolve(targetDir); }); }); ``` ### Technical Analysis The installer treats the registry-provided `skill.downloadUrl` as trusted. It selects either the HTTPS or HTTP client based solely on the URL prefix and then requests the destination without validating: - The URL protocol - The destination hostname or resolved IP address - Whether the destination belongs to an approved package host - Whether the destination resolves to loopback, link-local, private-network, or cloud metadata infrastructure - The package's cryptographic digest or publisher signature - The response content type or package format - The maximum response size The response is accumulated completely in memory through `Buffer.concat(chunks)` and written to disk without authenticity verification. Consequently, a malicious or compromised registry can direct the process to internal services or provide a modified package. The lack of a response-size limit also permits memory exhaustion if the remote endpoint sends a very large response. The current repository's `installer.js` is incomplete and is not exported by `src/index.js`. This reduces immediate reachability through ...[truncated 1689 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
src/installer.js:216
Finding

<![CDATA[Registry-Provided JavaScript Is Persisted Without Authenticity Verification]]>

Content
View full analysis
/index.js` without signature or digest verification. 5. A marketplace host, agent runtime, or another downstream component loads the installed skill. 6. The JavaScript executes with the privileges of that downstream Node.js process. ### Impact Assessment The immediate operation grants the attacker control over executable file ...[truncated 687 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
src/registry.js:70
Finding

<![CDATA[Registry Communication Can Be Downgraded to Plaintext HTTP]]>

Content
View full analysis
{ const client = url.startsWith('https:') ? https : http; const req = client.get(url, { timeout: 30000 }, (res) => { let data = ''; ``` ### Technical Analysis The registry manager accepts an arbitrary configured registry URL. If the resulting URL does not begin with `https:`, the code silently uses the plaintext HTTP client. Registry responses influence skill metadata, search results, dependency versions, package URLs, and inline source content. Plaintext HTTP provides neither transport confidentiality nor server authentication, allowing an on-path attacker to inspect and modify responses. The code also constructs the request URL through string concatenation rather than validating the base URL with `URL`. No signed metadata layer compensates for the lack of transport authentication. ### Attack Path 1. A user or deployment configures the marketplace with an `http://` registry URL. 2. The application requests skill or dependency metadata over plaintext HTTP. 3. An attacker with a suitable network position intercepts or modifies the response. 4. The attacker changes skill metadata, dependency versions, `downloadUrl`, or inline `code`. 5. The modified response is parsed and may be cached by the registry manager. 6. Marketplace operations subsequently consume the attacker-controlled metadata, potentially leading to malicious package installation. ### Impact Assessment A network attacker can compromise the integrity and confidentiality of registry traffic when HTTP is configured. The attacker may manipulate: - Search and catalog results - Skil ...[truncated 342 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (11)

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · src/rating.js (reported line 165)May include surrounding context.

js
return result;
  }

  // Update skill statistics
  _updateSkillStats(skillName) {
    const skillData = this.ratings[skillName];
    if (!skillData) return;

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Most of the descriptive content and API explanations are written in Chinese, which effectively forces a specific language for users reading the skill documentation. SQP-3 applies because the file does not offer an explicit language choice or justify the locale constraint as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file describes installation management including one-click install, dependency resolution, conflict handling, rollback, and elsewhere documents uninstall/delete capabilities, but it does not warn that these actions can modify the local environment or installed skills. For markdown files, SQP-2 applies when the description omits warnings about behavior that could affect user data or system integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code performs a network download from a skill-provided URL and writes the downloaded data directly to disk, but there is no visible confirmation prompt, log/print statement, or comment/docstring warning users about this behavior. Because the operation transmits data over the network and modifies local files, it meets the code-file criteria for a missing user warning.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/installer.js (reported line 265)May include surrounding context.

js
const dependencies = await this.resolveDependencies(skillName, targetVersion);
    
    // Remove the main skill from dependencies (we'll install it separately)
    const depList = Array.from(dependencies.entries())
      .filter(([key]) => !key.startsWith(`${skillName}@`))
      .map(([, value]) => value);

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code writes ratings, reviews, and associated user identifiers to local JSON files, which is a data-affecting file-write operation for a code file. Although the module has brief internal comments, there is no user-facing warning, confirmation, or visible disclosure in this file that submitted data will be persisted on disk under ./.marketplace-cache.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The code writes registry state to disk and later deletes registry entries and cached files, but there is no confirmation prompt, user-visible message, or explanatory warning in the file for these potentially destructive operations. Users invoking unregister or cache-clearing behavior may not be alerted that local data will be permanently changed or removed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code performs network requests to a remote registry and writes the returned data into local cache files. Although these operations are part of registry functionality, the file provides no confirmation prompt, user-visible logging, or explanatory comment/docstring warning that remote access and local file writes will occur.

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 per-user interaction history and preference data to a local JSON file without any visible access controls, retention limits, consent flow, or minimization. Even if this is intended for personalization, storing searched, viewed, installed, and rated activity on disk creates a privacy and data-exposure risk if the host is multi-user, the cache directory is readable by other processes, or the files are later collected in backups/log bundles.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The usage example configures a remote registry URL and installs a skill from it, which implies network access and retrieval of external packages, but the markdown provides no warning about contacting a remote service or trusting third-party package content. Under SQP-2 for markdown, user-facing documentation should disclose behaviors that may affect privacy or system integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The installer writes package.json and optionally index.js into the target directory, but this file creation is not accompanied by any confirmation, logging, or explanatory warning in the code. For a code file, file writes that affect the user's workspace should have some form of disclosure unless clearly communicated elsewhere.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.