Back to skill

Security audit

Molt Market Worker

Security checks for vulnerabilities and agentic risk

Overview

This skill is purpose-aligned for a marketplace worker, but it can place bids and submit work while handling credentials with weak safeguards.

Review this carefully before installing. Use it only if you are comfortable letting an agent interact with a marketplace account, place bids, and submit work. Keep autoBid disabled unless you have external guardrails, do not commit .env or worker-config.json, rotate any exposed key, and avoid changing apiBase away from the official service unless you fully trust the endpoint.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup-webhook.js:7
Finding

Credentials and Sensitive Data Can Be Redirected to an Arbitrary API Origin

Content
View full analysis

Vulnerability Details

File Location: worker-config.json:3; scripts/register.js:6, 24-28; scripts/setup-webhook.js:7-8, 27-35; scripts/check-jobs.js:6-7, 43-45, 63-67; scripts/bid.js:6-7, 18-22; scripts/deliver.js:6-7, 32-36; scripts/status.js:6-7, 12-14, 32-34, 41-43
Vulnerability Type: User-controlled API origin used for sensitive authenticated requests
Risk Level: High

Vulnerable Code

worker-config.json:3:

json
"apiBase": "https://moltmarket.store",

scripts/register.js:6, 24-28:

js
const API = process.env.MOLT_API_BASE || 'https://moltmarket.store';

const res = await fetch(`${API}/auth/register`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name, email, password, skills, description: description || undefined }),
});

scripts/setup-webhook.js:7-8, 27-35:

js
const API = config.apiBase || 'https://moltmarket.store';
const KEY = config.apiKey || process.env.MOLT_API_KEY;

const res = await fetch(`${API}/webhooks`, {
  method: 'POST',
  headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url,
    events,
    skill_filter: config.skills || [],
    category_filter: config.categories || [],
  }),
});

The other authenticated scripts use the same configurable apiBase value when transmitting the bearer token.

Technical Analysis

Registration legitimately requires transmitting the supplied name, email, password, skills, and description to the marketplace. Webhook registration and other account operations also legitimately require API authentication. However, the destination is taken from the MOLT_API_BASE environment variable or the editable worker-config.json file without enforcing HTTPS, validating the hostname, or obtaining confirmation before sending credentials to a non-default origin.

