Back to skill

Security audit

Jupiter Prediction Market

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Jupiter Prediction Market client, but it includes live financial actions and local API-key storage without enough guardrails.

Review this before installing if you plan to let an agent trade or manage payouts. Prefer the JUPITER_API_KEY environment variable over the config file, avoid unattended auto-claim or close-position workflows, require human approval for any order, claim, or position-closing action, and run it only in a workspace where local API-key files cannot be read by other users.

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

T09 · Insecure Skill Coding Practices

Warning
Location
src/utils/api-key.js:46
Finding

API Key Stored Without Restrictive File Permissions

Content
View full analysis

Vulnerability Details

File Location: src/utils/api-key.js, lines 46-52
Vulnerability Type: Plaintext credential storage with insufficient file-permission hardening
Risk Level: Medium

Vulnerable Code

javascript
if (!fs.existsSync(CONFIG_DIR)) {
  fs.mkdirSync(CONFIG_DIR, { recursive: true });
}

const trimmedKey = apiKey.trim();
fs.writeFileSync(API_KEY_FILE, JSON.stringify({ jupiterApiKey: trimmedKey }, null, 2));
return trimmedKey;

Technical Analysis

ApiKeyManager.setApiKey() stores the Jupiter API key as plaintext in config/api-key.json. Neither the directory nor the file is created with an explicit restrictive mode. Their effective permissions therefore depend on the process umask. Under a common 0022 umask, the directory may be created as 0755 and the file as 0644, allowing other local users to read the credential.

The code also checks only whether the path exists before writing it. It does not reject symbolic links or use exclusive, no-follow file creation. If an attacker who can write to the working directory prepares config/api-key.json as a symbolic link, the subsequent write may follow that link. Exploitability of this symlink scenario depends on the attacker already having suitable filesystem access and on operating-system protections.

Attack Path

  1. A victim runs the application from a directory accessible to another local user and calls JupiterPredictionClient.setApiKey() or ApiKeyManager.setApiKey().
  2. The method creates config/api-key.json using ambient umask-derived permissions and writes the API key in plaintext.
  3. If the resulting file is group- or world-readable, another local user reads it directly.
  4. Alternatively, where the attacker can modify the working directory beforehand, the attacker creates a malicious symbolic link at config/api-key.json; the application follows it when writing.
  5. The attacker obtains the Jupiter API key and submits authenticated requests to the Jupi ...[truncated 768 chars]
Remediation
View remediation

Remediation Suggestions

  • Create the configuration directory with owner-only permissions:
javascript
fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
fs.chmodSync(CONFIG_DIR, 0o700);
  • Write the key file with mode 0600. Prefer exclusive creation and an atomic replacement strategy that does not follow attacker-controlled symbolic links.
  • Before updating an existing path, inspect it with fs.lstatSync() and reject symbolic links or non-regular files.
  • Open files using restrictive flags and permissions, such as O_WRONLY | O_CREAT | O_EXCL where appropriate. On supported systems, use O_NOFOLLOW.
  • If atomic updates are needed, securely create a temporary file in the protected directory with 0600, write and synchronize it, then rename it over a validated regular destination.
  • Apply fs.chmodSync(API_KEY_FILE, 0o600) to securely migrate existing installations.
  • Prefer the JUPITER_API_KEY environment variable or an operating-system credential store instead of persistent plaintext storage.
  • Document that the project must not be run from a shared or attacker-writable working directory.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (32)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The SKILL.md presents the package as a complete trading and portfolio-management client, including order creation, position management, payouts, and autonomous workflows, while the analyzed content only substantiates limited read-oriented market discovery behavior. This mismatch can mislead operators and downstream agents into granting elevated trust, permissions, or financial authority to a skill whose real capabilities are unverified or incomplete.

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 78)May include surrounding context.

md
node scripts/scan-markets.js --crypto --limit=10 --min-volume=10000

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/scan-markets.js --crypto --limit=10 --min-volume=10000

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/find-opportunities.js --threshold=20 --min-volume=50000

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
node scripts/monitor-portfolio.js <wallet-address>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/auto-claim.js <wallet-address> [--dry-run] [--min=1]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `src/client.js` - Main API client class

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `src/client.js` - Main API client class

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `src/client.js` - Main API client class

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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).

Content

Scanner excerpt · documentation/api-reference.md (reported line 42)May include surrounding context.

