Back to skill

Security audit

Polymarket 交易助手

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed Polymarket trading toolkit, but it can use wallet keys to place real trades automatically without strong executable safety gates.

Install only if you intentionally want an agent to manage Polymarket trading. Use a dedicated low-balance wallet, keep dry-run mode on until tested, do not paste private keys into chat, update or pin dependencies, and avoid the no-confirmation auto-trade mode unless you accept real financial loss risk.

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

T09 · Insecure Skill Coding Practices

Error
Location
poly-resolution-tracking/scripts/scrape_source.py:48
Finding
Unrestricted resolution-source fetching enables server-side request forgery<![CDATA[ ## Vulnerability Details **File Location**: `poly-resolution-tracking/scripts/scrape_source.py:48-54`; reachable through `poly-resolution-tracking/scripts/monitor.py:198-232` **Vulnerability Type**: Server-side request forgery through unvalidated URLs **Risk Level**: High ### Vulnerable Code ```python def fetch_html(url: str, max_retries: int = 3, backoff: float = 1.0) -> str: """Fetch URL content as string with retry.""" for attempt in range(max_retries): try: req = urllib.request.Request(url, headers=HEADERS) with urllib.request.urlopen(req, timeout=30) as resp: return resp.read().decode("utf-8", errors="replace") ``` The monitor automatically extracts URLs from market descriptions and passes them to the unrestricted fetch function: ```python # Generic URL extraction urls = re.findall(r'https?://[^\s<>"]+', description) if urls: return { "type": "generic_url", "url": urls[0], } ``` ```python url = source.get("url", "") if source_type == "arena_leaderboard": return scrape_source(url, "arena_leaderboard") elif source_type == "generic_url" and url: return scrape_source(url, "generic") ``` The same implementation pattern exists in the corresponding `poly-resolution-tracking-zh` scripts. ### Technical Analysis The fetch function passes an externally derived URL directly to `urllib.request.urlopen`. It does not: - Restrict requests to HTTPS. - Maintain an allowlist of approved resolution-source domains. - Resolve and reject loopback, private, link-local, multicast, reserved, or cloud-metadata addresses. - Revalidate the destination after redirects. - Limit the response body size. - Prevent DNS rebinding between validation and connection. The URL can be provided directly through `scrape_source.py --url`, and the monitoring workflow can also obtain it from an untrusted Polymarket market description. This creates a reachable SSRF primitive rather than merely an ...[truncated 1491 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Permit only `https` URLs and reject all other schemes. 2. Use an explicit allowlist of trusted resolution-source domains where feasible. 3. Before connecting, resolve every hostname and reject all loopback, private, link-local, multicast, unspecified, reserved, and metadata-address ranges for both IPv4 and IPv6. 4. Disable automatic redirects or validate the scheme, hostname, port, and resolved address at every redirect. 5. Protect against DNS rebinding by connecting to the validated address while preserving the intended TLS hostname. 6. Block nonstandard ports unless explicitly required. 7. Apply a strict maximum response size and content-type allowlist. 8. Require explicit user approval before fetching a source URL extracted from third-party market text. 9. Apply the same changes to the English and Chinese variants. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
api-trade-polymarket/scripts/trade.ts:55
Finding
Live trading safety limits are not enforced by the executable layer<![CDATA[ ## Vulnerability Details **File Location**: `api-trade-polymarket/scripts/trade.ts:55-69, 85-90, 118-128` **Vulnerability Type**: Missing validation and fail-open order parameter handling **Risk Level**: High ### Vulnerable Code ```typescript const { values } = parseArgs({ options: { "token-id": { type: "string" }, side: { type: "string", default: "BUY" }, "order-type": { type: "string", default: "GTC" }, price: { type: "string" }, size: { type: "string" }, amount: { type: "string" }, }, strict: false, }); const tokenID = values["token-id"] as string | undefined; const sideStr = ((values.side as string) ?? "BUY").toUpperCase(); const orderTypeStr = ((values["order-type"] as string) ?? "GTC").toUpperCase(); const price = values.price ? parseFloat(values.price as string) : undefined; const size = values.size ? parseFloat(values.size as string) : undefined; const amount = values.amount ? parseFloat(values.amount as string) : undefined; ``` ```typescript const side = sideStr === "SELL" ? Side.SELL : Side.BUY; ``` ```typescript if (orderTypeStr === "FOK") { const orderAmount = amount ?? (size && price ? size * price : 0); if (!orderAmount || orderAmount <= 0) { console.log(JSON.stringify({ error: "FOK requires --amount or --size + --price", status: "arg_error" })); process.exit(1); } const resp = await (client as any).createAndPostMarketOrder( { tokenID, amount: orderAmount, side }, undefined, OrderType.FOK, ); ``` ```typescript } else { // GTC order if (!price || !size) { console.log(JSON.stringify({ error: "GTC requires --price and --size", status: "arg_error" })); process.exit(1); } const resp = await client.createAndPostOrder( { tokenID, price, size, side }, undefined, OrderType.GTC, ); ``` The Skill instructions document a `$500` per-trade safety limit, but `trade.ts` contains no corresponding hard limit. The autonomous trading orchestrator also defaults ...[truncated 2262 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set argument parsing to strict mode and reject all unknown options. 2. Validate `side` against exactly `BUY` and `SELL`; never use a default for an invalid supplied value. 3. Validate `order-type` against exactly the supported values. 4. Require `Number.isFinite()` for amount, price, and size. 5. Enforce positive values and valid market-specific price bounds. 6. Enforce the `$500` cap, or a lower configured cap, directly in `trade.ts`. 7. For GTC orders, calculate and cap the total notional value using `price * size`. 8. Verify balance, allowance, order-book bounds, and available position immediately before submission. 9. Default all autonomous workflows to dry-run. 10. Require an explicit `--live` flag and a short-lived confirmation identifier containing the token, side, order type, price, size, and maximum notional. 11. Add unit and integration tests covering invalid sides, unknown order types, `NaN`, infinity, negative values, oversized amounts, and direct script invocation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
poly-position-monitor/scripts/fetch_orders.py:133
Finding
CLOB credentials can be exposed through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `poly-position-monitor/scripts/fetch_orders.py:133-145` **Vulnerability Type**: Sensitive credential exposure through process arguments and shell history **Risk Level**: Medium ### Vulnerable Code ```python parser = argparse.ArgumentParser(description="Fetch open orders from Polymarket CLOB API") parser.add_argument("--config", type=str, help="Path to config.json") parser.add_argument("--api-key", type=str, help="CLOB API key") parser.add_argument("--secret", type=str, help="CLOB API secret") parser.add_argument("--passphrase", type=str, help="CLOB API passphrase") parser.add_argument("--market", type=str, nargs="*", help="Filter by condition ID(s)") parser.add_argument("--output", type=str, default=None, help="Output file (default: stdout)") args = parser.parse_args() if args.config: cfg = load_config(args.config) auth = cfg.get("clob_auth", {}) api_key = auth.get("api_key", "") secret = auth.get("secret", "") passphrase = auth.get("passphrase", "") else: api_key = args.api_key or os.environ.get("POLY_API_KEY", "") secret = args.secret or os.environ.get("POLY_SECRET", "") passphrase = args.passphrase or os.environ.get("POLY_PASSPHRASE", "") ``` The documented standalone invocation also encourages this usage: ```text python fetch_orders.py --api-key <key> --secret <secret> --passphrase <pass> ``` The same implementation is present in `poly-position-monitor-zh/scripts/fetch_orders.py`. ### Technical Analysis Command-line arguments are generally not an appropriate channel for secrets. Depending on the operating system and execution environment, complete process arguments may be visible through: - Process inspection tools. - `/proc` process metadata. - Shell history files. - Terminal logging. - Job schedulers and process supervisors. - Monitoring, crash-reporting, and telemetry systems. - Agent execution logs. Although the credentials are subsequently sent to the legitim ...[truncated 1232 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--api-key`, `--secret`, and `--passphrase` command-line options. 2. Prefer an operating-system secret store or a dedicated credential helper. 3. If environment variables are retained, inject them only into the target process and prevent them from being logged. 4. Alternatively, read secrets from standard input without echoing. 5. If a configuration file is supported, require restrictive permissions and reject files readable by other users. 6. Add explicit documentation warning users not to place secrets in command lines, shell scripts, reports, or logs. 7. Rotate credentials that have previously been supplied through command-line arguments. 8. Apply the same remediation to the English and Chinese variants. ]]>

T08 · Insecure Dependencies

Warning
Location
poly-position-monitor/scripts/requirements.txt:4
Finding
Credential-handling Python dependency is not pinned to an audited version<![CDATA[ ## Vulnerability Details **File Location**: `poly-position-monitor/scripts/requirements.txt:4` **Vulnerability Type**: Open-ended dependency version constraint **Risk Level**: Medium ### Vulnerable Code ```text # Core monitoring uses only Python standard library (urllib, json, smtplib). # py-clob-client is optional — required only for open order monitoring. py-clob-client>=0.34 ``` The same constraint is present in the corresponding Chinese monitoring package. ### Technical Analysis The `>=0.34` constraint allows package managers to install any later compatible release, including a release that did not exist when the Skill was audited. No Python lockfile or cryptographic hashes are provided. This dependency is especially sensitive because `fetch_orders.py` supplies it with the CLOB API key, secret, and passphrase. Imported Python packages can execute code at import time and can access process memory, environment variables, files available to the process, and network resources. This finding does not establish that the current `py-clob-client` package is malicious. The vulnerability is the inability to reproduce and constrain the reviewed dependency set. ### Attack Path 1. A future package release is compromised, malicious, or introduces a security regression. 2. A user installs dependencies using the open-ended `py-clob-client>=0.34` constraint. 3. The package manager selects the affected newer release. 4. The monitoring script imports and initializes that package with CLOB credentials. 5. Malicious dependency code can read credentials and data under the Skill process's privileges and transmit them externally. ### Impact Assessment A compromised dependency would execute with the same privileges as the monitoring process. Its possible scope includes: - Access to CLOB credentials passed into the client. - Access to relevant environment variables and readable configuration files. - Reading or modifying monitoring state and output files. - Send ...[truncated 207 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `py-clob-client` to an exact version that has been reviewed and tested. 2. Generate a reproducible lockfile for all direct and transitive Python dependencies. 3. Require cryptographic hashes during installation, such as with a hash-locked requirements file. 4. Review release notes, source changes, ownership changes, and dependency changes before upgrading. 5. Use an isolated virtual environment with minimal filesystem and network privileges. 6. Avoid exposing wallet private keys or unrelated secrets to the monitoring process. 7. Add automated dependency vulnerability and provenance checks to the release process. 8. Apply identical version and hash controls to duplicate language variants. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (140)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Undocumented comment retrieval and a primary focus on fetching market commentary rather than the advertised end-to-end trading workflow indicate hidden or poorly disclosed network behavior. Because comments and external content are untrusted input, this raises the risk of downstream prompt-injection, misinformation, or unsafe automation if consumed as part of analysis or trading decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
Undocumented comment retrieval and a primary focus on fetching market commentary rather than the advertised end-to-end trading workflow indicate hidden or poorly disclosed network behavior. Because comments and external content are untrusted input, this raises the risk of downstream prompt-injection, misinformation, or unsafe automation if consumed as part of analysis or trading decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Undocumented comment retrieval and a primary focus on fetching market commentary rather than the advertised end-to-end trading workflow indicate hidden or poorly disclosed network behavior. Because comments and external content are untrusted input, this raises the risk of downstream prompt-injection, misinformation, or unsafe automation if consumed as part of analysis or trading decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Undocumented comment retrieval and a primary focus on fetching market commentary rather than the advertised end-to-end trading workflow indicate hidden or poorly disclosed network behavior. Because comments and external content are untrusted input, this raises the risk of downstream prompt-injection, misinformation, or unsafe automation if consumed as part of analysis or trading decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Undocumented comment retrieval and a primary focus on fetching market commentary rather than the advertised end-to-end trading workflow indicate hidden or poorly disclosed network behavior. Because comments and external content are untrusted input, this raises the risk of downstream prompt-injection, misinformation, or unsafe automation if consumed as part of analysis or trading decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Undocumented comment retrieval and a primary focus on fetching market commentary rather than the advertised end-to-end trading workflow indicate hidden or poorly disclosed network behavior. Because comments and external content are untrusted input, this raises the risk of downstream prompt-injection, misinformation, or unsafe automation if consumed as part of analysis or trading decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
Undocumented comment retrieval and a primary focus on fetching market commentary rather than the advertised end-to-end trading workflow indicate hidden or poorly disclosed network behavior. Because comments and external content are untrusted input, this raises the risk of downstream prompt-injection, misinformation, or unsafe automation if consumed as part of analysis or trading decisions.

Missing User Warnings

High
Confidence
97% confidence
Finding
The markdown explicitly advertises fully automated live trading, including a mode marked '无需确认'/'without confirmation', which is highly dangerous in a financial agent context. When combined with optional wallet private key support, this creates a realistic path to unauthorized or unintended fund movement, loss from model error, prompt-injection-influenced trades, or abuse through accidental invocation.

Known Vulnerable Dependency: axios==1.13.5 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
95% confidence
Finding
The lockfile pins axios 1.13.5, and the provided advisories include SSRF/proxy-bypass and prototype-pollution-related MITM/credential-theft issues. In a trading skill that communicates with external APIs and may handle credentials or signed requests, a vulnerable HTTP client materially increases risk because requests may be redirected, proxied unexpectedly, or influenced by attacker-controlled network inputs.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
86% confidence
Finding
form-data 4.0.5 is flagged for CRLF injection via unescaped multipart field names and filenames. If any part of this trading tool uploads files or constructs multipart requests from user-controlled inputs, an attacker could manipulate request structure or smuggle headers/content, which is especially dangerous when interacting with external services and authenticated APIs.

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
88% confidence
Finding
ws 8.18.3 is flagged for uninitialized memory disclosure and memory-exhaustion DoS. In a market/trading skill, websocket connectivity is commonly used for real-time order books and market data, so these issues could expose process memory or let an attacker degrade availability by sending malicious frames/fragments.

Known Vulnerable Dependency: ws==8.18.0 — 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
89% confidence
Finding
ws 8.18.0 has the same disclosed memory disclosure and memory exhaustion weaknesses as the other ws instance. Having multiple vulnerable websocket versions in the dependency tree broadens exposure because either runtime path may be reached depending on which library establishes the connection.

Credential Access

High
Category
Privilege Escalation
Content
### 致命错误(中断全流程)

- 环境初始化失败(scripts 不存在、.env 缺失)
- 余额 < $10 且无持仓
- Market Pulse skill 执行失败(pulse/full 模式)
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

High
Confidence
95% confidence
Finding
The skill explicitly supports live order execution using a private key and funder address, yet it lacks a clear upfront warning that live trades involve real funds, may be irreversible, and can be triggered by following the workflow. In a trading context, omission of such safeguards materially increases the risk of accidental real-money loss, especially because the skill also includes broad activation language and mixes paper-trading and live-trading modes in one flow.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill advertises capabilities that inherently involve sensitive operations (trading, wallet use, monitoring, and automation) yet declares no explicit tool scope or permission boundaries. In a skill ecosystem, this increases the chance that the agent can invoke shell, network, filesystem, and environment access more broadly than users expect, which is especially risky when private keys and trading actions are in scope.

Vague Triggers

Medium
Confidence
94% confidence
Finding
Broad natural-language triggers can cause the skill to activate on ordinary conversation about trading or prediction markets, not just when the user intentionally requests this tool. In a skill that references private keys, automation, and live trading, accidental activation materially increases the risk of unintended network calls, credential use, or financially consequential actions.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly supports non-interactive real-money trading, selling, and order cancellation, yet it does not require an explicit user-facing warning or confirmation about financial loss, irreversible order effects, or automated execution risk. In the context of an agent skill that can be called by an orchestrator or another skill, this materially increases the chance of unintended or unsafe trades being executed on a live account.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The metadata requires a `PRIVATE_KEY` and related wallet parameters for live trading but provides no adjacent warning about secret-handling, account takeover risk, or the consequences of exposing signing credentials. In a skill designed for automated financial execution, normalizing private-key use without strong credential safety guidance makes accidental leakage, misuse, or insecure storage substantially more dangerous.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This reference provides directly usable order placement and cancellation examples for a real-money trading API without prominent warnings that these operations will execute live market actions. In an agent skill context, users or downstream agents may treat the examples as safe defaults, increasing the risk of unintended trades, order cancellations, and financial loss.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
1. **Dedicated wallet** — Use a separate wallet for API trading, not your main holdings
2. **Limited funds** — Only keep trading capital in the wallet
3. **File permissions** — `chmod 600 .env.aizen`
4. **.gitignore** — Ensure `.env.aizen` is gitignored (it is by default)
5. **Regular rotation** — Periodically rotate keys for security
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding
The usage example relies on `npx tsx`, which can fetch and execute a package version not explicitly pinned by the repository. That creates a supply-chain risk: if the resolved package version is compromised, typosquatted, or unexpectedly changes, a user running the documented command could execute attacker-controlled code. In a trading skill that handles wallet context and exchange access, this is more dangerous because any malicious dependency execution may expose credentials or manipulate trading operations.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Static analysis

No suspicious patterns detected.