Back to skill

Security audit

Polymarket Edge Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed Polymarket trading automation skill, but it has review-worthy financial safety gaps around dry-run behavior, scheduled execution, endpoint trust, and an unpinned SDK handling credentials and signed orders.

Review this before installing. Use it only in an isolated environment with narrowly scoped AION credentials, do not provide signed orders unless you intend live trading, avoid custom AION_BASE_URL values unless you fully trust the endpoint, and treat even dry-run or scheduled runs as potentially capable of auto-redeeming positions.

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

Error
Location
SKILL.md:20
Finding

Unpinned Third-Party SDK Controls Credential and Financial Operations

Content
View full analysis
AionMarketClient: """Get or create AionMarketClient singleton.""" global _client if _client is None: api_key = os.getenv("AION_API_KEY") if not api_key: raise ValueError("AION_API_KEY environment variable is required") base_url = os.getenv("AION_BASE_URL", "https://pm-t1.bxingupdate.com/bvapi") _client = AionMarketClient(api_key=api_key, base_url=base_url) return _client ``` ### Technical Analysis The Skill installs `aionmarket-sdk` without an exact version, package hash, or verified source declaration. The imported SDK controls all network and financial operations, including access to the AION API key, account briefing, redemption, market context, and signed-order submission. Because dependency resolution is not reproducible, a compromised future package version or package-registry incident could introduce arbitrary installation-time or runtime code after the Skill itself has been reviewed. The default service endpoint is also not an evident official Polymarket origin, while the project provides no local SDK implementation or integrity mechanism with which to validate the behavior of that dependency. ### Attack Path 1. An attacker compromises the package publisher, registry account, distribution infrastructure, or a newly resolved package release. 2. The user follows the documented `pip install aionmarket-sdk` command without a version or hash constraint. 3. Malicious dependency code execut ...[truncated 816 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
edge_trader.py:94
Finding

Dry-Run Mode Performs Potentially State-Changing Auto-Redemption

Content
View full analysis
None: """Auto-redeem resolved markets per AION best practices.""" try: client = get_client() results = client.auto_redeem() except Exception as exc: print(f"Auto-redeem skipped: {exc}") return if not isinstance(results, list): return redeemed = [r for r in results if r.get("success")] if redeemed: for item in redeemed: market_id = item.get("market_id") tx_hash = item.get("tx_hash") print(f"Redeemed {market_id}: tx={tx_hash}") ``` ```python def run_once(args: argparse.Namespace) -> int: """Execute one trading cycle.""" try: client = get_client() except ValueError as exc: print(f"Client error: {exc}") return 1 # Auto-redeem any claimable positions auto_redeem_if_possible() ``` ### Technical Analysis `run_once()` invokes `auto_redeem_if_possible()` before any check of `args.live`. Consequently, the documented default dry-run path calls `client.auto_redeem()` even though dry-run mode is presented as not submitting live orders. Redemption can be a state-changing financial or blockchain operation. Depending on the SDK and account configuration, it may claim positions, submit transactions, incur fees, invoke signing behavior, or alter account state. Although auto-redemption is disclosed as a feature, it is not protected by the explicit `--live` consent boundary that protects trade submission. Daemon mode magnifies the issue by repeating the redemption attempt every polling cycle. ### Attack Path 1. A user configures the required AION credentials and runs the Skill without `--live`, expecting simulation-only behavior. ...[truncated 757 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
edge_trader.py:499
Finding

Complete Signed Financial Orders Can Be Sent to an Arbitrary Configurable Endpoint

Content
View full analysis
AionMarketClient: """Get or create AionMarketClient singleton.""" global _client if _client is None: api_key = os.getenv("AION_API_KEY") if not api_key: raise ValueError("AION_API_KEY environment variable is required") base_url = os.getenv("AION_BASE_URL", "https://pm-t1.bxingupdate.com/bvapi") _client = AionMarketClient(api_key=api_key, base_url=base_url) return _client ``` ```python signed_order_json = os.getenv("AION_SIGNED_ORDER_JSON", "").strip() if not signed_order_json: decisions.append("SKIP: --live requires AION_SIGNED_ORDER_JSON") print_operator_summary(risk_alerts, decisions, order_updates) return 1 try: order_payload = json.loads(signed_order_json) except json.JSONDecodeError as exc: decisions.append(f"SKIP: Invalid AION_SIGNED_ORDER_JSON: {exc}") print_operator_summary(risk_alerts, decisions, order_updates) return 1 condition_id = get_condition_id(best["market"]) if not condition_id: decisions.append("SKIP: No condition ID for trade payload") print_operator_summary(risk_alerts, decisions, order_updates) return 1 payload = { "venue": VENUE, "marketConditionId": condition_id, "marketQuestion": get_question(best["market"]), "outcome": best["side"], "orderSize": round(amount_usd, 2), "price": round(best["yes_price"], 4), "isLimitOrder": True, "orderType": "GTC", "walletAddress": wallet_address, "reasoning": reasoning, "source": TRADE_SOURCE, "skill_slug": SKILL_SLUG, "order": order_payload, } try: result = client.trade(payload) except Exception as exc: decisions.append(f"SKIP: Trade submission failed: {exc}") print_operat ...[truncated 2351 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill references environment-based secrets and operational inputs such as AION_API_KEY, WALLET_PRIVATE_KEY, WALLET_ADDRESS, and AION_SIGNED_ORDER_JSON, but it does not declare an explicit tool scope or permission boundary. In an agent ecosystem, missing scope declarations can cause the runtime to grant broader environment access than operators expect, increasing the chance that sensitive trading credentials are exposed or misused by the skill or adjacent components.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest explicitly supports live order submission via wallet-linked context and a pre-signed order payload, but it does not clearly warn users that the skill can place real trades involving real funds and potentially irreversible financial loss. In a trading automation skill, omission of a prominent risk disclosure increases the chance of accidental enablement, unsafe credential provisioning, or users misunderstanding dry-run versus live-trading behavior.

Content

No source excerpt is available for this finding.