md
| `create(orderData)` | `POST /orders` | Create order |
| `listOrders(params)` | `GET /orders` | List orders |
| `status(orderPubkey)` | `GET /orders/status/:orderPubkey` | Order status |
| `cancelOrder(orderPubkey, ownerPubkey)` | `DELETE /orders/:orderPubkey` | Cancel |

### Positions

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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).

Content

Scanner excerpt · documentation/api-reference.md (reported line 50)May include surrounding context.

md
|--------|----------|-------------|
| `listPositions(params)` | `GET /positions` | List positions |
| `getPosition(positionPubkey)` | `GET /positions/:positionPubkey` | Get position |
| `closePosition(positionPubkey, ownerPubkey)` | `DELETE /positions/:positionPubkey` | Close |
| `claim(positionPubkey, ownerPubkey)` | `POST /positions/:positionPubkey/claim` | Claim |

### Social

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises code that uses environment variables and external network access, but it does not declare any explicit tool scope such as permissions or allowed-tools. In an agent setting, this weakens least-privilege controls and can let the runtime expose secrets or outbound connectivity more broadly than the skill consumer expects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill promotes autonomous trading, position management, and payout claiming but does not prominently warn that these actions can affect real funds and require careful human approval and risk limits. In financial-agent contexts, missing safety disclosures increases the chance that users or orchestrators enable unattended execution without understanding the monetary consequences.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file documents state-changing and potentially irreversible operations such as creating orders, canceling orders, and closing positions, but it does not include any cautionary note about financial impact or user data/system effects. Under the markdown-file criteria for SQP-2, descriptions should warn users when behavior can affect assets or system integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The example iterates through all claimable positions and calls client.claim(...) without any explicit warning, confirmation step, or clear labeling that this performs state-changing transactions. In an agent/trading-bot context, documentation examples are likely to be copied directly into automation, so this can cause unintended on-chain actions, wallet prompts, fees, or claims being executed without adequate human review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documented autoClaim workflow performs real, account-affecting claim operations in a loop with no explicit confirmation, safety prompt, or strong warning that it will execute live transactions unless dryRun is manually enabled. In the context of an autonomous trading/portfolio agent skill, this is more dangerous because users may copy the workflow directly into automation, causing unintended bulk claims, transaction fees, or operational mistakes on live wallets.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/client.js (reported line 4)May include surrounding context.

js
const fetch = require('cross-fetch');
const { ApiKeyManager, ApiKeyError } = require('./utils/api-key');

const BASE_URL = 'https://api.jup.ag/prediction/v1';

class JupiterPredictionError extends Error {
  constructor(message, status, code = 'API_ERROR') {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code sends orderData, params, orderPubkey, and ownerPubkey over network requests via post/get/delete, but the file contains no confirmation prompt, logging, comment, or docstring disclosing that user or system data is transmitted. Because these methods handle order creation and cancellation, a user-facing warning would help make the network activity and affected data explicit.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The close and closeAll methods perform deletion operations via HTTP delete, which appear to close positions and may be irreversible. In this file there is no confirmation prompt, user-facing log/message, or explanatory comment/docstring warning that these methods will close positions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The cancelOrder method sends a DELETE request to cancel an order, which is a potentially irreversible trading action. This file does not include any confirmation, user-visible log message, or explanatory comment/docstring indicating the action's impact.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The methods closePosition and closeAllPositions issue DELETE requests that can close one or all user positions, which is a safety-critical action. In this file there is no confirmation prompt, logging, comment, or docstring warning the caller that these operations are destructive.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes a Node.js client for interacting with Jupiter Prediction Market APIs and supporting trading workflows, but this utility adds local secret-management behavior by writing an API key to disk and deleting it later. Reading credentials from environment variables is a common implementation detail, but creating and removing a local config file is a separate capability that is not stated in the skill purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The API key is written in plaintext to config/api-key.json with no user-facing warning, consent flow, or visible indication that sensitive credentials will be persisted locally. In an agent or trading-bot context, this increases the chance that secrets are unintentionally left on disk, exposed through backups, source-control mistakes, shared workspaces, or permissive filesystem access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The removeApiKey method deletes config/api-key.json via fs.unlinkSync without any confirmation, log, or explanatory comment. This is a destructive file operation, and the file removal is not disclosed within the code shown.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The toJSON() method serializes and exposes the full error stack trace, which can leak internal file paths, library versions, code structure, and execution flow if returned to clients or logged in shared environments. In an API client used for trading and automated agents, these details can help an attacker fingerprint the environment or identify follow-on weaknesses.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.