This destination flexibil ...[truncated 1747 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin credential-bearing requests to https://moltmarket.store.
  • If custom API endpoints are an actual requirement, enforce HTTPS and validate the normalized hostname against an administrator-controlled allowlist.
  • Require explicit interactive confirmation before sending credentials to any non-default origin.
  • Reject URLs containing embedded credentials, unexpected ports, unsupported protocols, or ambiguous hostname encodings.
  • Configure redirects manually and never forward Authorization headers or registration credentials across origins.
  • Separate unauthenticated public-job requests from authenticated account requests so credentials are attached only where required.
  • Document the custom-endpoint capability and its security implications.
  • Add tests confirming that HTTP destinations, unapproved hosts, and cross-origin redirects are rejected.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/register.js:39
Finding

API Key Is Printed and Persisted in Multiple Plaintext Locations

Content
View full analysis

Vulnerability Details

File Location: scripts/register.js:39-50
Vulnerability Type: Plaintext credential exposure and insecure secret storage
Risk Level: Medium

Vulnerable Code

js
console.log(`\n✅ Registered! Agent: ${data.agent.name}`);
console.log(`   API Key: ${data.agent.api_key}`);
console.log(`   ID: ${data.agent.id}`);

// Save to config
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
config.apiKey = data.agent.api_key;
config.skills = skills;
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
console.log(`\n📝 Saved API key to worker-config.json`);

// Also save to .env
const envPath = path.join(__dirname, '..', '.env');
fs.appendFileSync(envPath, `\nMOLT_API_KEY=${data.agent.api_key}\n`);
console.log(`📝 Saved to .env`);

Technical Analysis

The registration response's API key is exposed through three channels:

  1. It is printed in full to standard output.
  2. It is written into the ordinary worker-config.json project file.
  3. It is appended to .env without requesting restrictive file permissions.

Storing the same secret in multiple locations unnecessarily expands its exposure surface. Terminal output may be retained in shell transcripts, CI logs, agent logs, or remote session recordings. Project configuration is also commonly copied, archived, shared, or committed to version control.

Repeated registration appends additional MOLT_API_KEY entries to .env, potentially retaining historical keys. The project structure provided for review contains no ignore file or other control demonstrating that these credential-bearing files are excluded from source control.

Attack Path

  1. The user runs node scripts/register.js.
  2. The returned API key is displayed in terminal output and saved in two plaintext files.
  3. A local user, logging system, backup process, source-control operation, or accidentally shared project archive obtains ...[truncated 820 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not print the complete API key. Display only a short masked fingerprint if confirmation is needed.
  • Store the key in one location rather than duplicating it in both JSON and .env.
  • Prefer an operating-system credential store or a dedicated secret-management facility.
  • If file storage is unavoidable, create the secret file with mode 0600 and verify ownership before writing.
  • Keep API keys out of worker-config.json; reserve that file for non-secret settings.
  • Replace an existing .env assignment instead of appending duplicate or historical credentials.
  • Add .env and any credential-bearing configuration to version-control and packaging ignore rules.
  • Provide key revocation and rotation instructions.
  • Warn users if the target secret file is group-readable, world-readable, tracked by source control, or a symbolic link.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/check-jobs.js:42
Finding

Configured Active-Bid Limit Is Not Enforced

Content
View full analysis

Vulnerability Details

File Location: scripts/check-jobs.js:42-54
Vulnerability Type: Broken economic safety control and fail-open authorization logic
Risk Level: Medium

Vulnerable Code

js
// Auto-bid if enabled
if (config.autoBid && scored.length > 0) {
  // Check how many active bids we have
  const profileRes = await fetch(`${API}/agents/me/profile`, {
    headers: { Authorization: `Bearer ${KEY}` },
  });
  const profile = await profileRes.json();

  // Get our existing bids by checking each job
  let activeBids = 0;
  // Simple: just bid on top match if under limit
  if (activeBids < (config.maxActiveBids || 5)) {
    const topJob = scored[0];

Technical Analysis

The code states that it will check the number of active bids, but it never performs that calculation. Although an authenticated profile request is made, the resulting profile object is unused. The activeBids variable is unconditionally initialized to zero immediately before the limit comparison.

Consequently, any positive maxActiveBids value causes the check to pass on every process invocation. In heartbeat or scheduled use, each invocation can submit another bid even after the configured limit has been reached. This defeats an explicit user-defined control intended to constrain autonomous marketplace commitments.

The logic also uses config.maxActiveBids || 5, meaning a deliberately configured value of zero is replaced with five. Although autoBid must separately be enabled, zero cannot function as a defensive limit once automatic bidding is active.

Attack Path

  1. The user enables autoBid and configures maxActiveBids to constrain autonomous activity.
  2. The script is invoked repeatedly through heartbeat processing or manual execution.
  3. Each run initializes activeBids to zero instead of retrieving pending bids.
  4. The comparison passes regardless of the account's actual number ...[truncated 896 chars]
Remediation
View remediation

Remediation Suggestions

  • Query a dedicated endpoint for the agent's pending or active bids before submitting a new bid.
  • Count only statuses that represent current commitments and compare that count to the configured limit.
  • Fail closed when the active-bid query fails, returns malformed data, or cannot be authenticated.
  • Use nullish handling rather than logical OR so a configured value of zero remains valid, for example: config.maxActiveBids ?? 5.
  • Validate that the limit is a non-negative integer.
  • Add idempotency protection to prevent repeated bidding on the same job.
  • Where supported, enforce the limit atomically on the server to avoid races between concurrent worker executions.
  • Add tests covering zero limits, exact-limit behavior, malformed API responses, concurrent invocations, and accounts already above the limit.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

While framed as a description mismatch, this instance points to undisclosed credential handling and automated economic actions: account registration, API-key storage, auto-bidding, and potential delivery on the user's behalf. When a skill can transact, communicate externally, and store credentials without prominent disclosure of those side effects, users may install it without understanding the operational and financial risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

While framed as a description mismatch, this instance points to undisclosed credential handling and automated economic actions: account registration, API-key storage, auto-bidding, and potential delivery on the user's behalf. When a skill can transact, communicate externally, and store credentials without prominent disclosure of those side effects, users may install it without understanding the operational and financial risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

While framed as a description mismatch, this instance points to undisclosed credential handling and automated economic actions: account registration, API-key storage, auto-bidding, and potential delivery on the user's behalf. When a skill can transact, communicate externally, and store credentials without prominent disclosure of those side effects, users may install it without understanding the operational and financial risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

While framed as a description mismatch, this instance points to undisclosed credential handling and automated economic actions: account registration, API-key storage, auto-bidding, and potential delivery on the user's behalf. When a skill can transact, communicate externally, and store credentials without prominent disclosure of those side effects, users may install it without understanding the operational and financial risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

While framed as a description mismatch, this instance points to undisclosed credential handling and automated economic actions: account registration, API-key storage, auto-bidding, and potential delivery on the user's behalf. When a skill can transact, communicate externally, and store credentials without prominent disclosure of those side effects, users may install it without understanding the operational and financial risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

While framed as a description mismatch, this instance points to undisclosed credential handling and automated economic actions: account registration, API-key storage, auto-bidding, and potential delivery on the user's behalf. When a skill can transact, communicate externally, and store credentials without prominent disclosure of those side effects, users may install it without understanding the operational and financial risk.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/register.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/register.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `scripts/check-jobs.js` | Manually check for matching jobs |

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

Appending the API key to a project .env file creates a plaintext credential artifact in a common location that is frequently copied, backed up, or accidentally committed to source control. If leaked, the key could enable account takeover of the agent worker context, unauthorized job operations, or abuse of any associated balance or API privileges.

Content

Scanner excerpt · scripts/register.js (reported line 49)May include surrounding context.

js
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
  console.log(`\n📝 Saved API key to worker-config.json`);

  // Also save to .env
  const envPath = path.join(__dirname, '..', '.env');
  fs.appendFileSync(envPath, `\nMOLT_API_KEY=${data.agent.api_key}\n`);
  console.log(`📝 Saved to .env`);

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/register.js (reported line 50)May include surrounding context.

js
console.log(`\n📝 Saved API key to worker-config.json`);

  // Also save to .env
  const envPath = path.join(__dirname, '..', '.env');
  fs.appendFileSync(envPath, `\nMOLT_API_KEY=${data.agent.api_key}\n`);
  console.log(`📝 Saved to .env`);

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documents network access, webhook registration, API-key usage, and environment-file storage, but it declares no explicit tool scope or permissions. In an agent ecosystem, missing capability boundaries makes it easier for a skill to obtain broader-than-expected access to network and secrets, increasing the chance of unauthorized external communication or credential misuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill describes autonomous bidding and delivery but does not prominently warn that it may take external actions on the user's behalf. In a marketplace context, silent automation can commit the user to obligations, send messages, and submit work without meaningful review, creating financial, reputational, and data-leak risks if the agent behaves incorrectly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script can automatically place bids via a POST request when config.autoBid is enabled, which is a state-changing action performed without an interactive confirmation step or a strong in-file warning. In the context of a freelancer marketplace worker, this can commit the user/account to engagements based solely on remote job data and local config, increasing the risk of unwanted financial, reputational, or operational consequences if misconfigured or abused.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script loads an API key from worker-config.json or the MOLT_API_KEY environment variable and exits if it is missing, but there is no comment, help text, or other disclosure explaining that sensitive credentials will be accessed. For code files, access to credentials should have at least some visible warning or explanatory documentation unless already clearly disclosed elsewhere in the skill description.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This script sends arbitrary delivery content to a remote API endpoint without an explicit, immediate warning at the point of transmission. In the context of an auto-freelancing skill that may process local files or stdin, this increases the risk that users unknowingly upload sensitive data, proprietary content, or secrets to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code sends the user's name, email, password, skills, and description to a remote HTTP endpoint. Although the script prints 'Registering...', it does not clearly disclose that sensitive registration data will be transmitted to an external service before submission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script persists the returned API key into worker-config.json and appends it to .env without checking file permissions, warning the user, or using a secure secret store. On multi-user systems, shared repos, backups, or accidental commits, this can expose the credential and allow unauthorized use of the worker account or API actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code makes an authenticated network request to a remote service using the user's API key, but provides no prior user-facing notice that account data will be sent to an external endpoint. The file contains error output, but no disclosure comment, prompt, or informational message describing the remote data access behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The setup flow says registration saves an API key to .env but does not clearly warn about the sensitivity of that credential or safe handling practices. Users may accidentally commit the key to source control, expose it to other skills, or store it with overly broad local access, leading to account takeover or unauthorized marketplace actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The code reads MOLT_API_KEY from the environment, which is a sensitive credential source. Although using an API key is necessary here, the file does not include any user-facing explanation or warning about credential access or handling.

Content

No source excerpt is available for this finding.

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
scripts/bid.js:8

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/check-jobs.js:8

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/deliver.js:8

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/register.js:6

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/setup-webhook.js:9

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/status.js:8

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/register.js:44